Просмотр исходного кода

Merge branch 'feature/192bit_security_' into 'master'

ESP_WIFI: Added GCMP, GMAC, WPA3 192 bit Support

Closes WIFI-3907 and WIFI-3778

See merge request espressif/esp-idf!14530
Jiang Jiang Jian 4 лет назад
Родитель
Сommit
40cfc91aa2
50 измененных файлов с 1457 добавлено и 584 удалено
  1. 0 1
      components/esp_rom/esp32c3/ld/esp32c3.rom.ld
  2. 0 1
      components/esp_rom/esp32s3/ld/esp32s3.rom.ld
  3. 13 0
      components/esp_wifi/Kconfig
  4. 21 13
      components/esp_wifi/include/esp_wifi_crypto_types.h
  5. 4 0
      components/esp_wifi/include/esp_wifi_types.h
  6. 1 1
      components/esp_wifi/lib
  7. 14 0
      components/wpa_supplicant/CMakeLists.txt
  8. 9 0
      components/wpa_supplicant/Kconfig
  9. 12 0
      components/wpa_supplicant/component.mk
  10. 15 13
      components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h
  11. 5 4
      components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h
  12. 15 13
      components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c
  13. 7 2
      components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c
  14. 1 1
      components/wpa_supplicant/include/utils/wpa_debug.h
  15. 38 43
      components/wpa_supplicant/src/ap/wpa_auth.c
  16. 1 1
      components/wpa_supplicant/src/ap/wpa_auth_i.h
  17. 7 2
      components/wpa_supplicant/src/common/defs.h
  18. 0 4
      components/wpa_supplicant/src/common/dpp.c
  19. 266 34
      components/wpa_supplicant/src/common/wpa_common.c
  20. 70 19
      components/wpa_supplicant/src/common/wpa_common.h
  21. 327 0
      components/wpa_supplicant/src/crypto/aes-gcm.c
  22. 17 14
      components/wpa_supplicant/src/crypto/crypto_ops.c
  23. 108 0
      components/wpa_supplicant/src/crypto/sha384-prf.c
  24. 101 18
      components/wpa_supplicant/src/crypto/tls_mbedtls.c
  25. 4 0
      components/wpa_supplicant/src/eap_peer/eap.c
  26. 2 0
      components/wpa_supplicant/src/eap_peer/eap.h
  27. 5 0
      components/wpa_supplicant/src/eap_peer/eap_tls_common.c
  28. 5 1
      components/wpa_supplicant/src/rsn_supp/pmksa_cache.c
  29. 1 1
      components/wpa_supplicant/src/rsn_supp/pmksa_cache.h
  30. 283 317
      components/wpa_supplicant/src/rsn_supp/wpa.c
  31. 1 1
      components/wpa_supplicant/src/rsn_supp/wpa_i.h
  32. 23 34
      components/wpa_supplicant/src/rsn_supp/wpa_ie.c
  33. 1 0
      components/wpa_supplicant/src/tls/tls.h
  34. 1 1
      docs/en/api-guides/wifi.rst
  35. 0 0
      examples/wifi/wifi_enterprise/CMakeLists.txt
  36. 0 0
      examples/wifi/wifi_enterprise/Makefile
  37. 16 15
      examples/wifi/wifi_enterprise/README.md
  38. 4 0
      examples/wifi/wifi_enterprise/main/CMakeLists.txt
  39. 24 5
      examples/wifi/wifi_enterprise/main/Kconfig.projbuild
  40. 0 0
      examples/wifi/wifi_enterprise/main/ca.pem
  41. 0 0
      examples/wifi/wifi_enterprise/main/client.crt
  42. 0 0
      examples/wifi/wifi_enterprise/main/client.key
  43. 0 0
      examples/wifi/wifi_enterprise/main/client.pem
  44. 3 3
      examples/wifi/wifi_enterprise/main/component.mk
  45. 0 0
      examples/wifi/wifi_enterprise/main/server.crt
  46. 0 0
      examples/wifi/wifi_enterprise/main/server.key
  47. 0 0
      examples/wifi/wifi_enterprise/main/server.pem
  48. 29 12
      examples/wifi/wifi_enterprise/main/wifi_enterprise_main.c
  49. 0 4
      examples/wifi/wpa2_enterprise/main/CMakeLists.txt
  50. 3 6
      tools/ci/check_copyright_ignore.txt

+ 0 - 1
components/esp_rom/esp32c3/ld/esp32c3.rom.ld

@@ -1567,7 +1567,6 @@ ppEnqueueRxq = 0x400016c8;
 ppEnqueueTxDone = 0x400016cc;
 ppGetTxQFirstAvail_Locked = 0x400016d0;
 ppGetTxframe = 0x400016d4;
-ppProcTxSecFrame = 0x400016dc;
 ppProcessRxPktHdr = 0x400016e0;
 ppProcessTxQ = 0x400016e4;
 ppRecordBarRRC = 0x400016e8;

+ 0 - 1
components/esp_rom/esp32s3/ld/esp32s3.rom.ld

@@ -1873,7 +1873,6 @@ ppEnqueueTxDone = 0x400055a4;
 ppGetTxQFirstAvail_Locked = 0x400055b0;
 ppGetTxframe = 0x400055bc;
 ppMapTxQueue = 0x400055c8;
-ppProcTxSecFrame = 0x400055d4;
 ppProcessRxPktHdr = 0x400055e0;
 ppProcessTxQ = 0x400055ec;
 ppRecordBarRRC = 0x400055f8;

+ 13 - 0
components/esp_wifi/Kconfig

@@ -312,4 +312,17 @@ menu "Wi-Fi"
             This function depends on BT-off
             because currently we don't support external coex and internal coex simultaneously.
 
+    config ESP_WIFI_GCMP_SUPPORT
+        bool "WiFi GCMP Support(GCMP128 and GCMP256)"
+        default n
+        depends on (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3)
+        help
+            Select this option to enable GCMP support. GCMP support is compulsory for WiFi Suite-B support.
+
+    config ESP_WIFI_GMAC_SUPPORT
+        bool "WiFi GMAC Support(GMAC128 and GMAC256)"
+        default n
+        help
+            Select this option to enable GMAC support. GMAC support is compulsory for WiFi 192 bit certification.
+
 endmenu  # Wi-Fi

+ 21 - 13
components/esp_wifi/include/esp_wifi_crypto_types.h

@@ -1,16 +1,8 @@
-// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 
 #ifndef __ESP_WIFI_CRYPTO_TYPES_H__
@@ -358,6 +350,21 @@ typedef uint8_t * (*esp_ccmp_decrypt_t)(const uint8_t *tk, const uint8_t *ieee80
 typedef uint8_t * (*esp_ccmp_encrypt_t)(const uint8_t *tk, uint8_t *frame, size_t len, size_t hdrlen,
                                         uint8_t *pn, int keyid, size_t *encrypted_len);
 
+/**
+ * @brief One-Key GMAC hash with AES for MIC computation
+ *
+ * @key: key for the hash operation
+ * @keylen: key length
+ * @iv: initialization vector
+ * @iv_len: initialization vector length
+ * @aad: aad
+ * @aad_len: aad length
+ * @mic: Buffer for MIC (128 bits, i.e., 16 bytes)
+ * Returns: 0 on success, -1 on failure
+ */
+typedef int (*esp_aes_gmac_t)(const uint8_t *key, size_t keylen, const uint8_t *iv, size_t iv_len,
+                              const uint8_t *aad, size_t aad_len, uint8_t *mic);
+
 /**
   * @brief The crypto callback function structure used when do station security connect.
   *        The structure can be set as software crypto or the crypto optimized by ESP32
@@ -390,6 +397,7 @@ typedef struct {
     esp_omac1_aes_128_t omac1_aes_128;
     esp_ccmp_decrypt_t ccmp_decrypt;
     esp_ccmp_encrypt_t ccmp_encrypt;
+    esp_aes_gmac_t aes_gmac;
 }wpa_crypto_funcs_t;
 
 /**

+ 4 - 0
components/esp_wifi/include/esp_wifi_types.h

@@ -142,6 +142,10 @@ typedef enum {
     WIFI_CIPHER_TYPE_TKIP_CCMP,  /**< the cipher type is TKIP and CCMP */
     WIFI_CIPHER_TYPE_AES_CMAC128,/**< the cipher type is AES-CMAC-128 */
     WIFI_CIPHER_TYPE_SMS4,       /**< the cipher type is SMS4 */
+    WIFI_CIPHER_TYPE_GCMP,       /**< the cipher type is GCMP */
+    WIFI_CIPHER_TYPE_GCMP256,    /**< the cipher type is GCMP-256 */
+    WIFI_CIPHER_TYPE_AES_GMAC128,/**< the cipher type is AES-GMAC-128 */
+    WIFI_CIPHER_TYPE_AES_GMAC256,/**< the cipher type is AES-GMAC-256 */
     WIFI_CIPHER_TYPE_UNKNOWN,    /**< the cipher type is unknown */
 } wifi_cipher_type_t;
 

+ 1 - 1
components/esp_wifi/lib

@@ -1 +1 @@
-Subproject commit 049fbb7f22962fc4e2316e732ad08fc95b14149f
+Subproject commit 0c3f24cc83d595f60e3b785e3eb098c3bc5ce2d3

+ 14 - 0
components/wpa_supplicant/CMakeLists.txt

@@ -10,6 +10,7 @@ set(srcs "port/os_xtensa.c"
     "src/crypto/aes-siv.c"
     "src/crypto/sha256-kdf.c"
     "src/crypto/ccmp.c"
+    "src/crypto/aes-gcm.c"
     "src/crypto/crypto_ops.c"
     "src/crypto/dh_group5.c"
     "src/crypto/dh_groups.c"
@@ -19,6 +20,7 @@ set(srcs "port/os_xtensa.c"
     "src/crypto/sha384-tlsprf.c"
     "src/crypto/sha256-prf.c"
     "src/crypto/sha1-prf.c"
+    "src/crypto/sha384-prf.c"
     "src/crypto/md4-internal.c"
     "src/eap_peer/chap.c"
     "src/eap_peer/eap.c"
@@ -194,6 +196,18 @@ endif()
 if(CONFIG_WPA_WPS_STRICT)
     target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_WPS_STRICT)
 endif()
+if(CONFIG_WPA_SUITE_B_192)
+    target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_SUITEB192)
+endif()
+if(CONFIG_WPA_SUITE_B)
+    target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_SUITEB)
+endif()
+if(CONFIG_ESP_WIFI_GCMP_SUPPORT)
+    target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_GCMP)
+endif()
+if(CONFIG_ESP_WIFI_GMAC_SUPPORT)
+    target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_GMAC)
+endif()
 
 if(CONFIG_WPA_MBO_SUPPORT)
     target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_MBO)

+ 9 - 0
components/wpa_supplicant/Kconfig

@@ -18,6 +18,15 @@ menu "Supplicant"
             Select this option to enable WAPI-PSK
             which is a Chinese National Standard Encryption for Wireless LANs (GB 15629.11-2003).
 
+    config WPA_SUITE_B_192
+        bool "Enable NSA suite B support with 192 bit key"
+        default n
+        select ESP_WIFI_GCMP_SUPPORT
+        select ESP_WIFI_GMAC_SUPPORT
+        help
+            Select this option to enable 192 bit NSA suite-B.
+            This is necessary to support WPA3 192 bit security.
+
     config WPA_DEBUG_PRINT
         bool "Print debug messages from WPA Supplicant"
         default n

+ 12 - 0
components/wpa_supplicant/component.mk

@@ -85,3 +85,15 @@ endif
 ifdef CONFIG_WPA_MBO_SUPPORT
 	CFLAGS += -DCONFIG_MBO
 endif
+ifdef CONFIG_WPA_SUITE_B_192
+	CFLAGS += -DCONFIG_SUITEB192
+endif
+ifdef CONFIG_WPA_SUITE_B
+	CFLAGS += -DCONFIG_SUITEB
+endif
+ifdef CONFIG_ESP_WIFI_GCMP_SUPPORT
+	CFLAGS += -DCONFIG_GCMP
+endif
+ifdef CONFIG_ESP_WIFI_GMAC_SUPPORT
+	CFLAGS += -DCONFIG_GMAC
+endif

