#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;
}
-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;
}
-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
* "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;
}
-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;
* 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)
}
-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,
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));
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));
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,
{
/* 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;
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) {
&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);
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) {
&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);
/* 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;
/* 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;
}
/* 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;
}