5cc2f7b17df647c76ad63d049c902b62ecb0a824
[librecmc/librecmc.git] /
1 From a6ea665300919d6a3af22b1f4237203647fda93a Mon Sep 17 00:00:00 2001
2 From: Jouni Malinen <j@w1.fi>
3 Date: Tue, 17 Oct 2017 00:01:11 +0300
4 Subject: [PATCH] Additional consistentcy checks for PTK component lengths
5
6 Verify that TK, KCK, and KEK lengths are set to consistent values within
7 struct wpa_ptk before using them in supplicant. This is an additional
8 layer of protection against unexpected states.
9
10 Signed-off-by: Jouni Malinen <j@w1.fi>
11 ---
12  src/common/wpa_common.c |  6 ++++++
13  src/rsn_supp/wpa.c      | 26 ++++++++++++++++++++------
14  2 files changed, 26 insertions(+), 6 deletions(-)
15
16 --- a/src/common/wpa_common.c
17 +++ b/src/common/wpa_common.c
18 @@ -100,6 +100,12 @@ int wpa_eapol_key_mic(const u8 *key, siz
19  {
20         u8 hash[SHA512_MAC_LEN];
21  
22 +       if (key_len == 0) {
23 +               wpa_printf(MSG_DEBUG,
24 +                          "WPA: KCK not set - cannot calculate MIC");
25 +               return -1;
26 +       }
27 +
28         switch (ver) {
29  #ifndef CONFIG_FIPS
30         case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
31 --- a/src/rsn_supp/wpa.c
32 +++ b/src/rsn_supp/wpa.c
33 @@ -725,6 +725,11 @@ static int wpa_supplicant_install_ptk(st
34  
35         alg = wpa_cipher_to_alg(sm->pairwise_cipher);
36         keylen = wpa_cipher_key_len(sm->pairwise_cipher);
37 +       if (keylen <= 0 || (unsigned int) keylen != sm->ptk.tk_len) {
38 +               wpa_printf(MSG_DEBUG, "WPA: TK length mismatch: %d != %lu",
39 +                          keylen, (long unsigned int) sm->ptk.tk_len);
40 +               return -1;
41 +       }
42         rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
43  
44         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
45 @@ -745,6 +750,7 @@ static int wpa_supplicant_install_ptk(st
46  
47         /* TK is not needed anymore in supplicant */
48         os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
49 +       sm->ptk.tk_len = 0;
50         sm->ptk.installed = 1;
51  
52         if (sm->wpa_ptk_rekey) {
53 @@ -1717,9 +1723,10 @@ static int wpa_supplicant_verify_eapol_k
54         os_memcpy(mic, key + 1, mic_len);
55         if (sm->tptk_set) {
56                 os_memset(key + 1, 0, mic_len);
57 -               wpa_eapol_key_mic(sm->tptk.kck, sm->tptk.kck_len, sm->key_mgmt,
58 -                                 ver, buf, len, (u8 *) (key + 1));
59 -               if (os_memcmp_const(mic, key + 1, mic_len) != 0) {
60 +               if (wpa_eapol_key_mic(sm->tptk.kck, sm->tptk.kck_len,
61 +                                     sm->key_mgmt,
62 +                                     ver, buf, len, (u8 *) (key + 1)) < 0 ||
63 +                   os_memcmp_const(mic, key + 1, mic_len) != 0) {
64                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
65                                 "WPA: Invalid EAPOL-Key MIC "
66                                 "when using TPTK - ignoring TPTK");
67 @@ -1742,9 +1749,10 @@ static int wpa_supplicant_verify_eapol_k
68  
69         if (!ok && sm->ptk_set) {
70                 os_memset(key + 1, 0, mic_len);
71 -               wpa_eapol_key_mic(sm->ptk.kck, sm->ptk.kck_len, sm->key_mgmt,
72 -                                 ver, buf, len, (u8 *) (key + 1));
73 -               if (os_memcmp_const(mic, key + 1, mic_len) != 0) {
74 +               if (wpa_eapol_key_mic(sm->ptk.kck, sm->ptk.kck_len,
75 +                                     sm->key_mgmt,
76 +                                     ver, buf, len, (u8 *) (key + 1)) < 0 ||
77 +                   os_memcmp_const(mic, key + 1, mic_len) != 0) {
78                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
79                                 "WPA: Invalid EAPOL-Key MIC - "
80                                 "dropping packet");
81 @@ -4167,6 +4175,11 @@ int fils_process_assoc_resp(struct wpa_s
82  
83         alg = wpa_cipher_to_alg(sm->pairwise_cipher);
84         keylen = wpa_cipher_key_len(sm->pairwise_cipher);
85 +       if (keylen <= 0 || (unsigned int) keylen != sm->ptk.tk_len) {
86 +               wpa_printf(MSG_DEBUG, "FILS: TK length mismatch: %u != %lu",
87 +                          keylen, (long unsigned int) sm->ptk.tk_len);
88 +               goto fail;
89 +       }
90         rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
91         wpa_hexdump_key(MSG_DEBUG, "FILS: Set TK to driver",
92                         sm->ptk.tk, keylen);
93 @@ -4183,6 +4196,7 @@ int fils_process_assoc_resp(struct wpa_s
94          * takes care of association frame encryption/decryption. */
95         /* TK is not needed anymore in supplicant */
96         os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
97 +       sm->ptk.tk_len = 0;
98         sm->ptk.installed = 1;
99  
100         /* FILS HLP Container */