+ 15 - 13
components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h

@@ -1,16 +1,8 @@
-// Hardware crypto support Copyright 2019 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #ifndef _ESP_WPA2_H
 #define _ESP_WPA2_H
@@ -209,6 +201,16 @@ esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable);
   */
 esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type);
 
+/**
+  * @brief  enable/disable 192 bit suite b certification checks
+  *
+  * @param  enable: bool to enable/disable it.
+  *
+  * @return
+  *    - ESP_OK: succeed
+  */
+esp_err_t esp_wifi_sta_wpa2_set_suiteb_192bit_certification(bool enable);
+
 #ifdef __cplusplus
 }
 #endif

+ 5 - 4
components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h

@@ -65,7 +65,8 @@ enum {
     WPA2_AUTH_ENT_SHA256= 0x0a,
     WAPI_AUTH_PSK       = 0x0b,
     WAPI_AUTH_CERT      = 0x0c,
-    WPA2_AUTH_INVALID   = 0x0d,
+    WPA2_AUTH_ENT_SHA384_SUITE_B = 0x0d,
+    WPA2_AUTH_INVALID   = 0x0e,
 };
 
 typedef enum {
@@ -109,7 +110,7 @@ typedef struct {
 struct wpa_funcs {
     bool (*wpa_sta_init)(void);
     bool (*wpa_sta_deinit)(void);
-    void (*wpa_sta_connect)(uint8_t *bssid);
+    int (*wpa_sta_connect)(uint8_t *bssid);
     void (*wpa_sta_disconnected_cb)(uint8_t reason_code);
     int (*wpa_sta_rx_eapol)(u8 *src_addr, u8 *buf, u32 len);
     bool (*wpa_sta_in_4way_handshake)(void);
@@ -172,11 +173,11 @@ typedef struct {
     uint32_t arg_size;
 } wifi_ipc_config_t;
 
-#define WPA_IGTK_LEN 16
+#define WPA_IGTK_MAX_LEN 32
 typedef struct {
     uint8_t keyid[2];
     uint8_t pn[6];
-    uint8_t igtk[WPA_IGTK_LEN];
+    uint8_t igtk[WPA_IGTK_MAX_LEN];
 } wifi_wpa_igtk_t;
 
 typedef struct {

+ 15 - 13
components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c

@@ -1,16 +1,8 @@
-// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #include <string.h>
 
@@ -1173,3 +1165,13 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types
     }
     return ESP_OK;
 }
+
+esp_err_t esp_wifi_sta_wpa2_set_suiteb_192bit_certification(bool enable)
+{
+#ifdef CONFIG_SUITEB192
+    g_wpa_suiteb_certification = enable;
+    return ESP_OK;
+#else
+    return ESP_FAIL;
+#endif
+}

+ 7 - 2
components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c

@@ -165,15 +165,20 @@ bool  wpa_deattach(void)
     return true;
 }
 
-void  wpa_sta_connect(uint8_t *bssid)
+int wpa_sta_connect(uint8_t *bssid)
 {
     /* use this API to set AP specific IEs during connection */
     int ret = 0;
     ret = wpa_config_profile();
     if (ret == 0) {
         ret = wpa_config_bss(bssid);
-        WPA_ASSERT(ret == 0);
+        if (ret) {
+            wpa_printf(MSG_DEBUG, "Rejecting bss, validation failed");
+            return ret;
+        }
     }
+
+    return 0;
 }
 
 void wpa_config_done(void)

+ 1 - 1
components/wpa_supplicant/include/utils/wpa_debug.h

@@ -176,7 +176,7 @@ void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
  *
  * Note: New line '\n' is added to the end of the text when printing to stdout.
  */
-void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4);
+#define wpa_msg(...) do {} while(0)
 
 /**
  * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors

+ 38 - 43
components/wpa_supplicant/src/ap/wpa_auth.c

@@ -36,7 +36,8 @@
 
 static void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx);
 static int wpa_sm_step(struct wpa_state_machine *sm);
-static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len);
+static int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data,
+			      size_t data_len);
 static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
                   struct wpa_group *group);
 static void wpa_request_new_ptk(struct wpa_state_machine *sm);
@@ -642,6 +643,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *s
         if (sm->pairwise == WPA_CIPHER_CCMP ||
             sm->pairwise == WPA_CIPHER_GCMP) {
             if (wpa_use_aes_cmac(sm) &&
+                !wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) &&
                 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
                 return;
             }
@@ -655,7 +657,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *s
 
     if (key_info & WPA_KEY_INFO_REQUEST) {
         if (sm->req_replay_counter_used &&
-        	memcmp(key->replay_counter, sm->req_replay_counter,
+            os_memcmp(key->replay_counter, sm->req_replay_counter,
                   WPA_REPLAY_COUNTER_LEN) <= 0) {
             return;
         }
@@ -809,7 +811,8 @@ continue_processing:
 
     sm->MICVerified = FALSE;
     if (sm->PTK_valid && !sm->update_snonce) {
-        if (wpa_verify_key_mic(&sm->PTK, data, data_len)) {
+        if (wpa_verify_key_mic(sm->wpa_key_mgmt, &sm->PTK, data,
+                       data_len)) {
             return;
         }
         sm->MICVerified = TRUE;
@@ -1065,10 +1068,10 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
         if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
             version == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
             if (aes_wrap(sm->PTK.kek, 16, (key_data_len - 8) / 8, buf,
-            		(u8 *) (key + 1))) {
-            	os_free(hdr);
-            	os_free(buf);
-            	return;
+                    (u8 *) (key + 1))) {
+                os_free(hdr);
+                os_free(buf);
+                return;
             }
             WPA_PUT_BE16(key->key_data_length, key_data_len);
         } else {
@@ -1090,8 +1093,9 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
             os_free(hdr);
             return;
         }
-        wpa_eapol_key_mic(sm->PTK.kck, version, (u8 *) hdr, len,
-                  key->key_mic);
+        wpa_eapol_key_mic(sm->PTK.kck, sm->PTK.kck_len,
+              sm->wpa_key_mgmt, version,
+              (u8 *) hdr, len, key->key_mic);
     }
 
     wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx, 1);
@@ -1112,7 +1116,7 @@ int hostap_eapol_resend_process(void *timeout_ctx)
         sm->in_step_loop = 0;
         wpa_sm_step(sm);
     } else {
-    	wpa_printf( MSG_INFO, "Station left, stop send EAPOL frame");
+        wpa_printf( MSG_INFO, "Station left, stop send EAPOL frame");
     }
 
     return ESP_OK;
@@ -1161,16 +1165,15 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
     ets_timer_arm(&sm->resend_eapol, 1000, 0);
 }
 
-
-static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len)
+static int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data,
+			      size_t data_len)
 {
     struct ieee802_1x_hdr *hdr;
     struct wpa_eapol_key *key;
     u16 key_info;
     int ret = 0;
-    int mic_ret = 0;
-    u8 mic[16];
-    char debug_log[8];
+    u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
+    size_t mic_len = 16;
 
     if (data_len < sizeof(*hdr) + sizeof(*key)){
         wpa_printf( MSG_DEBUG, "invalid data length, len=%u\n", data_len);
@@ -1180,23 +1183,16 @@ static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len)
     hdr = (struct ieee802_1x_hdr *) data;
     key = (struct wpa_eapol_key *) (hdr + 1);
     key_info = WPA_GET_BE16(key->key_info);
-    memcpy(mic, key->key_mic, 16);
-    memset(key->key_mic, 0, 16);
-
-    mic_ret = wpa_eapol_key_mic(PTK->kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, data_len, key->key_mic);
-    if ( mic_ret || memcmp(mic, key->key_mic, 16) != 0) {
+    os_memcpy(mic, key->key_mic, mic_len);
+    os_memset(key->key_mic, 0, mic_len);
+    if (wpa_eapol_key_mic(PTK->kck, PTK->kck_len, akmp,
+                          key_info & WPA_KEY_INFO_TYPE_MASK,
+                          data, data_len, key->key_mic) ||
+        os_memcmp_const(mic, key->key_mic, mic_len) != 0)
         ret = -1;
-    }
-    os_memset(debug_log, 0, 8);
-    os_memcpy(debug_log, "you mic", sizeof("you mic"));
-    wpa_dump_mem(debug_log, mic, 16);
-    os_memset(debug_log, 0, 8);
-    os_memcpy(debug_log, "my mic", sizeof("my mic"));
-    wpa_dump_mem(debug_log, key->key_mic, 16);
-
-    memcpy(key->key_mic, mic, 16);
+    os_memcpy(key->key_mic, mic, mic_len);
     return ret;
-}
+ }
 
 
 void wpa_remove_ptk(struct wpa_state_machine *sm)
@@ -1505,21 +1501,19 @@ SM_STATE(WPA_PTK, PTKSTART)
 }
 
 
-static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *pmk,
-              struct wpa_ptk *ptk)
+static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
+			  const u8 *pmk, struct wpa_ptk *ptk)
 {
-    size_t ptk_len = sm->pairwise != WPA_CIPHER_TKIP ? 48 : 64;
 #ifdef CONFIG_IEEE80211R
+    size_t ptk_len = sm->pairwise != WPA_CIPHER_TKIP ? 48 : 64;
+
     if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))
         return wpa_auth_derive_ptk_ft(sm, pmk, ptk, ptk_len);
 #endif /* CONFIG_IEEE80211R */
 
-    wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
-               sm->wpa_auth->addr, sm->addr, sm->ANonce, sm->SNonce,
-               (u8 *) ptk, ptk_len,
-               wpa_key_mgmt_sha256(sm->wpa_key_mgmt));
-
-    return 0;
+    return wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
+                  sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce,
+                  ptk, sm->wpa_key_mgmt, sm->pairwise);
 }
 
 
@@ -1548,9 +1542,10 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
             pmk = sm->PMK;
         }
 
-        wpa_derive_ptk(sm, pmk, &PTK);
+        wpa_derive_ptk(sm, sm->SNonce, pmk, &PTK);
 
-        if (wpa_verify_key_mic(&PTK, sm->last_rx_eapol_key,
+        if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK,
+                       sm->last_rx_eapol_key,
                        sm->last_rx_eapol_key_len) == 0) {
             wpa_printf( MSG_DEBUG, "mic verify ok, pmk=%p\n", pmk);
             ok = 1;
@@ -1825,7 +1820,7 @@ SM_STATE(WPA_PTK, PTKINITDONE)
         enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise);
         int klen = wpa_cipher_key_len(sm->pairwise);
         if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
-                     sm->PTK.tk1, klen)) {
+                     sm->PTK.tk, klen)) {
             wpa_sta_disconnect(sm->wpa_auth, sm->addr);
             return;
         }
@@ -2305,7 +2300,7 @@ static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
 #ifdef CONFIG_IEEE80211W
     if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION &&
         wpa_auth_set_key(wpa_auth, group->vlan_id, WIFI_WPA_ALG_IGTK,
-        		 broadcast_ether_addr, group->GN_igtk,
+                 broadcast_ether_addr, group->GN_igtk,
                  group->IGTK[group->GN_igtk - 4],
                  WPA_IGTK_LEN) < 0)
         ret = -1;

+ 1 - 1
components/wpa_supplicant/src/ap/wpa_auth_i.h

@@ -202,7 +202,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
 		   u8 *buf, size_t len, const u8 *subelem,
 		   size_t subelem_len);
 int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
-			   struct wpa_ptk *ptk, size_t ptk_len);
+			   struct wpa_ptk *ptk);
 struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void);
 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache);
 void wpa_ft_install_ptk(struct wpa_state_machine *sm);

+ 7 - 2
components/wpa_supplicant/src/common/defs.h

@@ -23,8 +23,11 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean;
 #define WPA_CIPHER_TKIP                 BIT(1)
 #define WPA_CIPHER_CCMP                 BIT(3)
 #define WPA_CIPHER_AES_128_CMAC         BIT(5)
