diff options
author | Jouni Malinen <j@w1.fi> | 2008-12-02 21:29:26 +0200 |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2008-12-02 21:29:26 +0200 |
commit | 806f869918f8220adc48aa53f8081bd1018cc2e7 (patch) | |
tree | 0253436eb82d63ee256f0121233b762ea5d961db /src | |
parent | f54e2c34bf822dbc30074c01196451224f5fd2cb (diff) | |
download | external_wpa_supplicant_8_ti-806f869918f8220adc48aa53f8081bd1018cc2e7.zip external_wpa_supplicant_8_ti-806f869918f8220adc48aa53f8081bd1018cc2e7.tar.gz external_wpa_supplicant_8_ti-806f869918f8220adc48aa53f8081bd1018cc2e7.tar.bz2 |
EAP-AKA': Use HMAC-SHA-256-128 for AT_MAC
Diffstat (limited to 'src')
-rw-r--r-- | src/eap_common/eap_sim_common.c | 79 | ||||
-rw-r--r-- | src/eap_common/eap_sim_common.h | 7 | ||||
-rw-r--r-- | src/eap_peer/eap_aka_prime.c | 23 | ||||
-rw-r--r-- | src/eap_server/eap_aka_prime.c | 18 |
4 files changed, 117 insertions, 10 deletions
diff --git a/src/eap_common/eap_sim_common.c b/src/eap_common/eap_sim_common.c index 318702a..7b7918c 100644 --- a/src/eap_common/eap_sim_common.c +++ b/src/eap_common/eap_sim_common.c @@ -17,6 +17,7 @@ #include "common.h" #include "eap_common/eap_defs.h" #include "sha1.h" +#include "sha256.h" #include "crypto.h" #include "aes_wrap.h" #include "wpabuf.h" @@ -232,6 +233,74 @@ void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac, } +#ifdef EAP_AKA_PRIME +int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req, + const u8 *mac, const u8 *extra, size_t extra_len) +{ + unsigned char hmac[SHA256_MAC_LEN]; + const u8 *addr[2]; + size_t len[2]; + u8 *tmp; + + if (mac == NULL || wpabuf_len(req) < EAP_SIM_MAC_LEN || + mac < wpabuf_head_u8(req) || + mac > wpabuf_head_u8(req) + wpabuf_len(req) - EAP_SIM_MAC_LEN) + return -1; + + tmp = os_malloc(wpabuf_len(req)); + if (tmp == NULL) + return -1; + + addr[0] = tmp; + len[0] = wpabuf_len(req); + addr[1] = extra; + len[1] = extra_len; + + /* HMAC-SHA-256-128 */ + os_memcpy(tmp, wpabuf_head(req), wpabuf_len(req)); + os_memset(tmp + (mac - wpabuf_head_u8(req)), 0, EAP_SIM_MAC_LEN); + wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC - msg", + tmp, wpabuf_len(req)); + wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC - extra data", + extra, extra_len); + wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA': Verify MAC - K_aut", + k_aut, EAP_AKA_PRIME_K_AUT_LEN); + hmac_sha256_vector(k_aut, EAP_AKA_PRIME_K_AUT_LEN, 2, addr, len, hmac); + wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC: MAC", + hmac, EAP_SIM_MAC_LEN); + os_free(tmp); + + return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1; +} + + +void eap_sim_add_mac_sha256(const u8 *k_aut, const u8 *msg, size_t msg_len, + u8 *mac, const u8 *extra, size_t extra_len) +{ + unsigned char hmac[SHA256_MAC_LEN]; + const u8 *addr[2]; + size_t len[2]; + + addr[0] = msg; + len[0] = msg_len; + addr[1] = extra; + len[1] = extra_len; + + /* HMAC-SHA-256-128 */ + os_memset(mac, 0, EAP_SIM_MAC_LEN); + wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC - msg", msg, msg_len); + wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC - extra data", + extra, extra_len); + wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA': Add MAC - K_aut", + k_aut, EAP_AKA_PRIME_K_AUT_LEN); + hmac_sha256_vector(k_aut, EAP_AKA_PRIME_K_AUT_LEN, 2, addr, len, hmac); + os_memcpy(mac, hmac, EAP_SIM_MAC_LEN); + wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC: MAC", + mac, EAP_SIM_MAC_LEN); +} +#endif /* EAP_AKA_PRIME */ + + int eap_sim_parse_attr(const u8 *start, const u8 *end, struct eap_sim_attrs *attr, int aka, int encr) { @@ -642,6 +711,7 @@ u8 * eap_sim_parse_encr(const u8 *k_encr, const u8 *encr_data, struct eap_sim_msg { struct wpabuf *buf; size_t mac, iv, encr; /* index from buf */ + int type; }; @@ -655,6 +725,7 @@ struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype) if (msg == NULL) return NULL; + msg->type = type; msg->buf = wpabuf_alloc(EAP_SIM_INIT_LEN); if (msg->buf == NULL) { os_free(msg); @@ -686,6 +757,14 @@ struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, const u8 *k_aut, eap = wpabuf_mhead(msg->buf); eap->length = host_to_be16(wpabuf_len(msg->buf)); +#ifdef EAP_AKA_PRIME + if (k_aut && msg->mac && msg->type == EAP_TYPE_AKA_PRIME) { + eap_sim_add_mac_sha256(k_aut, (u8 *) wpabuf_head(msg->buf), + wpabuf_len(msg->buf), + (u8 *) wpabuf_mhead(msg->buf) + + msg->mac, extra, extra_len); + } else +#endif /* EAP_AKA_PRIME */ if (k_aut && msg->mac) { eap_sim_add_mac(k_aut, (u8 *) wpabuf_head(msg->buf), wpabuf_len(msg->buf), diff --git a/src/eap_common/eap_sim_common.h b/src/eap_common/eap_sim_common.h index d64ef13..7d2093c 100644 --- a/src/eap_common/eap_sim_common.h +++ b/src/eap_common/eap_sim_common.h @@ -70,6 +70,8 @@ #define EAP_AKA_MIN_RES_LEN 4 #define EAP_AKA_MAX_RES_LEN 16 #define EAP_AKA_CHECKCODE_LEN 20 + +#define EAP_AKA_PRIME_K_AUT_LEN 32 #define EAP_AKA_PRIME_CHECKCODE_LEN 32 struct wpabuf; @@ -90,6 +92,11 @@ int eap_sim_verify_mac(const u8 *k_aut, const struct wpabuf *req, const u8 *mac, const u8 *extra, size_t extra_len); void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac, const u8 *extra, size_t extra_len); +int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req, + const u8 *mac, const u8 *extra, + size_t extra_len); +void eap_sim_add_mac_sha256(const u8 *k_aut, const u8 *msg, size_t msg_len, + u8 *mac, const u8 *extra, size_t extra_len); /* EAP-SIM/AKA Attributes (0..127 non-skippable) */ diff --git a/src/eap_peer/eap_aka_prime.c b/src/eap_peer/eap_aka_prime.c index c2151b1..367549b 100644 --- a/src/eap_peer/eap_aka_prime.c +++ b/src/eap_peer/eap_aka_prime.c @@ -32,7 +32,7 @@ struct eap_aka_data { size_t res_len; u8 nonce_s[EAP_SIM_NONCE_S_LEN]; u8 mk[EAP_SIM_MK_LEN]; - u8 k_aut[EAP_SIM_K_AUT_LEN]; + u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN]; u8 k_encr[EAP_SIM_K_ENCR_LEN]; u8 msk[EAP_SIM_KEYING_DATA_LEN]; u8 emsk[EAP_EMSK_LEN]; @@ -630,6 +630,18 @@ static struct wpabuf * eap_aka_process_identity(struct eap_sm *sm, } +static int eap_aka_verify_mac(struct eap_aka_data *data, + const struct wpabuf *req, + const u8 *mac, const u8 *extra, + size_t extra_len) +{ + if (data->eap_method == EAP_TYPE_AKA_PRIME) + return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra, + extra_len); + return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len); +} + + static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm, struct eap_aka_data *data, u8 id, @@ -693,8 +705,7 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm, data->mk); eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk, data->emsk); - if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0)) - { + if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " "used invalid AT_MAC"); return eap_aka_client_error(data, id, @@ -782,8 +793,7 @@ static int eap_aka_process_notification_auth(struct eap_aka_data *data, return -1; } - if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0)) - { + if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { wpa_printf(MSG_WARNING, "EAP-AKA: Notification message " "used invalid AT_MAC"); return -1; @@ -861,8 +871,7 @@ static struct wpabuf * eap_aka_process_reauthentication( } data->reauth = 1; - if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0)) - { + if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication " "did not have valid AT_MAC"); return eap_aka_client_error(data, id, diff --git a/src/eap_server/eap_aka_prime.c b/src/eap_server/eap_aka_prime.c index c4d7359..a065656 100644 --- a/src/eap_server/eap_aka_prime.c +++ b/src/eap_server/eap_aka_prime.c @@ -26,7 +26,7 @@ struct eap_aka_data { u8 mk[EAP_SIM_MK_LEN]; u8 nonce_s[EAP_SIM_NONCE_S_LEN]; - u8 k_aut[EAP_SIM_K_AUT_LEN]; + u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN]; u8 k_encr[EAP_SIM_K_ENCR_LEN]; u8 msk[EAP_SIM_KEYING_DATA_LEN]; u8 emsk[EAP_EMSK_LEN]; @@ -660,6 +660,18 @@ static void eap_aka_process_identity(struct eap_sm *sm, } +static int eap_aka_verify_mac(struct eap_aka_data *data, + const struct wpabuf *req, + const u8 *mac, const u8 *extra, + size_t extra_len) +{ + if (data->eap_method == EAP_TYPE_AKA_PRIME) + return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra, + extra_len); + return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len); +} + + static void eap_aka_process_challenge(struct eap_sm *sm, struct eap_aka_data *data, struct wpabuf *respData, @@ -680,7 +692,7 @@ static void eap_aka_process_challenge(struct eap_sm *sm, return; } if (attr->mac == NULL || - eap_sim_verify_mac(data->k_aut, respData, attr->mac, NULL, 0)) { + eap_aka_verify_mac(data, respData, attr->mac, NULL, 0)) { wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " "did not include valid AT_MAC"); data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; @@ -785,7 +797,7 @@ static void eap_aka_process_reauth(struct eap_sm *sm, wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Reauthentication"); if (attr->mac == NULL || - eap_sim_verify_mac(data->k_aut, respData, attr->mac, data->nonce_s, + eap_aka_verify_mac(data, respData, attr->mac, data->nonce_s, EAP_SIM_NONCE_S_LEN)) { wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message " "did not include valid AT_MAC"); |