]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-TEAP: Fix TLS-PRF for TLS ciphersuites that use SHA384
authorJouni Malinen <j@w1.fi>
Fri, 16 Aug 2019 18:16:44 +0000 (21:16 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 16 Aug 2019 18:16:44 +0000 (21:16 +0300)
These need to be using the HMAC-based TLS-PRF with SHA384 instead of
SHA256 as the hash algorithm.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/eap_common/eap_teap_common.c
src/eap_common/eap_teap_common.h
src/eap_peer/eap_teap.c
src/eap_server/eap_server_teap.c

index fbca1b5e41c0e4a050115ed6eb8595fc80a55977..ea90f589daa4100da088cbe0cc32d9509342937c 100644 (file)
@@ -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));
index 585ec7c2f69a189a7078c980578ed703e48dba64..32443dc36e261978de3723ed34511f7a524c041f 100644 (file)
@@ -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,
index 07ecbd447b1e8b14e38a6d0a72f6113f4835bfc6..7ab919b165734b0a75770faf7be9bd10ed32fd65 100644 (file)
@@ -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);
index d8e5414d456369fad730e570595329be8c927f82..dd8ffd3dbba746938ba5b127ec96034629e6d996 100644 (file)
@@ -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;
        }