-#define WPA_CIPHER_GCMP                 BIT(6)
 #define WPA_CIPHER_SMS4                 BIT(10)
+#define WPA_CIPHER_GCMP                 BIT(11)
+#define WPA_CIPHER_GCMP_256             BIT(12)
+#define WPA_CIPHER_BIP_GMAC_128         BIT(13)
+#define WPA_CIPHER_BIP_GMAC_256         BIT(14)
 
 #define WPA_KEY_MGMT_IEEE8021X BIT(0)
 #define WPA_KEY_MGMT_PSK BIT(1)
@@ -143,7 +146,9 @@ enum wpa_cipher {
 	CIPHER_WEP40,
 	CIPHER_TKIP,
 	CIPHER_CCMP,
-	CIPHER_WEP104
+	CIPHER_WEP104,
+	CIPHER_SMS4,
+	CIPHER_GCMP_256,
 };
 
 /**

+ 0 - 4
components/wpa_supplicant/src/common/dpp.c

@@ -52,10 +52,6 @@ static const struct dpp_curve_params dpp_curves[] = {
 	{ NULL, 0, 0, 0, 0, NULL, 0, NULL }
 };
 
-void wpa_msg(void *ctx, int level, const char *fmt, ...)
-{
-}
-
 static struct wpabuf *
 gas_build_req(u8 action, u8 dialog_token, size_t size)
 {

+ 266 - 34
components/wpa_supplicant/src/common/wpa_common.c

@@ -21,13 +21,36 @@
 #include "rsn_supp/wpa.h"
 #include "crypto/sha1.h"
 #include "crypto/sha256.h"
+#include "crypto/sha384.h"
 #include "crypto/md5.h"
 #include "crypto/aes.h"
 #include "crypto/aes_wrap.h"
 
 #define MD5_MAC_LEN 16
 
-#ifndef CONFIG_NO_WPA2
+static unsigned int wpa_kck_len(int akmp)
+{
+	if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
+		return 24;
+	return 16;
+}
+
+static unsigned int wpa_kek_len(int akmp)
+{
+	if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
+		return 32;
+	return 16;
+}
+
+
+unsigned int wpa_mic_len(int akmp)
+{
+	if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
+		return 24;
+
+	return 16;
+}
+
 static int rsn_selector_to_bitfield(const u8 *s)
 {
 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
@@ -40,10 +63,23 @@ static int rsn_selector_to_bitfield(const u8 *s)
 		return WPA_CIPHER_CCMP;
 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP104)
 		return WPA_CIPHER_WEP104;
+#ifdef COFIG_GCMP
+	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP)
+		return WPA_CIPHER_GCMP;
+	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP_256)
+		return WPA_CIPHER_GCMP_256;
+#endif
 #ifdef CONFIG_IEEE80211W
 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
 		return WPA_CIPHER_AES_128_CMAC;
+#ifdef COFIG_GMAC
+	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_128)
+		return WPA_CIPHER_BIP_GMAC_128;
+	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_256)
+		return WPA_CIPHER_BIP_GMAC_256;
+#endif
 #endif /* CONFIG_IEEE80211W */
+
 	return 0;
 }
 
@@ -69,6 +105,14 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
 		return WPA_KEY_MGMT_PSK_SHA256;
 #endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_SUITEB
+	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B)
+		return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
+#endif
+#ifdef CONFIG_SUITEB192
+	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
+		return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
+#endif
 	return 0;
 }
 
@@ -97,7 +141,14 @@ static int wpa_key_mgmt_to_bitfield(const u8 *s)
 		return WPA_KEY_MGMT_WPA_NONE;
 	return 0;
 }
-#endif /* CONFIG_NO_WPA2 */
+
+int wpa_cipher_valid_mgmt_group(int cipher)
+{
+	return cipher == WPA_CIPHER_AES_128_CMAC ||
+		cipher == WPA_CIPHER_BIP_GMAC_128 ||
+		cipher == WPA_CIPHER_BIP_GMAC_256;
+}
+
 /**
  * wpa_parse_wpa_ie_rsn - Parse RSN IE
  * @rsn_ie: Buffer containing RSN IE
@@ -108,7 +159,6 @@ static int wpa_key_mgmt_to_bitfield(const u8 *s)
 int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
 			 struct wpa_ie_data *data)
 {
-#ifndef CONFIG_NO_WPA2
 	const struct rsn_ie_hdr *hdr;
 	const u8 *pos;
 	int left;
@@ -122,8 +172,9 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
 	data->capabilities = 0;
 	data->pmkid = NULL;
 	data->num_pmkid = 0;
-	data->mgmt_group_cipher = 0;
+	data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
 
+	wpa_hexdump(MSG_DEBUG, "rsn_ie", rsn_ie, rsn_ie_len);
 	if (rsn_ie_len == 0) {
 		/* No RSN IE - fail silently */
 		return -1;
@@ -142,7 +193,7 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
 	if (hdr->elem_id != WLAN_EID_RSN ||
 	    hdr->len != rsn_ie_len - 2 ||
 	    WPA_GET_LE16(hdr->version) != RSN_VERSION) {
-    	    #ifdef DEBUG_PRINT
+	    #ifdef DEBUG_PRINT
 		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
 			   __func__);
 	     #endif
@@ -240,6 +291,19 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
 		}
 	}
 
+	if (left >= 4) {
+		data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
+		if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) {
+			wpa_printf(MSG_DEBUG,
+				   "%s: Unsupported management group cipher 0x%x (%08x)",
+				   __func__, data->mgmt_group_cipher,
+				   WPA_GET_BE32(pos));
+			return -10;
+		}
+		pos += RSN_SELECTOR_LEN;
+		left -= RSN_SELECTOR_LEN;
+	}
+
 	if (left > 0) {
 	    #ifdef DEBUG_PRINT
 		wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
@@ -248,9 +312,6 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
 	}
 
 	return 0;
-#else /* CONFIG_NO_WPA2 */
-	return -1;
-#endif /* CONFIG_NO_WPA2 */
 }
 
 int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
@@ -365,6 +426,8 @@ int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
 /**
  * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
  * @key: EAPOL-Key Key Confirmation Key (KCK)
+ * @key_len: KCK length in octets
+ * @akmp: WPA_KEY_MGMT_* used in key derivation
  * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
  * @buf: Pointer to the beginning of the EAPOL header (version field)
  * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
@@ -380,26 +443,49 @@ int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
  * happened during final editing of the standard and the correct behavior is
  * defined in the last draft (IEEE 802.11i/D10).
  */
-int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
-		      u8 *mic)
+int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
+		      const u8 *buf, size_t len, u8 *mic)
 {
-	u8 hash[SHA1_MAC_LEN];
+	u8 hash[SHA384_MAC_LEN];
 
 	switch (ver) {
 	case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
-		    return hmac_md5(key, 16, buf, len, mic);
+		return hmac_md5(key, key_len, buf, len, mic);
 	case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
-		if (hmac_sha1(key, 16, buf, len, hash))
+		if (hmac_sha1(key, key_len, buf, len, hash))
 			return -1;
 		memcpy(mic, hash, MD5_MAC_LEN);
 		break;
+	case WPA_KEY_INFO_TYPE_AES_128_CMAC:
+		return omac1_aes_128(key, buf, len, mic);
 #ifdef CONFIG_IEEE80211W
-#ifdef CONFIG_WPA3_SAE
        case WPA_KEY_INFO_TYPE_AKM_DEFINED:
+		switch (akmp) {
+#ifdef CONFIG_WPA3_SAE
+		case WPA_KEY_MGMT_SAE:
+			return omac1_aes_128(key, buf, len, mic);
 #endif /* CONFIG_WPA3_SAE */
-	case WPA_KEY_INFO_TYPE_AES_128_CMAC:
-		return omac1_aes_128(key, buf, len, mic);
+#ifdef CONFIG_SUITEB
+		case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
+			if (hmac_sha256(key, key_len, buf, len, hash))
+				return -1;
+			os_memcpy(mic, hash, MD5_MAC_LEN);
+			break;
+#endif /* CONFIG_SUITEB */
+#ifdef CONFIG_SUITEB192
+		case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
+			if (hmac_sha384(key, key_len, buf, len, hash))
+				return -1;
+			os_memcpy(mic, hash, 24);
+			break;
+#endif /* CONFIG_SUITEB192 */
+
 #endif /* CONFIG_IEEE80211W */
+		default:
+			return -1;
+		}
+		break;
+
 	default:
 		return -1;
 	}
@@ -443,6 +529,70 @@ int wpa_compare_rsn_ie(int ft_initial_assoc,
 	return -1;
 }
 
+#ifdef CONFIG_SUITEB
+/**
+ * rsn_pmkid_suite_b - Calculate PMK identifier for Suite B AKM
+ * @kck: Key confirmation key
+ * @kck_len: Length of kck in bytes
+ * @aa: Authenticator address
+ * @spa: Supplicant address
+ * @pmkid: Buffer for PMKID
+ * Returns: 0 on success, -1 on failure
+ *
+ * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
+ * PMKID = Truncate(HMAC-SHA-256(KCK, "PMK Name" || AA || SPA))
+ */
+int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
+		      const u8 *spa, u8 *pmkid)
+{
+	char *title = "PMK Name";
+	const u8 *addr[3];
+	const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
+	unsigned char hash[SHA256_MAC_LEN];
+
+	addr[0] = (u8 *) title;
+	addr[1] = aa;
+	addr[2] = spa;
+
+	if (hmac_sha256_vector(kck, kck_len, 3, addr, len, hash) < 0)
+		return -1;
+	os_memcpy(pmkid, hash, PMKID_LEN);
+	return 0;
+}
+#endif /* CONFIG_SUITEB */
+
+#ifdef CONFIG_SUITEB192
+/**
+ * rsn_pmkid_suite_b_192 - Calculate PMK identifier for Suite B AKM
+ * @kck: Key confirmation key
+ * @kck_len: Length of kck in bytes
+ * @aa: Authenticator address
+ * @spa: Supplicant address
+ * @pmkid: Buffer for PMKID
+ * Returns: 0 on success, -1 on failure
+ *
+ * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
+ * PMKID = Truncate(HMAC-SHA-384(KCK, "PMK Name" || AA || SPA))
+ */
+int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
+			  const u8 *spa, u8 *pmkid)
+{
+	char *title = "PMK Name";
+	const u8 *addr[3];
+	const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
+	unsigned char hash[SHA384_MAC_LEN];
+
+	addr[0] = (u8 *) title;
+	addr[1] = aa;
+	addr[2] = spa;
+
+	if (hmac_sha384_vector(kck, kck_len, 3, addr, len, hash) < 0)
+		return -1;
+	os_memcpy(pmkid, hash, PMKID_LEN);
+	return 0;
+}
+#endif /* CONFIG_SUITEB192 */
+
 #ifdef DEBUG_PRINT
 /**
  * wpa_cipher_txt - Convert cipher suite to a text string
@@ -464,6 +614,14 @@ const char * wpa_cipher_txt(int cipher)
 		return "CCMP";
 	case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
 		return "CCMP+TKIP";
+	case WPA_CIPHER_GCMP:
+		return "GCMP";
+	case WPA_CIPHER_GCMP_256:
+		return "GCMP-256";
+	case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
+		return "WPA2-EAP-SUITE-B";
+	case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
+		return "WPA2-EAP-SUITE-B-192";
 	default:
 		return "UNKNOWN";
 	}
@@ -480,8 +638,9 @@ const char * wpa_cipher_txt(int cipher)
  * @nonce1: ANonce or SNonce
  * @nonce2: SNonce or ANonce
  * @ptk: Buffer for pairwise transient key
- * @ptk_len: Length of PTK
- * @use_sha256: Whether to use SHA256-based KDF
+ * @akmp: Negotiated AKM
+ * @cipher: Negotiated pairwise cipher
+ * Returns: 0 on success, -1 on failure
  *
  * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
  * PTK = PRF-X(PMK, "Pairwise key expansion",
@@ -492,12 +651,14 @@ const char * wpa_cipher_txt(int cipher)
  *             Min(MAC_I, MAC_P) || Max(MAC_I, MAC_P) ||
  *             Min(INonce, PNonce) || Max(INonce, PNonce))
  */
