EAP-AKA': Use HMAC-SHA-256-128 for AT_MAC
This commit is contained in:
parent
f54e2c34bf
commit
806f869918
4 changed files with 117 additions and 10 deletions
|
@ -17,6 +17,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "eap_common/eap_defs.h"
|
#include "eap_common/eap_defs.h"
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
|
#include "sha256.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "aes_wrap.h"
|
#include "aes_wrap.h"
|
||||||
#include "wpabuf.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,
|
int eap_sim_parse_attr(const u8 *start, const u8 *end,
|
||||||
struct eap_sim_attrs *attr, int aka, int encr)
|
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 eap_sim_msg {
|
||||||
struct wpabuf *buf;
|
struct wpabuf *buf;
|
||||||
size_t mac, iv, encr; /* index from 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)
|
if (msg == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
msg->type = type;
|
||||||
msg->buf = wpabuf_alloc(EAP_SIM_INIT_LEN);
|
msg->buf = wpabuf_alloc(EAP_SIM_INIT_LEN);
|
||||||
if (msg->buf == NULL) {
|
if (msg->buf == NULL) {
|
||||||
os_free(msg);
|
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 = wpabuf_mhead(msg->buf);
|
||||||
eap->length = host_to_be16(wpabuf_len(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) {
|
if (k_aut && msg->mac) {
|
||||||
eap_sim_add_mac(k_aut, (u8 *) wpabuf_head(msg->buf),
|
eap_sim_add_mac(k_aut, (u8 *) wpabuf_head(msg->buf),
|
||||||
wpabuf_len(msg->buf),
|
wpabuf_len(msg->buf),
|
||||||
|
|
|
@ -70,6 +70,8 @@
|
||||||
#define EAP_AKA_MIN_RES_LEN 4
|
#define EAP_AKA_MIN_RES_LEN 4
|
||||||
#define EAP_AKA_MAX_RES_LEN 16
|
#define EAP_AKA_MAX_RES_LEN 16
|
||||||
#define EAP_AKA_CHECKCODE_LEN 20
|
#define EAP_AKA_CHECKCODE_LEN 20
|
||||||
|
|
||||||
|
#define EAP_AKA_PRIME_K_AUT_LEN 32
|
||||||
#define EAP_AKA_PRIME_CHECKCODE_LEN 32
|
#define EAP_AKA_PRIME_CHECKCODE_LEN 32
|
||||||
|
|
||||||
struct wpabuf;
|
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);
|
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,
|
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);
|
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) */
|
/* EAP-SIM/AKA Attributes (0..127 non-skippable) */
|
||||||
|
|
|
@ -32,7 +32,7 @@ struct eap_aka_data {
|
||||||
size_t res_len;
|
size_t res_len;
|
||||||
u8 nonce_s[EAP_SIM_NONCE_S_LEN];
|
u8 nonce_s[EAP_SIM_NONCE_S_LEN];
|
||||||
u8 mk[EAP_SIM_MK_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 k_encr[EAP_SIM_K_ENCR_LEN];
|
||||||
u8 msk[EAP_SIM_KEYING_DATA_LEN];
|
u8 msk[EAP_SIM_KEYING_DATA_LEN];
|
||||||
u8 emsk[EAP_EMSK_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,
|
static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
|
||||||
struct eap_aka_data *data,
|
struct eap_aka_data *data,
|
||||||
u8 id,
|
u8 id,
|
||||||
|
@ -693,8 +705,7 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
|
||||||
data->mk);
|
data->mk);
|
||||||
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
|
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
|
||||||
data->emsk);
|
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 "
|
wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
|
||||||
"used invalid AT_MAC");
|
"used invalid AT_MAC");
|
||||||
return eap_aka_client_error(data, id,
|
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;
|
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 "
|
wpa_printf(MSG_WARNING, "EAP-AKA: Notification message "
|
||||||
"used invalid AT_MAC");
|
"used invalid AT_MAC");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -861,8 +871,7 @@ static struct wpabuf * eap_aka_process_reauthentication(
|
||||||
}
|
}
|
||||||
|
|
||||||
data->reauth = 1;
|
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 "
|
wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
|
||||||
"did not have valid AT_MAC");
|
"did not have valid AT_MAC");
|
||||||
return eap_aka_client_error(data, id,
|
return eap_aka_client_error(data, id,
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
struct eap_aka_data {
|
struct eap_aka_data {
|
||||||
u8 mk[EAP_SIM_MK_LEN];
|
u8 mk[EAP_SIM_MK_LEN];
|
||||||
u8 nonce_s[EAP_SIM_NONCE_S_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 k_encr[EAP_SIM_K_ENCR_LEN];
|
||||||
u8 msk[EAP_SIM_KEYING_DATA_LEN];
|
u8 msk[EAP_SIM_KEYING_DATA_LEN];
|
||||||
u8 emsk[EAP_EMSK_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,
|
static void eap_aka_process_challenge(struct eap_sm *sm,
|
||||||
struct eap_aka_data *data,
|
struct eap_aka_data *data,
|
||||||
struct wpabuf *respData,
|
struct wpabuf *respData,
|
||||||
|
@ -680,7 +692,7 @@ static void eap_aka_process_challenge(struct eap_sm *sm,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (attr->mac == NULL ||
|
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 "
|
wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
|
||||||
"did not include valid AT_MAC");
|
"did not include valid AT_MAC");
|
||||||
data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
|
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");
|
wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Reauthentication");
|
||||||
|
|
||||||
if (attr->mac == NULL ||
|
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)) {
|
EAP_SIM_NONCE_S_LEN)) {
|
||||||
wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message "
|
wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message "
|
||||||
"did not include valid AT_MAC");
|
"did not include valid AT_MAC");
|
||||||
|
|
Loading…
Reference in a new issue