From 5b904b3e421da51bb742f0265ce0b57cb979ae0c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 12 Dec 2015 11:20:05 +0200 Subject: [PATCH] EAP-FAST: Check T-PRF result in MSK/EMSK derivation Pass the error return from sha1_t_prf() to callers. Signed-off-by: Jouni Malinen --- src/eap_common/eap_fast_common.c | 20 ++++++++++++-------- src/eap_common/eap_fast_common.h | 4 ++-- src/eap_peer/eap_fast.c | 5 +++-- src/eap_server/eap_server_fast.c | 10 ++++++++-- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/eap_common/eap_fast_common.c b/src/eap_common/eap_fast_common.c index 151cc7859..e8587fdaa 100644 --- a/src/eap_common/eap_fast_common.c +++ b/src/eap_common/eap_fast_common.c @@ -111,22 +111,24 @@ u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn, } -void eap_fast_derive_eap_msk(const u8 *simck, u8 *msk) +int eap_fast_derive_eap_msk(const u8 *simck, u8 *msk) { /* * RFC 4851, Section 5.4: EAP Master Session Key Generation * MSK = T-PRF(S-IMCK[j], "Session Key Generating Function", 64) */ - sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, - "Session Key Generating Function", (u8 *) "", 0, - msk, EAP_FAST_KEY_LEN); + if (sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, + "Session Key Generating Function", (u8 *) "", 0, + msk, EAP_FAST_KEY_LEN) < 0) + return -1; wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (MSK)", msk, EAP_FAST_KEY_LEN); + return 0; } -void eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk) +int eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk) { /* * RFC 4851, Section 5.4: EAP Master Session Key Genreration @@ -134,11 +136,13 @@ void eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk) * "Extended Session Key Generating Function", 64) */ - sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, - "Extended Session Key Generating Function", (u8 *) "", 0, - emsk, EAP_EMSK_LEN); + if (sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, + "Extended Session Key Generating Function", (u8 *) "", 0, + emsk, EAP_EMSK_LEN) < 0) + return -1; wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (EMSK)", emsk, EAP_EMSK_LEN); + return 0; } diff --git a/src/eap_common/eap_fast_common.h b/src/eap_common/eap_fast_common.h index d59a8450b..6756dd23f 100644 --- a/src/eap_common/eap_fast_common.h +++ b/src/eap_common/eap_fast_common.h @@ -99,8 +99,8 @@ void eap_fast_derive_master_secret(const u8 *pac_key, const u8 *server_random, const u8 *client_random, u8 *master_secret); u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn, const char *label, size_t len); -void eap_fast_derive_eap_msk(const u8 *simck, u8 *msk); -void eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk); +int eap_fast_derive_eap_msk(const u8 *simck, u8 *msk); +int eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk); int eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, int tlv_type, u8 *pos, size_t len); diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c index 6e8b12fd6..8b6b7fd92 100644 --- a/src/eap_peer/eap_fast.c +++ b/src/eap_peer/eap_fast.c @@ -260,8 +260,9 @@ static void eap_fast_deinit(struct eap_sm *sm, void *priv) static int eap_fast_derive_msk(struct eap_fast_data *data) { - eap_fast_derive_eap_msk(data->simck, data->key_data); - eap_fast_derive_eap_emsk(data->simck, data->emsk); + if (eap_fast_derive_eap_msk(data->simck, data->key_data) < 0 || + eap_fast_derive_eap_emsk(data->simck, data->emsk) < 0) + return -1; data->success = 1; return 0; } diff --git a/src/eap_server/eap_server_fast.c b/src/eap_server/eap_server_fast.c index 47210e148..e348eb3e2 100644 --- a/src/eap_server/eap_server_fast.c +++ b/src/eap_server/eap_server_fast.c @@ -1564,7 +1564,10 @@ static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len) if (eapKeyData == NULL) return NULL; - eap_fast_derive_eap_msk(data->simck, eapKeyData); + if (eap_fast_derive_eap_msk(data->simck, eapKeyData) < 0) { + os_free(eapKeyData); + return NULL; + } *len = EAP_FAST_KEY_LEN; return eapKeyData; @@ -1583,7 +1586,10 @@ static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len) if (eapKeyData == NULL) return NULL; - eap_fast_derive_eap_emsk(data->simck, eapKeyData); + if (eap_fast_derive_eap_emsk(data->simck, eapKeyData) < 0) { + os_free(eapKeyData); + return NULL; + } *len = EAP_EMSK_LEN; return eapKeyData;