-void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
-		    const u8 *addr1, const u8 *addr2,
-		    const u8 *nonce1, const u8 *nonce2,
-		    u8 *ptk, size_t ptk_len, int use_sha256)
+int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
+		   const u8 *addr1, const u8 *addr2,
+		   const u8 *nonce1, const u8 *nonce2,
+		   struct wpa_ptk *ptk, int akmp, int cipher)
 {
 	u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
+	u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
+	size_t ptk_len;
 
 	if (memcmp(addr1, addr2, ETH_ALEN) < 0) {
 		memcpy(data, addr1, ETH_ALEN);
@@ -517,19 +678,42 @@ void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
 			  WPA_NONCE_LEN);
 	}
 
-	if (use_sha256) {
+	ptk->kck_len = wpa_kck_len(akmp);
+	ptk->kek_len = wpa_kek_len(akmp);
+	ptk->tk_len = wpa_cipher_key_len(cipher);
+	ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
+
+#if defined(CONFIG_SUITEB192)
+	if (wpa_key_mgmt_sha384(akmp)) {
+		wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
+		if (sha384_prf(pmk, pmk_len, label, data, sizeof(data),
+					tmp, ptk_len) < 0)
+			return -1;
+	} else
+#endif
+	if (wpa_key_mgmt_sha256(akmp))
 		sha256_prf(pmk, pmk_len, label, data, sizeof(data),
-			ptk, ptk_len);
-	}
+			   tmp, ptk_len);
 	else
-	{
-	    sha1_prf(pmk, pmk_len, label, data, sizeof(data), ptk, ptk_len);
-	}
+		sha1_prf(pmk, pmk_len, label, data, sizeof(data), tmp, ptk_len);
+
 	wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR"\n",
 		   MAC2STR(addr1), MAC2STR(addr2));
 
 	wpa_hexdump(MSG_MSGDUMP, "WPA: PMK", pmk, pmk_len);
-	wpa_hexdump(MSG_MSGDUMP, "WPA: PTK", ptk, ptk_len);
+	wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_len);
+
+	os_memcpy(ptk->kck, tmp, ptk->kck_len);
+	wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", ptk->kck, ptk->kck_len);
+
+	os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
+	wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
+
+	os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
+	wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
+
+	os_memset(tmp, 0, sizeof(tmp));
+	return 0;
 }
 
 /**
@@ -570,11 +754,23 @@ void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
 int wpa_cipher_key_len(int cipher)
 {
 	switch (cipher) {
+	case WPA_CIPHER_TKIP:
+#ifdef CONFIG_GCMP
+	case WPA_CIPHER_GCMP_256:
+#endif
+#ifdef CONFIG_GMAC
+	case WPA_CIPHER_BIP_GMAC_256:
+#endif
+		return 32;
 	case WPA_CIPHER_CCMP:
+#ifdef CONFIG_GCMP
 	case WPA_CIPHER_GCMP:
+#endif
+#ifdef CONFIG_GMAC
+	case WPA_CIPHER_BIP_GMAC_128:
+#endif
+	case WPA_CIPHER_AES_128_CMAC:
 		return 16;
-	case WPA_CIPHER_TKIP:
-		return 32;
 	case WPA_CIPHER_WEP104:
 		return 13;
 	case WPA_CIPHER_WEP40:
@@ -584,18 +780,35 @@ int wpa_cipher_key_len(int cipher)
 	return 0;
 }
 
+int wpa_cipher_rsc_len(int cipher)
+{
+	switch (cipher) {
+	case WPA_CIPHER_GCMP_256:
+	case WPA_CIPHER_CCMP:
+	case WPA_CIPHER_GCMP:
+	case WPA_CIPHER_TKIP:
+		return 6;
+	}
+
+	return 0;
+}
+
 int wpa_cipher_to_alg(int cipher)
 {
 	switch (cipher) {
 	case WPA_CIPHER_CCMP:
 		return WIFI_WPA_ALG_CCMP;
+#ifdef CONFIG_GCMP
+	case WPA_CIPHER_GCMP_256:
 	case WPA_CIPHER_GCMP:
 		return WIFI_WPA_ALG_GCMP;
+#endif
 	case WPA_CIPHER_TKIP:
 		return WIFI_WPA_ALG_TKIP;
 	case WPA_CIPHER_WEP104:
+		return WIFI_WPA_ALG_WEP104;
 	case WPA_CIPHER_WEP40:
-		return WIFI_WPA_ALG_WEP;
+		return WIFI_WPA_ALG_WEP40;
 	}
 	return WIFI_WPA_ALG_NONE;
 }
@@ -605,8 +818,12 @@ u32 wpa_cipher_to_suite(int proto, int cipher)
 	if (cipher & WPA_CIPHER_CCMP)
 		return (proto == WPA_PROTO_RSN ?
 			RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
+#ifdef CONFIG_GCMP
+	if (cipher & WPA_CIPHER_GCMP_256)
+		return RSN_CIPHER_SUITE_GCMP_256;
 	if (cipher & WPA_CIPHER_GCMP)
 		return RSN_CIPHER_SUITE_GCMP;
+#endif
 	if (cipher & WPA_CIPHER_TKIP)
 		return (proto == WPA_PROTO_RSN ?
 			RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
@@ -619,6 +836,14 @@ u32 wpa_cipher_to_suite(int proto, int cipher)
 	if (cipher & WPA_CIPHER_NONE)
 		return (proto == WPA_PROTO_RSN ?
 			RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
+	if (cipher & WPA_CIPHER_AES_128_CMAC)
+		return RSN_CIPHER_SUITE_AES_128_CMAC;
+#if CONFIG_GMAC
+	if (cipher & WPA_CIPHER_BIP_GMAC_128)
+		return RSN_CIPHER_SUITE_BIP_GMAC_128;
+	if (cipher & WPA_CIPHER_BIP_GMAC_256)
+		return RSN_CIPHER_SUITE_BIP_GMAC_256;
+#endif
 	return 0;
 }
 
@@ -626,8 +851,9 @@ int rsn_cipher_put_suites(u8 *pos, int ciphers)
 {
 	int num_suites = 0;
 
-	if (ciphers & WPA_CIPHER_CCMP) {
-		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
+#ifdef CONFIG_GCMP
+	if (ciphers & WPA_CIPHER_GCMP_256) {
+		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP_256);
 		pos += RSN_SELECTOR_LEN;
 		num_suites++;
 	}
@@ -636,6 +862,12 @@ int rsn_cipher_put_suites(u8 *pos, int ciphers)
 		pos += RSN_SELECTOR_LEN;
 		num_suites++;
 	}
+#endif
+	if (ciphers & WPA_CIPHER_CCMP) {
+		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
+		pos += RSN_SELECTOR_LEN;
+		num_suites++;
+	}
 	if (ciphers & WPA_CIPHER_TKIP) {
 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
 		pos += RSN_SELECTOR_LEN;

+ 70 - 19
components/wpa_supplicant/src/common/wpa_common.h

@@ -22,6 +22,8 @@
 /* IEEE 802.11i */
 #define PMKID_LEN 16
 #define PMK_LEN 32
+#define PMK_LEN_MAX 64
+#define PMK_LEN_SUITE_B_192 48
 #define WPA_REPLAY_COUNTER_LEN 8
 #define WPA_NONCE_LEN 32
 #define WPA_KEY_RSC_LEN 8
@@ -65,6 +67,10 @@
 #define RSN_AUTH_KEY_MGMT_802_1X_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
 #define RSN_AUTH_KEY_MGMT_PSK_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
 #define RSN_AUTH_KEY_MGMT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
+#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
+#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192 RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
+#define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_192 \
+RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
 
 #define RSN_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x0f, 0xac, 0)
 #define RSN_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
@@ -76,6 +82,11 @@
 #endif /* CONFIG_IEEE80211W */
 #define RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED RSN_SELECTOR(0x00, 0x0f, 0xac, 7)
 #define RSN_CIPHER_SUITE_GCMP RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
+#define RSN_CIPHER_SUITE_GCMP_256 RSN_SELECTOR(0x00, 0x0f, 0xac, 9)
+#define RSN_CIPHER_SUITE_CCMP_256 RSN_SELECTOR(0x00, 0x0f, 0xac, 10)
+#define RSN_CIPHER_SUITE_BIP_GMAC_128 RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
+#define RSN_CIPHER_SUITE_BIP_GMAC_256 RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
+#define RSN_CIPHER_SUITE_BIP_CMAC_256 RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
 
 /* EAPOL-Key Key Data Encapsulation
  * GroupKey and PeerKey require encryption, otherwise, encryption is optional.
@@ -167,22 +178,39 @@ struct wpa_eapol_key {
 	/* followed by key_data_length bytes of key_data */
 } STRUCT_PACKED;
 
+struct wpa_eapol_key_192 {
+	u8 type;
+	/* Note: key_info, key_length, and key_data_length are unaligned */
+	u8 key_info[2]; /* big endian */
+	u8 key_length[2]; /* big endian */
+	u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
+	u8 key_nonce[WPA_NONCE_LEN];
+	u8 key_iv[16];
+	u8 key_rsc[WPA_KEY_RSC_LEN];
+	u8 key_id[8]; /* Reserved in IEEE 802.11i/RSN */
+	u8 key_mic[24];
+	u8 key_data_length[2]; /* big endian */
+	/* followed by key_data_length bytes of key_data */
+} STRUCT_PACKED;
+
+#define WPA_EAPOL_KEY_MIC_MAX_LEN 24
+#define WPA_KCK_MAX_LEN 24
+#define WPA_KEK_MAX_LEN 32
+
+#define WPA_TK_MAX_LEN 32
+
 /**
  * struct wpa_ptk - WPA Pairwise Transient Key
  * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
  */
 struct wpa_ptk {
-	u8 kck[16]; /* EAPOL-Key Key Confirmation Key (KCK) */
-	u8 kek[16]; /* EAPOL-Key Key Encryption Key (KEK) */
-	u8 tk1[16]; /* Temporal Key 1 (TK1) */
-	union {
-		u8 tk2[16]; /* Temporal Key 2 (TK2) */
-		struct {
-			u8 tx_mic_key[8];
-			u8 rx_mic_key[8];
-		} auth;
-	} u;
-} STRUCT_PACKED;
+	u8 kck[WPA_KCK_MAX_LEN]; /* EAPOL-Key Key Confirmation Key (KCK) */
+	u8 kek[WPA_KEK_MAX_LEN]; /* EAPOL-Key Key Encryption Key (KEK) */
+	u8 tk[WPA_TK_MAX_LEN]; /* Temporal Key (TK) */
+	size_t kck_len;
+	size_t kek_len;
+	size_t tk_len;
+};
 
 struct wpa_gtk_data {
 	enum wpa_alg alg;
@@ -320,6 +348,28 @@ struct rsn_sppamsdu_sup {
     bool require;
 };
 
+#ifdef CONFIG_SUITEB
+int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
+		      const u8 *spa, u8 *pmkid);
+#else /* CONFIG_SUITEB */
+static inline int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
+				    const u8 *spa, u8 *pmkid)
+{
+	return -1;
+}
+#endif /* CONFIG_SUITEB */
+
+#ifdef CONFIG_SUITEB192
+int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
+			  const u8 *spa, u8 *pmkid);
+#else /* CONFIG_SUITEB192 */
+static inline int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len,
+					const u8 *aa, const u8 *spa, u8 *pmkid)
+{
+	return -1;
+}
+#endif /* CONFIG_SUITEB192 */
+
 const char * wpa_cipher_txt(int cipher);
 
 int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
@@ -327,24 +377,24 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
 int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
 		     struct wpa_ie_data *data);
 
-int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
-		      u8 *mic);
 int wpa_compare_rsn_ie(int ft_initial_assoc,
 		       const u8 *ie1, size_t ie1len,
 		       const u8 *ie2, size_t ie2len);
 
