added --with-sim-reader option to configure script
authorMartin Willi <martin@strongswan.org>
Wed, 14 Mar 2007 15:39:45 +0000 (15:39 -0000)
committerMartin Willi <martin@strongswan.org>
Wed, 14 Mar 2007 15:39:45 +0000 (15:39 -0000)
some cleanups in eap_sim

configure.in
src/charon/sa/authenticators/eap/eap_sim.c
src/charon/sa/authenticators/eap/eap_sim.h

index 812e4d4..aeaf468 100644 (file)
@@ -80,6 +80,12 @@ AC_ARG_WITH(
     [AC_SUBST(eapdir, "${ipsecdir}/eap")]
 )
 
     [AC_SUBST(eapdir, "${ipsecdir}/eap")]
 )
 
+AC_ARG_WITH(
+    [sim-reader],
+    AS_HELP_STRING([--with-sim-reader=library.so],[library containing the sim_run_alg() function for EAP-SIM]),
+    [AC_DEFINE_UNQUOTED(SIM_READER_LIB, "$withval")]
+)
+
 AC_ARG_ENABLE(
     [http],
     AS_HELP_STRING([--enable-http],[enable OCSP and fetching of Certificates and CRLs over HTTP (default is NO). Requires libcurl.]),
 AC_ARG_ENABLE(
     [http],
     AS_HELP_STRING([--enable-http],[enable OCSP and fetching of Certificates and CRLs over HTTP (default is NO). Requires libcurl.]),
index dbdfe38..da9df6e 100644 (file)
@@ -142,7 +142,7 @@ struct private_eap_sim_t {
 #define RAND_LEN 16
 /** length of the k_encr key */
 #define KENCR_LEN 16
 #define RAND_LEN 16
 /** length of the k_encr key */
 #define KENCR_LEN 16
-/** length of the k_Auth value */
+/** length of the k_auth key */
 #define KAUTH_LEN 16
 /** length of the MSK */
 #define MSK_LEN 64
 #define KAUTH_LEN 16
 /** length of the MSK */
 #define MSK_LEN 64
@@ -257,6 +257,14 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier
                        }
                        case AT_IDENTITY:
                        {
                        }
                        case AT_IDENTITY:
                        {
+                               /* align up to four byte */
+                               if (data.len % 4)
+                               {
+                                       chunk_t tmp = chunk_alloca((data.len/4)*4 + 4);
+                                       memset(tmp.ptr, 0, tmp.len);
+                                       memcpy(tmp.ptr, data.ptr, data.len);
+                                       data = tmp;
+                               }
                                *pos.ptr = data.len/4 + 1;
                                pos = chunk_skip(pos, 1);
                                /* actual length in bytes */
                                *pos.ptr = data.len/4 + 1;
                                pos = chunk_skip(pos, 1);
                                /* actual length in bytes */
@@ -315,10 +323,9 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier
                signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
                signer->set_key(signer, this->k_auth);
                mac_data = chunk_cata("cc", message, mac_data);
                signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
                signer->set_key(signer, this->k_auth);
                mac_data = chunk_cata("cc", message, mac_data);
-               DBG3(DBG_IKE, "AT_MAC signature of %B", &mac_data);
-               DBG3(DBG_IKE, "using k_auth %B", &this->k_auth);
                signer->get_signature(signer, mac_data, mac_pos);
                signer->get_signature(signer, mac_data, mac_pos);
-               DBG3(DBG_IKE, "is %b", mac_pos, MAC_LEN);
+               DBG3(DBG_IKE, "AT_MAC signature of %B\n is %b",
+                        &mac_data, mac_pos, MAC_LEN);
                signer->destroy(signer);
        }
        
                signer->destroy(signer);
        }
        
@@ -350,7 +357,6 @@ static status_t process_start(private_eap_sim_t *this, eap_payload_t *in,
                        {
                                /* check if server supports our implementation */
                                bool found = FALSE;
                        {
                                /* check if server supports our implementation */
                                bool found = FALSE;
-                               
                                if (data.len > 2)
                                {
                                        /* read actual length first */
                                if (data.len > 2)
                                {
                                        /* read actual length first */
@@ -409,7 +415,7 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
 {
        chunk_t message, data, tmp, kcs, kc, sreses, sres, mk;
        sim_attribute_t attribute;
 {
        chunk_t message, data, tmp, kcs, kc, sreses, sres, mk;
        sim_attribute_t attribute;
-       u_int8_t identifier;
+       u_int8_t identifier, i;
        chunk_t mac = chunk_empty, rands = chunk_empty;
        signer_t *signer;
        hasher_t *hasher;
        chunk_t mac = chunk_empty, rands = chunk_empty;
        signer_t *signer;
        hasher_t *hasher;
@@ -431,7 +437,8 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
                        case AT_MAC:
                        {
                                /* backup MAC, zero it inline for later verification */
                        case AT_MAC:
                        {
                                /* backup MAC, zero it inline for later verification */
-                               mac = chunk_clonea(chunk_skip(data, 2));
+                               data = chunk_skip(data, 2);
+                               mac = chunk_clonea(data);
                                memset(data.ptr, 0, data.len);
                                break;
                        }
                                memset(data.ptr, 0, data.len);
                                break;
                        }
@@ -443,7 +450,7 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
        }
        
        /* excepting two or three RAND, each 16 bytes. We require two valid
        }
        
        /* excepting two or three RAND, each 16 bytes. We require two valid
-        * and different (!) RANDs */
+        * and different RANDs */
        if ((rands.len != 2 * RAND_LEN && rands.len != 3 * RAND_LEN) ||
                memeq(rands.ptr, rands.ptr + RAND_LEN, RAND_LEN))
        {
        if ((rands.len != 2 * RAND_LEN && rands.len != 3 * RAND_LEN) ||
                memeq(rands.ptr, rands.ptr + RAND_LEN, RAND_LEN))
        {
@@ -468,8 +475,8 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
        while (rands.len > 0)
        {
                int kc_len = kc.len, sres_len = sres.len;
        while (rands.len > 0)
        {
                int kc_len = kc.len, sres_len = sres.len;
-       
-               if (this->alg(rands.ptr, RAND_LEN, kc.ptr, &kc_len, sres.ptr, &sres_len))
+               
+               if (this->alg(rands.ptr, RAND_LEN, sres.ptr, &sres_len, kc.ptr, &kc_len))
                {
                        DBG1(DBG_IKE, "unable to get triplets from SIM");
                        *out = build_payload(this, identifier, SIM_CLIENT_ERROR,
                {
                        DBG1(DBG_IKE, "unable to get triplets from SIM");
                        *out = build_payload(this, identifier, SIM_CLIENT_ERROR,
@@ -477,18 +484,21 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
                                                                 AT_END);
                        return NEED_MORE;
                }
                                                                 AT_END);
                        return NEED_MORE;
                }
+               DBG3(DBG_IKE, "got triplet for RAND %b\n  Kc %b\n  SRES %b",
+                        rands.ptr, RAND_LEN, sres.ptr, sres_len, kc.ptr, kc_len);
                kc = chunk_skip(kc, kc_len);
                sres = chunk_skip(sres, sres_len);
                rands = chunk_skip(rands, RAND_LEN);
        }
        
                kc = chunk_skip(kc, kc_len);
                sres = chunk_skip(sres, sres_len);
                rands = chunk_skip(rands, RAND_LEN);
        }
        
-       /* build MK */
+       /* build MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version) */
        tmp = chunk_cata("ccccc", this->peer->get_encoding(this->peer), kcs,
                                         this->nonce, this->version_list, this->version);
        hasher = hasher_create(HASH_SHA1);
        mk = chunk_alloca(hasher->get_hash_size(hasher));
        hasher->get_hash(hasher, tmp, mk.ptr);
        hasher->destroy(hasher);
        tmp = chunk_cata("ccccc", this->peer->get_encoding(this->peer), kcs,
                                         this->nonce, this->version_list, this->version);
        hasher = hasher_create(HASH_SHA1);
        mk = chunk_alloca(hasher->get_hash_size(hasher));
        hasher->get_hash(hasher, tmp, mk.ptr);
        hasher->destroy(hasher);
+       DBG3(DBG_IKE, "MK = SHA1(%B\n) = %B", &tmp, &mk);
        
        /* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf()
         * FIPS PRF has 320 bit block size, we need 160 byte for keys
        
        /* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf()
         * FIPS PRF has 320 bit block size, we need 160 byte for keys
@@ -496,10 +506,10 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
        prf = prf_create(PRF_FIPS_SHA1_160);
        prf->set_key(prf, mk);
        tmp = chunk_alloca(prf->get_block_size(prf) * 4);
        prf = prf_create(PRF_FIPS_SHA1_160);
        prf->set_key(prf, mk);
        tmp = chunk_alloca(prf->get_block_size(prf) * 4);
-       prf->get_bytes(prf, chunk_empty, tmp.ptr);
-       prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 1);
-       prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 2);
-       prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 3);
+       for (i = 0; i < 4; i++)
+       {
+               prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * i);
+       }
        prf->destroy(prf);
        chunk_free(&this->k_encr);
        chunk_free(&this->k_auth);
        prf->destroy(prf);
        chunk_free(&this->k_encr);
        chunk_free(&this->k_auth);
@@ -507,23 +517,17 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
        chunk_free(&this->emsk);
        chunk_split(tmp, "aaaa", KENCR_LEN, &this->k_encr, KAUTH_LEN, &this->k_auth,
                                MSK_LEN, &this->msk, EMSK_LEN, &this->emsk);
        chunk_free(&this->emsk);
        chunk_split(tmp, "aaaa", KENCR_LEN, &this->k_encr, KAUTH_LEN, &this->k_auth,
                                MSK_LEN, &this->msk, EMSK_LEN, &this->emsk);
-       DBG3(DBG_IKE, "MK %B", &mk);
-       DBG3(DBG_IKE, "K_encr %B", &this->k_encr);
-       DBG3(DBG_IKE, "K_auth %B", &this->k_auth);
-       DBG3(DBG_IKE, "MSK %B", &this->msk);
-       DBG3(DBG_IKE, "EMSK %B", &this->emsk);
+       DBG3(DBG_IKE, "K_encr %B\nK_auth %B\nMSK %B\nEMSK %B",
+                &this->k_encr, &this->k_auth, &this->msk, &this->emsk);
        
        /* verify AT_MAC attribute, signature is over "EAP packet | NONCE_MT"  */
        signer = signer_create(AUTH_HMAC_SHA1_128);
        signer->set_key(signer, this->k_auth);
        
        /* verify AT_MAC attribute, signature is over "EAP packet | NONCE_MT"  */
        signer = signer_create(AUTH_HMAC_SHA1_128);
        signer->set_key(signer, this->k_auth);
-       tmp = chunk_cata("cc", message, this->nonce);
-       DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &tmp);
-       DBG3(DBG_IKE, "using k_auth %B", &this->k_auth);
+       tmp = chunk_cata("cc", in->get_data(in), this->nonce);
        if (!signer->verify_signature(signer, tmp, mac))
        {
        if (!signer->verify_signature(signer, tmp, mac))
        {
-               DBG1(DBG_IKE, "MAC in AT_MAC attribute verification failed");
+               DBG1(DBG_IKE, "AT_MAC verification failed");
                signer->destroy(signer);
                signer->destroy(signer);
-               chunk_free(&this->msk);
                *out = build_payload(this, identifier, SIM_CLIENT_ERROR,
                                                         AT_CLIENT_ERROR_CODE, client_error_general,
                                                         AT_END);
                *out = build_payload(this, identifier, SIM_CLIENT_ERROR,
                                                         AT_CLIENT_ERROR_CODE, client_error_general,
                                                         AT_END);
index a29afb4..4efcbbc 100644 (file)
@@ -95,7 +95,7 @@ typedef int (*sim_algo_t)(const unsigned char *rand, int rand_length,
 
 #ifndef SIM_READER_LIB
 /** the library containing the cardreader with the SIM function */
 
 #ifndef SIM_READER_LIB
 /** the library containing the cardreader with the SIM function */
-#define SIM_READER_LIB "/root/strongswan-shared/trunk/src/charon/sa/authenticators/eap/sim_reader/sim_api.so"
+#define SIM_READER_LIB "(unspecified)"
 #endif /* SIM_READER_LIB */
 
 #ifndef SIM_READER_ALG
 #endif /* SIM_READER_LIB */
 
 #ifndef SIM_READER_ALG
@@ -104,7 +104,6 @@ typedef int (*sim_algo_t)(const unsigned char *rand, int rand_length,
 #endif /* SIM_READER_ALG */
 
 
 #endif /* SIM_READER_ALG */
 
 
-
 /**
  * @brief Implementation of the eap_method_t interface using EAP-SIM.
  *
 /**
  * @brief Implementation of the eap_method_t interface using EAP-SIM.
  *