From 54940f58a409e3143b053b0cc2c0dfa0f8fee904 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Sat, 9 Oct 2021 22:57:32 +0530 Subject: [PATCH] esp_wifi: Add WPA3 192-bit certification support --- .../esp_supplicant/include/esp_wpa2.h | 28 +++-- .../esp_supplicant/src/esp_wpa2.c | 28 +++-- .../wpa_supplicant/src/crypto/tls_mbedtls.c | 119 +++++++++++++++--- components/wpa_supplicant/src/eap_peer/eap.c | 4 + components/wpa_supplicant/src/eap_peer/eap.h | 2 + .../src/eap_peer/eap_tls_common.c | 5 + components/wpa_supplicant/src/rsn_supp/wpa.c | 12 +- components/wpa_supplicant/src/tls/tls.h | 1 + tools/ci/check_copyright_ignore.txt | 3 - 9 files changed, 154 insertions(+), 48 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h b/components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h index c6c2930a0f..9777a424e1 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h +++ b/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 diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c index beaa5b6462..24a033d06f 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c +++ b/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 @@ -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 +} diff --git a/components/wpa_supplicant/src/crypto/tls_mbedtls.c b/components/wpa_supplicant/src/crypto/tls_mbedtls.c index 23d8d9d700..ff7cc68ba5 100644 --- a/components/wpa_supplicant/src/crypto/tls_mbedtls.c +++ b/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; } diff --git a/components/wpa_supplicant/src/eap_peer/eap.c b/components/wpa_supplicant/src/eap_peer/eap.c index a2bdf5e1ab..2367bfa5c0 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.c +++ b/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; } diff --git a/components/wpa_supplicant/src/eap_peer/eap.h b/components/wpa_supplicant/src/eap_peer/eap.h index 5432f43c32..9c488031ad 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.h +++ b/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); diff --git a/components/wpa_supplicant/src/eap_peer/eap_tls_common.c b/components/wpa_supplicant/src/eap_peer/eap_tls_common.c index 3fd0e17a77..6af5df82f6 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_tls_common.c +++ b/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, diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 87a61e8096..5e917b68ac 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -2204,14 +2204,24 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, #ifdef CONFIG_IEEE80211W if (esp_wifi_sta_pmf_enabled()) { wifi_config_t wifi_cfg; + wifi_cipher_type_t mgmt_cipher = esp_wifi_sta_get_mgmt_group_cipher(); esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg); sm->pmf_cfg = wifi_cfg.sta.pmf_cfg; - sm->mgmt_group_cipher = cipher_type_map_public_to_supp(esp_wifi_sta_get_mgmt_group_cipher()); + sm->mgmt_group_cipher = cipher_type_map_public_to_supp(mgmt_cipher); if (sm->mgmt_group_cipher == WPA_CIPHER_NONE) { wpa_printf(MSG_ERROR, "mgmt_cipher %d not supported", mgmt_cipher); return -1; } +#ifdef CONFIG_SUITEB192 + extern bool g_wpa_suiteb_certification; + if (g_wpa_suiteb_certification) { + if (mgmt_cipher != WIFI_CIPHER_TYPE_AES_GMAC256) { + wpa_printf(MSG_ERROR, "suite-b 192bit certification, only GMAC256 is supported"); + return -1; + } + } +#endif } else { memset(&sm->pmf_cfg, 0, sizeof(sm->pmf_cfg)); sm->mgmt_group_cipher = WPA_CIPHER_NONE; diff --git a/components/wpa_supplicant/src/tls/tls.h b/components/wpa_supplicant/src/tls/tls.h index a3f42231fe..163352c288 100644 --- a/components/wpa_supplicant/src/tls/tls.h +++ b/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 diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 5f2c289ec1..417c75386f 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -2944,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 @@ -3061,7 +3059,6 @@ 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