-void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
-		    const u8 *addr1, const u8 *addr2,
-		    const u8 *nonce1, const u8 *nonce2,
-		    u8 *ptk, size_t ptk_len, int use_sha256);
+int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
+		      const u8 *buf, size_t len, u8 *mic);
+int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
+		   const u8 *addr1, const u8 *addr2,
+		   const u8 *nonce1, const u8 *nonce2,
+		   struct wpa_ptk *ptk, int akmp, int cipher);
 
 void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
 	       u8 *pmkid, int use_sha256);
 
 int wpa_cipher_key_len(int cipher);
-
+int wpa_cipher_rsc_len(int cipher);
 int wpa_cipher_to_alg(int cipher);
-
+int wpa_cipher_valid_mgmt_group(int cipher);
 u32 wpa_cipher_to_suite(int proto, int cipher);
 
 int wpa_cipher_put_suites(u8 *pos, int ciphers);
@@ -353,5 +403,6 @@ int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
            struct wpa_ie_data *data);
 
 int rsn_cipher_put_suites(u8 *pos, int ciphers);
+unsigned int wpa_mic_len(int akmp);
 
 #endif /* WPA_COMMON_H */

+ 327 - 0
components/wpa_supplicant/src/crypto/aes-gcm.c

@@ -0,0 +1,327 @@
+/*
+ * Galois/Counter Mode (GCM) and GMAC with AES
+ *
+ * Copyright (c) 2012, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "aes.h"
+#include "aes_wrap.h"
+
+static void inc32(u8 *block)
+{
+	u32 val;
+	val = WPA_GET_BE32(block + AES_BLOCK_SIZE - 4);
+	val++;
+	WPA_PUT_BE32(block + AES_BLOCK_SIZE - 4, val);
+}
+
+
+static void xor_block(u8 *dst, const u8 *src)
+{
+	u32 *d = (u32 *) dst;
+	u32 *s = (u32 *) src;
+	*d++ ^= *s++;
+	*d++ ^= *s++;
+	*d++ ^= *s++;
+	*d++ ^= *s++;
+}
+
+
+static void shift_right_block(u8 *v)
+{
+	u32 val;
+
+	val = WPA_GET_BE32(v + 12);
+	val >>= 1;
+	if (v[11] & 0x01)
+		val |= 0x80000000;
+	WPA_PUT_BE32(v + 12, val);
+
+	val = WPA_GET_BE32(v + 8);
+	val >>= 1;
+	if (v[7] & 0x01)
+		val |= 0x80000000;
+	WPA_PUT_BE32(v + 8, val);
+
+	val = WPA_GET_BE32(v + 4);
+	val >>= 1;
+	if (v[3] & 0x01)
+		val |= 0x80000000;
+	WPA_PUT_BE32(v + 4, val);
+
+	val = WPA_GET_BE32(v);
+	val >>= 1;
+	WPA_PUT_BE32(v, val);
+}
+
+
+/* Multiplication in GF(2^128) */
+static void gf_mult(const u8 *x, const u8 *y, u8 *z)
+{
+	u8 v[16];
+	int i, j;
+
+	os_memset(z, 0, 16); /* Z_0 = 0^128 */
+	os_memcpy(v, y, 16); /* V_0 = Y */
+
+	for (i = 0; i < 16; i++) {
+		for (j = 0; j < 8; j++) {
+			if (x[i] & BIT(7 - j)) {
+				/* Z_(i + 1) = Z_i XOR V_i */
+				xor_block(z, v);
+			} else {
+				/* Z_(i + 1) = Z_i */
+			}
+
+			if (v[15] & 0x01) {
+				/* V_(i + 1) = (V_i >> 1) XOR R */
+				shift_right_block(v);
+				/* R = 11100001 || 0^120 */
+				v[0] ^= 0xe1;
+			} else {
+				/* V_(i + 1) = V_i >> 1 */
+				shift_right_block(v);
+			}
+		}
+	}
+}
+
+
+static void ghash_start(u8 *y)
+{
+	/* Y_0 = 0^128 */
+	os_memset(y, 0, 16);
+}
+
+
+static void ghash(const u8 *h, const u8 *x, size_t xlen, u8 *y)
+{
+	size_t m, i;
+	const u8 *xpos = x;
+	u8 tmp[16];
+
+	m = xlen / 16;
+
+	for (i = 0; i < m; i++) {
+		/* Y_i = (Y^(i-1) XOR X_i) dot H */
+		xor_block(y, xpos);
+		xpos += 16;
+
+		/* dot operation:
+		 * multiplication operation for binary Galois (finite) field of
+		 * 2^128 elements */
+		gf_mult(y, h, tmp);
+		os_memcpy(y, tmp, 16);
+	}
+
+	if (x + xlen > xpos) {
+		/* Add zero padded last block */
+		size_t last = x + xlen - xpos;
+		os_memcpy(tmp, xpos, last);
+		os_memset(tmp + last, 0, sizeof(tmp) - last);
+
+		/* Y_i = (Y^(i-1) XOR X_i) dot H */
+		xor_block(y, tmp);
+
+		/* dot operation:
+		 * multiplication operation for binary Galois (finite) field of
+		 * 2^128 elements */
+		gf_mult(y, h, tmp);
+		os_memcpy(y, tmp, 16);
+	}
+
+	/* Return Y_m */
+}
+
+
+static void aes_gctr(void *aes, const u8 *icb, const u8 *x, size_t xlen, u8 *y)
+{
+	size_t i, n, last;
+	u8 cb[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
+	const u8 *xpos = x;
+	u8 *ypos = y;
+
+	if (xlen == 0)
+		return;
+
+	n = xlen / 16;
+
+	os_memcpy(cb, icb, AES_BLOCK_SIZE);
+	/* Full blocks */
+	for (i = 0; i < n; i++) {
+		aes_encrypt(aes, cb, ypos);
+		xor_block(ypos, xpos);
+		xpos += AES_BLOCK_SIZE;
+		ypos += AES_BLOCK_SIZE;
+		inc32(cb);
+	}
+
+	last = x + xlen - xpos;
+	if (last) {
+		/* Last, partial block */
+		aes_encrypt(aes, cb, tmp);
+		for (i = 0; i < last; i++)
+			*ypos++ = *xpos++ ^ tmp[i];
+	}
+}
+
+
+static void * aes_gcm_init_hash_subkey(const u8 *key, size_t key_len, u8 *H)
+{
+	void *aes;
+
+	aes = aes_encrypt_init(key, key_len);
+	if (aes == NULL)
+		return NULL;
+
+	/* Generate hash subkey H = AES_K(0^128) */
+	os_memset(H, 0, AES_BLOCK_SIZE);
+	aes_encrypt(aes, H, H);
+	wpa_hexdump_key(MSG_EXCESSIVE, "Hash subkey H for GHASH",
+			H, AES_BLOCK_SIZE);
+	return aes;
+}
+
+
+static void aes_gcm_prepare_j0(const u8 *iv, size_t iv_len, const u8 *H, u8 *J0)
+{
+	u8 len_buf[16];
+
+	if (iv_len == 12) {
+		/* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */
+		os_memcpy(J0, iv, iv_len);
+		os_memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len);
+		J0[AES_BLOCK_SIZE - 1] = 0x01;
+	} else {
+		/*
+		 * s = 128 * ceil(len(IV)/128) - len(IV)
+		 * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64)
+		 */
+		ghash_start(J0);
+		ghash(H, iv, iv_len, J0);
+		WPA_PUT_BE64(len_buf, 0);
+		WPA_PUT_BE64(len_buf + 8, iv_len * 8);
+		ghash(H, len_buf, sizeof(len_buf), J0);
+	}
+}
+
+
+static void aes_gcm_gctr(void *aes, const u8 *J0, const u8 *in, size_t len,
+			 u8 *out)
+{
+	u8 J0inc[AES_BLOCK_SIZE];
+
+	if (len == 0)
+		return;
+
+	os_memcpy(J0inc, J0, AES_BLOCK_SIZE);
+	inc32(J0inc);
+	aes_gctr(aes, J0inc, in, len, out);
+}
+
+
+static void aes_gcm_ghash(const u8 *H, const u8 *aad, size_t aad_len,
+			  const u8 *crypt, size_t crypt_len, u8 *S)
+{
+	u8 len_buf[16];
+
+	/*
+	 * u = 128 * ceil[len(C)/128] - len(C)
+	 * v = 128 * ceil[len(A)/128] - len(A)
+	 * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64)
+	 * (i.e., zero padded to block size A || C and lengths of each in bits)
+	 */
+	ghash_start(S);
+	ghash(H, aad, aad_len, S);
+	ghash(H, crypt, crypt_len, S);
+	WPA_PUT_BE64(len_buf, aad_len * 8);
+	WPA_PUT_BE64(len_buf + 8, crypt_len * 8);
+	ghash(H, len_buf, sizeof(len_buf), S);
+
+	wpa_hexdump_key(MSG_EXCESSIVE, "S = GHASH_H(...)", S, 16);
+}
+
+
+/**
+ * aes_gcm_ae - GCM-AE_K(IV, P, A)
+ */
+int aes_gcm_ae(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len,
+	       const u8 *plain, size_t plain_len,
+	       const u8 *aad, size_t aad_len, u8 *crypt, u8 *tag)
+{
+	u8 H[AES_BLOCK_SIZE];
+	u8 J0[AES_BLOCK_SIZE];
+	u8 S[16];
+	void *aes;
+
+	aes = aes_gcm_init_hash_subkey(key, key_len, H);
+	if (aes == NULL)
+		return -1;
+
+	aes_gcm_prepare_j0(iv, iv_len, H, J0);
+
+	/* C = GCTR_K(inc_32(J_0), P) */
+	aes_gcm_gctr(aes, J0, plain, plain_len, crypt);
+
+	aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S);
+
+	/* T = MSB_t(GCTR_K(J_0, S)) */
+	aes_gctr(aes, J0, S, sizeof(S), tag);
+
+	/* Return (C, T) */
+
+	aes_encrypt_deinit(aes);
+
+	return 0;
+}
+
+
+/**
+ * aes_gcm_ad - GCM-AD_K(IV, C, A, T)
+ */
+int aes_gcm_ad(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len,
+	       const u8 *crypt, size_t crypt_len,
+	       const u8 *aad, size_t aad_len, const u8 *tag, u8 *plain)
+{
+	u8 H[AES_BLOCK_SIZE];
+	u8 J0[AES_BLOCK_SIZE];
+	u8 S[16], T[16];
+	void *aes;
+
+	aes = aes_gcm_init_hash_subkey(key, key_len, H);
+	if (aes == NULL)
+		return -1;
+
+	aes_gcm_prepare_j0(iv, iv_len, H, J0);
+
+	/* P = GCTR_K(inc_32(J_0), C) */
+	aes_gcm_gctr(aes, J0, crypt, crypt_len, plain);
+
+	aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S);
+
+	/* T' = MSB_t(GCTR_K(J_0, S)) */
+	aes_gctr(aes, J0, S, sizeof(S), T);
+
+	aes_encrypt_deinit(aes);
+
+	if (os_memcmp_const(tag, T, 16) != 0) {
+		wpa_printf(MSG_EXCESSIVE, "GCM: Tag mismatch");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+int aes_gmac(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len,
+	     const u8 *aad, size_t aad_len, u8 *tag)
+{
+	return aes_gcm_ae(key, key_len, iv, iv_len, NULL, 0, aad, aad_len, NULL,
+			  tag);
+}

+ 17 - 14
components/wpa_supplicant/src/crypto/crypto_ops.c

@@ -1,16 +1,8 @@
-// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #include "utils/common.h"
 #include "aes_wrap.h"
@@ -44,6 +36,16 @@ static void esp_aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
 	aes_decrypt(ctx, crypt, plain);
 }
 
