diff --git a/src/eap_common/eap_teap_common.c b/src/eap_common/eap_teap_common.c index fbca1b5e4..ea90f589d 100644 --- a/src/eap_common/eap_teap_common.c +++ b/src/eap_common/eap_teap_common.c @@ -17,6 +17,9 @@ #include "eap_teap_common.h" +static int tls_cipher_suite_mac_sha384(u16 cs); + + void eap_teap_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len) { struct teap_tlv_hdr hdr; @@ -67,24 +70,27 @@ struct wpabuf * eap_teap_tlv_eap_payload(struct wpabuf *buf) } -static int eap_teap_tls_prf(const u8 *secret, size_t secret_len, +static int eap_teap_tls_prf(u16 tls_cs, const u8 *secret, size_t secret_len, const char *label, const u8 *seed, size_t seed_len, u8 *out, size_t outlen) { /* TODO: TLS-PRF for TLSv1.3 */ + if (tls_cipher_suite_mac_sha384(tls_cs)) + return tls_prf_sha384(secret, secret_len, label, seed, seed_len, + out, outlen); return tls_prf_sha256(secret, secret_len, label, seed, seed_len, out, outlen); } -int eap_teap_derive_eap_msk(const u8 *simck, u8 *msk) +int eap_teap_derive_eap_msk(u16 tls_cs, const u8 *simck, u8 *msk) { /* * RFC 7170, Section 5.4: EAP Master Session Key Generation * MSK = TLS-PRF(S-IMCK[j], "Session Key Generating Function", 64) */ - if (eap_teap_tls_prf(simck, EAP_TEAP_SIMCK_LEN, + if (eap_teap_tls_prf(tls_cs, simck, EAP_TEAP_SIMCK_LEN, "Session Key Generating Function", (u8 *) "", 0, msk, EAP_TEAP_KEY_LEN) < 0) return -1; @@ -94,7 +100,7 @@ int eap_teap_derive_eap_msk(const u8 *simck, u8 *msk) } -int eap_teap_derive_eap_emsk(const u8 *simck, u8 *emsk) +int eap_teap_derive_eap_emsk(u16 tls_cs, const u8 *simck, u8 *emsk) { /* * RFC 7170, Section 5.4: EAP Master Session Key Generation @@ -102,7 +108,7 @@ int eap_teap_derive_eap_emsk(const u8 *simck, u8 *emsk) * "Extended Session Key Generating Function", 64) */ - if (eap_teap_tls_prf(simck, EAP_TEAP_SIMCK_LEN, + if (eap_teap_tls_prf(tls_cs, simck, EAP_TEAP_SIMCK_LEN, "Extended Session Key Generating Function", (u8 *) "", 0, emsk, EAP_EMSK_LEN) < 0) return -1; @@ -112,7 +118,7 @@ int eap_teap_derive_eap_emsk(const u8 *simck, u8 *emsk) } -int eap_teap_derive_cmk_basic_pw_auth(const u8 *s_imck_msk, u8 *cmk) +int eap_teap_derive_cmk_basic_pw_auth(u16 tls_cs, const u8 *s_imck_msk, u8 *cmk) { u8 imsk[32], imck[EAP_TEAP_IMCK_LEN]; int res; @@ -123,7 +129,7 @@ int eap_teap_derive_cmk_basic_pw_auth(const u8 *s_imck_msk, u8 *cmk) * published. For now, derive CMK[0] based on S-IMCK[0] and * IMSK of 32 octets of zeros. */ os_memset(imsk, 0, 32); - res = eap_teap_tls_prf(s_imck_msk, EAP_TEAP_SIMCK_LEN, + res = eap_teap_tls_prf(tls_cs, s_imck_msk, EAP_TEAP_SIMCK_LEN, "Inner Methods Compound Keys", imsk, 32, imck, sizeof(imck)); if (res < 0) @@ -136,7 +142,8 @@ int eap_teap_derive_cmk_basic_pw_auth(const u8 *s_imck_msk, u8 *cmk) } -int eap_teap_derive_imck(const u8 *prev_s_imck_msk, const u8 *prev_s_imck_emsk, +int eap_teap_derive_imck(u16 tls_cs, + const u8 *prev_s_imck_msk, const u8 *prev_s_imck_emsk, const u8 *msk, size_t msk_len, const u8 *emsk, size_t emsk_len, u8 *s_imck_msk, u8 *cmk_msk, @@ -170,14 +177,16 @@ int eap_teap_derive_imck(const u8 *prev_s_imck_msk, const u8 *prev_s_imck_emsk, context[0] = 0; context[1] = 0; context[2] = 64; - if (eap_teap_tls_prf(emsk, emsk_len, "TEAPbindkey@ietf.org", + if (eap_teap_tls_prf(tls_cs, emsk, emsk_len, + "TEAPbindkey@ietf.org", context, sizeof(context), imsk, 64) < 0) return -1; wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: IMSK from EMSK", imsk, 32); - res = eap_teap_tls_prf(prev_s_imck_emsk, EAP_TEAP_SIMCK_LEN, + res = eap_teap_tls_prf(tls_cs, + prev_s_imck_emsk, EAP_TEAP_SIMCK_LEN, "Inner Methods Compound Keys", imsk, 32, imck, EAP_TEAP_IMCK_LEN); forced_memzero(imsk, sizeof(imsk)); @@ -207,7 +216,7 @@ int eap_teap_derive_imck(const u8 *prev_s_imck_msk, const u8 *prev_s_imck_emsk, wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Zero IMSK", imsk, 32); } - res = eap_teap_tls_prf(prev_s_imck_msk, EAP_TEAP_SIMCK_LEN, + res = eap_teap_tls_prf(tls_cs, prev_s_imck_msk, EAP_TEAP_SIMCK_LEN, "Inner Methods Compound Keys", imsk, 32, imck, EAP_TEAP_IMCK_LEN); forced_memzero(imsk, sizeof(imsk)); diff --git a/src/eap_common/eap_teap_common.h b/src/eap_common/eap_teap_common.h index 585ec7c2f..32443dc36 100644 --- a/src/eap_common/eap_teap_common.h +++ b/src/eap_common/eap_teap_common.h @@ -195,10 +195,12 @@ void eap_teap_put_tlv(struct wpabuf *buf, u16 type, const void *data, u16 len); void eap_teap_put_tlv_buf(struct wpabuf *buf, u16 type, const struct wpabuf *data); struct wpabuf * eap_teap_tlv_eap_payload(struct wpabuf *buf); -int eap_teap_derive_eap_msk(const u8 *simck, u8 *msk); -int eap_teap_derive_eap_emsk(const u8 *simck, u8 *emsk); -int eap_teap_derive_cmk_basic_pw_auth(const u8 *s_imck_msk, u8 *cmk); -int eap_teap_derive_imck(const u8 *prev_s_imck_msk, const u8 *prev_s_imck_emsk, +int eap_teap_derive_eap_msk(u16 tls_cs, const u8 *simck, u8 *msk); +int eap_teap_derive_eap_emsk(u16 tls_cs, const u8 *simck, u8 *emsk); +int eap_teap_derive_cmk_basic_pw_auth(u16 tls_cs, const u8 *s_imck_msk, + u8 *cmk); +int eap_teap_derive_imck(u16 tls_cs, + const u8 *prev_s_imck_msk, const u8 *prev_s_imck_emsk, const u8 *msk, size_t msk_len, const u8 *emsk, size_t emsk_len, u8 *s_imck_msk, u8 *cmk_msk, diff --git a/src/eap_peer/eap_teap.c b/src/eap_peer/eap_teap.c index 07ecbd447..7ab919b16 100644 --- a/src/eap_peer/eap_teap.c +++ b/src/eap_peer/eap_teap.c @@ -277,8 +277,10 @@ static int eap_teap_derive_msk(struct eap_teap_data *data) { /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j] * is used in this derivation */ - if (eap_teap_derive_eap_msk(data->simck_msk, data->key_data) < 0 || - eap_teap_derive_eap_emsk(data->simck_msk, data->emsk) < 0) + if (eap_teap_derive_eap_msk(data->tls_cs, data->simck_msk, + data->key_data) < 0 || + eap_teap_derive_eap_emsk(data->tls_cs, data->simck_msk, + data->emsk) < 0) return -1; data->success = 1; return 0; @@ -680,7 +682,8 @@ static int eap_teap_get_cmk(struct eap_sm *sm, struct eap_teap_data *data, data->simck_idx + 1); if (!data->phase2_method) - return eap_teap_derive_cmk_basic_pw_auth(data->simck_msk, + return eap_teap_derive_cmk_basic_pw_auth(data->tls_cs, + data->simck_msk, cmk_msk); if (!data->phase2_method || !data->phase2_priv) { @@ -712,7 +715,8 @@ static int eap_teap_get_cmk(struct eap_sm *sm, struct eap_teap_data *data, &emsk_len); } - res = eap_teap_derive_imck(data->simck_msk, data->simck_emsk, + res = eap_teap_derive_imck(data->tls_cs, + data->simck_msk, data->simck_emsk, msk, msk_len, emsk, emsk_len, data->simck_msk, cmk_msk, data->simck_emsk, cmk_emsk); diff --git a/src/eap_server/eap_server_teap.c b/src/eap_server/eap_server_teap.c index d8e5414d4..dd8ffd3db 100644 --- a/src/eap_server/eap_server_teap.c +++ b/src/eap_server/eap_server_teap.c @@ -309,7 +309,8 @@ static int eap_teap_update_icmk(struct eap_sm *sm, struct eap_teap_data *data) data->simck_idx + 1); if (sm->eap_teap_auth == 1) - return eap_teap_derive_cmk_basic_pw_auth(data->simck_msk, + return eap_teap_derive_cmk_basic_pw_auth(data->tls_cs, + data->simck_msk, data->cmk_msk); if (!data->phase2_method || !data->phase2_priv) { @@ -332,7 +333,8 @@ static int eap_teap_update_icmk(struct eap_sm *sm, struct eap_teap_data *data) &emsk_len); } - res = eap_teap_derive_imck(data->simck_msk, data->simck_emsk, + res = eap_teap_derive_imck(data->tls_cs, + data->simck_msk, data->simck_emsk, msk, msk_len, emsk, emsk_len, data->simck_msk, data->cmk_msk, data->simck_emsk, data->cmk_emsk); @@ -1643,7 +1645,8 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm, /* FIX: Need to derive CMK here. However, how is that * supposed to be done? RFC 7170 does not tell that for * the no-inner-auth case. */ - eap_teap_derive_cmk_basic_pw_auth(data->simck_msk, + eap_teap_derive_cmk_basic_pw_auth(data->tls_cs, + data->simck_msk, data->cmk_msk); eap_teap_state(data, CRYPTO_BINDING); return 1; @@ -1853,7 +1856,8 @@ static u8 * eap_teap_getKey(struct eap_sm *sm, void *priv, size_t *len) /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j] * is used in this derivation */ - if (eap_teap_derive_eap_msk(data->simck_msk, eapKeyData) < 0) { + if (eap_teap_derive_eap_msk(data->tls_cs, data->simck_msk, + eapKeyData) < 0) { os_free(eapKeyData); return NULL; } @@ -1877,7 +1881,8 @@ static u8 * eap_teap_get_emsk(struct eap_sm *sm, void *priv, size_t *len) /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j] * is used in this derivation */ - if (eap_teap_derive_eap_emsk(data->simck_msk, eapKeyData) < 0) { + if (eap_teap_derive_eap_emsk(data->tls_cs, data->simck_msk, + eapKeyData) < 0) { os_free(eapKeyData); return NULL; }