+static int esp_aes_gmac(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len,
+			const u8 *aad, size_t aad_len, u8 *tag)
+{
+#if CONFIG_GMAC
+	return aes_gmac(key, key_len, iv, iv_len, aad, aad_len, tag);
+#else
+	return 0;
+#endif
+}
+
 /*
  * This structure is used to set the cyrpto callback function for station to connect when in security mode.
  * These functions either call MbedTLS API's if USE_MBEDTLS_CRYPTO flag is set through Kconfig, or native
@@ -76,7 +78,8 @@ const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = {
     .aes_128_decrypt = (esp_aes_128_decrypt_t)aes_128_cbc_decrypt,
     .omac1_aes_128 = (esp_omac1_aes_128_t)omac1_aes_128,
     .ccmp_decrypt = (esp_ccmp_decrypt_t)ccmp_decrypt,
-    .ccmp_encrypt = (esp_ccmp_encrypt_t)ccmp_encrypt
+    .ccmp_encrypt = (esp_ccmp_encrypt_t)ccmp_encrypt,
+    .aes_gmac = (esp_aes_gmac_t)esp_aes_gmac,
 };
 
 const mesh_crypto_funcs_t g_wifi_default_mesh_crypto_funcs = {

+ 108 - 0
components/wpa_supplicant/src/crypto/sha384-prf.c

@@ -0,0 +1,108 @@
+/*
+ * SHA384-based KDF (IEEE 802.11ac)
+ * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "sha384.h"
+#include "crypto.h"
+
+
+/**
+ * sha384_prf - SHA384-based Key derivation function (IEEE 802.11ac, 11.6.1.7.2)
+ * @key: Key for KDF
+ * @key_len: Length of the key in bytes
+ * @label: A unique label for each purpose of the PRF
+ * @data: Extra data to bind into the key
+ * @data_len: Length of the data
+ * @buf: Buffer for the generated pseudo-random key
+ * @buf_len: Number of bytes of key to generate
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is used to derive new, cryptographically separate keys from a
+ * given key.
+ */
+int sha384_prf(const u8 *key, size_t key_len, const char *label,
+	       const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
+{
+	return sha384_prf_bits(key, key_len, label, data, data_len, buf,
+			       buf_len * 8);
+}
+
+
+/**
+ * sha384_prf_bits - IEEE Std 802.11ac-2013, 11.6.1.7.2 Key derivation function
+ * @key: Key for KDF
+ * @key_len: Length of the key in bytes
+ * @label: A unique label for each purpose of the PRF
+ * @data: Extra data to bind into the key
+ * @data_len: Length of the data
+ * @buf: Buffer for the generated pseudo-random key
+ * @buf_len: Number of bits of key to generate
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is used to derive new, cryptographically separate keys from a
+ * given key. If the requested buf_len is not divisible by eight, the least
+ * significant 1-7 bits of the last octet in the output are not part of the
+ * requested output.
+ */
+int sha384_prf_bits(const u8 *key, size_t key_len, const char *label,
+		    const u8 *data, size_t data_len, u8 *buf,
+		    size_t buf_len_bits)
+{
+	u16 counter = 1;
+	size_t pos, plen;
+	u8 hash[SHA384_MAC_LEN];
+	const u8 *addr[4];
+	size_t len[4];
+	u8 counter_le[2], length_le[2];
+	size_t buf_len = (buf_len_bits + 7) / 8;
+
+	addr[0] = counter_le;
+	len[0] = 2;
+	addr[1] = (u8 *) label;
+	len[1] = os_strlen(label);
+	addr[2] = data;
+	len[2] = data_len;
+	addr[3] = length_le;
+	len[3] = sizeof(length_le);
+
+	WPA_PUT_LE16(length_le, buf_len_bits);
+	pos = 0;
+	while (pos < buf_len) {
+		plen = buf_len - pos;
+		WPA_PUT_LE16(counter_le, counter);
+		if (plen >= SHA384_MAC_LEN) {
+			if (hmac_sha384_vector(key, key_len, 4, addr, len,
+					       &buf[pos]) < 0)
+				return -1;
+			pos += SHA384_MAC_LEN;
+		} else {
+			if (hmac_sha384_vector(key, key_len, 4, addr, len,
+					       hash) < 0)
+				return -1;
+			os_memcpy(&buf[pos], hash, plen);
+			pos += plen;
+			break;
+		}
+		counter++;
+	}
+
+	/*
+	 * Mask out unused bits in the last octet if it does not use all the
+	 * bits.
+	 */
+	if (buf_len_bits % 8) {
+		u8 mask = 0xff << (8 - buf_len_bits % 8);
+		buf[pos - 1] &= mask;
+	}
+
+	forced_memzero(hash, sizeof(hash));
+
+	return 0;
+}

+ 101 - 18
components/wpa_supplicant/src/crypto/tls_mbedtls.c

@@ -1,17 +1,7 @@
-/**
- * Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+/*
+ * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * SPDX-License-Identifier: Apache-2.0
  */
 
 #include "utils/includes.h"
@@ -196,6 +186,35 @@ static int set_ca_cert(tls_context_t *tls, const unsigned char *cacert, size_t c
 	return 0;
 }
 
+#ifdef CONFIG_SUITEB192
+static int tls_sig_hashes_for_suiteb[] = {
+#if defined(MBEDTLS_SHA512_C)
+	MBEDTLS_MD_SHA512,
+	MBEDTLS_MD_SHA384,
+#endif
+	MBEDTLS_MD_NONE
+};
+
+const mbedtls_x509_crt_profile suiteb_mbedtls_x509_crt_profile =
+{
+#if defined(MBEDTLS_SHA512_C)
+	MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
+	MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ) |
+#endif
+	0,
+	0xFFFFFFF, /* Any PK alg    */
+	MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
+	1024,
+};
+
+static void tls_set_suiteb_config(tls_context_t *tls)
+{
+	const mbedtls_x509_crt_profile *crt_profile = &suiteb_mbedtls_x509_crt_profile;
+	mbedtls_ssl_conf_cert_profile(&tls->conf, crt_profile);
+	mbedtls_ssl_conf_sig_hashes(&tls->conf, tls_sig_hashes_for_suiteb);
+}
+#endif
+
 static int tls_sig_hashes_for_eap[] = {
 #if defined(MBEDTLS_SHA512_C)
 	MBEDTLS_MD_SHA512,
@@ -380,11 +399,64 @@ static const int eap_ciphersuite_preference[] =
 	MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA,
 	MBEDTLS_TLS_PSK_WITH_RC4_128_SHA,
 #endif
+	0
 };
 
-static void tls_set_ciphersuite(tls_context_t *tls)
+#ifdef CONFIG_SUITEB192
+static const int suiteb_rsa_ciphersuite_preference[] =
+{
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA512_C)
+	MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+	MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+#endif
+#endif
+	0
+};
+
+static const int suiteb_ecc_ciphersuite_preference[] =
+{
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA512_C)
+	MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+#endif
+#endif
+	0
+};
+static const int suiteb_ciphersuite_preference[] =
+{
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA512_C)
+	MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+	MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+	MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+#endif
+#endif
+	0
+};
+#endif
+
+static void tls_set_ciphersuite(const struct tls_connection_params *cfg, tls_context_t *tls)
 {
 	/* Only set ciphersuite if cert's key length is high or ciphersuites are set by user */
+#ifdef CONFIG_SUITEB192
+	if (cfg->flags & TLS_CONN_SUITEB) {
+		/* cipher suites will be set based on certificate */
+		mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(&tls->clientkey);
+		if (pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) {
+			mbedtls_ssl_conf_ciphersuites(&tls->conf,
+						      suiteb_rsa_ciphersuite_preference);
+		} else if (pk_alg == MBEDTLS_PK_ECDSA ||
+			   pk_alg == MBEDTLS_PK_ECKEY ||
+			   pk_alg == MBEDTLS_PK_ECKEY_DH) {
+			mbedtls_ssl_conf_ciphersuites(&tls->conf,
+						      suiteb_ecc_ciphersuite_preference);
+		} else {
+			mbedtls_ssl_conf_ciphersuites(&tls->conf,
+						      suiteb_ciphersuite_preference);
+		}
+	} else
+#endif
 	if (tls->ciphersuite[0]) {
 		mbedtls_ssl_conf_ciphersuites(&tls->conf, tls->ciphersuite);
 	} else if (mbedtls_pk_get_bitlen(&tls->clientkey) > 2048 ||
@@ -396,20 +468,31 @@ static void tls_set_ciphersuite(tls_context_t *tls)
 static int set_client_config(const struct tls_connection_params *cfg, tls_context_t *tls)
 {
 	int ret;
+	int preset = MBEDTLS_SSL_PRESET_DEFAULT;
 	assert(cfg != NULL);
 	assert(tls != NULL);
 
+#ifdef CONFIG_SUITEB192
+	if (cfg->flags & TLS_CONN_SUITEB)
+		preset = MBEDTLS_SSL_PRESET_SUITEB;
+#endif
 	ret = mbedtls_ssl_config_defaults(&tls->conf,
 					MBEDTLS_SSL_IS_CLIENT,
 					MBEDTLS_SSL_TRANSPORT_STREAM,
-					MBEDTLS_SSL_PRESET_DEFAULT);
+					preset);
 	if (ret != 0) {
 		wpa_printf(MSG_ERROR, "mbedtls_ssl_config_defaults returned -0x%x", -ret);
 		return ret;
 	}
 
-	/* Enable SHA1 support since it's not enabled by default in mbedtls */
-	tls_enable_sha1_config(tls);
+	if (preset != MBEDTLS_SSL_PRESET_SUITEB) {
+		/* Enable SHA1 support since it's not enabled by default in mbedtls */
+		tls_enable_sha1_config(tls);
+#ifdef CONFIG_SUITEB192
+	} else {
+		tls_set_suiteb_config(tls);
+#endif
+	}
 
 	if (cfg->ca_cert_blob != NULL) {
 		ret = set_ca_cert(tls, cfg->ca_cert_blob, cfg->ca_cert_blob_len);
@@ -432,7 +515,7 @@ static int set_client_config(const struct tls_connection_params *cfg, tls_contex
 	/* Usages of default ciphersuites can take a lot of time on low end device
 	 * and can cause watchdog. Enabling the ciphers which are secured enough
 	 * but doesn't take that much processing power */
-	tls_set_ciphersuite(tls);
+	tls_set_ciphersuite(cfg, tls);
 
 	return 0;
 }

+ 4 - 0
components/wpa_supplicant/src/eap_peer/eap.c

@@ -483,6 +483,10 @@ int eap_peer_config_init(
 		sm->config.phase2 = "auth=MSCHAPV2";
 	}
 
+	if (g_wpa_suiteb_certification) {
+		sm->config.flags = TLS_CONN_SUITEB;
+	}
+
 	return 0;
 
 }

+ 2 - 0
components/wpa_supplicant/src/eap_peer/eap.h

@@ -41,6 +41,8 @@ int g_wpa_new_password_len;
 
 char *g_wpa_ttls_phase2_type;
 
+bool g_wpa_suiteb_certification;
+
 const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len);
 void eap_deinit_prev_method(struct eap_sm *sm, const char *txt);
 struct wpabuf * eap_sm_build_nak(struct eap_sm *sm, EapType type, u8 id);

+ 5 - 0
components/wpa_supplicant/src/eap_peer/eap_tls_common.c

@@ -79,6 +79,11 @@ static void eap_tls_params_from_conf1(struct tls_connection_params *params,
 		params->flags |= TLS_CONN_DISABLE_TIME_CHECKS;
 	else
 		params->flags &= (~TLS_CONN_DISABLE_TIME_CHECKS);
+
+	if (config->flags & TLS_CONN_SUITEB)
+		params->flags |= TLS_CONN_SUITEB;
+	else
+		params->flags &= (~TLS_CONN_SUITEB);
 }
 
 static int eap_tls_params_from_conf(struct eap_sm *sm,

+ 5 - 1
components/wpa_supplicant/src/rsn_supp/pmksa_cache.c

@@ -109,7 +109,7 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
     struct rsn_pmksa_cache_entry *entry, *pos, *prev;
     int64_t now_sec = esp_timer_get_time() / 1e6;
 
-    if (pmk_len > PMK_LEN)
+    if (pmk_len > PMK_LEN_MAX)
         return NULL;
 
     if (wpa_key_mgmt_suite_b(akmp) && !kck)
@@ -122,6 +122,10 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
     entry->pmk_len = pmk_len;
     if (pmkid)
         os_memcpy(entry->pmkid, pmkid, PMKID_LEN);
+    else if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
+        rsn_pmkid_suite_b_192(kck, kck_len, aa, spa, entry->pmkid);
+    else if (wpa_key_mgmt_suite_b(akmp))
+        rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
     else
         rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
                   wpa_key_mgmt_sha256(akmp));

+ 1 - 1
components/wpa_supplicant/src/rsn_supp/pmksa_cache.h

@@ -15,7 +15,7 @@
 struct rsn_pmksa_cache_entry {
     struct rsn_pmksa_cache_entry *next;
     u8 pmkid[PMKID_LEN];
-    u8 pmk[PMK_LEN];
+    u8 pmk[PMK_LEN_MAX];
     size_t pmk_len;
     os_time_t expiration;
     int akmp; /* WPA_KEY_MGMT_* */

Разница между файлами не показана из-за своего большого размера
+ 283 - 317
components/wpa_supplicant/src/rsn_supp/wpa.c


+ 1 - 1
components/wpa_supplicant/src/rsn_supp/wpa_i.h

@@ -30,7 +30,7 @@ struct install_key {
  * struct wpa_sm - Internal WPA state machine data
  */
 struct wpa_sm {
-    u8 pmk[PMK_LEN];
+    u8 pmk[PMK_LEN_MAX];
     size_t pmk_len;
 
     struct wpa_ptk ptk, tptk;

+ 23 - 34
components/wpa_supplicant/src/rsn_supp/wpa_ie.c

@@ -115,16 +115,16 @@ static int  wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
 }
 
 
-static int  wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
+static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
                   int pairwise_cipher, int group_cipher,
                   int key_mgmt, int mgmt_group_cipher,
                   struct wpa_sm *sm)
 {
-#ifndef CONFIG_NO_WPA2
     u8 *pos;
     struct rsn_ie_hdr *hdr;
     u16 capab;
     u8 min_len = 0;
+    u32 suite;
 
     if (rsn_ie_len < sizeof(*hdr) + RSN_SELECTOR_LEN +
             2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN + 2 +
@@ -134,11 +134,6 @@ static int  wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
         return -1;
     }
 
-    /* For WPA2-PSK, if the RSNE in AP beacon/probe response doesn't specify the
-     * pairwise cipher or AKM suite, the RSNE IE in association request
-     * should only contain group cihpher suite, otherwise the WPA2 improvements
-     * certification will fail.
-     */
     if ( (sm->ap_notify_completed_rsne == true) || (key_mgmt == WPA_KEY_MGMT_IEEE8021X) ) {
         min_len = sizeof(*hdr) + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN + 2;
     } else {
@@ -154,19 +149,13 @@ static int  wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
     WPA_PUT_LE16(hdr->version, RSN_VERSION);
     pos = (u8 *) (hdr + 1);
 
-    if (group_cipher == WPA_CIPHER_CCMP) {
-        RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
-    } else if (group_cipher == WPA_CIPHER_TKIP) {
-        RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
-    } else if (group_cipher == WPA_CIPHER_WEP104) {
-        RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP104);
-    } else if (group_cipher == WPA_CIPHER_WEP40) {
-        RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP40);
-    } else {
-        wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
-               group_cipher);
-        return -1;
+    suite = wpa_cipher_to_suite(WPA_PROTO_RSN, group_cipher);
+    if (suite == 0) {
+            wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
+                       group_cipher);
+            return -1;
     }
+    RSN_SELECTOR_PUT(pos, suite);
     pos += RSN_SELECTOR_LEN;
 
     if ( (sm->ap_notify_completed_rsne == false) && (key_mgmt != WPA_KEY_MGMT_IEEE8021X) ) {
@@ -176,21 +165,19 @@ static int  wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
 
     *pos++ = 1;
     *pos++ = 0;
-    if (pairwise_cipher == WPA_CIPHER_CCMP) {
-        RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
-    } else if (pairwise_cipher == WPA_CIPHER_TKIP) {
-        RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
-    } else if (pairwise_cipher == WPA_CIPHER_NONE) {
-        RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
-    } else {
-        wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
-               pairwise_cipher);
-        return -1;
+    suite = wpa_cipher_to_suite(WPA_PROTO_RSN, pairwise_cipher);
+    if (suite == 0 ||
+         (pairwise_cipher == WPA_CIPHER_NONE)) {
+            wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
+                       pairwise_cipher);
+            return -1;
     }
+    RSN_SELECTOR_PUT(pos, suite);
     pos += RSN_SELECTOR_LEN;
 
     *pos++ = 1;
     *pos++ = 0;
+
     if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
         RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
     } else if (key_mgmt == WPA_KEY_MGMT_PSK) {
@@ -211,6 +198,10 @@ static int  wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
         RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
 #endif /* CONFIG_WPA3_SAE */
 #endif /* CONFIG_IEEE80211W */
+    } else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
+        RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192);
+    } else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
+        RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
     } else {
         wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
                key_mgmt);
@@ -250,7 +241,7 @@ static int  wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
     }
 
 #ifdef CONFIG_IEEE80211W
-    if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
+    if (wpa_cipher_valid_mgmt_group(mgmt_group_cipher)) {
         if (!sm->cur_pmksa) {
             /* 0 PMKID Count */
             WPA_PUT_LE16(pos, 0);
@@ -258,7 +249,8 @@ static int  wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
         }
 
         /* Management Group Cipher Suite */
-        RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
+        RSN_SELECTOR_PUT(pos, wpa_cipher_to_suite(WPA_PROTO_RSN,
+                                                  mgmt_group_cipher));;
         pos += RSN_SELECTOR_LEN;
     }
 #endif /* CONFIG_IEEE80211W */
@@ -268,9 +260,6 @@ static int  wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
     WPA_ASSERT((size_t) (pos - rsn_ie) <= rsn_ie_len);
 
     return pos - rsn_ie;
-#else /* CONFIG_NO_WPA2 */
-    return -1;
-#endif /* CONFIG_NO_WPA2 */
 }
 
 

+ 1 - 0
components/wpa_supplicant/src/tls/tls.h

@@ -82,6 +82,7 @@ struct tls_config {
 #define TLS_CONN_DISABLE_SESSION_TICKET BIT(2)
 #define TLS_CONN_REQUEST_OCSP BIT(3)
 #define TLS_CONN_REQUIRE_OCSP BIT(4)
+#define TLS_CONN_SUITEB BIT(11)
 
 /**
  * struct tls_connection_params - Parameters for TLS connection

+ 1 - 1
docs/en/api-guides/wifi.rst

@@ -1428,7 +1428,7 @@ For establishing a secure connection, AP and Station negotiate and agree on the
      - MSCHAP and MSCHAP-V2.
 
 
-Detailed information on creating certificates and how to run wpa2_enterprise example on {IDF_TARGET_NAME} can be found in :example:`wifi/wpa2_enterprise`.
+Detailed information on creating certificates and how to run wpa2_enterprise example on {IDF_TARGET_NAME} can be found in :example:`wifi/wifi_enterprise`.
 
 .. only:: esp32s2 or esp32c3
 

+ 0 - 0
examples/wifi/wpa2_enterprise/CMakeLists.txt → examples/wifi/wifi_enterprise/CMakeLists.txt


+ 0 - 0
examples/wifi/wpa2_enterprise/Makefile → examples/wifi/wifi_enterprise/Makefile


+ 16 - 15
examples/wifi/wpa2_enterprise/README.md → examples/wifi/wifi_enterprise/README.md

@@ -1,6 +1,6 @@
 # WPA2 Enterprise Example
 
-This example shows how ESP32 connects to AP with wpa2 enterprise encryption. Example does the following steps:
+This example shows how ESP32 connects to AP with Wi-Fi enterprise encryption. The example does the following steps:
 
 1. Install CA certificate which is optional.
 2. Install client certificate and client key which is required in TLS method and optional in PEAP and TTLS methods.
@@ -9,12 +9,13 @@ This example shows how ESP32 connects to AP with wpa2 enterprise encryption. Exa
 5. Enable wpa2 enterprise.
 6. Connect to AP.
 
-*Note:* 1. The certificates currently are generated and are present in examples.wifi/wpa2_enterprise/main folder.
+*Note:* 1. The certificates currently are generated and are present in examples/wifi/wifi_enterprise/main folder.
         2. The expiration date of the certificates is 2027/06/05.
+        3. In case using suite-b, please use appropriate certificates such as RSA-3072 or p384 EC certificates.
 
 The steps to create new certificates are given below.
 
-## The file wpa2_ca.pem, wpa2_ca.key, wpa2_server.pem, wpa2_server.crt and wpa2_server.key can be used to configure AP with wpa2 enterprise encryption. 
+## The file ca.pem, ca.key, server.pem, server.crt and server.key can be used to configure AP with enterprise encryption.
 
 ## How to use Example
 
@@ -36,7 +37,7 @@ idf.py menuconfig
 idf.py -p PORT flash monitor
 ```
 
-## Steps to create wpa2_ent openssl certs
+## Steps to create enterprise openssl certs
 
 1. make directry tree
 
@@ -56,27 +57,27 @@ idf.py -p PORT flash monitor
       extendedKeyUsage = 1.3.6.1.5.5.7.3.1
 
 2. ca.pem: root certificate, foundation of certificate verigy
-  openssl req -new -x509 -keyout wpa2_ca.key -out wpa2_ca.pem
+  openssl req -new -x509 -keyout ca.key -out ca.pem
 
 3. generate rsa keys for client and server
-  openssl genrsa -out wpa2_client.key 2048
-  openssl genrsa -out wpa2_server.key 2048
+  openssl genrsa -out client.key 2048
+  openssl genrsa -out server.key 2048
 
 4. generate certificate signing req for both client and server
-  openssl req -new -key wpa2_client.key -out wpa2_client.csr
-  openssl req -new -key wpa2_server.key -out wpa2_server.csr
+  openssl req -new -key client.key -out client.csr
+  openssl req -new -key server.key -out server.csr
 
 5. create certs (.crt) for client nd server
-  openssl ca -batch -keyfile wpa2_ca.key -cert wpa2_ca.pem -in wpa2_client.csr -key (password) -out wpa2_client.crt -extensions xpserver_ext -extfile xpextensions
-  openssl ca -batch -keyfile wpa2_ca.key -cert wpa2_ca.pem -in wpa2_server.csr -key (password) -out wpa2_server.crt -extensions xpserver_ext -extfile xpextensions
+  openssl ca -batch -keyfile ca.key -cert ca.pem -in client.csr -key (password) -out client.crt -extensions xpserver_ext -extfile xpextensions
+  openssl ca -batch -keyfile ca.key -cert ca.pem -in server.csr -key (password) -out server.crt -extensions xpserver_ext -extfile xpextensions
 
 6. export .p12 files
-  openssl pkcs12 -export -out wpa2_client.p12 -inkey wpa2_client.key -in wpa2_client.crt
-  openssl pkcs12 -export -out wpa2_server.p12 -inkey wpa2_server.key -in wpa2_server.crt
+  openssl pkcs12 -export -out client.p12 -inkey client.key -in client.crt
+  openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt
 
 7. create .pem files
-  openssl pkcs12 -in wpa2_client.p12 -out wpa2_client.pem
-  openssl pkcs12 -in wpa2_server.p12 -out wpa2_server.pem
+  openssl pkcs12 -in client.p12 -out client.pem
+  openssl pkcs12 -in server.p12 -out server.pem
 
    
 

+ 4 - 0
examples/wifi/wifi_enterprise/main/CMakeLists.txt

@@ -0,0 +1,4 @@
+# Embed CA, certificate & key directly into binary
+idf_component_register(SRCS "wifi_enterprise_main.c"
+                    INCLUDE_DIRS "."
+                    EMBED_TXTFILES ca.pem client.crt client.key)

+ 24 - 5
examples/wifi/wpa2_enterprise/main/Kconfig.projbuild → examples/wifi/wifi_enterprise/main/Kconfig.projbuild

@@ -1,16 +1,35 @@
 menu "Example Configuration"
 
+    choice
+        prompt "Enterprise configuration to be used"
+        default EXAMPLE_WPA_WPA2_ENTERPRISE
+        config EXAMPLE_WPA_WPA2_ENTERPRISE
+            bool "WPA_WPA2_ENT"
+        config EXAMPLE_WPA3_ENTERPRISE
+            bool "WPA3_ENT"
+        config EXAMPLE_WPA3_192BIT_ENTERPRISE
+            bool "WPA3_192BIT_ENT"
+            depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
+    endchoice
+
     config EXAMPLE_WIFI_SSID
         string "WiFi SSID"
         default "wpa2_test"
         help
             SSID (network name) for the example to connect to.
 
-    config EXAMPLE_VALIDATE_SERVER_CERT
-        bool "Validate server"
-        default y
-        help
-            Validate the servers' certificate using CA cert.
+    if EXAMPLE_WPA_WPA2_ENTERPRISE
+        config EXAMPLE_VALIDATE_SERVER_CERT
+            bool "Validate server"
+            default y
+            help
+                Validate the servers' certificate using CA cert.
+    endif
+
+    if !EXAMPLE_WPA_WPA2_ENTERPRISE
+        config EXAMPLE_VALIDATE_SERVER_CERT
+            default y
+    endif
 
     choice
         prompt "EAP method for the example to use"

+ 0 - 0
examples/wifi/wpa2_enterprise/main/wpa2_ca.pem → examples/wifi/wifi_enterprise/main/ca.pem


+ 0 - 0
examples/wifi/wpa2_enterprise/main/wpa2_client.crt → examples/wifi/wifi_enterprise/main/client.crt


+ 0 - 0
examples/wifi/wpa2_enterprise/main/wpa2_client.key → examples/wifi/wifi_enterprise/main/client.key


+ 0 - 0
examples/wifi/wpa2_enterprise/main/wpa2_client.pem → examples/wifi/wifi_enterprise/main/client.pem


+ 3 - 3
examples/wifi/wpa2_enterprise/main/component.mk → examples/wifi/wifi_enterprise/main/component.mk

@@ -5,6 +5,6 @@
 
 # embed files from the "certs" directory as binary data symbols
 # in the app
-COMPONENT_EMBED_TXTFILES := wpa2_ca.pem
-COMPONENT_EMBED_TXTFILES += wpa2_client.crt
-COMPONENT_EMBED_TXTFILES += wpa2_client.key
+COMPONENT_EMBED_TXTFILES := ca.pem
+COMPONENT_EMBED_TXTFILES += client.crt
+COMPONENT_EMBED_TXTFILES += client.key

+ 0 - 0
examples/wifi/wpa2_enterprise/main/wpa2_server.crt → examples/wifi/wifi_enterprise/main/server.crt


+ 0 - 0
examples/wifi/wpa2_enterprise/main/wpa2_server.key → examples/wifi/wifi_enterprise/main/server.key


+ 0 - 0
examples/wifi/wpa2_enterprise/main/wpa2_server.pem → examples/wifi/wifi_enterprise/main/server.pem


+ 29 - 12
examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c → examples/wifi/wifi_enterprise/main/wifi_enterprise_main.c

@@ -58,9 +58,9 @@ const int CONNECTED_BIT = BIT0;
 
 static const char *TAG = "example";
 
-/* CA cert, taken from wpa2_ca.pem
-   Client cert, taken from wpa2_client.crt
-   Client key, taken from wpa2_client.key
+/* CA cert, taken from ca.pem
+   Client cert, taken from client.crt
+   Client key, taken from client.key
 
    The PEM, CRT and KEY file were provided by the person or organization
    who configured the AP with wpa2 enterprise.
@@ -69,15 +69,15 @@ static const char *TAG = "example";
    in the component.mk COMPONENT_EMBED_TXTFILES variable.
 */
 #ifdef CONFIG_EXAMPLE_VALIDATE_SERVER_CERT
-extern uint8_t ca_pem_start[] asm("_binary_wpa2_ca_pem_start");
-extern uint8_t ca_pem_end[]   asm("_binary_wpa2_ca_pem_end");
+extern uint8_t ca_pem_start[] asm("_binary_ca_pem_start");
+extern uint8_t ca_pem_end[]   asm("_binary_ca_pem_end");
 #endif /* CONFIG_EXAMPLE_VALIDATE_SERVER_CERT */
 
 #ifdef CONFIG_EXAMPLE_EAP_METHOD_TLS
-extern uint8_t client_crt_start[] asm("_binary_wpa2_client_crt_start");
-extern uint8_t client_crt_end[]   asm("_binary_wpa2_client_crt_end");
-extern uint8_t client_key_start[] asm("_binary_wpa2_client_key_start");
-extern uint8_t client_key_end[]   asm("_binary_wpa2_client_key_end");
+extern uint8_t client_crt_start[] asm("_binary_client_crt_start");
+extern uint8_t client_crt_end[]   asm("_binary_client_crt_end");
+extern uint8_t client_key_start[] asm("_binary_client_key_start");
+extern uint8_t client_key_end[]   asm("_binary_client_key_end");
 #endif /* CONFIG_EXAMPLE_EAP_METHOD_TLS */
 
 #if defined CONFIG_EXAMPLE_EAP_METHOD_TTLS
@@ -122,6 +122,18 @@ static void initialise_wifi(void)
     wifi_config_t wifi_config = {
         .sta = {
             .ssid = EXAMPLE_WIFI_SSID,
+#if defined(CONFIG_EXAMPLE_WPA3_ENTERPRISE)
+            .pmf_cfg = {
+                .capable = true,
+                .required = false
+            },
+#endif
+#if defined (CONFIG_EXAMPLE_WPA3_192BIT_ENTERPRISE)
+            .pmf_cfg = {
+                .capable = true,
+                .required = true
+            },
+#endif
         },
     };
     ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
@@ -129,9 +141,11 @@ static void initialise_wifi(void)
     ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)EXAMPLE_EAP_ID, strlen(EXAMPLE_EAP_ID)) );
 
-#ifdef CONFIG_EXAMPLE_VALIDATE_SERVER_CERT
+#if defined(CONFIG_EXAMPLE_VALIDATE_SERVER_CERT) || \
+    defined(CONFIG_EXAMPLE_WPA3_ENTERPRISE) || \
+    defined(CONFIG_EXAMPLE_WPA3_192BIT_ENTERPRISE)
     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_ca_cert(ca_pem_start, ca_pem_bytes) );
-#endif /* CONFIG_EXAMPLE_VALIDATE_SERVER_CERT */
+#endif /* CONFIG_EXAMPLE_VALIDATE_SERVER_CERT */ /* EXAMPLE_WPA3_ENTERPRISE */
 
 #ifdef CONFIG_EXAMPLE_EAP_METHOD_TLS
     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_cert_key(client_crt_start, client_crt_bytes,\
@@ -146,7 +160,10 @@ static void initialise_wifi(void)
 #if defined CONFIG_EXAMPLE_EAP_METHOD_TTLS
     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(TTLS_PHASE2_METHOD) );
 #endif /* CONFIG_EXAMPLE_EAP_METHOD_TTLS */
-
+#if defined (CONFIG_EXAMPLE_WPA3_192BIT_ENTERPRISE)
+    ESP_LOGI(TAG, "Enabling 192 bit certification");
+    ESP_ERROR_CHECK(esp_wifi_sta_wpa2_set_suiteb_192bit_certification(true));
+#endif
     ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_enable() );
     ESP_ERROR_CHECK( esp_wifi_start() );
 }

+ 0 - 4
examples/wifi/wpa2_enterprise/main/CMakeLists.txt

@@ -1,4 +0,0 @@
-# Embed CA, certificate & key directly into binary
-idf_component_register(SRCS "wpa2_enterprise_main.c"
-                    INCLUDE_DIRS "."
-                    EMBED_TXTFILES wpa2_ca.pem wpa2_client.crt wpa2_client.key)

+ 3 - 6
tools/ci/check_copyright_ignore.txt

@@ -1218,7 +1218,6 @@ components/esp_wifi/include/esp_private/wifi_os_adapter.h
 components/esp_wifi/include/esp_private/wifi_types.h
 components/esp_wifi/include/esp_smartconfig.h
 components/esp_wifi/include/esp_wifi.h
-components/esp_wifi/include/esp_wifi_crypto_types.h
 components/esp_wifi/include/esp_wifi_default.h
 components/esp_wifi/include/esp_wifi_netif.h
 components/esp_wifi/include/smartconfig_ack.h
@@ -2945,14 +2944,12 @@ components/wifi_provisioning/src/wifi_scan.c
 components/wpa_supplicant/esp_supplicant/include/esp_dpp.h
 components/wpa_supplicant/esp_supplicant/include/esp_rrm.h
 components/wpa_supplicant/esp_supplicant/include/esp_wpa.h
-components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h
 components/wpa_supplicant/esp_supplicant/include/esp_wps.h
 components/wpa_supplicant/esp_supplicant/src/esp_dpp.c
 components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h
 components/wpa_supplicant/esp_supplicant/src/esp_hostap.c
 components/wpa_supplicant/esp_supplicant/src/esp_hostap.h
 components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h
-components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c
 components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c
 components/wpa_supplicant/esp_supplicant/src/esp_wpa3_i.h
 components/wpa_supplicant/esp_supplicant/src/esp_wpa_err.h
@@ -3002,6 +2999,7 @@ components/wpa_supplicant/src/common/wpa_supplicant_i.h
 components/wpa_supplicant/src/crypto/aes-cbc.c
 components/wpa_supplicant/src/crypto/aes-ccm.c
 components/wpa_supplicant/src/crypto/aes-ctr.c
+components/wpa_supplicant/src/crypto/aes-gcm.c
 components/wpa_supplicant/src/crypto/aes-internal-dec.c
 components/wpa_supplicant/src/crypto/aes-internal-enc.c
 components/wpa_supplicant/src/crypto/aes-internal.c
@@ -3024,7 +3022,6 @@ components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c
 components/wpa_supplicant/src/crypto/crypto_mbedtls-ec.c
 components/wpa_supplicant/src/crypto/crypto_mbedtls-rsa.c
 components/wpa_supplicant/src/crypto/crypto_mbedtls.c
-components/wpa_supplicant/src/crypto/crypto_ops.c
 components/wpa_supplicant/src/crypto/des-internal.c
 components/wpa_supplicant/src/crypto/des_i.h
 components/wpa_supplicant/src/crypto/dh_group5.c
@@ -3056,12 +3053,12 @@ components/wpa_supplicant/src/crypto/sha256.c
 components/wpa_supplicant/src/crypto/sha256.h
 components/wpa_supplicant/src/crypto/sha256_i.h
 components/wpa_supplicant/src/crypto/sha384-internal.c
+components/wpa_supplicant/src/crypto/sha384-prf.c
 components/wpa_supplicant/src/crypto/sha384-tlsprf.c
 components/wpa_supplicant/src/crypto/sha384.h
 components/wpa_supplicant/src/crypto/sha384_i.h
 components/wpa_supplicant/src/crypto/sha512-internal.c
 components/wpa_supplicant/src/crypto/sha512_i.h
-components/wpa_supplicant/src/crypto/tls_mbedtls.c
 components/wpa_supplicant/src/drivers/driver.h
 components/wpa_supplicant/src/eap_peer/chap.c
 components/wpa_supplicant/src/eap_peer/chap.h
@@ -3955,7 +3952,7 @@ examples/wifi/roaming/main/roaming_example.c
 examples/wifi/scan/main/scan.c
 examples/wifi/smart_config/main/smartconfig_main.c
 examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c
-examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c
+examples/wifi/wifi_enterprise/main/wifi_enterprise_main.c
 examples/wifi/wps/main/wps.c
 tools/ble/lib_ble_client.py
 tools/ble/lib_gap.py

Некоторые файлы не были показаны из-за большого количества измененных файлов