diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index 7571af4569..1b6d1b2b7a 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -316,6 +316,7 @@ menu "Wi-Fi" config ESP32_WIFI_ENABLE_WPA3_SAE bool "Enable WPA3-Personal" default y + depends on WPA_MBEDTLS_CRYPTO help Select this option to allow the device to establish a WPA3-Personal connection with eligible AP's. PMF (Protected Management Frames) is a prerequisite feature for a WPA3 connection, it needs to be diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 7783a6d315..bbe4009cee 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -642,6 +642,13 @@ menu "mbedTLS" This option is generally faster than CCM. + config MBEDTLS_NIST_KW_C + bool "NIST key wrapping (KW) and KW padding (KWP)" + default n + depends on MBEDTLS_AES_C + help + Enable NIST key wrapping and key wrapping padding. + endmenu # Symmetric Ciphers config MBEDTLS_RIPEMD160_C diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 565383e32b..1ff7ea4ad5 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -2460,6 +2460,21 @@ #undef MBEDTLS_THREADING_PTHREAD #endif +/** + * \def MBEDTLS_NIST_KW_C + * + * Enable AES key wrapping as per NIST + * + * Requires: MBEDTLS_AES_C + * + * Uncomment this to enable aes key wrap. + */ +#ifdef CONFIG_MBEDTLS_NIST_KW_C +#define MBEDTLS_NIST_KW_C +#else +#undef MBEDTLS_NIST_KW_C +#endif + /* \} name SECTION: Module configuration options */ #if defined(TARGET_LIKE_MBED) diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index 7eeabccb1c..220a0ccd76 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -7,46 +7,19 @@ set(srcs "port/os_xtensa.c" "src/common/wpa_common.c" "src/common/dpp.c" "src/utils/bitfield.c" - "src/crypto/aes-ctr.c" "src/crypto/aes-siv.c" "src/crypto/sha256-kdf.c" - "src/crypto/aes-cbc.c" - "src/crypto/aes-ccm.c" - "src/crypto/aes-internal-dec.c" - "src/crypto/aes-internal-enc.c" - "src/crypto/aes-internal.c" - "src/crypto/aes-omac1.c" - "src/crypto/aes-unwrap.c" - "src/crypto/aes-wrap.c" - "src/crypto/sha256-tlsprf.c" - "src/crypto/bignum.c" "src/crypto/ccmp.c" - "src/crypto/crypto_mbedtls.c" - "src/crypto/crypto_mbedtls-bignum.c" - "src/crypto/crypto_mbedtls-ec.c" "src/crypto/crypto_ops.c" - "src/crypto/crypto_internal-cipher.c" - "src/crypto/crypto_internal-modexp.c" - "src/crypto/crypto_internal-rsa.c" - "src/crypto/crypto_mbedtls-rsa.c" - "src/crypto/crypto_internal.c" - "src/crypto/des-internal.c" "src/crypto/dh_group5.c" "src/crypto/dh_groups.c" - "src/crypto/md4-internal.c" - "src/crypto/md5-internal.c" - "src/crypto/md5.c" "src/crypto/ms_funcs.c" - "src/crypto/rc4.c" - "src/crypto/sha1-internal.c" - "src/crypto/sha1-pbkdf2.c" - "src/crypto/sha1.c" - "src/crypto/sha256-internal.c" - "src/crypto/sha256.c" "src/crypto/sha1-tlsprf.c" "src/crypto/sha256-tlsprf.c" "src/crypto/sha384-tlsprf.c" "src/crypto/sha256-prf.c" + "src/crypto/sha1-prf.c" + "src/crypto/md4-internal.c" "src/eap_peer/chap.c" "src/eap_peer/eap.c" "src/eap_peer/eap_common.c" @@ -93,6 +66,7 @@ else() "src/tls/pkcs1.c" "src/tls/pkcs5.c" "src/tls/pkcs8.c" + "src/tls/bignum.c" "src/tls/rsa.c" "src/tls/tls_internal.c" "src/tls/tlsv1_client.c" @@ -104,8 +78,64 @@ else() "src/tls/tlsv1_server.c" "src/tls/tlsv1_server_read.c" "src/tls/tlsv1_server_write.c" - "src/tls/x509v3.c" - ) + "src/tls/x509v3.c") +endif() + +if(CONFIG_WPA_MBEDTLS_CRYPTO) + set(crypto_src + "src/crypto/crypto_mbedtls.c" + "src/crypto/crypto_mbedtls-bignum.c" + "src/crypto/crypto_mbedtls-ec.c") + # Add internal RC4 if RC4 is disabled in mbedtls + if(CONFIG_MBEDTLS_RC4_DISABLED) + set(crypto_src ${crypto_src} "src/crypto/rc4.c") + endif() + if(NOT CONFIG_MBEDTLS_DES_C) + set(crypto_src ${crypto_src} "src/crypto/des-internal.c") + endif() + # Enabling this only for WiFi is probably not a good idea since MbedTLS + # uses generic crypto init/update functions for this. That causes + # binary size increment since all the other enabled module + # functions will also linked in. Even after not using direct MbedTLS APIs + # for these, these API are still faster since these all will be using + # AES APIs which is using hardware AES blocks. + if(NOT CONFIG_MBEDTLS_CMAC_C) + set(crypto_src ${crypto_src} "src/crypto/aes-omac1.c") + endif() + if(NOT CONFIG_MBEDTLS_NIST_KW_C) + set(crypto_src ${crypto_src} + "src/crypto/aes-wrap.c" + "src/crypto/aes-unwrap.c") + endif() + if(NOT CONFIG_MBEDTLS_NIST_KW_C OR NOT CONFIG_MBEDTLS_CMAC_C OR NOT CONFIG_MBEDTLS_CCM_C) + set(crypto_src ${crypto_src} "src/crypto/aes-ccm.c") + endif() +else() + set(crypto_src + "src/crypto/rc4.c" + "src/crypto/aes-ctr.c" + "src/crypto/aes-cbc.c" + "src/crypto/aes-ccm.c" + "src/crypto/aes-internal-dec.c" + "src/crypto/aes-internal-enc.c" + "src/crypto/aes-internal.c" + "src/crypto/aes-omac1.c" + "src/crypto/aes-unwrap.c" + "src/crypto/aes-wrap.c" + "src/crypto/crypto_internal-cipher.c" + "src/crypto/crypto_internal-modexp.c" + "src/crypto/crypto_internal-rsa.c" + "src/crypto/crypto_mbedtls-rsa.c" + "src/crypto/crypto_internal.c" + "src/crypto/des-internal.c" + "src/crypto/md4-internal.c" + "src/crypto/md5-internal.c" + "src/crypto/md5.c" + "src/crypto/sha1-internal.c" + "src/crypto/sha1-pbkdf2.c" + "src/crypto/sha1.c" + "src/crypto/sha256-internal.c" + "src/crypto/sha256.c") endif() if(CONFIG_WPA_11KV_SUPPORT) @@ -122,9 +152,9 @@ else() set(roaming_src "") endif() -idf_component_register(SRCS "${srcs}" "${tls_src}" "${roaming_src}" +idf_component_register(SRCS "${srcs}" "${tls_src}" "${roaming_src}" "${crypto_src}" INCLUDE_DIRS include port/include include/esp_supplicant - PRIV_INCLUDE_DIRS src + PRIV_INCLUDE_DIRS src src/utils PRIV_REQUIRES mbedtls esp_timer) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-strict-aliasing) diff --git a/components/wpa_supplicant/Kconfig b/components/wpa_supplicant/Kconfig index 35e5a804a7..c98b38bcaa 100644 --- a/components/wpa_supplicant/Kconfig +++ b/components/wpa_supplicant/Kconfig @@ -1,10 +1,10 @@ menu "Supplicant" config WPA_MBEDTLS_CRYPTO - bool "Use MbedTLS crypto API's" + bool "Use MbedTLS crypto APIs" default y help - Select this option to use MbedTLS crypto API's which utilize hardware acceleration. + Select this option to use MbedTLS crypto APIs which utilize hardware acceleration. config WPA_WAPI_PSK bool "Enable WAPI PSK support" diff --git a/components/wpa_supplicant/component.mk b/components/wpa_supplicant/component.mk index 14ffe934c2..ace0d6258a 100644 --- a/components/wpa_supplicant/component.mk +++ b/components/wpa_supplicant/component.mk @@ -1,6 +1,6 @@ # supplicant make file -COMPONENT_PRIV_INCLUDEDIRS := src +COMPONENT_PRIV_INCLUDEDIRS := src src/utils COMPONENT_SRCDIRS := port src/ap src/common src/crypto src/eap_peer src/rsn_supp src/tls src/utils src/esp_supplicant src/wps COMPONENT_ADD_INCLUDEDIRS := include port/include include/esp_supplicant src/utils @@ -21,10 +21,46 @@ ifeq ($(CONFIG_WPA_MBEDTLS_CRYPTO), y) src/tls/tlsv1_server.o \ src/tls/tlsv1_server_read.o \ src/tls/tlsv1_server_write.o \ - src/tls/x509v3.o + src/tls/x509v3.o \ + src/crypto/aes-ctr.o \ + src/crypto/aes-cbc.o \ + src/crypto/aes-internal-dec.o \ + src/crypto/aes-internal-enc.o \ + src/crypto/aes-internal.o \ + src/crypto/crypto_internal-cipher.o \ + src/crypto/crypto_internal-modexp.o \ + src/crypto/crypto_internal-rsa.o \ + src/crypto/crypto_mbedtls-rsa.o \ + src/crypto/crypto_internal.o \ + src/crypto/md5-internal.o \ + src/crypto/md5.o \ + src/crypto/sha1-internal.o \ + src/crypto/sha1-pbkdf2.o \ + src/crypto/sha1.o \ + src/crypto/sha256-internal.o \ + src/crypto/sha256.o else - COMPONENT_OBJEXCLUDE := src/crypto/tls_mbedtls.o + COMPONENT_OBJEXCLUDE += src/crypto/tls_mbedtls.o \ + src/crypto/crypto_mbedtls.o \ + src/crypto/crypto_mbedtls-bignum.o \ + src/crypto/crypto_mbedtls-ec.o endif + +ifneq ($(CONFIG_MBEDTLS_RC4_DISABLED), y) + COMPONENT_OBJEXCLUDE += src/crypto/rc4.o +endif +ifeq ($(CONFIG_MBEDTLS_DES_C), y) + COMPONENT_OBJEXCLUDE += src/crypto/des-internal.o +endif +ifeq ($(CONFIG_MBEDTLS_CMAC_C), y) + COMPONENT_OBJEXCLUDE += src/crypto/aes-omac1.o +endif +ifeq ($(CONFIG_MBEDTLS_NIST_KW_C), y) + COMPONENT_OBJEXCLUDE += src/crypto/aes-wrap.o + COMPONENT_OBJEXCLUDE += src/crypto/aes-unwrap.o + COMPONENT_OBJEXCLUDE += src/crypto/aes-ccm.o +endif + ifneq ($(CONFIG_WPA_11KV_SUPPORT), y) COMPONENT_OBJEXCLUDE += src/common/rrm.o \ src/common/wnm_sta.o \ diff --git a/components/wpa_supplicant/include/utils/wpa_debug.h b/components/wpa_supplicant/include/utils/wpa_debug.h index 124786923a..9714617a60 100644 --- a/components/wpa_supplicant/include/utils/wpa_debug.h +++ b/components/wpa_supplicant/include/utils/wpa_debug.h @@ -28,6 +28,7 @@ #define MSG_INFO ESP_LOG_INFO #define MSG_DEBUG ESP_LOG_DEBUG #define MSG_MSGDUMP ESP_LOG_VERBOSE +#define MSG_EXCESSIVE ESP_LOG_VERBOSE #else enum { MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR }; diff --git a/components/wpa_supplicant/port/include/os.h b/components/wpa_supplicant/port/include/os.h index 66eea39d85..74e1e349e9 100644 --- a/components/wpa_supplicant/port/include/os.h +++ b/components/wpa_supplicant/port/include/os.h @@ -19,6 +19,7 @@ #include #include #include "esp_err.h" +#include "supplicant_opt.h" typedef time_t os_time_t; @@ -308,4 +309,27 @@ static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size) return NULL; return os_realloc(ptr, nmemb * size); } + +#ifdef USE_MBEDTLS_CRYPTO +void forced_memzero(void *ptr, size_t len); +#else +/* Try to prevent most compilers from optimizing out clearing of memory that + * becomes unaccessible after this function is called. This is mostly the case + * for clearing local stack variables at the end of a function. This is not + * exactly perfect, i.e., someone could come up with a compiler that figures out + * the pointer is pointing to memset and then end up optimizing the call out, so + * try go a bit further by storing the first octet (now zero) to make this even + * a bit more difficult to optimize out. Once memset_s() is available, that + * could be used here instead. */ +static void * (* const volatile memset_func)(void *, int, size_t) = memset; +static uint8_t forced_memzero_val; + +static inline void forced_memzero(void *ptr, size_t len) +{ + memset_func(ptr, 0, len); + if (len) { + forced_memzero_val = ((uint8_t *) ptr)[0]; + } +} +#endif #endif /* OS_H */ diff --git a/components/wpa_supplicant/port/include/supplicant_opt.h b/components/wpa_supplicant/port/include/supplicant_opt.h index b70ffd4c6d..59b428d546 100644 --- a/components/wpa_supplicant/port/include/supplicant_opt.h +++ b/components/wpa_supplicant/port/include/supplicant_opt.h @@ -21,6 +21,7 @@ #define USE_MBEDTLS_CRYPTO 1 #else #define CONFIG_TLS_INTERNAL_CLIENT +#define CONFIG_CRYPTO_INTERNAL #define CONFIG_TLSV12 #endif diff --git a/components/wpa_supplicant/port/os_xtensa.c b/components/wpa_supplicant/port/os_xtensa.c index 48df398c4e..53ed080ca8 100644 --- a/components/wpa_supplicant/port/os_xtensa.c +++ b/components/wpa_supplicant/port/os_xtensa.c @@ -29,6 +29,7 @@ #include #include "esp_system.h" #include "utils/common.h" +#include "mbedtls/platform_util.h" int os_get_time(struct os_time *t) { @@ -59,3 +60,10 @@ void os_sleep(os_time_t sec, os_time_t usec) usleep(usec); } } + +#ifdef USE_MBEDTLS_CRYPTO +void forced_memzero(void *ptr, size_t len) +{ + mbedtls_platform_zeroize(ptr, len); +} +#endif diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 906214b344..a76a7e8dce 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -1064,7 +1064,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth, buf, key_data_len); if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || version == WPA_KEY_INFO_TYPE_AES_128_CMAC) { - if (aes_wrap(sm->PTK.kek, (key_data_len - 8) / 8, buf, + if (aes_wrap(sm->PTK.kek, 16, (key_data_len - 8) / 8, buf, (u8 *) (key + 1))) { os_free(hdr); os_free(buf); diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index 4d8a325f0d..6dd71891a3 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -23,6 +23,7 @@ #include "crypto/sha256.h" #include "crypto/md5.h" #include "crypto/aes.h" +#include "crypto/aes_wrap.h" #define MD5_MAC_LEN 16 diff --git a/components/wpa_supplicant/src/crypto/aes-cbc.c b/components/wpa_supplicant/src/crypto/aes-cbc.c index 03d7a68ba6..0835f2cfb7 100644 --- a/components/wpa_supplicant/src/crypto/aes-cbc.c +++ b/components/wpa_supplicant/src/crypto/aes-cbc.c @@ -3,40 +3,16 @@ * * Copyright (c) 2003-2007, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ -/* - * 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 - * - * Hardware crypto support Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD - * - * 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. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "aes.h" #include "aes_wrap.h" -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/aes.h" - /** * aes_128_cbc_encrypt - AES-128 CBC encryption * @key: Encryption key @@ -45,77 +21,16 @@ * @data_len: Length of data in bytes (must be divisible by 16) * Returns: 0 on success, -1 on failure */ -int -aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) -{ - int ret = 0; - mbedtls_aes_context ctx; - u8 cbc[AES_BLOCK_SIZE]; - - mbedtls_aes_init(&ctx); - - ret = mbedtls_aes_setkey_enc(&ctx, key, 128); - if(ret < 0) { - mbedtls_aes_free(&ctx); - return ret; - } - - os_memcpy(cbc, iv, AES_BLOCK_SIZE); - ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, data_len, cbc, data, data); - mbedtls_aes_free(&ctx); - - return ret; -} - - -/** - * aes_128_cbc_decrypt - AES-128 CBC decryption - * @key: Decryption key - * @iv: Decryption IV for CBC mode (16 bytes) - * @data: Data to decrypt in-place - * @data_len: Length of data in bytes (must be divisible by 16) - * Returns: 0 on success, -1 on failure - */ -int -aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) -{ - int ret = 0; - mbedtls_aes_context ctx; - u8 cbc[AES_BLOCK_SIZE]; - - mbedtls_aes_init(&ctx); - - ret = mbedtls_aes_setkey_dec(&ctx, key, 128); - if(ret < 0) { - mbedtls_aes_free(&ctx); - return ret; - } - - os_memcpy(cbc, iv, AES_BLOCK_SIZE); - ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, data_len, cbc, data, data); - mbedtls_aes_free(&ctx); - - return ret; - -} -#else /* USE_MBEDTLS_CRYPTO */ - -/** - * aes_128_cbc_encrypt - AES-128 CBC encryption - * @key: Encryption key - * @iv: Encryption IV for CBC mode (16 bytes) - * @data: Data to encrypt in-place - * @data_len: Length of data in bytes (must be divisible by 16) - * Returns: 0 on success, -1 on failure - */ -int -aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) +int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) { void *ctx; u8 cbc[AES_BLOCK_SIZE]; u8 *pos = data; int i, j, blocks; + if (TEST_FAIL()) + return -1; + ctx = aes_encrypt_init(key, 16); if (ctx == NULL) return -1; @@ -142,14 +57,16 @@ aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) * @data_len: Length of data in bytes (must be divisible by 16) * Returns: 0 on success, -1 on failure */ -int -aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) +int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) { void *ctx; u8 cbc[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE]; u8 *pos = data; int i, j, blocks; + if (TEST_FAIL()) + return -1; + ctx = aes_decrypt_init(key, 16); if (ctx == NULL) return -1; @@ -167,4 +84,3 @@ aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) aes_decrypt_deinit(ctx); return 0; } -#endif /* USE_MBEDTLS_CRYPTO */ diff --git a/components/wpa_supplicant/src/crypto/aes-ccm.c b/components/wpa_supplicant/src/crypto/aes-ccm.c index 53e43cbd8b..cb130b8528 100644 --- a/components/wpa_supplicant/src/crypto/aes-ccm.c +++ b/components/wpa_supplicant/src/crypto/aes-ccm.c @@ -8,10 +8,9 @@ */ #ifdef CONFIG_IEEE80211W +#include "includes.h" -#include "utils/includes.h" - -#include "utils/common.h" +#include "common.h" #include "aes.h" #include "aes_wrap.h" @@ -42,7 +41,7 @@ static void aes_ccm_auth_start(void *aes, size_t M, size_t L, const u8 *nonce, os_memcpy(&b[1], nonce, 15 - L); WPA_PUT_BE16(&b[AES_BLOCK_SIZE - L], plain_len); - wpa_hexdump_key(MSG_DEBUG, "CCM B_0", b, AES_BLOCK_SIZE); + wpa_hexdump_key(MSG_EXCESSIVE, "CCM B_0", b, AES_BLOCK_SIZE); aes_encrypt(aes, b, x); /* X_1 = E(K, B_0) */ if (!aad_len) @@ -121,13 +120,13 @@ static void aes_ccm_encr_auth(void *aes, size_t M, u8 *x, u8 *a, u8 *auth) size_t i; u8 tmp[AES_BLOCK_SIZE]; - wpa_hexdump_key(MSG_DEBUG, "CCM T", x, M); + wpa_hexdump_key(MSG_EXCESSIVE, "CCM T", x, M); /* U = T XOR S_0; S_0 = E(K, A_0) */ WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], 0); aes_encrypt(aes, a, tmp); for (i = 0; i < M; i++) auth[i] = x[i] ^ tmp[i]; - wpa_hexdump_key(MSG_DEBUG, "CCM U", auth, M); + wpa_hexdump_key(MSG_EXCESSIVE, "CCM U", auth, M); } @@ -136,13 +135,13 @@ static void aes_ccm_decr_auth(void *aes, size_t M, u8 *a, const u8 *auth, u8 *t) size_t i; u8 tmp[AES_BLOCK_SIZE]; - wpa_hexdump_key(MSG_DEBUG, "CCM U", auth, M); + wpa_hexdump_key(MSG_EXCESSIVE, "CCM U", auth, M); /* U = T XOR S_0; S_0 = E(K, A_0) */ WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], 0); aes_encrypt(aes, a, tmp); for (i = 0; i < M; i++) t[i] = auth[i] ^ tmp[i]; - wpa_hexdump_key(MSG_DEBUG, "CCM T", t, M); + wpa_hexdump_key(MSG_EXCESSIVE, "CCM T", t, M); } @@ -177,10 +176,9 @@ int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, /* AES-CCM with fixed L=2 and aad_len <= 30 assumption */ -int aes_ccm_ad(const u8 *key, size_t key_len, u8 *nonce, +int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, size_t M, const u8 *crypt, size_t crypt_len, - const u8 *aad, size_t aad_len, const u8 *auth, - u8 *plain, bool skip_auth) + const u8 *aad, size_t aad_len, const u8 *auth, u8 *plain) { const size_t L = 2; void *aes; @@ -201,18 +199,13 @@ int aes_ccm_ad(const u8 *key, size_t key_len, u8 *nonce, /* plaintext = msg XOR (S_1 | S_2 | ... | S_n) */ aes_ccm_encr(aes, L, crypt, crypt_len, plain, a); - if (skip_auth) { - aes_encrypt_deinit(aes); - return 0; - } - aes_ccm_auth_start(aes, M, L, nonce, aad, aad_len, crypt_len, x); aes_ccm_auth(aes, plain, crypt_len, x); aes_encrypt_deinit(aes); - if (os_memcmp(x, t, M) != 0) { - wpa_printf(MSG_DEBUG, "CCM: Auth mismatch"); + if (os_memcmp_const(x, t, M) != 0) { + wpa_printf(MSG_EXCESSIVE, "CCM: Auth mismatch"); return -1; } diff --git a/components/wpa_supplicant/src/crypto/aes-ctr.c b/components/wpa_supplicant/src/crypto/aes-ctr.c index fc2278ce44..8ce05b894d 100644 --- a/components/wpa_supplicant/src/crypto/aes-ctr.c +++ b/components/wpa_supplicant/src/crypto/aes-ctr.c @@ -6,14 +6,12 @@ * This software may be distributed under the terms of the BSD license. * See README for more details. */ -#include "utils/includes.h" -#include "utils/common.h" -#include "crypto/aes.h" -#include "crypto/aes_wrap.h" -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/aes.h" -#endif +#include "includes.h" + +#include "common.h" +#include "aes.h" +#include "aes_wrap.h" /** * aes_ctr_encrypt - AES-128/192/256 CTR mode encryption @@ -27,21 +25,6 @@ int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, u8 *data, size_t data_len) { -#ifdef USE_MBEDTLS_CRYPTO - int ret; - mbedtls_aes_context ctx; - uint8_t stream_block[AES_BLOCK_SIZE]; - size_t offset = 0; - - mbedtls_aes_init(&ctx); - ret = mbedtls_aes_setkey_enc(&ctx, key, key_len * 8); - if (ret < 0) - goto cleanup; - ret = mbedtls_aes_crypt_ctr(&ctx, data_len, &offset, (u8 *)nonce, stream_block, data, data); -cleanup: - mbedtls_aes_free(&ctx); - return ret; -#else void *ctx; size_t j, len, left = data_len; int i; @@ -70,7 +53,6 @@ cleanup: } aes_encrypt_deinit(ctx); return 0; -#endif } diff --git a/components/wpa_supplicant/src/crypto/aes-internal-dec.c b/components/wpa_supplicant/src/crypto/aes-internal-dec.c index 8c91b5c00e..7482295949 100644 --- a/components/wpa_supplicant/src/crypto/aes-internal-dec.c +++ b/components/wpa_supplicant/src/crypto/aes-internal-dec.c @@ -2,41 +2,30 @@ * AES (Rijndael) cipher - decrypt * * Modifications to public domain implementation: - * - support only 128-bit keys * - cleanup * - use C pre-processor to make it easier to change S table access * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at * cost of reduced throughput (quite small difference on Pentium 4, * 10-25% when using -O1 or -O2 optimization) * - * Copyright (c) 2003-2005, Jouni Malinen + * Copyright (c) 2003-2012, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "crypto.h" #include "aes_i.h" - - -//static unsigned char aes_priv_buf[AES_PRIV_SIZE]; - /** * Expand the cipher key into the decryption key schedule. * * @return the number of rounds for the given cipher key size. */ -static int rijndaelKeySetupDec(u32 rk[], const u8 cipherKey[], int keyBits) +static int rijndaelKeySetupDec(u32 rk[], const u8 cipherKey[], int keyBits) { int Nr, i, j; u32 temp; @@ -67,7 +56,7 @@ static int rijndaelKeySetupDec(u32 rk[], const u8 cipherKey[], int keyBits) return Nr; } -void * aes_decrypt_init(const u8 *key, size_t len) +void * aes_decrypt_init(const u8 *key, size_t len) { u32 *rk; int res; @@ -83,7 +72,7 @@ void * aes_decrypt_init(const u8 *key, size_t len) return rk; } -static void rijndaelDecrypt(const u32 rk[/*44*/], int Nr, const u8 ct[16], +static void rijndaelDecrypt(const u32 rk[/*44*/], int Nr, const u8 ct[16], u8 pt[16]) { u32 s0, s1, s2, s3, t0, t1, t2, t3; @@ -158,14 +147,16 @@ d##3 = TD0(s##3) ^ TD1(s##2) ^ TD2(s##1) ^ TD3(s##0) ^ rk[4 * i + 3] PUTU32(pt + 12, s3); } -void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) + +int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) { u32 *rk = ctx; rijndaelDecrypt(ctx, rk[AES_PRIV_NR_POS], crypt, plain); + return 0; } -void aes_decrypt_deinit(void *ctx) +void aes_decrypt_deinit(void *ctx) { os_memset(ctx, 0, AES_PRIV_SIZE); os_free(ctx); diff --git a/components/wpa_supplicant/src/crypto/aes-internal-enc.c b/components/wpa_supplicant/src/crypto/aes-internal-enc.c index 56084e4489..baeffcaf63 100644 --- a/components/wpa_supplicant/src/crypto/aes-internal-enc.c +++ b/components/wpa_supplicant/src/crypto/aes-internal-enc.c @@ -2,33 +2,25 @@ * AES (Rijndael) cipher - encrypt * * Modifications to public domain implementation: - * - support only 128-bit keys * - cleanup * - use C pre-processor to make it easier to change S table access * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at * cost of reduced throughput (quite small difference on Pentium 4, * 10-25% when using -O1 or -O2 optimization) * - * Copyright (c) 2003-2005, Jouni Malinen + * Copyright (c) 2003-2012, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" -#include "utils/common.h" +#include "includes.h" + +#include "common.h" #include "crypto.h" #include "aes_i.h" -#include "os.h" - -void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16]) +static void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16]) { u32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL @@ -103,10 +95,14 @@ d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3] } -void * aes_encrypt_init(const u8 *key, size_t len) +void * aes_encrypt_init(const u8 *key, size_t len) { u32 *rk; int res; + + if (TEST_FAIL()) + return NULL; + rk = os_malloc(AES_PRIV_SIZE); if (rk == NULL) return NULL; @@ -120,14 +116,15 @@ void * aes_encrypt_init(const u8 *key, size_t len) } -void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) { u32 *rk = ctx; rijndaelEncrypt(ctx, rk[AES_PRIV_NR_POS], plain, crypt); + return 0; } -void aes_encrypt_deinit(void *ctx) +void aes_encrypt_deinit(void *ctx) { os_memset(ctx, 0, AES_PRIV_SIZE); os_free(ctx); diff --git a/components/wpa_supplicant/src/crypto/aes-internal.c b/components/wpa_supplicant/src/crypto/aes-internal.c index 93592f1dc8..bd4535d209 100644 --- a/components/wpa_supplicant/src/crypto/aes-internal.c +++ b/components/wpa_supplicant/src/crypto/aes-internal.c @@ -2,28 +2,21 @@ * AES (Rijndael) cipher * * Modifications to public domain implementation: - * - support only 128-bit keys * - cleanup * - use C pre-processor to make it easier to change S table access * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at * cost of reduced throughput (quite small difference on Pentium 4, * 10-25% when using -O1 or -O2 optimization) * - * Copyright (c) 2003-2005, Jouni Malinen + * Copyright (c) 2003-2012, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "crypto.h" #include "aes_i.h" @@ -53,7 +46,6 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define AES_SMALL_TABLES /* Te0[x] = S [x].[02, 01, 01, 03]; @@ -69,7 +61,7 @@ Td3[x] = Si[x].[09, 0d, 0b, 0e]; Td4[x] = Si[x].[01, 01, 01, 01]; */ -const u32 Te0[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Te0[256] = { 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, @@ -136,7 +128,7 @@ const u32 Te0[256] /* ICACHE_RODATA_ATTR */ = { 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, }; #ifndef AES_SMALL_TABLES -const u32 Te1[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Te1[256] = { 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, @@ -202,7 +194,7 @@ const u32 Te1[256] /* ICACHE_RODATA_ATTR */ = { 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, }; -const u32 Te2[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Te2[256] = { 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, @@ -268,7 +260,7 @@ const u32 Te2[256] /* ICACHE_RODATA_ATTR */ = { 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, }; -const u32 Te3[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Te3[256] = { 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, @@ -335,7 +327,7 @@ const u32 Te3[256] /* ICACHE_RODATA_ATTR */ = { 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, }; -const u32 Te4[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Te4[256] = { 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, @@ -402,7 +394,7 @@ const u32 Te4[256] /* ICACHE_RODATA_ATTR */ = { 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, }; #endif /* AES_SMALL_TABLES */ -const u32 Td0[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Td0[256] = { 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, @@ -469,7 +461,7 @@ const u32 Td0[256] /* ICACHE_RODATA_ATTR */ = { 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, }; #ifndef AES_SMALL_TABLES -const u32 Td1[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Td1[256] = { 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, @@ -535,7 +527,7 @@ const u32 Td1[256] /* ICACHE_RODATA_ATTR */ = { 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, }; -const u32 Td2[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Td2[256] = { 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, @@ -602,7 +594,7 @@ const u32 Td2[256] /* ICACHE_RODATA_ATTR */ = { 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, }; -const u32 Td3[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Td3[256] = { 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, @@ -668,7 +660,7 @@ const u32 Td3[256] /* ICACHE_RODATA_ATTR */ = { 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, }; -const u32 Td4[256] /* ICACHE_RODATA_ATTR */ = { +const u32 Td4[256] = { 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, @@ -734,13 +726,13 @@ const u32 Td4[256] /* ICACHE_RODATA_ATTR */ = { 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, }; -const u32 rcon[] /* ICACHE_RODATA_ATTR */ = { +const u32 rcon[] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; #else /* AES_SMALL_TABLES */ -const u8 Td4s[256] /* ICACHE_RODATA_ATTR */ = { +const u8 Td4s[256] = { 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, @@ -774,7 +766,7 @@ const u8 Td4s[256] /* ICACHE_RODATA_ATTR */ = { 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, }; -const u8 rcons[] /* ICACHE_RODATA_ATTR */ = { +const u8 rcons[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; diff --git a/components/wpa_supplicant/src/crypto/aes-omac1.c b/components/wpa_supplicant/src/crypto/aes-omac1.c index 415b7955b3..8642516340 100644 --- a/components/wpa_supplicant/src/crypto/aes-omac1.c +++ b/components/wpa_supplicant/src/crypto/aes-omac1.c @@ -7,10 +7,11 @@ * See README for more details. */ +#include "includes.h" -#include "utils/common.h" -#include "crypto/aes.h" -#include "crypto/aes_wrap.h" +#include "common.h" +#include "aes.h" +#include "aes_wrap.h" static void gf_mulx(u8 *pad) { @@ -47,6 +48,9 @@ int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *pos, *end; size_t i, e, left, total_len; + if (TEST_FAIL()) + return -1; + ctx = aes_encrypt_init(key, key_len); if (ctx == NULL) return -1; diff --git a/components/wpa_supplicant/src/crypto/aes-siv.c b/components/wpa_supplicant/src/crypto/aes-siv.c index bcf1600aae..b8b152f7ca 100644 --- a/components/wpa_supplicant/src/crypto/aes-siv.c +++ b/components/wpa_supplicant/src/crypto/aes-siv.c @@ -6,12 +6,12 @@ * See README for more details. */ -#include "utils/includes.h" -#include "utils/common.h" +#include "includes.h" -#include "crypto/aes.h" -#include "crypto/aes_wrap.h" -#include "crypto/aes_siv.h" +#include "common.h" +#include "aes.h" +#include "aes_wrap.h" +#include "aes_siv.h" static const u8 zero[AES_BLOCK_SIZE]; diff --git a/components/wpa_supplicant/src/crypto/aes-unwrap.c b/components/wpa_supplicant/src/crypto/aes-unwrap.c index 3418249b4c..ec793d9dbf 100644 --- a/components/wpa_supplicant/src/crypto/aes-unwrap.c +++ b/components/wpa_supplicant/src/crypto/aes-unwrap.c @@ -1,81 +1,44 @@ /* - * AES key unwrap (128-bit KEK, RFC3394) + * AES key unwrap (RFC3394) * * Copyright (c) 2003-2007, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ -/* - * 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 - * - * Hardware crypto support Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD - * - * 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. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/aes.h" -#else /* USE_MBEDTLS_CRYPTO */ +#include "common.h" #include "aes.h" #include "aes_wrap.h" -#endif /* USE_MBEDTLS_CRYPTO */ /** - * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394) + * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (RFC3394) * @kek: Key encryption key (KEK) + * @kek_len: Length of KEK in octets * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16 * bytes * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits * @plain: Plaintext key, n * 64 bits * Returns: 0 on success, -1 on failure (e.g., integrity verification failed) */ -int -aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain) +int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, + u8 *plain) { - u8 a[8], *r, b[16]; + u8 a[8], *r, b[AES_BLOCK_SIZE]; int i, j; -#ifdef USE_MBEDTLS_CRYPTO - int32_t ret = 0; - mbedtls_aes_context ctx; -#else /* USE_MBEDTLS_CRYPTO */ void *ctx; -#endif /* USE_MBEDTLS_CRYPTO */ + unsigned int t; /* 1) Initialize variables. */ os_memcpy(a, cipher, 8); r = plain; os_memcpy(r, cipher + 8, 8 * n); -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_aes_init(&ctx); - ret = mbedtls_aes_setkey_dec(&ctx, kek, 128); - if (ret < 0) { - mbedtls_aes_free(&ctx); - return ret; - } -#else /* USE_MBEDTLS_CRYPTO */ - ctx = aes_decrypt_init(kek, 16); + ctx = aes_decrypt_init(kek, kek_len); if (ctx == NULL) return -1; -#endif /* USE_MBEDTLS_CRYPTO */ /* 2) Compute intermediate values. * For j = 5 to 0 @@ -88,24 +51,20 @@ aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain) r = plain + (n - 1) * 8; for (i = n; i >= 1; i--) { os_memcpy(b, a, 8); - b[7] ^= n * j + i; + t = n * j + i; + b[7] ^= t; + b[6] ^= t >> 8; + b[5] ^= t >> 16; + b[4] ^= t >> 24; os_memcpy(b + 8, r, 8); -#ifdef USE_MBEDTLS_CRYPTO - ret = mbedtls_internal_aes_decrypt(&ctx, b, b); -#else /* USE_MBEDTLS_CRYPTO */ aes_decrypt(ctx, b, b); -#endif /* USE_MBEDTLS_CRYPTO */ os_memcpy(a, b, 8); os_memcpy(r, b + 8, 8); r -= 8; } } -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_aes_free(&ctx); -#else /* USE_MBEDTLS_CRYPTO */ aes_decrypt_deinit(ctx); -#endif /* USE_MBEDTLS_CRYPTO */ /* 3) Output results. * diff --git a/components/wpa_supplicant/src/crypto/aes-wrap.c b/components/wpa_supplicant/src/crypto/aes-wrap.c index 42e60660b6..7ed34e803e 100644 --- a/components/wpa_supplicant/src/crypto/aes-wrap.c +++ b/components/wpa_supplicant/src/crypto/aes-wrap.c @@ -1,55 +1,34 @@ /* - * AES Key Wrap Algorithm (128-bit KEK) (RFC3394) + * AES Key Wrap Algorithm (RFC3394) * * Copyright (c) 2003-2007, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. */ -/* - * 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 - * - * Hardware crypto support Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD - * - * 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. - */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "aes.h" #include "aes_wrap.h" -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/aes.h" -#endif /* USE_MBEDTLS_CRYPTO */ /** - * aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394) - * @kek: 16-octet Key encryption key (KEK) + * aes_wrap - Wrap keys with AES Key Wrap Algorithm (RFC3394) + * @kek: Key encryption key (KEK) + * @kek_len: Length of KEK in octets * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16 * bytes * @plain: Plaintext key to be wrapped, n * 64 bits * @cipher: Wrapped key, (n + 1) * 64 bits * Returns: 0 on success, -1 on failure */ -int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher) +int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) { - u8 *a, *r, b[16]; + u8 *a, *r, b[AES_BLOCK_SIZE]; int i, j; -#ifdef USE_MBEDTLS_CRYPTO - int32_t ret = 0; - mbedtls_aes_context ctx; -#else /* USE_MBEDTLS_CRYPTO */ void *ctx; -#endif /* USE_MBEDTLS_CRYPTO */ + unsigned int t; a = cipher; r = cipher + 8; @@ -58,18 +37,9 @@ int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher) os_memset(a, 0xa6, 8); os_memcpy(r, plain, 8 * n); -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_aes_init(&ctx); - ret = mbedtls_aes_setkey_enc(&ctx, kek, 128); - if (ret < 0) { - mbedtls_aes_free(&ctx); - return ret; - } -#else /* USE_MBEDTLS_CRYPTO */ - ctx = aes_encrypt_init(kek, 16); + ctx = aes_encrypt_init(kek, kek_len); if (ctx == NULL) return -1; -#endif /* USE_MBEDTLS_CRYPTO */ /* 2) Calculate intermediate values. * For j = 0 to 5 @@ -83,24 +53,18 @@ int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher) for (i = 1; i <= n; i++) { os_memcpy(b, a, 8); os_memcpy(b + 8, r, 8); -#ifdef USE_MBEDTLS_CRYPTO - ret = mbedtls_internal_aes_encrypt(&ctx, b, b); - if (ret != 0) - break; -#else /* USE_MBEDTLS_CRYPTO */ aes_encrypt(ctx, b, b); -#endif /* USE_MBEDTLS_CRYPTO */ os_memcpy(a, b, 8); - a[7] ^= n * j + i; + t = n * j + i; + a[7] ^= t; + a[6] ^= t >> 8; + a[5] ^= t >> 16; + a[4] ^= t >> 24; os_memcpy(r, b + 8, 8); r += 8; } } -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_aes_free(&ctx); -#else /* USE_MBEDTLS_CRYPTO */ aes_encrypt_deinit(ctx); -#endif /* USE_MBEDTLS_CRYPTO */ /* 3) Output the results. * diff --git a/components/wpa_supplicant/src/crypto/aes.h b/components/wpa_supplicant/src/crypto/aes.h index ee71688b92..8ab3de2ee8 100644 --- a/components/wpa_supplicant/src/crypto/aes.h +++ b/components/wpa_supplicant/src/crypto/aes.h @@ -2,14 +2,8 @@ * AES functions * Copyright (c) 2003-2006, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef AES_H @@ -18,19 +12,10 @@ #define AES_BLOCK_SIZE 16 void * aes_encrypt_init(const u8 *key, size_t len); -void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt); +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt); void aes_encrypt_deinit(void *ctx); void * aes_decrypt_init(const u8 *key, size_t len); -void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain); +int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain); void aes_decrypt_deinit(void *ctx); -int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac); - -int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, - size_t M, const u8 *plain, size_t plain_len, - const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth); -int aes_ccm_ad(const u8 *key, size_t key_len, u8 *nonce, - size_t M, const u8 *crypt, size_t crypt_len, - const u8 *aad, size_t aad_len, const u8 *auth, - u8 *plain, bool skip_auth); #endif /* AES_H */ diff --git a/components/wpa_supplicant/src/crypto/aes_i.h b/components/wpa_supplicant/src/crypto/aes_i.h index 1063422a81..b20ec92203 100644 --- a/components/wpa_supplicant/src/crypto/aes_i.h +++ b/components/wpa_supplicant/src/crypto/aes_i.h @@ -1,15 +1,9 @@ /* * AES (Rijndael) cipher - * Copyright (c) 2003-2005, Jouni Malinen + * Copyright (c) 2003-2012, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef AES_I_H @@ -71,7 +65,7 @@ extern const u8 rcons[10]; #else /* AES_SMALL_TABLES */ -#define RCON(i) (rcons[(i)] << 24) +#define RCON(i) ((u32) rcons[(i)] << 24) static inline u32 rotr(u32 val, int bits) { @@ -100,10 +94,10 @@ static inline u32 rotr(u32 val, int bits) #define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) #define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) #define TD3(i) rotr(Td0[(i) & 0xff], 24) -#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) -#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) -#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) -#define TD44(i) (Td4s[(i) & 0xff]) +#define TD41(i) ((u32) Td4s[((i) >> 24) & 0xff] << 24) +#define TD42(i) ((u32) Td4s[((i) >> 16) & 0xff] << 16) +#define TD43(i) ((u32) Td4s[((i) >> 8) & 0xff] << 8) +#define TD44(i) ((u32) Td4s[(i) & 0xff]) #define TD0_(i) Td0[(i) & 0xff] #define TD1_(i) rotr(Td0[(i) & 0xff], 8) #define TD2_(i) rotr(Td0[(i) & 0xff], 16) diff --git a/components/wpa_supplicant/src/crypto/aes_wrap.h b/components/wpa_supplicant/src/crypto/aes_wrap.h index 4ee77e972d..b70b1d26e5 100644 --- a/components/wpa_supplicant/src/crypto/aes_wrap.h +++ b/components/wpa_supplicant/src/crypto/aes_wrap.h @@ -1,42 +1,40 @@ /* * AES-based functions * - * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394) - * - One-Key CBC MAC (OMAC1) hash with AES-128 - * - AES-128 CTR mode encryption + * - AES Key Wrap Algorithm (RFC3394) + * - One-Key CBC MAC (OMAC1) hash with AES-128 and AES-256 + * - AES-128/192/256 CTR mode encryption * - AES-128 EAX mode encryption/decryption * - AES-128 CBC + * - AES-GCM + * - AES-CCM * - * Copyright (c) 2003-2007, Jouni Malinen + * Copyright (c) 2003-2012, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef AES_WRAP_H #define AES_WRAP_H -int __must_check aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher); -int __must_check aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain); +int __must_check aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, + u8 *cipher); +int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n, + const u8 *cipher, u8 *plain); int __must_check omac1_aes_vector(const u8 *key, size_t key_len, - size_t num_elem, const u8 *addr[], - const size_t *len, u8 *mac); + size_t num_elem, const u8 *addr[], + const size_t *len, u8 *mac); int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac); int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac); int __must_check omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, - u8 *mac); + u8 *mac); int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out); int __must_check aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, - u8 *data, size_t data_len); + u8 *data, size_t data_len); int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, u8 *data, size_t data_len); int __must_check aes_128_eax_encrypt(const u8 *key, @@ -51,4 +49,25 @@ int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len); int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len); +int __must_check 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); +int __must_check 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); +int __must_check 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); +int __must_check aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth); +int __must_check aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *auth, + u8 *plain); + #endif /* AES_WRAP_H */ diff --git a/components/wpa_supplicant/src/crypto/bignum.c b/components/wpa_supplicant/src/crypto/bignum.c deleted file mode 100644 index 1572afa259..0000000000 --- a/components/wpa_supplicant/src/crypto/bignum.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Big number math - * Copyright (c) 2006, Jouni Malinen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "utils/includes.h" -#include "utils/common.h" -#include "utils/wpabuf.h" -#include "utils/wpa_debug.h" -#include "bignum.h" - -#define CONFIG_INTERNAL_LIBTOMMATH -#ifdef CONFIG_INTERNAL_LIBTOMMATH -#include "libtommath.h" -#else /* CONFIG_INTERNAL_LIBTOMMATH */ -#include -#endif /* CONFIG_INTERNAL_LIBTOMMATH */ - - -/* - * The current version is just a wrapper for LibTomMath library, so - * struct bignum is just typecast to mp_int. - */ - -/** - * bignum_init - Allocate memory for bignum - * Returns: Pointer to allocated bignum or %NULL on failure - */ -struct bignum * -bignum_init(void) -{ - struct bignum *n = (struct bignum *)os_zalloc(sizeof(mp_int)); - if (n == NULL) - return NULL; - if (mp_init((mp_int *) n) != MP_OKAY) { - os_free(n); - n = NULL; - } - return n; -} - - -/** - * bignum_deinit - Free bignum - * @n: Bignum from bignum_init() - */ -void -bignum_deinit(struct bignum *n) -{ - if (n) { - mp_clear((mp_int *) n); - os_free(n); - } -} - - -/** - * bignum_get_unsigned_bin - Get length of bignum as an unsigned binary buffer - * @n: Bignum from bignum_init() - * Returns: Length of n if written to a binary buffer - */ -size_t -bignum_get_unsigned_bin_len(struct bignum *n) -{ - return mp_unsigned_bin_size((mp_int *) n); -} - - -/** - * bignum_get_unsigned_bin - Set binary buffer to unsigned bignum - * @n: Bignum from bignum_init() - * @buf: Buffer for the binary number - * @len: Length of the buffer, can be %NULL if buffer is known to be long - * enough. Set to used buffer length on success if not %NULL. - * Returns: 0 on success, -1 on failure - */ -int -bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len) -{ - size_t need = mp_unsigned_bin_size((mp_int *) n); - if (len && need > *len) { - *len = need; - return -1; - } - if (mp_to_unsigned_bin((mp_int *) n, buf) != MP_OKAY) { - wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); - return -1; - } - if (len) - *len = need; - return 0; -} - - -/** - * bignum_set_unsigned_bin - Set bignum based on unsigned binary buffer - * @n: Bignum from bignum_init(); to be set to the given value - * @buf: Buffer with unsigned binary value - * @len: Length of buf in octets - * Returns: 0 on success, -1 on failure - */ -int -bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len) -{ - if (mp_read_unsigned_bin((mp_int *) n, (u8 *) buf, len) != MP_OKAY) { - wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); - return -1; - } - return 0; -} - - -/** - * bignum_cmp - Signed comparison - * @a: Bignum from bignum_init() - * @b: Bignum from bignum_init() - * Returns: 0 on success, -1 on failure - */ -int -bignum_cmp(const struct bignum *a, const struct bignum *b) -{ - return mp_cmp((mp_int *) a, (mp_int *) b); -} - - -/** - * bignum_cmd_d - Compare bignum to standard integer - * @a: Bignum from bignum_init() - * @b: Small integer - * Returns: 0 on success, -1 on failure - */ -int -bignum_cmp_d(const struct bignum *a, unsigned long b) -{ - return mp_cmp_d((mp_int *) a, b); -} - - -/** - * bignum_add - c = a + b - * @a: Bignum from bignum_init() - * @b: Bignum from bignum_init() - * @c: Bignum from bignum_init(); used to store the result of a + b - * Returns: 0 on success, -1 on failure - */ -int -bignum_add(const struct bignum *a, const struct bignum *b, - struct bignum *c) -{ - if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { - wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); - return -1; - } - return 0; -} - - -/** - * bignum_sub - c = a - b - * @a: Bignum from bignum_init() - * @b: Bignum from bignum_init() - * @c: Bignum from bignum_init(); used to store the result of a - b - * Returns: 0 on success, -1 on failure - */ -int -bignum_sub(const struct bignum *a, const struct bignum *b, - struct bignum *c) -{ - if (mp_sub((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { - wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); - return -1; - } - return 0; -} - - -/** - * bignum_mul - c = a * b - * @a: Bignum from bignum_init() - * @b: Bignum from bignum_init() - * @c: Bignum from bignum_init(); used to store the result of a * b - * Returns: 0 on success, -1 on failure - */ -int -bignum_mul(const struct bignum *a, const struct bignum *b, - struct bignum *c) -{ - if (mp_mul((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { - wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); - return -1; - } - return 0; -} - - -/** - * bignum_mulmod - d = a * b (mod c) - * @a: Bignum from bignum_init() - * @b: Bignum from bignum_init() - * @c: Bignum from bignum_init(); modulus - * @d: Bignum from bignum_init(); used to store the result of a * b (mod c) - * Returns: 0 on success, -1 on failure - */ -int -bignum_mulmod(const struct bignum *a, const struct bignum *b, - const struct bignum *c, struct bignum *d) -{ - if (mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) - != MP_OKAY) { - wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); - return -1; - } - return 0; -} - - -/** - * bignum_exptmod - Modular exponentiation: d = a^b (mod c) - * @a: Bignum from bignum_init(); base - * @b: Bignum from bignum_init(); exponent - * @c: Bignum from bignum_init(); modulus - * @d: Bignum from bignum_init(); used to store the result of a^b (mod c) - * Returns: 0 on success, -1 on failure - */ -int -bignum_exptmod(const struct bignum *a, const struct bignum *b, - const struct bignum *c, struct bignum *d) -{ - if (mp_exptmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) - != MP_OKAY) { - wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); - return -1; - } - return 0; -} diff --git a/components/wpa_supplicant/src/crypto/bignum.h b/components/wpa_supplicant/src/crypto/bignum.h deleted file mode 100644 index f25e26783a..0000000000 --- a/components/wpa_supplicant/src/crypto/bignum.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Big number math - * Copyright (c) 2006, Jouni Malinen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#ifndef BIGNUM_H -#define BIGNUM_H - -struct bignum; - -struct bignum * bignum_init(void); -void bignum_deinit(struct bignum *n); -size_t bignum_get_unsigned_bin_len(struct bignum *n); -int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len); -int bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len); -int bignum_cmp(const struct bignum *a, const struct bignum *b); -int bignum_cmp_d(const struct bignum *a, unsigned long b); -int bignum_add(const struct bignum *a, const struct bignum *b, - struct bignum *c); -int bignum_sub(const struct bignum *a, const struct bignum *b, - struct bignum *c); -int bignum_mul(const struct bignum *a, const struct bignum *b, - struct bignum *c); -int bignum_mulmod(const struct bignum *a, const struct bignum *b, - const struct bignum *c, struct bignum *d); -int bignum_exptmod(const struct bignum *a, const struct bignum *b, - const struct bignum *c, struct bignum *d); - -#endif /* BIGNUM_H */ diff --git a/components/wpa_supplicant/src/crypto/ccmp.c b/components/wpa_supplicant/src/crypto/ccmp.c index 152c23417b..3b66d5fc18 100644 --- a/components/wpa_supplicant/src/crypto/ccmp.c +++ b/components/wpa_supplicant/src/crypto/ccmp.c @@ -12,11 +12,12 @@ #include "utils/common.h" #include "common/ieee802_11_defs.h" -#include "aes.h" -#include "aes_wrap.h" +#include "crypto/aes.h" +#include "crypto/aes_wrap.h" + static void ccmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data, - u8 *aad, size_t *aad_len, u8 *nonce, bool espnow_pkt) + u8 *aad, size_t *aad_len, u8 *nonce) { u16 fc, stype, seq; int qos = 0, addr4 = 0; @@ -41,7 +42,7 @@ static void ccmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data, qc += ETH_ALEN; nonce[0] = qc[0] & 0x0f; } - } else if (!espnow_pkt && WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) + } else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) nonce[0] |= 0x10; /* Management */ fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA); @@ -135,12 +136,13 @@ static void ccmp_aad_nonce_pv1(const u8 *hdr, const u8 *a1, const u8 *a2, } -u8 * ccmp_decrypt(const u8 *tk, const u8 *hdr, const u8 *data, - size_t data_len, size_t *decrypted_len, bool espnow_pkt) +u8 * ccmp_decrypt(const u8 *tk, const u8 *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len, bool espnow_pkt) { u8 aad[30], nonce[13]; size_t aad_len; size_t mlen; + size_t tag_len = 8; u8 *plain; if (data_len < 8 + 8) @@ -154,12 +156,18 @@ u8 * ccmp_decrypt(const u8 *tk, const u8 *hdr, const u8 *data, os_memset(aad, 0, sizeof(aad)); ccmp_aad_nonce((const struct ieee80211_hdr *)hdr, data, aad, &aad_len, - nonce, espnow_pkt); + nonce); wpa_hexdump(MSG_DEBUG, "CCMP AAD", aad, aad_len); wpa_hexdump(MSG_DEBUG, "CCMP nonce", nonce, 13); - if (aes_ccm_ad(tk, 16, nonce, 8, data + 8, mlen, aad, aad_len, - data + 8 + mlen, plain, espnow_pkt ? true : false) < 0) { +#ifdef ESPRESSIF_USE + if (espnow_pkt) { + tag_len = 0; + nonce[0] = 0; + } +#endif + if (aes_ccm_ad(tk, 16, nonce, tag_len, data + 8, mlen, aad, aad_len, + data + 8 + mlen, plain) < 0) { os_free(plain); return NULL; } @@ -210,12 +218,13 @@ u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, *pos++ = pn[0]; /* PN5 */ os_memset(aad, 0, sizeof(aad)); - ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce, false); + ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce); wpa_hexdump(MSG_DEBUG, "CCMP AAD", aad, aad_len); wpa_hexdump(MSG_DEBUG, "CCMP nonce", nonce, 13); if (aes_ccm_ae(tk, 16, nonce, 8, frame + hdrlen, plen, aad, aad_len, pos, pos + plen) < 0) { + wpa_printf(MSG_ERROR, "aes ccm ae failed"); os_free(crypt); return NULL; } @@ -289,12 +298,12 @@ u8 * ccmp_256_decrypt(const u8 *tk, const u8 *hdr, const u8 *data, os_memset(aad, 0, sizeof(aad)); ccmp_aad_nonce((const struct ieee80211_hdr *)hdr, data, aad, - &aad_len, nonce, false); + &aad_len, nonce); wpa_hexdump(MSG_DEBUG, "CCMP-256 AAD", aad, aad_len); wpa_hexdump(MSG_DEBUG, "CCMP-256 nonce", nonce, 13); if (aes_ccm_ad(tk, 32, nonce, 16, data + 8, mlen, aad, aad_len, - data + 8 + mlen, plain, false) < 0) { + data + 8 + mlen, plain) < 0) { os_free(plain); return NULL; } @@ -335,7 +344,7 @@ u8 * ccmp_256_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, *pos++ = pn[0]; /* PN5 */ os_memset(aad, 0, sizeof(aad)); - ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce, false); + ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce); wpa_hexdump(MSG_DEBUG, "CCMP-256 AAD", aad, aad_len); wpa_hexdump(MSG_DEBUG, "CCMP-256 nonce", nonce, 13); diff --git a/components/wpa_supplicant/src/crypto/crypto.h b/components/wpa_supplicant/src/crypto/crypto.h index c67da4145c..75234e229c 100644 --- a/components/wpa_supplicant/src/crypto/crypto.h +++ b/components/wpa_supplicant/src/crypto/crypto.h @@ -1,15 +1,9 @@ /* - * WPA Supplicant / wrapper functions for crypto libraries - * Copyright (c) 2004-2009, Jouni Malinen + * Wrapper functions for crypto libraries + * Copyright (c) 2004-2017, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. * * This file defines the cryptographic functions that need to be implemented * for wpa_supplicant and hostapd. When TLS is not used, internal @@ -27,8 +21,6 @@ #ifndef CRYPTO_H #define CRYPTO_H -#include "utils/common.h" - /** * md4_vector - MD4 hash for data vector * @num_elem: Number of elements in the data vector @@ -49,21 +41,6 @@ int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac); */ int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac); -#ifdef CONFIG_FIPS -/** - * md5_vector_non_fips_allow - MD5 hash for data vector (non-FIPS use allowed) - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash - * Returns: 0 on success, -1 on failure - */ -int md5_vector_non_fips_allow(size_t num_elem, const u8 *addr[], - const size_t *len, u8 *mac); -#else /* CONFIG_FIPS */ -#define md5_vector_non_fips_allow md5_vector -#endif /* CONFIG_FIPS */ - /** * sha1_vector - SHA-1 hash for data vector @@ -102,13 +79,36 @@ int __must_check fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac); +/** + * sha384_vector - SHA384 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 on failure + */ +int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac); + +/** + * sha512_vector - SHA512 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 on failure + */ +int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac); + /** * des_encrypt - Encrypt one block with DES * @clear: 8 octets (in) * @key: 7 octets (in) (no parity bits included) * @cypher: 8 octets (out) + * Returns: 0 on success, -1 on failure */ -void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher); +int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher); /** * aes_encrypt_init - Initialize AES for encryption @@ -123,8 +123,9 @@ void * aes_encrypt_init(const u8 *key, size_t len); * @ctx: Context pointer from aes_encrypt_init() * @plain: Plaintext data to be encrypted (16 bytes) * @crypt: Buffer for the encrypted data (16 bytes) + * Returns: 0 on success, -1 on failure */ -void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt); +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt); /** * aes_encrypt_deinit - Deinitialize AES encryption @@ -145,8 +146,9 @@ void * aes_decrypt_init(const u8 *key, size_t len); * @ctx: Context pointer from aes_encrypt_init() * @crypt: Encrypted data (16 bytes) * @plain: Buffer for the decrypted data (16 bytes) + * Returns: 0 on success, -1 on failure */ -void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain); +int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain); /** * aes_decrypt_deinit - Deinitialize AES decryption @@ -156,9 +158,10 @@ void aes_decrypt_deinit(void *ctx); enum crypto_hash_alg { - CRYPTO_HASH_ALG_MD5, CRYPTO_HASH_ALG_SHA1, - CRYPTO_HASH_ALG_HMAC_MD5, CRYPTO_HASH_ALG_HMAC_SHA1, - CRYPTO_HASH_ALG_SHA256, CRYPTO_HASH_ALG_HMAC_SHA256 + CRYPTO_HASH_ALG_MD5, CRYPTO_HASH_ALG_SHA1, + CRYPTO_HASH_ALG_HMAC_MD5, CRYPTO_HASH_ALG_HMAC_SHA1, + CRYPTO_HASH_ALG_SHA256, CRYPTO_HASH_ALG_HMAC_SHA256, + CRYPTO_HASH_ALG_SHA384, CRYPTO_HASH_ALG_SHA512 }; struct crypto_hash; @@ -209,6 +212,7 @@ void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len); */ int crypto_hash_finish(struct crypto_hash *ctx, u8 *hash, size_t *len); + enum crypto_cipher_alg { CRYPTO_CIPHER_NULL = 0, CRYPTO_CIPHER_ALG_AES, CRYPTO_CIPHER_ALG_3DES, CRYPTO_CIPHER_ALG_DES, CRYPTO_CIPHER_ALG_RC2, CRYPTO_CIPHER_ALG_RC4 @@ -273,6 +277,7 @@ int __must_check crypto_cipher_decrypt(struct crypto_cipher *ctx, */ void crypto_cipher_deinit(struct crypto_cipher *ctx); + struct crypto_public_key; struct crypto_private_key; @@ -292,6 +297,10 @@ struct crypto_private_key; */ struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len); +struct crypto_public_key * +crypto_public_key_import_parts(const u8 *n, size_t n_len, + const u8 *e, size_t e_len); + /** * crypto_private_key_import - Import an RSA private key * @key: Key buffer (DER encoded RSA private key) @@ -408,6 +417,14 @@ int __must_check crypto_public_key_decrypt_pkcs1( struct crypto_public_key *key, const u8 *crypt, size_t crypt_len, u8 *plain, size_t *plain_len); +int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, + u8 *pubkey); +int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len, + const u8 *order, size_t order_len, + const u8 *privkey, size_t privkey_len, + const u8 *pubkey, size_t pubkey_len, + u8 *secret, size_t *len); + /** * crypto_global_init - Initialize crypto wrapper * @@ -467,6 +484,17 @@ int __must_check crypto_mod_exp(const u8 *base, size_t base_len, int rc4_skip(const u8 *key, size_t keylen, size_t skip, u8 *data, size_t data_len); +/** + * crypto_get_random - Generate cryptographically strong pseudo-random bytes + * @buf: Buffer for data + * @len: Number of bytes to generate + * Returns: 0 on success, -1 on failure + * + * If the PRNG does not have enough entropy to ensure unpredictable byte + * sequence, this functions must return -1. + */ +int crypto_get_random(void *buf, size_t len); + /** * struct crypto_bignum - bignum @@ -498,6 +526,13 @@ struct crypto_bignum * crypto_bignum_init(void); */ struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len); +/** + * crypto_bignum_init_set - Allocate memory for bignum and set the value (uint) + * @val: Value to set + * Returns: Pointer to allocated bignum or %NULL on failure + */ +struct crypto_bignum * crypto_bignum_init_uint(unsigned int val); + /** * crypto_bignum_deinit - Free bignum * @n: Bignum from crypto_bignum_init() or crypto_bignum_init_set() @@ -514,7 +549,15 @@ void crypto_bignum_deinit(struct crypto_bignum *n, int clear); * Returns: Number of octets written on success, -1 on failure */ int crypto_bignum_to_bin(const struct crypto_bignum *a, - u8 *buf, size_t buflen, size_t padlen); + u8 *buf, size_t buflen, size_t padlen); + +/** + * crypto_bignum_rand - Create a random number in range of modulus + * @r: Bignum; set to a random value + * @m: Bignum; modulus + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m); /** * crypto_bignum_add - c = a + b @@ -524,8 +567,8 @@ int crypto_bignum_to_bin(const struct crypto_bignum *a, * Returns: 0 on success, -1 on failure */ int crypto_bignum_add(const struct crypto_bignum *a, - const struct crypto_bignum *b, - struct crypto_bignum *c); + const struct crypto_bignum *b, + struct crypto_bignum *c); /** * crypto_bignum_mod - c = a % b @@ -535,8 +578,8 @@ int crypto_bignum_add(const struct crypto_bignum *a, * Returns: 0 on success, -1 on failure */ int crypto_bignum_mod(const struct crypto_bignum *a, - const struct crypto_bignum *b, - struct crypto_bignum *c); + const struct crypto_bignum *b, + struct crypto_bignum *c); /** * crypto_bignum_exptmod - Modular exponentiation: d = a^b (mod c) @@ -547,9 +590,9 @@ int crypto_bignum_mod(const struct crypto_bignum *a, * Returns: 0 on success, -1 on failure */ int crypto_bignum_exptmod(const struct crypto_bignum *a, - const struct crypto_bignum *b, - const struct crypto_bignum *c, - struct crypto_bignum *d); + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d); /** * crypto_bignum_inverse - Inverse a bignum so that a * c = 1 (mod b) @@ -559,8 +602,8 @@ int crypto_bignum_exptmod(const struct crypto_bignum *a, * Returns: 0 on success, -1 on failure */ int crypto_bignum_inverse(const struct crypto_bignum *a, - const struct crypto_bignum *b, - struct crypto_bignum *c); + const struct crypto_bignum *b, + struct crypto_bignum *c); /** * crypto_bignum_sub - c = a - b @@ -570,8 +613,8 @@ int crypto_bignum_inverse(const struct crypto_bignum *a, * Returns: 0 on success, -1 on failure */ int crypto_bignum_sub(const struct crypto_bignum *a, - const struct crypto_bignum *b, - struct crypto_bignum *c); + const struct crypto_bignum *b, + struct crypto_bignum *c); /** * crypto_bignum_div - c = a / b @@ -581,8 +624,21 @@ int crypto_bignum_sub(const struct crypto_bignum *a, * Returns: 0 on success, -1 on failure */ int crypto_bignum_div(const struct crypto_bignum *a, - const struct crypto_bignum *b, - struct crypto_bignum *c); + const struct crypto_bignum *b, + struct crypto_bignum *c); + +/** + * crypto_bignum_addmod - d = a + b (mod c) + * @a: Bignum + * @b: Bignum + * @c: Bignum + * @d: Bignum; used to store the result of (a + b) % c + * Returns: 0 on success, -1 on failure + */ +int crypto_bignum_addmod(const struct crypto_bignum *a, + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d); /** * crypto_bignum_mulmod - d = a * b (mod c) @@ -593,9 +649,9 @@ int crypto_bignum_div(const struct crypto_bignum *a, * Returns: 0 on success, -1 on failure */ int crypto_bignum_mulmod(const struct crypto_bignum *a, - const struct crypto_bignum *b, - const struct crypto_bignum *c, - struct crypto_bignum *d); + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d); /** * crypto_bignum_cmp - Compare two bignums @@ -604,7 +660,7 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a, * Returns: -1 if a < b, 0 if a == b, or 1 if a > b */ int crypto_bignum_cmp(const struct crypto_bignum *a, - const struct crypto_bignum *b); + const struct crypto_bignum *b); /** * crypto_bignum_bits - Get size of a bignum in bits @@ -967,15 +1023,6 @@ struct crypto_ec_point *crypto_ec_get_public_key(struct crypto_key *key); */ int crypto_get_order(struct crypto_ec_group *group, struct crypto_bignum *x); -/** - * crypto_bignum_addmod: a = (b + c) mod d - * Return : 0 in success - */ -int crypto_bignum_addmod(struct crypto_bignum *a, - struct crypto_bignum *b, - struct crypto_bignum *c, - struct crypto_bignum *d); - /** * crypto_ec_get_affine_coordinates : get affine corrdinate of ec curve * @e: ec curve diff --git a/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c b/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c index 9ca428cfe3..ad0930a5a9 100644 --- a/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c +++ b/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c @@ -5,32 +5,14 @@ * This software may be distributed under the terms of the BSD license. * See README for more details. */ -/* - * 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 - * - * Hardware crypto support Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD - * - * 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. - */ -#include "utils/common.h" -#include "utils/includes.h" +#include "includes.h" + +#include "common.h" #include "crypto.h" #include "aes.h" -#if defined(CONFIG_DES) || defined(CONFIG_DES3) #include "des_i.h" -#endif -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/aes.h" -#endif /* USE_MBEDTLS_CRYPTO */ + struct crypto_cipher { enum crypto_cipher_alg alg; @@ -42,38 +24,29 @@ struct crypto_cipher { } rc4; struct { u8 cbc[32]; -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_aes_context ctx_enc; - mbedtls_aes_context ctx_dec; -#else /* USE_MBEDTLS_CRYPTO */ void *ctx_enc; void *ctx_dec; -#endif /* USE_MBEDTLS_CRYPTO */ } aes; -#ifdef CONFIG_DES3 struct { struct des3_key_s key; u8 cbc[8]; } des3; -#endif -#ifdef CONFIG_DES struct { u32 ek[32]; u32 dk[32]; u8 cbc[8]; } des; -#endif } u; }; -struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, +struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, const u8 *iv, const u8 *key, size_t key_len) { struct crypto_cipher *ctx; - ctx = (struct crypto_cipher *)os_zalloc(sizeof(*ctx)); + ctx = os_zalloc(sizeof(*ctx)); if (ctx == NULL) return NULL; @@ -89,12 +62,6 @@ struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, os_memcpy(ctx->u.rc4.key, key, key_len); break; case CRYPTO_CIPHER_ALG_AES: -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_aes_init(&(ctx->u.aes.ctx_enc)); - mbedtls_aes_setkey_enc(&(ctx->u.aes.ctx_enc), key, key_len * 8); - mbedtls_aes_init(&(ctx->u.aes.ctx_dec)); - mbedtls_aes_setkey_dec(&(ctx->u.aes.ctx_dec), key, key_len * 8); -#else /* USE_MBEDTLS_CRYPTO */ ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len); if (ctx->u.aes.ctx_enc == NULL) { os_free(ctx); @@ -106,10 +73,8 @@ struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, os_free(ctx); return NULL; } -#endif /* USE_MBEDTLS_CRYPTO */ os_memcpy(ctx->u.aes.cbc, iv, AES_BLOCK_SIZE); break; -#ifdef CONFIG_DES3 case CRYPTO_CIPHER_ALG_3DES: if (key_len != 24) { os_free(ctx); @@ -118,8 +83,6 @@ struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, des3_key_setup(key, &ctx->u.des3.key); os_memcpy(ctx->u.des3.cbc, iv, 8); break; -#endif -#ifdef CONFIG_DES case CRYPTO_CIPHER_ALG_DES: if (key_len != 8) { os_free(ctx); @@ -128,7 +91,6 @@ struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk); os_memcpy(ctx->u.des.cbc, iv, 8); break; -#endif default: os_free(ctx); return NULL; @@ -138,7 +100,7 @@ struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, } -int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, +int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, u8 *crypt, size_t len) { size_t i, j, blocks; @@ -158,20 +120,13 @@ int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, for (i = 0; i < blocks; i++) { for (j = 0; j < AES_BLOCK_SIZE; j++) ctx->u.aes.cbc[j] ^= plain[j]; -#ifdef USE_MBEDTLS_CRYPTO - if (mbedtls_internal_aes_encrypt(&(ctx->u.aes.ctx_enc), - ctx->u.aes.cbc, ctx->u.aes.cbc) != 0) - return -1; -#else /* USE_MBEDTLS_CRYPTO */ aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc, ctx->u.aes.cbc); -#endif /* USE_MBEDTLS_CRYPTO */ os_memcpy(crypt, ctx->u.aes.cbc, AES_BLOCK_SIZE); plain += AES_BLOCK_SIZE; crypt += AES_BLOCK_SIZE; } break; -#ifdef CONFIG_DES3 case CRYPTO_CIPHER_ALG_3DES: if (len % 8) return -1; @@ -186,8 +141,6 @@ int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, crypt += 8; } break; -#endif -#ifdef CONFIG_DES case CRYPTO_CIPHER_ALG_DES: if (len % 8) return -1; @@ -202,7 +155,6 @@ int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, crypt += 8; } break; -#endif default: return -1; } @@ -211,7 +163,7 @@ int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, } -int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, +int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, u8 *plain, size_t len) { size_t i, j, blocks; @@ -231,13 +183,7 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, blocks = len / AES_BLOCK_SIZE; for (i = 0; i < blocks; i++) { os_memcpy(tmp, crypt, AES_BLOCK_SIZE); -#ifdef USE_MBEDTLS_CRYPTO - if (mbedtls_internal_aes_decrypt(&(ctx->u.aes.ctx_dec), - crypt, plain) != 0) - return -1; -#else /* USE_MBEDTLS_CRYPTO */ aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain); -#endif /* USE_MBEDTLS_CRYPTO */ for (j = 0; j < AES_BLOCK_SIZE; j++) plain[j] ^= ctx->u.aes.cbc[j]; os_memcpy(ctx->u.aes.cbc, tmp, AES_BLOCK_SIZE); @@ -245,7 +191,6 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, crypt += AES_BLOCK_SIZE; } break; -#ifdef CONFIG_DES3 case CRYPTO_CIPHER_ALG_3DES: if (len % 8) return -1; @@ -260,8 +205,6 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, crypt += 8; } break; -#endif -#ifdef CONFIG_DES case CRYPTO_CIPHER_ALG_DES: if (len % 8) return -1; @@ -276,7 +219,6 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, crypt += 8; } break; -#endif default: return -1; } @@ -285,22 +227,15 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, } -void crypto_cipher_deinit(struct crypto_cipher *ctx) +void crypto_cipher_deinit(struct crypto_cipher *ctx) { switch (ctx->alg) { case CRYPTO_CIPHER_ALG_AES: -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_aes_free(&(ctx->u.aes.ctx_enc)); - mbedtls_aes_free(&(ctx->u.aes.ctx_dec)); -#else /* USE_MBEDTLS_CRYPTO */ aes_encrypt_deinit(ctx->u.aes.ctx_enc); aes_decrypt_deinit(ctx->u.aes.ctx_dec); -#endif /* USE_MBEDTLS_CRYPTO */ break; -#ifdef CONFIG_DES3 case CRYPTO_CIPHER_ALG_3DES: break; -#endif default: break; } diff --git a/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c b/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c index 2807d329c9..6819f1a6ab 100644 --- a/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c +++ b/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c @@ -2,83 +2,91 @@ * Crypto wrapper for internal crypto implementation - modexp * Copyright (c) 2006-2009, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ -/* - * Hardware crypto support Copyright 2017-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. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/bignum.h" -#else /* USE_MBEDTLS_CRYPTO */ -#include "bignum.h" -#endif /* USE_MBEDTLS_CRYPTO */ +#include "common.h" +#include "tls/bignum.h" #include "crypto.h" -#ifdef USE_MBEDTLS_CRYPTO -int -crypto_mod_exp(const uint8_t *base, size_t base_len, - const uint8_t *power, size_t power_len, - const uint8_t *modulus, size_t modulus_len, - uint8_t *result, size_t *result_len) + +int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, + u8 *pubkey) { - mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result, bn_rinv; - int ret = 0; - mbedtls_mpi_init(&bn_base); - mbedtls_mpi_init(&bn_exp); - mbedtls_mpi_init(&bn_modulus); - mbedtls_mpi_init(&bn_result); - mbedtls_mpi_init(&bn_rinv); + size_t pubkey_len, pad; - mbedtls_mpi_read_binary(&bn_base, base, base_len); - mbedtls_mpi_read_binary(&bn_exp, power, power_len); - mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len); - - ret = mbedtls_mpi_exp_mod(&bn_result, &bn_base, &bn_exp, &bn_modulus, &bn_rinv); - if (ret < 0) { - mbedtls_mpi_free(&bn_base); - mbedtls_mpi_free(&bn_exp); - mbedtls_mpi_free(&bn_modulus); - mbedtls_mpi_free(&bn_result); - mbedtls_mpi_free(&bn_rinv); - return ret; + if (os_get_random(privkey, prime_len) < 0) + return -1; + if (os_memcmp(privkey, prime, prime_len) > 0) { + /* Make sure private value is smaller than prime */ + privkey[0] = 0; } - ret = mbedtls_mpi_write_binary(&bn_result, result, *result_len); + pubkey_len = prime_len; + if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len, + pubkey, &pubkey_len) < 0) + return -1; + if (pubkey_len < prime_len) { + pad = prime_len - pubkey_len; + os_memmove(pubkey + pad, pubkey, pubkey_len); + os_memset(pubkey, 0, pad); + } - mbedtls_mpi_free(&bn_base); - mbedtls_mpi_free(&bn_exp); - mbedtls_mpi_free(&bn_modulus); - mbedtls_mpi_free(&bn_result); - mbedtls_mpi_free(&bn_rinv); - - return ret; + return 0; } -#else /* USE_MBEDTLS_CRYPTO */ -int -crypto_mod_exp(const u8 *base, size_t base_len, + + +int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len, + const u8 *order, size_t order_len, + const u8 *privkey, size_t privkey_len, + const u8 *pubkey, size_t pubkey_len, + u8 *secret, size_t *len) +{ + struct bignum *pub; + int res = -1; + + if (pubkey_len > prime_len || + (pubkey_len == prime_len && + os_memcmp(pubkey, prime, prime_len) >= 0)) + return -1; + + pub = bignum_init(); + if (!pub || bignum_set_unsigned_bin(pub, pubkey, pubkey_len) < 0 || + bignum_cmp_d(pub, 1) <= 0) + goto fail; + + if (order) { + struct bignum *p, *q, *tmp; + int failed; + + /* verify: pubkey^q == 1 mod p */ + p = bignum_init(); + q = bignum_init(); + tmp = bignum_init(); + failed = !p || !q || !tmp || + bignum_set_unsigned_bin(p, prime, prime_len) < 0 || + bignum_set_unsigned_bin(q, order, order_len) < 0 || + bignum_exptmod(pub, q, p, tmp) < 0 || + bignum_cmp_d(tmp, 1) != 0; + bignum_deinit(p); + bignum_deinit(q); + bignum_deinit(tmp); + if (failed) + goto fail; + } + + res = crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len, + prime, prime_len, secret, len); +fail: + bignum_deinit(pub); + return res; +} + + +int crypto_mod_exp(const u8 *base, size_t base_len, const u8 *power, size_t power_len, const u8 *modulus, size_t modulus_len, u8 *result, size_t *result_len) @@ -112,4 +120,3 @@ error: bignum_deinit(bn_result); return ret; } -#endif /* USE_MBEDTLS_CRYPTO */ diff --git a/components/wpa_supplicant/src/crypto/crypto_internal-rsa.c b/components/wpa_supplicant/src/crypto/crypto_internal-rsa.c index ec27b6d977..dc7f350af0 100644 --- a/components/wpa_supplicant/src/crypto/crypto_internal-rsa.c +++ b/components/wpa_supplicant/src/crypto/crypto_internal-rsa.c @@ -6,30 +6,36 @@ * See README for more details. */ -#include "utils/common.h" +#include "includes.h" + +#include "common.h" #include "crypto.h" - -#include "utils/includes.h" -#include "utils/common.h" -#include "utils/wpa_debug.h" - #include "tls/rsa.h" #include "tls/pkcs1.h" #include "tls/pkcs8.h" -#ifndef USE_MBEDTLS_CRYPTO /* Dummy structures; these are just typecast to struct crypto_rsa_key */ struct crypto_public_key; struct crypto_private_key; -struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len) +struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len) { return (struct crypto_public_key *) crypto_rsa_import_public_key(key, len); } -struct crypto_private_key * crypto_private_key_import(const u8 *key, + +struct crypto_public_key * +crypto_public_key_import_parts(const u8 *n, size_t n_len, + const u8 *e, size_t e_len) +{ + return (struct crypto_public_key *) + crypto_rsa_import_public_key_parts(n, n_len, e, e_len); +} + + +struct crypto_private_key * crypto_private_key_import(const u8 *key, size_t len, const char *passwd) { @@ -55,7 +61,7 @@ struct crypto_private_key * crypto_private_key_import(const u8 *key, } -struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf, +struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf, size_t len) { /* No X.509 support in crypto_internal.c */ @@ -63,7 +69,7 @@ struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf, } -int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key, +int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen) { @@ -72,7 +78,7 @@ int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key, } -int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key, +int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen) { @@ -81,7 +87,7 @@ int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key, } -int crypto_private_key_sign_pkcs1(struct crypto_private_key *key, +int crypto_private_key_sign_pkcs1(struct crypto_private_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen) { @@ -90,23 +96,22 @@ int crypto_private_key_sign_pkcs1(struct crypto_private_key *key, } -void crypto_public_key_free(struct crypto_public_key *key) +void crypto_public_key_free(struct crypto_public_key *key) { crypto_rsa_free((struct crypto_rsa_key *) key); } -void crypto_private_key_free(struct crypto_private_key *key) +void crypto_private_key_free(struct crypto_private_key *key) { crypto_rsa_free((struct crypto_rsa_key *) key); } -int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key, +int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key, const u8 *crypt, size_t crypt_len, u8 *plain, size_t *plain_len) { return pkcs1_decrypt_public_key((struct crypto_rsa_key *) key, crypt, crypt_len, plain, plain_len); } -#endif diff --git a/components/wpa_supplicant/src/crypto/crypto_internal.c b/components/wpa_supplicant/src/crypto/crypto_internal.c index 8d6af0c9e7..3d14babe5a 100644 --- a/components/wpa_supplicant/src/crypto/crypto_internal.c +++ b/components/wpa_supplicant/src/crypto/crypto_internal.c @@ -5,32 +5,14 @@ * This software may be distributed under the terms of the BSD license. * See README for more details. */ -/* - * 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 - * - * Hardware crypto support Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD - * - * 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. - */ -#include "utils/includes.h" -#include "utils/common.h" +#include "includes.h" + +#include "common.h" #include "crypto.h" +#include "sha256_i.h" #include "sha1_i.h" #include "md5_i.h" -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/sha256.h" -#else -#include "sha256_i.h" -#endif struct crypto_hash { enum crypto_hash_alg alg; @@ -38,19 +20,21 @@ struct crypto_hash { struct MD5Context md5; struct SHA1Context sha1; #ifdef CONFIG_SHA256 -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_context sha256; -#else /* USE_MBEDTLS_CRYPTO */ struct sha256_state sha256; -#endif /* USE_MBEDTLS_CRYPTO */ #endif /* CONFIG_SHA256 */ +#ifdef CONFIG_INTERNAL_SHA384 + struct sha384_state sha384; +#endif /* CONFIG_INTERNAL_SHA384 */ +#ifdef CONFIG_INTERNAL_SHA512 + struct sha512_state sha512; +#endif /* CONFIG_INTERNAL_SHA512 */ } u; u8 key[64]; size_t key_len; }; -struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, +struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, size_t key_len) { struct crypto_hash *ctx; @@ -58,7 +42,7 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, u8 tk[32]; size_t i; - ctx = (struct crypto_hash *)os_zalloc(sizeof(*ctx)); + ctx = os_zalloc(sizeof(*ctx)); if (ctx == NULL) return NULL; @@ -73,14 +57,19 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, break; #ifdef CONFIG_SHA256 case CRYPTO_HASH_ALG_SHA256: -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts_ret(&ctx->u.sha256, 0); -#else /* USE_MBEDTLS_CRYPTO */ sha256_init(&ctx->u.sha256); -#endif /* USE_MBEDTLS_CRYPTO */ break; #endif /* CONFIG_SHA256 */ +#ifdef CONFIG_INTERNAL_SHA384 + case CRYPTO_HASH_ALG_SHA384: + sha384_init(&ctx->u.sha384); + break; +#endif /* CONFIG_INTERNAL_SHA384 */ +#ifdef CONFIG_INTERNAL_SHA512 + case CRYPTO_HASH_ALG_SHA512: + sha512_init(&ctx->u.sha512); + break; +#endif /* CONFIG_INTERNAL_SHA512 */ case CRYPTO_HASH_ALG_HMAC_MD5: if (key_len > sizeof(k_pad)) { MD5Init(&ctx->u.md5); @@ -122,17 +111,9 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, #ifdef CONFIG_SHA256 case CRYPTO_HASH_ALG_HMAC_SHA256: if (key_len > sizeof(k_pad)) { -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts_ret(&ctx->u.sha256, 0); - mbedtls_sha256_update_ret(&ctx->u.sha256, key, key_len); - mbedtls_sha256_finish_ret(&ctx->u.sha256, tk); - mbedtls_sha256_free(&ctx->u.sha256); -#else /* USE_MBEDTLS_CRYPTO */ sha256_init(&ctx->u.sha256); sha256_process(&ctx->u.sha256, key, key_len); sha256_done(&ctx->u.sha256, tk); -#endif /* USE_MBEDTLS_CRYPTO */ key = tk; key_len = 32; } @@ -144,14 +125,8 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); for (i = 0; i < sizeof(k_pad); i++) k_pad[i] ^= 0x36; -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts_ret(&ctx->u.sha256, 0); - mbedtls_sha256_update_ret(&ctx->u.sha256, k_pad, sizeof(k_pad)); -#else /* USE_MBEDTLS_CRYPTO */ sha256_init(&ctx->u.sha256); sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad)); -#endif /* USE_MBEDTLS_CRYPTO */ break; #endif /* CONFIG_SHA256 */ default: @@ -163,7 +138,7 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, } -void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) +void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) { if (ctx == NULL) return; @@ -180,20 +155,26 @@ void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) #ifdef CONFIG_SHA256 case CRYPTO_HASH_ALG_SHA256: case CRYPTO_HASH_ALG_HMAC_SHA256: -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_update_ret(&ctx->u.sha256, data, len); -#else /* USE_MBEDTLS_CRYPTO */ sha256_process(&ctx->u.sha256, data, len); -#endif /* USE_MBEDTLS_CRYPTO */ break; #endif /* CONFIG_SHA256 */ +#ifdef CONFIG_INTERNAL_SHA384 + case CRYPTO_HASH_ALG_SHA384: + sha384_process(&ctx->u.sha384, data, len); + break; +#endif /* CONFIG_INTERNAL_SHA384 */ +#ifdef CONFIG_INTERNAL_SHA512 + case CRYPTO_HASH_ALG_SHA512: + sha512_process(&ctx->u.sha512, data, len); + break; +#endif /* CONFIG_INTERNAL_SHA512 */ default: break; } } -int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) +int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) { u8 k_pad[64]; size_t i; @@ -233,14 +214,31 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) return -1; } *len = 32; -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_finish_ret(&ctx->u.sha256, mac); - mbedtls_sha256_free(&ctx->u.sha256); -#else /* USE_MBEDTLS_CRYPTO */ sha256_done(&ctx->u.sha256, mac); -#endif /* USE_MBEDTLS_CRYPTO */ break; #endif /* CONFIG_SHA256 */ +#ifdef CONFIG_INTERNAL_SHA384 + case CRYPTO_HASH_ALG_SHA384: + if (*len < 48) { + *len = 48; + os_free(ctx); + return -1; + } + *len = 48; + sha384_done(&ctx->u.sha384, mac); + break; +#endif /* CONFIG_INTERNAL_SHA384 */ +#ifdef CONFIG_INTERNAL_SHA512 + case CRYPTO_HASH_ALG_SHA512: + if (*len < 64) { + *len = 64; + os_free(ctx); + return -1; + } + *len = 64; + sha512_done(&ctx->u.sha512, mac); + break; +#endif /* CONFIG_INTERNAL_SHA512 */ case CRYPTO_HASH_ALG_HMAC_MD5: if (*len < 16) { *len = 16; @@ -290,31 +288,17 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) } *len = 32; -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_finish_ret(&ctx->u.sha256, mac); - mbedtls_sha256_free(&ctx->u.sha256); -#else /* USE_MBEDTLS_CRYPTO */ sha256_done(&ctx->u.sha256, mac); -#endif /* USE_MBEDTLS_CRYPTO */ os_memcpy(k_pad, ctx->key, ctx->key_len); os_memset(k_pad + ctx->key_len, 0, sizeof(k_pad) - ctx->key_len); for (i = 0; i < sizeof(k_pad); i++) k_pad[i] ^= 0x5c; -#ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts_ret(&ctx->u.sha256, 0); - mbedtls_sha256_update_ret(&ctx->u.sha256, k_pad, sizeof(k_pad)); - mbedtls_sha256_update_ret(&ctx->u.sha256, mac, 32); - mbedtls_sha256_finish_ret(&ctx->u.sha256, mac); - mbedtls_sha256_free(&ctx->u.sha256); -#else /* USE_MBEDTLS_CRYPTO */ sha256_init(&ctx->u.sha256); sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad)); sha256_process(&ctx->u.sha256, mac, 32); sha256_done(&ctx->u.sha256, mac); -#endif /* USE_MBEDTLS_CRYPTO */ break; #endif /* CONFIG_SHA256 */ default: @@ -324,16 +308,19 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) os_free(ctx); + if (TEST_FAIL()) + return -1; + return 0; } -int crypto_global_init(void) +int crypto_global_init(void) { return 0; } -void crypto_global_deinit(void) +void crypto_global_deinit(void) { } diff --git a/components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c b/components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c index 890655631d..155021ec17 100644 --- a/components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c +++ b/components/wpa_supplicant/src/crypto/crypto_mbedtls-bignum.c @@ -251,10 +251,10 @@ int crypto_bignum_to_string(const struct crypto_bignum *a, return outlen; } -int crypto_bignum_addmod(struct crypto_bignum *a, - struct crypto_bignum *b, - struct crypto_bignum *c, - struct crypto_bignum *d) +int crypto_bignum_addmod(const struct crypto_bignum *a, + const struct crypto_bignum *b, + const struct crypto_bignum *c, + struct crypto_bignum *d) { struct crypto_bignum *tmp = crypto_bignum_init(); int ret = -1; diff --git a/components/wpa_supplicant/src/crypto/crypto_mbedtls.c b/components/wpa_supplicant/src/crypto/crypto_mbedtls.c index b2c2ff569f..9d9fb0e5fd 100644 --- a/components/wpa_supplicant/src/crypto/crypto_mbedtls.c +++ b/components/wpa_supplicant/src/crypto/crypto_mbedtls.c @@ -28,9 +28,27 @@ #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" #include "mbedtls/md.h" +#include "mbedtls/aes.h" +#include "mbedtls/bignum.h" +#include "mbedtls/pkcs5.h" +#include "mbedtls/cmac.h" +#include "mbedtls/nist_kw.h" +#include "mbedtls/des.h" +#include "mbedtls/ccm.h" +#include "mbedtls/arc4.h" -int mbedtls_hmac_vector(mbedtls_md_type_t md_type, const u8 *key, size_t key_len, - size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) +#include "common.h" +#include "utils/wpabuf.h" +#include "dh_group5.h" +#include "sha1.h" +#include "sha256.h" +#include "md5.h" +#include "aes_wrap.h" +#include "crypto.h" +#include "mbedtls/esp_config.h" + +static int digest_vector(mbedtls_md_type_t md_type, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) { size_t i; const mbedtls_md_info_t *md_info; @@ -39,16 +57,169 @@ int mbedtls_hmac_vector(mbedtls_md_type_t md_type, const u8 *key, size_t key_len mbedtls_md_init(&md_ctx); - if((md_info = mbedtls_md_info_from_type(md_type)) == NULL ) + md_info = mbedtls_md_info_from_type(md_type); + if (!md_info) { + wpa_printf(MSG_ERROR, "mbedtls_md_info_from_type() failed"); return -1; + } - if ((ret = mbedtls_md_setup( &md_ctx, md_info, 1)) != 0) + ret = mbedtls_md_setup(&md_ctx, md_info, 0); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_md_setup() returned error"); + goto cleanup; + } + + ret = mbedtls_md_starts(&md_ctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_md_starts returned error"); + goto cleanup; + } + + for (i = 0; i < num_elem; i++) { + ret = mbedtls_md_update(&md_ctx, addr[i], len[i]); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_md_update ret=%d", ret); + goto cleanup; + } + } + + ret = mbedtls_md_finish(&md_ctx, mac); +cleanup: + mbedtls_md_free(&md_ctx); + + return ret; + +} + +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac) +{ + return digest_vector(MBEDTLS_MD_SHA256, num_elem, addr, len, mac); +} + +int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac) +{ + return digest_vector(MBEDTLS_MD_SHA384, num_elem, addr, len, mac); +} + +int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) +{ + return digest_vector(MBEDTLS_MD_SHA1, num_elem, addr, len, mac); +} + +int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) +{ + return digest_vector(MBEDTLS_MD_MD5, num_elem, addr, len, mac); +} + +#ifdef MBEDTLS_MD4_C +int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) +{ + return digest_vector(MBEDTLS_MD_MD4, num_elem, addr, len, mac); +} +#endif + +struct crypto_hash { + mbedtls_md_context_t ctx; +}; + +struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, + size_t key_len) +{ + struct crypto_hash *ctx; + mbedtls_md_type_t md_type; + const mbedtls_md_info_t *md_info; + int ret; + + switch (alg) { + case CRYPTO_HASH_ALG_HMAC_MD5: + md_type = MBEDTLS_MD_MD5; + break; + case CRYPTO_HASH_ALG_HMAC_SHA1: + md_type = MBEDTLS_MD_SHA1; + break; + case CRYPTO_HASH_ALG_HMAC_SHA256: + md_type = MBEDTLS_MD_SHA256; + break; + default: + return NULL; + } + + ctx = os_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + return NULL; + } + + mbedtls_md_init(&ctx->ctx); + md_info = mbedtls_md_info_from_type(md_type); + if (!md_info) { + os_free(ctx); + return NULL; + } + ret = mbedtls_md_setup(&ctx->ctx, md_info, 1); + if (ret != 0) { + os_free(ctx); + return NULL; + } + mbedtls_md_hmac_starts(&ctx->ctx, key, key_len); + + return ctx; +} + +void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) +{ + if (ctx == NULL) { + return; + } + mbedtls_md_hmac_update(&ctx->ctx, data, len); +} + +int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) +{ + if (ctx == NULL) { + return -2; + } + + if (mac == NULL || len == NULL) { + mbedtls_md_free(&ctx->ctx); + bin_clear_free(ctx, sizeof(*ctx)); + return 0; + } + mbedtls_md_hmac_finish(&ctx->ctx, mac); + mbedtls_md_free(&ctx->ctx); + bin_clear_free(ctx, sizeof(*ctx)); + + return 0; +} + +static int hmac_vector(mbedtls_md_type_t md_type, + const u8 *key, size_t key_len, + size_t num_elem, const u8 *addr[], + const size_t *len, u8 *mac) +{ + size_t i; + const mbedtls_md_info_t *md_info; + mbedtls_md_context_t md_ctx; + int ret; + + mbedtls_md_init(&md_ctx); + + md_info = mbedtls_md_info_from_type(md_type); + if (!md_info) { + return -1; + } + + ret = mbedtls_md_setup(&md_ctx, md_info, 1); + if (ret != 0) { return(ret); + } mbedtls_md_hmac_starts(&md_ctx, key, key_len); - for( i = 0; i < num_elem; i++) + for (i = 0; i < num_elem; i++) { mbedtls_md_hmac_update(&md_ctx, addr[i], len[i]); + } mbedtls_md_hmac_finish(&md_ctx, mac); @@ -60,8 +231,8 @@ int mbedtls_hmac_vector(mbedtls_md_type_t md_type, const u8 *key, size_t key_len int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return mbedtls_hmac_vector(MBEDTLS_MD_SHA384, key, key_len, num_elem, addr, - len, mac); + return hmac_vector(MBEDTLS_MD_SHA384, key, key_len, num_elem, addr, + len, mac); } @@ -70,3 +241,672 @@ int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, { return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac); } + +int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + return hmac_vector(MBEDTLS_MD_SHA256, key, key_len, num_elem, addr, + len, mac); +} + +int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, + size_t data_len, u8 *mac) +{ + return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); +} + +int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + return hmac_vector(MBEDTLS_MD_MD5, key, key_len, + num_elem, addr, len, mac); +} + +int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, + u8 *mac) +{ + return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac); +} + +int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + return hmac_vector(MBEDTLS_MD_SHA1, key, key_len, num_elem, addr, + len, mac); +} + +int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, + u8 *mac) +{ + return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac); +} + +static void *aes_crypt_init(int mode, const u8 *key, size_t len) +{ + int ret = -1; + mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); + if (!aes) { + return NULL; + } + mbedtls_aes_init(aes); + + if (mode == MBEDTLS_AES_ENCRYPT) { + ret = mbedtls_aes_setkey_enc(aes, key, len * 8); + } else if (mode == MBEDTLS_AES_DECRYPT){ + ret = mbedtls_aes_setkey_dec(aes, key, len * 8); + } + if (ret < 0) { + mbedtls_aes_free(aes); + os_free(aes); + wpa_printf(MSG_ERROR, "%s: mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec failed", __func__); + return NULL; + } + + return (void *) aes; +} + +static int aes_crypt(void *ctx, int mode, const u8 *in, u8 *out) +{ + return mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, + mode, in, out); +} + +static void aes_crypt_deinit(void *ctx) +{ + mbedtls_aes_free((mbedtls_aes_context *)ctx); + os_free(ctx); +} + +void *aes_encrypt_init(const u8 *key, size_t len) +{ + return aes_crypt_init(MBEDTLS_AES_ENCRYPT, key, len); +} + +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) +{ + return aes_crypt(ctx, MBEDTLS_AES_ENCRYPT, plain, crypt); +} + +void aes_encrypt_deinit(void *ctx) +{ + return aes_crypt_deinit(ctx); +} + +void * aes_decrypt_init(const u8 *key, size_t len) +{ + return aes_crypt_init(MBEDTLS_AES_DECRYPT, key, len); +} + +int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) +{ + return aes_crypt(ctx, MBEDTLS_AES_DECRYPT, crypt, plain); +} + +void aes_decrypt_deinit(void *ctx) +{ + return aes_crypt_deinit(ctx); +} + +int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) +{ + int ret = 0; + mbedtls_aes_context ctx; + u8 cbc[MBEDTLS_AES_BLOCK_SIZE]; + + mbedtls_aes_init(&ctx); + + ret = mbedtls_aes_setkey_enc(&ctx, key, 128); + if (ret < 0) { + mbedtls_aes_free(&ctx); + return ret; + } + + os_memcpy(cbc, iv, MBEDTLS_AES_BLOCK_SIZE); + ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, + data_len, cbc, data, data); + mbedtls_aes_free(&ctx); + + return ret; +} + +int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) +{ + int ret = 0; + mbedtls_aes_context ctx; + u8 cbc[MBEDTLS_AES_BLOCK_SIZE]; + + mbedtls_aes_init(&ctx); + + ret = mbedtls_aes_setkey_dec(&ctx, key, 128); + if (ret < 0) { + mbedtls_aes_free(&ctx); + return ret; + } + + os_memcpy(cbc, iv, MBEDTLS_AES_BLOCK_SIZE); + ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, + data_len, cbc, data, data); + mbedtls_aes_free(&ctx); + + return ret; + +} + +struct crypto_cipher { + mbedtls_cipher_context_t ctx_enc; + mbedtls_cipher_context_t ctx_dec; +}; + +static int crypto_init_cipher_ctx(mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info, + const u8 *iv, const u8 *key, + mbedtls_operation_t operation) +{ + mbedtls_cipher_init(ctx); + int ret; + + ret = mbedtls_cipher_setup(ctx, cipher_info); + if (ret != 0) { + return -1; + } + + if (mbedtls_cipher_setkey(ctx, key, cipher_info->key_bitlen, + operation) != 0) { + wpa_printf(MSG_ERROR, "mbedtls_cipher_setkey returned error"); + return -1; + } + if (mbedtls_cipher_set_iv(ctx, iv, cipher_info->iv_size) != 0) { + wpa_printf(MSG_ERROR, "mbedtls_cipher_set_iv returned error"); + return -1; + } + if (mbedtls_cipher_reset(ctx) != 0) { + wpa_printf(MSG_ERROR, "mbedtls_cipher_reset() returned error"); + return -1; + } + + return 0; +} + +static mbedtls_cipher_type_t alg_to_mbedtls_cipher(enum crypto_cipher_alg alg, + size_t key_len) +{ + switch (alg) { +#ifdef MBEDTLS_ARC4_C + case CRYPTO_CIPHER_ALG_RC4: + return MBEDTLS_CIPHER_ARC4_128; +#endif + case CRYPTO_CIPHER_ALG_AES: + if (key_len == 16) { + return MBEDTLS_CIPHER_AES_128_CBC; + } + if (key_len == 24) { + return MBEDTLS_CIPHER_AES_192_CBC; + } + if (key_len == 32) { + return MBEDTLS_CIPHER_AES_256_CBC; + } + break; +#ifdef MBEDTLS_DES_C + case CRYPTO_CIPHER_ALG_3DES: + return MBEDTLS_CIPHER_DES_EDE3_CBC; + case CRYPTO_CIPHER_ALG_DES: + return MBEDTLS_CIPHER_DES_CBC; +#endif + default: + break; + } + + return MBEDTLS_CIPHER_NONE; +} + +struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg, + const u8 *iv, const u8 *key, + size_t key_len) +{ + struct crypto_cipher *ctx; + mbedtls_cipher_type_t cipher_type; + const mbedtls_cipher_info_t *cipher_info; + + ctx = (struct crypto_cipher *)os_zalloc(sizeof(*ctx)); + if (!ctx) { + return NULL; + } + + cipher_type = alg_to_mbedtls_cipher(alg, key_len); + if (cipher_type == MBEDTLS_CIPHER_NONE) { + goto cleanup; + } + + cipher_info = mbedtls_cipher_info_from_type(cipher_type); + if (cipher_info == NULL) { + goto cleanup; + } + + /* Init both ctx encryption/decryption */ + if (crypto_init_cipher_ctx(&ctx->ctx_enc, cipher_info, iv, key, + MBEDTLS_ENCRYPT) < 0) { + goto cleanup; + } + + if (crypto_init_cipher_ctx(&ctx->ctx_dec, cipher_info, iv, key, + MBEDTLS_DECRYPT) < 0) { + goto cleanup; + } + + return ctx; + +cleanup: + os_free(ctx); + return NULL; +} + +#if 0 +int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, + u8 *crypt, size_t len) +{ + int ret; + size_t olen = 1200; + + ret = mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen); + if (ret != 0) { + return -1; + } + + ret = mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen); + if (ret != 0) { + return -1; + } + + return 0; +} + +int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, + u8 *plain, size_t len) +{ + int ret; + size_t olen = 1200; + + ret = mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen); + if (ret != 0) { + return -1; + } + + ret = mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen); + if (ret != 0) { + return -1; + } + + return 0; +} +#endif + +void crypto_cipher_deinit(struct crypto_cipher *ctx) +{ + mbedtls_cipher_free(&ctx->ctx_enc); + mbedtls_cipher_free(&ctx->ctx_dec); + os_free(ctx); +} + +int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, + u8 *data, size_t data_len) +{ + int ret; + mbedtls_aes_context ctx; + uint8_t stream_block[MBEDTLS_AES_BLOCK_SIZE]; + size_t offset = 0; + + mbedtls_aes_init(&ctx); + ret = mbedtls_aes_setkey_enc(&ctx, key, key_len * 8); + if (ret < 0) { + goto cleanup; + } + ret = mbedtls_aes_crypt_ctr(&ctx, data_len, &offset, (u8 *)nonce, + stream_block, data, data); +cleanup: + mbedtls_aes_free(&ctx); + return ret; +} + +int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, + u8 *data, size_t data_len) +{ + return aes_ctr_encrypt(key, 16, nonce, data, data_len); +} + + +#ifdef MBEDTLS_NIST_KW_C +int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) +{ + mbedtls_nist_kw_context ctx; + size_t olen; + int ret = 0; + mbedtls_nist_kw_init(&ctx); + + ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, + kek, kek_len * 8, 1); + if (ret != 0) { + return ret; + } + + ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain, + n * 8, cipher, &olen, (n + 1) * 8); + + mbedtls_nist_kw_free(&ctx); + return ret; +} + +int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, + u8 *plain) +{ + mbedtls_nist_kw_context ctx; + size_t olen; + int ret = 0; + mbedtls_nist_kw_init(&ctx); + + ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, + kek, kek_len * 8, 0); + if (ret != 0) { + return ret; + } + + ret = mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher, + (n + 1) * 8, plain, &olen, (n * 8)); + + mbedtls_nist_kw_free(&ctx); + return ret; +} +#endif + +int crypto_mod_exp(const uint8_t *base, size_t base_len, + const uint8_t *power, size_t power_len, + const uint8_t *modulus, size_t modulus_len, + uint8_t *result, size_t *result_len) +{ + mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result, bn_rinv; + int ret = 0; + + mbedtls_mpi_init(&bn_base); + mbedtls_mpi_init(&bn_exp); + mbedtls_mpi_init(&bn_modulus); + mbedtls_mpi_init(&bn_result); + mbedtls_mpi_init(&bn_rinv); + + mbedtls_mpi_read_binary(&bn_base, base, base_len); + mbedtls_mpi_read_binary(&bn_exp, power, power_len); + mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len); + + ret = mbedtls_mpi_exp_mod(&bn_result, &bn_base, &bn_exp, &bn_modulus, + &bn_rinv); + if (ret < 0) { + mbedtls_mpi_free(&bn_base); + mbedtls_mpi_free(&bn_exp); + mbedtls_mpi_free(&bn_modulus); + mbedtls_mpi_free(&bn_result); + mbedtls_mpi_free(&bn_rinv); + return ret; + } + + ret = mbedtls_mpi_write_binary(&bn_result, result, *result_len); + + mbedtls_mpi_free(&bn_base); + mbedtls_mpi_free(&bn_exp); + mbedtls_mpi_free(&bn_modulus); + mbedtls_mpi_free(&bn_result); + mbedtls_mpi_free(&bn_rinv); + + return ret; +} + +int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, + int iterations, u8 *buf, size_t buflen) +{ + + mbedtls_md_context_t sha1_ctx; + const mbedtls_md_info_t *info_sha1; + int ret; + + mbedtls_md_init(&sha1_ctx); + + info_sha1 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + if (info_sha1 == NULL) { + ret = -1; + goto cleanup; + } + + if ((ret = mbedtls_md_setup(&sha1_ctx, info_sha1, 1)) != 0) { + ret = -1; + goto cleanup; + } + + ret = mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx, (const u8 *) passphrase, + os_strlen(passphrase) , ssid, + ssid_len, iterations, 32, buf); + if (ret != 0) { + ret = -1; + goto cleanup; + } + +cleanup: + mbedtls_md_free(&sha1_ctx); + return ret; +} + +#ifdef MBEDTLS_DES_C +int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) +{ + int ret; + mbedtls_des_context des; + u8 pkey[8], next, tmp; + int i; + + /* Add parity bits to the key */ + next = 0; + for (i = 0; i < 7; i++) { + tmp = key[i]; + pkey[i] = (tmp >> i) | next | 1; + next = tmp << (7 - i); + } + pkey[i] = next | 1; + + mbedtls_des_init(&des); + ret = mbedtls_des_setkey_enc(&des, pkey); + if (ret < 0) { + return ret; + } + ret = mbedtls_des_crypt_ecb(&des, clear, cypher); + mbedtls_des_free(&des); + + return ret; +} +#endif + +/* Only enable this if all other ciphers are using MbedTLS implementation */ +#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_CMAC_C) && defined(MBEDTLS_NIST_KW_C) +int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth) +{ + int ret; + mbedtls_ccm_context ccm; + + mbedtls_ccm_init(&ccm); + + ret = mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES, + key, key_len * 8); + if (ret < 0) { + wpa_printf(MSG_ERROR, "mbedtls_ccm_setkey failed"); + goto cleanup; + } + + ret = mbedtls_ccm_encrypt_and_tag(&ccm, plain_len, nonce, 13, aad, + aad_len, plain, crypt, auth, M); + +cleanup: + mbedtls_ccm_free(&ccm); + + return ret; +} + +int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *auth, + u8 *plain) +{ + int ret; + mbedtls_ccm_context ccm; + + mbedtls_ccm_init(&ccm); + + ret = mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES, + key, key_len * 8); + if (ret < 0) { + goto cleanup;; + } + + ret = mbedtls_ccm_star_auth_decrypt(&ccm, crypt_len, + nonce, 13, aad, aad_len, + crypt, plain, auth, M); + +cleanup: + mbedtls_ccm_free(&ccm); + + return ret; +} +#endif + +#ifdef MBEDTLS_ARC4_C +int rc4_skip(const u8 *key, size_t keylen, size_t skip, + u8 *data, size_t data_len) +{ + int ret; + unsigned char skip_buf_in[16]; + unsigned char skip_buf_out[16]; + mbedtls_arc4_context ctx; + unsigned char *obuf = os_malloc(data_len); + + if (!obuf) { + wpa_printf(MSG_ERROR, "%s:memory allocation failed", __func__); + return -1; + } + mbedtls_arc4_init(&ctx); + mbedtls_arc4_setup(&ctx, key, keylen); + while (skip >= sizeof(skip_buf_in)) { + size_t len = skip; + if (len > sizeof(skip_buf_in)) { + len = sizeof(skip_buf_in); + } + if ((ret = mbedtls_arc4_crypt(&ctx, len, skip_buf_in, + skip_buf_out)) != 0) { + wpa_printf(MSG_ERROR, "rc4 encryption failed"); + return -1; + } + os_memcpy(skip_buf_in, skip_buf_out, 16); + skip -= len; + } + + mbedtls_arc4_crypt(&ctx, data_len, data, obuf); + + memcpy(data, obuf, data_len); + os_free(obuf); + + return 0; +} +#endif + +#ifdef MBEDTLS_CMAC_C +int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + const mbedtls_cipher_info_t *cipher_info; + int i, ret = 0; + mbedtls_cipher_type_t cipher_type; + mbedtls_cipher_context_t ctx; + + switch (key_len) { + case 16: + cipher_type = MBEDTLS_CIPHER_AES_128_ECB; + break; + case 24: + cipher_type = MBEDTLS_CIPHER_AES_192_ECB; + break; + case 32: + cipher_type = MBEDTLS_CIPHER_AES_256_ECB; + break; + default: + cipher_type = MBEDTLS_CIPHER_NONE; + break; + } + cipher_info = mbedtls_cipher_info_from_type(cipher_type); + if (cipher_info == NULL) { + /* Failing at this point must be due to a build issue */ + ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + goto cleanup; + } + + if (key == NULL || mac == NULL) { + return -1; + } + + mbedtls_cipher_init(&ctx); + + ret = mbedtls_cipher_setup(&ctx, cipher_info); + if (ret != 0) { + goto cleanup; + } + + ret = mbedtls_cipher_cmac_starts(&ctx, key, key_len * 8); + if (ret != 0) { + goto cleanup; + } + + for (i = 0 ; i < num_elem; i++) { + ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]); + if (ret != 0) { + goto cleanup; + } + } + + ret = mbedtls_cipher_cmac_finish(&ctx, mac); +cleanup: + mbedtls_cipher_free(&ctx); + return(ret); +} + +int omac1_aes_128_vector(const u8 *key, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + return omac1_aes_vector(key, 16, num_elem, addr, len, mac); +} + +int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) +{ + return omac1_aes_128_vector(key, 1, &data, &data_len, mac); +} +#endif + +int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, + u8 *pubkey) +{ + size_t pubkey_len, pad; + + if (os_get_random(privkey, prime_len) < 0) { + return -1; + } + if (os_memcmp(privkey, prime, prime_len) > 0) { + /* Make sure private value is smaller than prime */ + privkey[0] = 0; + } + + pubkey_len = prime_len; + if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len, + pubkey, &pubkey_len) < 0) { + return -1; + } + if (pubkey_len < prime_len) { + pad = prime_len - pubkey_len; + os_memmove(pubkey + pad, pubkey, pubkey_len); + os_memset(pubkey, 0, pad); + } + + return 0; +} diff --git a/components/wpa_supplicant/src/crypto/crypto_ops.c b/components/wpa_supplicant/src/crypto/crypto_ops.c index 56e428b8d6..be4d67c504 100644 --- a/components/wpa_supplicant/src/crypto/crypto_ops.c +++ b/components/wpa_supplicant/src/crypto/crypto_ops.c @@ -22,6 +22,28 @@ #include "esp_wpa.h" #include "ccmp.h" +#define DEFAULT_KEK_LEN 16 + +static int esp_aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher) +{ + return aes_wrap(kek, DEFAULT_KEK_LEN, n, plain, cipher); +} + +static int esp_aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain) +{ + return aes_unwrap(kek, DEFAULT_KEK_LEN, n, cipher, plain); +} + +static void esp_aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) +{ + aes_encrypt(ctx, plain, crypt); +} + +static void esp_aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) +{ + aes_decrypt(ctx, crypt, plain); +} + /* * 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 @@ -31,8 +53,8 @@ const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = { .size = sizeof(wpa_crypto_funcs_t), .version = ESP_WIFI_CRYPTO_VERSION, - .aes_wrap = (esp_aes_wrap_t)aes_wrap, - .aes_unwrap = (esp_aes_unwrap_t)aes_unwrap, + .aes_wrap = (esp_aes_wrap_t)esp_aes_wrap, + .aes_unwrap = (esp_aes_unwrap_t)esp_aes_unwrap, .hmac_sha256_vector = (esp_hmac_sha256_vector_t)hmac_sha256_vector, .sha256_prf = (esp_sha256_prf_t)sha256_prf, .hmac_md5 = (esp_hmac_md5_t)hmac_md5, @@ -44,10 +66,10 @@ const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = { .pbkdf2_sha1 = (esp_pbkdf2_sha1_t)pbkdf2_sha1, .rc4_skip = (esp_rc4_skip_t)rc4_skip, .md5_vector = (esp_md5_vector_t)md5_vector, - .aes_encrypt = (esp_aes_encrypt_t)aes_encrypt, + .aes_encrypt = (esp_aes_encrypt_t)esp_aes_encrypt, .aes_encrypt_init = (esp_aes_encrypt_init_t)aes_encrypt_init, .aes_encrypt_deinit = (esp_aes_encrypt_deinit_t)aes_encrypt_deinit, - .aes_decrypt = (esp_aes_decrypt_t)aes_decrypt, + .aes_decrypt = (esp_aes_decrypt_t)esp_aes_decrypt, .aes_decrypt_init = (esp_aes_decrypt_init_t)aes_decrypt_init, .aes_decrypt_deinit = (esp_aes_decrypt_deinit_t)aes_decrypt_deinit, .aes_128_encrypt = (esp_aes_128_encrypt_t)aes_128_cbc_encrypt, diff --git a/components/wpa_supplicant/src/crypto/des-internal.c b/components/wpa_supplicant/src/crypto/des-internal.c index ed9674d2c2..4ed6957802 100644 --- a/components/wpa_supplicant/src/crypto/des-internal.c +++ b/components/wpa_supplicant/src/crypto/des-internal.c @@ -8,12 +8,11 @@ * See README for more details. */ +#include "includes.h" -#include "utils/includes.h" - -#include "utils/common.h" +#include "common.h" #include "crypto.h" -//#include "des_i.h" +#include "des_i.h" /* * This implementation is based on a DES implementation included in @@ -246,6 +245,7 @@ static const u32 SP8[64] = 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL }; + static void cookey(const u32 *raw1, u32 *keyout) { u32 *cook; @@ -396,7 +396,7 @@ static void desfunc(u32 *block, const u32 *keys) /* wpa_supplicant/hostapd specific wrapper */ -void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) +int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) { u8 pkey[8], next, tmp; int i; @@ -421,9 +421,10 @@ void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) os_memset(pkey, 0, sizeof(pkey)); os_memset(ek, 0, sizeof(ek)); + return 0; } -/* + void des_key_setup(const u8 *key, u32 *ek, u32 *dk) { deskey(key, 0, ek); @@ -490,4 +491,4 @@ void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain) desfunc(work, key->dk[2]); WPA_PUT_BE32(plain, work[0]); WPA_PUT_BE32(plain + 4, work[1]); -}*/ +} diff --git a/components/wpa_supplicant/src/crypto/dh_group5.c b/components/wpa_supplicant/src/crypto/dh_group5.c index 0a228b5f36..425c848acb 100644 --- a/components/wpa_supplicant/src/crypto/dh_group5.c +++ b/components/wpa_supplicant/src/crypto/dh_group5.c @@ -1,43 +1,41 @@ /* * Diffie-Hellman group 5 operations - * Copyright (c) 2009, Jouni Malinen + * Copyright (c) 2009, 2012, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "dh_groups.h" #include "dh_group5.h" -void * -dh5_init(struct wpabuf **priv, struct wpabuf **publ) +void * dh5_init(struct wpabuf **priv, struct wpabuf **publ) { + wpabuf_free(*publ); *publ = dh_init(dh_groups_get(5), priv); - if (*publ == 0) + if (*publ == NULL) return NULL; return (void *) 1; } -struct wpabuf * -dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, +void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ) +{ + return (void *) 1; +} + + +struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, const struct wpabuf *own_private) { return dh_derive_shared(peer_public, own_private, dh_groups_get(5)); } -void -dh5_free(void *ctx) +void dh5_free(void *ctx) { } diff --git a/components/wpa_supplicant/src/crypto/dh_group5.h b/components/wpa_supplicant/src/crypto/dh_group5.h index 822d47a6e3..abee8eaafb 100644 --- a/components/wpa_supplicant/src/crypto/dh_group5.h +++ b/components/wpa_supplicant/src/crypto/dh_group5.h @@ -1,23 +1,16 @@ /* * Diffie-Hellman group 5 operations - * Copyright (c) 2009, Jouni Malinen + * Copyright (c) 2009, 2012, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef DH_GROUP5_H #define DH_GROUP5_H -#include "utils/wpabuf.h" - void * dh5_init(struct wpabuf **priv, struct wpabuf **publ); +void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ); struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, const struct wpabuf *own_private); void dh5_free(void *ctx); diff --git a/components/wpa_supplicant/src/crypto/dh_groups.c b/components/wpa_supplicant/src/crypto/dh_groups.c index 63fdb3897c..cd82dc28c1 100644 --- a/components/wpa_supplicant/src/crypto/dh_groups.c +++ b/components/wpa_supplicant/src/crypto/dh_groups.c @@ -2,25 +2,17 @@ * Diffie-Hellman groups * Copyright (c) 2007, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "crypto.h" #include "random.h" #include "dh_groups.h" -#include "utils/wpabuf.h" -#include "utils/wpa_debug.h" -#include "esp_wifi_crypto_types.h" + #ifdef ALL_DH_GROUPS @@ -43,7 +35,6 @@ static const u8 dh_group1_prime[96] = { 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - static const u8 dh_group1_order[96] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x87, 0xED, 0x51, 0x10, 0xB4, 0x61, 0x1A, @@ -82,7 +73,6 @@ static const u8 dh_group2_prime[128] = { 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - static const u8 dh_group2_order[128] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x87, 0xED, 0x51, 0x10, 0xB4, 0x61, 0x1A, @@ -135,7 +125,6 @@ static const u8 dh_group5_prime[192] = { 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - static const u8 dh_group5_order[192] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x87, 0xED, 0x51, 0x10, 0xB4, 0x61, 0x1A, @@ -204,7 +193,6 @@ static const u8 dh_group14_prime[256] = { 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - static const u8 dh_group14_order[256] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x87, 0xED, 0x51, 0x10, 0xB4, 0x61, 0x1A, @@ -295,7 +283,6 @@ static const u8 dh_group15_prime[384] = { 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - static const u8 dh_group15_order[384] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x87, 0xED, 0x51, 0x10, 0xB4, 0x61, 0x1A, @@ -418,7 +405,6 @@ static const u8 dh_group16_prime[512] = { 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - static const u8 dh_group16_order[512] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x87, 0xED, 0x51, 0x10, 0xB4, 0x61, 0x1A, @@ -589,7 +575,6 @@ static const u8 dh_group17_prime[768] = { 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - static const u8 dh_group17_order[768] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x87, 0xED, 0x51, 0x10, 0xB4, 0x61, 0x1A, @@ -824,7 +809,6 @@ static const u8 dh_group18_prime[1024] = { 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - static const u8 dh_group18_order[1024] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x87, 0xED, 0x51, 0x10, 0xB4, 0x61, 0x1A, @@ -1153,7 +1137,6 @@ static const u8 dh_group24_prime[] = { 0x69, 0x38, 0x77, 0xFA, 0xD7, 0xEF, 0x09, 0xCA, 0xDB, 0x09, 0x4A, 0xE9, 0x1E, 0x1A, 0x15, 0x97 }; - static const u8 dh_group24_order[] = { 0x8C, 0xF8, 0x36, 0x42, 0xA7, 0x09, 0xA0, 0x97, 0xB4, 0x47, 0x99, 0x76, 0x40, 0x12, 0x9D, 0xA2, @@ -1163,11 +1146,13 @@ static const u8 dh_group24_order[] = { #endif /* ALL_DH_GROUPS */ + #define DH_GROUP(id,safe) \ { id, dh_group ## id ## _generator, sizeof(dh_group ## id ## _generator), \ dh_group ## id ## _prime, sizeof(dh_group ## id ## _prime), \ dh_group ## id ## _order, sizeof(dh_group ## id ## _order), safe } + static const struct dh_group dh_groups[] = { DH_GROUP(5, 1), #ifdef ALL_DH_GROUPS @@ -1184,11 +1169,10 @@ static const struct dh_group dh_groups[] = { #endif /* ALL_DH_GROUPS */ }; -#define NUM_DH_GROUPS (sizeof(dh_groups) / sizeof(dh_groups[0])) +#define NUM_DH_GROUPS ARRAY_SIZE(dh_groups) -const struct dh_group * -dh_groups_get(int id) +const struct dh_group * dh_groups_get(int id) { size_t i; @@ -1199,14 +1183,14 @@ dh_groups_get(int id) return NULL; } + /** * dh_init - Initialize Diffie-Hellman handshake * @dh: Selected Diffie-Hellman group * @priv: Pointer for returning Diffie-Hellman private key * Returns: Diffie-Hellman public value */ -struct wpabuf * -dh_init(const struct dh_group *dh, struct wpabuf **priv) +struct wpabuf * dh_init(const struct dh_group *dh, struct wpabuf **priv) { struct wpabuf *pv; size_t pv_len; @@ -1262,8 +1246,7 @@ dh_init(const struct dh_group *dh, struct wpabuf **priv) * @dh: Selected Diffie-Hellman group * Returns: Diffie-Hellman shared key */ -struct wpabuf * -dh_derive_shared(const struct wpabuf *peer_public, +struct wpabuf * dh_derive_shared(const struct wpabuf *peer_public, const struct wpabuf *own_private, const struct dh_group *dh) { @@ -1286,7 +1269,6 @@ dh_derive_shared(const struct wpabuf *peer_public, wpa_printf(MSG_INFO, "DH: crypto_mod_exp failed"); return NULL; } - wpabuf_put(shared, shared_len); wpa_hexdump_buf_key(MSG_DEBUG, "DH: shared key", shared); diff --git a/components/wpa_supplicant/src/crypto/dh_groups.h b/components/wpa_supplicant/src/crypto/dh_groups.h index 6ce4a2a185..d0e74b9206 100644 --- a/components/wpa_supplicant/src/crypto/dh_groups.h +++ b/components/wpa_supplicant/src/crypto/dh_groups.h @@ -2,14 +2,8 @@ * Diffie-Hellman groups * Copyright (c) 2007, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef DH_GROUPS_H diff --git a/components/wpa_supplicant/src/crypto/md4-internal.c b/components/wpa_supplicant/src/crypto/md4-internal.c index 839ef41ea2..cf408e84fa 100644 --- a/components/wpa_supplicant/src/crypto/md4-internal.c +++ b/components/wpa_supplicant/src/crypto/md4-internal.c @@ -1,31 +1,39 @@ /* * MD4 hash implementation + * Copyright (c) 2006, Jouni Malinen * - * This software may be distributed under the terms of BSD license. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" -#include "utils/common.h" +#include "includes.h" + +#include "common.h" #include "crypto.h" -#define MD4_BLOCK_LENGTH 64 -#define MD4_DIGEST_LENGTH 16 +#define MD4_BLOCK_LENGTH 64 +#define MD4_DIGEST_LENGTH 16 typedef struct MD4Context { - u32 state[4]; - u64 count; - u8 buffer[MD4_BLOCK_LENGTH]; + u32 state[4]; /* state */ + u64 count; /* number of bits, mod 2^64 */ + u8 buffer[MD4_BLOCK_LENGTH]; /* input buffer */ } MD4_CTX; + static void MD4Init(MD4_CTX *ctx); static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len); static void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx); + int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { MD4_CTX ctx; size_t i; + if (TEST_FAIL()) + return -1; + MD4Init(&ctx); for (i = 0; i < num_elem; i++) MD4Update(&ctx, addr[i], len[i]); @@ -33,33 +41,60 @@ int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) return 0; } -#define MD4_DIGEST_STRING_LENGTH (MD4_DIGEST_LENGTH * 2 + 1) -static void MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH]); +/* ===== start - public domain MD4 implementation ===== */ +/* $OpenBSD: md4.c,v 1.7 2005/08/08 08:05:35 espie Exp $ */ -#define PUT_64BIT_LE(cp, value) do { \ - (cp)[7] = (value) >> 56; \ - (cp)[6] = (value) >> 48; \ - (cp)[5] = (value) >> 40; \ - (cp)[4] = (value) >> 32; \ - (cp)[3] = (value) >> 24; \ - (cp)[2] = (value) >> 16; \ - (cp)[1] = (value) >> 8; \ +/* + * This code implements the MD4 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * Todd C. Miller modified the MD5 code to do MD4 based on RFC 1186. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD4Context structure, pass it to MD4Init, call MD4Update as + * needed on buffers full of bytes, and then call MD4Final, which + * will fill a supplied 16-byte array with the digest. + */ + +#define MD4_DIGEST_STRING_LENGTH (MD4_DIGEST_LENGTH * 2 + 1) + + +static void +MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH]); + +#define PUT_64BIT_LE(cp, value) do { \ + (cp)[7] = (value) >> 56; \ + (cp)[6] = (value) >> 48; \ + (cp)[5] = (value) >> 40; \ + (cp)[4] = (value) >> 32; \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ (cp)[0] = (value); } while (0) -#define PUT_32BIT_LE(cp, value) do { \ - (cp)[3] = (value) >> 24; \ - (cp)[2] = (value) >> 16; \ - (cp)[1] = (value) >> 8; \ +#define PUT_32BIT_LE(cp, value) do { \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ (cp)[0] = (value); } while (0) -static u8 PADDING[MD4_BLOCK_LENGTH] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +static const u8 PADDING[MD4_BLOCK_LENGTH] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +/* + * Start MD4 accumulation. + * Set bit count to 0 and buffer to mysterious initialization constants. + */ static void MD4Init(MD4_CTX *ctx) { ctx->count = 0; @@ -69,13 +104,19 @@ static void MD4Init(MD4_CTX *ctx) ctx->state[3] = 0x10325476; } +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len) { size_t have, need; + /* Check how many bytes we already have and how many more we need. */ have = (size_t)((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1)); need = MD4_BLOCK_LENGTH - have; + /* Update bitcount */ ctx->count += (u64)len << 3; if (len >= need) { @@ -87,6 +128,7 @@ static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len) have = 0; } + /* Process data in MD4_BLOCK_LENGTH-byte chunks. */ while (len >= MD4_BLOCK_LENGTH) { MD4Transform(ctx->state, input); input += MD4_BLOCK_LENGTH; @@ -94,108 +136,140 @@ static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len) } } + /* Handle any remaining bytes of data. */ if (len != 0) os_memcpy(ctx->buffer + have, input, len); } +/* + * Pad pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ static void MD4Pad(MD4_CTX *ctx) { u8 count[8]; size_t padlen; + /* Convert count to 8 bytes in little endian order. */ PUT_64BIT_LE(count, ctx->count); + /* Pad out to 56 mod 64. */ padlen = MD4_BLOCK_LENGTH - - ((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1)); + ((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1)); if (padlen < 1 + 8) padlen += MD4_BLOCK_LENGTH; - MD4Update(ctx, PADDING, padlen - 8); + MD4Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ MD4Update(ctx, count, 8); } +/* + * Final wrapup--call MD4Pad, fill in digest and zero out ctx. + */ static void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx) { int i; MD4Pad(ctx); if (digest != NULL) { - for (i = 0; i < 4; i ++) + for (i = 0; i < 4; i++) PUT_32BIT_LE(digest + i * 4, ctx->state[i]); os_memset(ctx, 0, sizeof(*ctx)); } } -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) ((x & y) | (x & z) | (y & z)) -#define F3(x, y, z) (x ^ y ^ z) -#define MD4SETP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s) ) +/* The three core functions - F1 is optimized somewhat */ -static void MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH]) +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) ((x & y) | (x & z) | (y & z)) +#define F3(x, y, z) (x ^ y ^ z) + +/* This is the central step in the MD4 algorithm. */ +#define MD4STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s) ) + +/* + * The core of the MD4 algorithm, this alters an existing MD4 hash to + * reflect the addition of 16 longwords of new data. MD4Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void +MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH]) { u32 a, b, c, d, in[MD4_BLOCK_LENGTH / 4]; +#if BYTE_ORDER == LITTLE_ENDIAN os_memcpy(in, block, sizeof(in)); +#else + for (a = 0; a < MD4_BLOCK_LENGTH / 4; a++) { + in[a] = (u32)( + (u32)(block[a * 4 + 0]) | + (u32)(block[a * 4 + 1]) << 8 | + (u32)(block[a * 4 + 2]) << 16 | + (u32)(block[a * 4 + 3]) << 24); + } +#endif a = state[0]; b = state[1]; c = state[2]; d = state[3]; - MD4SETP(F1, a, b, c, d, in[ 0], 3); - MD4SETP(F1, d, a, b, c, in[ 1], 7); - MD4SETP(F1, c, d, a, b, in[ 2], 11); - MD4SETP(F1, b, c, d, a, in[ 3], 19); - MD4SETP(F1, a, b, c, d, in[ 4], 3); - MD4SETP(F1, d, a, b, c, in[ 5], 7); - MD4SETP(F1, c, d, a, b, in[ 6], 11); - MD4SETP(F1, b, c, d, a, in[ 7], 19); - MD4SETP(F1, a, b, c, d, in[ 8], 3); - MD4SETP(F1, d, a, b, c, in[ 9], 7); - MD4SETP(F1, c, d, a, b, in[10], 11); - MD4SETP(F1, b, c, d, a, in[11], 19); - MD4SETP(F1, a, b, c, d, in[12], 3); - MD4SETP(F1, d, a, b, c, in[13], 7); - MD4SETP(F1, c, d, a, b, in[14], 11); - MD4SETP(F1, b, c, d, a, in[15], 19); + MD4STEP(F1, a, b, c, d, in[ 0], 3); + MD4STEP(F1, d, a, b, c, in[ 1], 7); + MD4STEP(F1, c, d, a, b, in[ 2], 11); + MD4STEP(F1, b, c, d, a, in[ 3], 19); + MD4STEP(F1, a, b, c, d, in[ 4], 3); + MD4STEP(F1, d, a, b, c, in[ 5], 7); + MD4STEP(F1, c, d, a, b, in[ 6], 11); + MD4STEP(F1, b, c, d, a, in[ 7], 19); + MD4STEP(F1, a, b, c, d, in[ 8], 3); + MD4STEP(F1, d, a, b, c, in[ 9], 7); + MD4STEP(F1, c, d, a, b, in[10], 11); + MD4STEP(F1, b, c, d, a, in[11], 19); + MD4STEP(F1, a, b, c, d, in[12], 3); + MD4STEP(F1, d, a, b, c, in[13], 7); + MD4STEP(F1, c, d, a, b, in[14], 11); + MD4STEP(F1, b, c, d, a, in[15], 19); - MD4SETP(F2, a, b, c, d, in[ 0] + 0x5a827999, 3); - MD4SETP(F2, d, a, b, c, in[ 4] + 0x5a827999, 5); - MD4SETP(F2, c, d, a, b, in[ 8] + 0x5a827999, 9); - MD4SETP(F2, b, c, d, a, in[12] + 0x5a827999, 13); - MD4SETP(F2, a, b, c, d, in[ 1] + 0x5a827999, 3); - MD4SETP(F2, d, a, b, c, in[ 5] + 0x5a827999, 5); - MD4SETP(F2, c, d, a, b, in[ 9] + 0x5a827999, 9); - MD4SETP(F2, b, c, d, a, in[13] + 0x5a827999, 13); - MD4SETP(F2, a, b, c, d, in[ 2] + 0x5a827999, 3); - MD4SETP(F2, d, a, b, c, in[ 6] + 0x5a827999, 5); - MD4SETP(F2, c, d, a, b, in[10] + 0x5a827999, 9); - MD4SETP(F2, b, c, d, a, in[14] + 0x5a827999, 13); - MD4SETP(F2, a, b, c, d, in[ 3] + 0x5a827999, 3); - MD4SETP(F2, d, a, b, c, in[ 7] + 0x5a827999, 5); - MD4SETP(F2, c, d, a, b, in[11] + 0x5a827999, 9); - MD4SETP(F2, b, c, d, a, in[15] + 0x5a827999, 13); + MD4STEP(F2, a, b, c, d, in[ 0] + 0x5a827999, 3); + MD4STEP(F2, d, a, b, c, in[ 4] + 0x5a827999, 5); + MD4STEP(F2, c, d, a, b, in[ 8] + 0x5a827999, 9); + MD4STEP(F2, b, c, d, a, in[12] + 0x5a827999, 13); + MD4STEP(F2, a, b, c, d, in[ 1] + 0x5a827999, 3); + MD4STEP(F2, d, a, b, c, in[ 5] + 0x5a827999, 5); + MD4STEP(F2, c, d, a, b, in[ 9] + 0x5a827999, 9); + MD4STEP(F2, b, c, d, a, in[13] + 0x5a827999, 13); + MD4STEP(F2, a, b, c, d, in[ 2] + 0x5a827999, 3); + MD4STEP(F2, d, a, b, c, in[ 6] + 0x5a827999, 5); + MD4STEP(F2, c, d, a, b, in[10] + 0x5a827999, 9); + MD4STEP(F2, b, c, d, a, in[14] + 0x5a827999, 13); + MD4STEP(F2, a, b, c, d, in[ 3] + 0x5a827999, 3); + MD4STEP(F2, d, a, b, c, in[ 7] + 0x5a827999, 5); + MD4STEP(F2, c, d, a, b, in[11] + 0x5a827999, 9); + MD4STEP(F2, b, c, d, a, in[15] + 0x5a827999, 13); - MD4SETP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1, 3); - MD4SETP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1, 9); - MD4SETP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11); - MD4SETP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15); - MD4SETP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1, 3); - MD4SETP(F3, d, a, b, c, in[10] + 0x6ed9eba1, 9); - MD4SETP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11); - MD4SETP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15); - MD4SETP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1, 3); - MD4SETP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1, 9); - MD4SETP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11); - MD4SETP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15); - MD4SETP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1, 3); - MD4SETP(F3, d, a, b, c, in[11] + 0x6ed9eba1, 9); - MD4SETP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11); - MD4SETP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15); + MD4STEP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1, 3); + MD4STEP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1, 9); + MD4STEP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11); + MD4STEP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15); + MD4STEP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1, 3); + MD4STEP(F3, d, a, b, c, in[10] + 0x6ed9eba1, 9); + MD4STEP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11); + MD4STEP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15); + MD4STEP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1, 3); + MD4STEP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1, 9); + MD4STEP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11); + MD4STEP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15); + MD4STEP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1, 3); + MD4STEP(F3, d, a, b, c, in[11] + 0x6ed9eba1, 9); + MD4STEP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11); + MD4STEP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15); state[0] += a; state[1] += b; state[2] += c; state[3] += d; } +/* ===== end - public domain MD4 implementation ===== */ diff --git a/components/wpa_supplicant/src/crypto/md5-internal.c b/components/wpa_supplicant/src/crypto/md5-internal.c index 74b50247f2..944698a632 100644 --- a/components/wpa_supplicant/src/crypto/md5-internal.c +++ b/components/wpa_supplicant/src/crypto/md5-internal.c @@ -2,19 +2,13 @@ * MD5 hash implementation and interface functions * Copyright (c) 2003-2005, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "md5.h" #include "md5_i.h" #include "crypto.h" @@ -34,12 +28,14 @@ typedef struct MD5Context MD5_CTX; * @mac: Buffer for the hash * Returns: 0 on success, -1 of failure */ -int -md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) +int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { MD5_CTX ctx; size_t i; + if (TEST_FAIL()) + return -1; + MD5Init(&ctx); for (i = 0; i < num_elem; i++) MD5Update(&ctx, addr[i], len[i]); @@ -88,8 +84,7 @@ static void byteReverse(unsigned char *buf, unsigned longs) * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious * initialization constants. */ -void -MD5Init(struct MD5Context *ctx) +void MD5Init(struct MD5Context *ctx) { ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; @@ -104,8 +99,7 @@ MD5Init(struct MD5Context *ctx) * Update context to reflect the concatenation of another buffer full * of bytes. */ -void -MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) { u32 t; @@ -153,8 +147,7 @@ MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ -void -MD5Final(unsigned char digest[16], struct MD5Context *ctx) +void MD5Final(unsigned char digest[16], struct MD5Context *ctx) { unsigned count; unsigned char *p; @@ -186,13 +179,13 @@ MD5Final(unsigned char digest[16], struct MD5Context *ctx) byteReverse(ctx->in, 14); /* Append length in bits and transform */ - ((u32 *) ctx->in)[14] = ctx->bits[0]; - ((u32 *) ctx->in)[15] = ctx->bits[1]; + ((u32 *) aliasing_hide_typecast(ctx->in, u32))[14] = ctx->bits[0]; + ((u32 *) aliasing_hide_typecast(ctx->in, u32))[15] = ctx->bits[1]; MD5Transform(ctx->buf, (u32 *) ctx->in); byteReverse((unsigned char *) ctx->buf, 4); os_memcpy(digest, ctx->buf, 16); - os_memset(ctx, 0, sizeof(struct MD5Context)); /* In case it's sensitive */ + os_memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ } /* The four core functions - F1 is optimized somewhat */ @@ -212,8 +205,7 @@ MD5Final(unsigned char digest[16], struct MD5Context *ctx) * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ -static void -MD5Transform(u32 buf[4], u32 const in[16]) +static void MD5Transform(u32 buf[4], u32 const in[16]) { register u32 a, b, c, d; diff --git a/components/wpa_supplicant/src/crypto/md5.c b/components/wpa_supplicant/src/crypto/md5.c index 3678b4af60..f64dfd3d43 100644 --- a/components/wpa_supplicant/src/crypto/md5.c +++ b/components/wpa_supplicant/src/crypto/md5.c @@ -2,19 +2,13 @@ * MD5 hash implementation and interface functions * Copyright (c) 2003-2005, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "md5.h" #include "crypto.h" @@ -29,14 +23,14 @@ * @mac: Buffer for the hash (16 bytes) * Returns: 0 on success, -1 on failure */ -int -hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, +int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { u8 k_pad[64]; /* padding - key XORd with ipad/opad */ u8 tk[16]; const u8 *_addr[6]; size_t i, _len[6]; + int res; if (num_elem > 5) { /* @@ -92,7 +86,10 @@ hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, _len[0] = 64; _addr[1] = mac; _len[1] = MD5_MAC_LEN; - return md5_vector(2, _addr, _len, mac); + res = md5_vector(2, _addr, _len, mac); + os_memset(k_pad, 0, sizeof(k_pad)); + os_memset(tk, 0, sizeof(tk)); + return res; } @@ -105,8 +102,7 @@ hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, * @mac: Buffer for the hash (16 bytes) * Returns: 0 on success, -1 on failure */ -int -hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, +int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac) { return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac); diff --git a/components/wpa_supplicant/src/crypto/md5.h b/components/wpa_supplicant/src/crypto/md5.h index 6de3a5b5f1..33f8426c57 100644 --- a/components/wpa_supplicant/src/crypto/md5.h +++ b/components/wpa_supplicant/src/crypto/md5.h @@ -2,14 +2,8 @@ * MD5 hash implementation and interface functions * Copyright (c) 2003-2009, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef MD5_H @@ -17,19 +11,9 @@ #define MD5_MAC_LEN 16 -int hmac_md5_vector(const uint8_t *key, size_t key_len, size_t num_elem, - const uint8_t *addr[], const size_t *len, uint8_t *mac); -int hmac_md5(const uint8_t *key, size_t key_len, const uint8_t *data, size_t data_len, - uint8_t *mac); -#ifdef CONFIG_FIPS -int hmac_md5_vector_non_fips_allow(const uint8_t *key, size_t key_len, - size_t num_elem, const uint8_t *addr[], - const size_t *len, uint8_t *mac); -int hmac_md5_non_fips_allow(const uint8_t *key, size_t key_len, const uint8_t *data, - size_t data_len, uint8_t *mac); -#else /* CONFIG_FIPS */ -#define hmac_md5_vector_non_fips_allow hmac_md5_vector -#define hmac_md5_non_fips_allow hmac_md5 -#endif /* CONFIG_FIPS */ +int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac); +int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, + u8 *mac); #endif /* MD5_H */ diff --git a/components/wpa_supplicant/src/crypto/md5_i.h b/components/wpa_supplicant/src/crypto/md5_i.h index b7f6596052..7dfc10037d 100644 --- a/components/wpa_supplicant/src/crypto/md5_i.h +++ b/components/wpa_supplicant/src/crypto/md5_i.h @@ -2,14 +2,8 @@ * MD5 internal definitions * Copyright (c) 2003-2005, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef MD5_I_H diff --git a/components/wpa_supplicant/src/crypto/ms_funcs.c b/components/wpa_supplicant/src/crypto/ms_funcs.c index 05a148525e..aff7d33f4e 100644 --- a/components/wpa_supplicant/src/crypto/ms_funcs.c +++ b/components/wpa_supplicant/src/crypto/ms_funcs.c @@ -6,10 +6,9 @@ * See README for more details. */ +#include "includes.h" -#include "utils/includes.h" - -#include "utils/common.h" +#include "common.h" #include "sha1.h" #include "ms_funcs.h" #include "crypto.h" @@ -24,8 +23,8 @@ * Returns: 0 on success, -1 on failure */ static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len, - u8 *ucs2_buffer, size_t ucs2_buffer_size, - size_t *ucs2_string_size) + u8 *ucs2_buffer, size_t ucs2_buffer_size, + size_t *ucs2_string_size) { size_t i, j; @@ -49,7 +48,7 @@ static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len, WPA_PUT_LE16(ucs2_buffer + j, ((c & 0x1F) << 6) | (c2 & 0x3F)); j += 2; - } else if (i == utf8_string_len || + } else if (i == utf8_string_len - 1 || j >= ucs2_buffer_size - 1) { /* incomplete surrogate */ return -1; @@ -59,6 +58,7 @@ static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len, WPA_PUT_LE16(ucs2_buffer + j, ((c & 0xF) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)); + j += 2; } } } @@ -78,9 +78,8 @@ static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len, * @challenge: 8-octet Challenge (OUT) * Returns: 0 on success, -1 on failure */ -static int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge, - const u8 *username, size_t username_len, - u8 *challenge) +int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge, + const u8 *username, size_t username_len, u8 *challenge) { u8 hash[SHA1_MAC_LEN]; const unsigned char *addr[3]; @@ -108,7 +107,7 @@ static int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge, * Returns: 0 on success, -1 on failure */ int nt_password_hash(const u8 *password, size_t password_len, - u8 *password_hash) + u8 *password_hash) { u8 buf[512], *pos; size_t len, max_len; @@ -141,17 +140,20 @@ int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash) * @challenge: 8-octet Challenge (IN) * @password_hash: 16-octet PasswordHash (IN) * @response: 24-octet Response (OUT) + * Returns: 0 on success, -1 on failure */ -void challenge_response(const u8 *challenge, const u8 *password_hash, - u8 *response) +int challenge_response(const u8 *challenge, const u8 *password_hash, + u8 *response) { u8 zpwd[7]; - des_encrypt(challenge, password_hash, response); - des_encrypt(challenge, password_hash + 7, response + 8); + + if (des_encrypt(challenge, password_hash, response) < 0 || + des_encrypt(challenge, password_hash + 7, response + 8) < 0) + return -1; zpwd[0] = password_hash[14]; zpwd[1] = password_hash[15]; os_memset(zpwd + 2, 0, 5); - des_encrypt(challenge, zpwd, response + 16); + return des_encrypt(challenge, zpwd, response + 16); } @@ -167,19 +169,18 @@ void challenge_response(const u8 *challenge, const u8 *password_hash, * Returns: 0 on success, -1 on failure */ int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge, - const u8 *username, size_t username_len, - const u8 *password, size_t password_len, - u8 *response) + const u8 *username, size_t username_len, + const u8 *password, size_t password_len, + u8 *response) { u8 challenge[8]; u8 password_hash[16]; if (challenge_hash(peer_challenge, auth_challenge, username, - username_len, challenge)) + username_len, challenge) || + nt_password_hash(password, password_len, password_hash) || + challenge_response(challenge, password_hash, response)) return -1; - if (nt_password_hash(password, password_len, password_hash)) - return -1; - challenge_response(challenge, password_hash, response); return 0; } @@ -195,18 +196,18 @@ int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge, * Returns: 0 on success, -1 on failure */ int generate_nt_response_pwhash(const u8 *auth_challenge, - const u8 *peer_challenge, - const u8 *username, size_t username_len, - const u8 *password_hash, - u8 *response) + const u8 *peer_challenge, + const u8 *username, size_t username_len, + const u8 *password_hash, + u8 *response) { u8 challenge[8]; if (challenge_hash(peer_challenge, auth_challenge, username, username_len, - challenge)) + challenge) || + challenge_response(challenge, password_hash, response)) return -1; - challenge_response(challenge, password_hash, response); return 0; } @@ -257,12 +258,9 @@ int generate_authenticator_response_pwhash( addr2[1] = challenge; addr2[2] = magic2; - if (hash_nt_password_hash(password_hash, password_hash_hash)) - return -1; - if (sha1_vector(3, addr1, len1, response)) - return -1; - - if (challenge_hash(peer_challenge, auth_challenge, username, + if (hash_nt_password_hash(password_hash, password_hash_hash) || + sha1_vector(3, addr1, len1, response) || + challenge_hash(peer_challenge, auth_challenge, username, username_len, challenge)) return -1; return sha1_vector(3, addr2, len2, response); @@ -283,10 +281,10 @@ int generate_authenticator_response_pwhash( * Returns: 0 on success, -1 on failure */ int generate_authenticator_response(const u8 *password, size_t password_len, - const u8 *peer_challenge, - const u8 *auth_challenge, - const u8 *username, size_t username_len, - const u8 *nt_response, u8 *response) + const u8 *peer_challenge, + const u8 *auth_challenge, + const u8 *username, size_t username_len, + const u8 *nt_response, u8 *response) { u8 password_hash[16]; if (nt_password_hash(password, password_len, password_hash)) @@ -306,12 +304,13 @@ int generate_authenticator_response(const u8 *password, size_t password_len, * Returns: 0 on success, -1 on failure */ int nt_challenge_response(const u8 *challenge, const u8 *password, - size_t password_len, u8 *response) + size_t password_len, u8 *response) { u8 password_hash[16]; - if (nt_password_hash(password, password_len, password_hash)) + + if (nt_password_hash(password, password_len, password_hash) || + challenge_response(challenge, password_hash, response)) return -1; - challenge_response(challenge, password_hash, response); return 0; } @@ -324,7 +323,7 @@ int nt_challenge_response(const u8 *challenge, const u8 *password, * Returns: 0 on success, -1 on failure */ int get_master_key(const u8 *password_hash_hash, const u8 *nt_response, - u8 *master_key) + u8 *master_key) { static const u8 magic1[27] = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, @@ -356,8 +355,8 @@ int get_master_key(const u8 *password_hash_hash, const u8 *nt_response, * Returns: 0 on success, -1 on failure */ int get_asymetric_start_key(const u8 *master_key, u8 *session_key, - size_t session_key_len, int is_send, - int is_server) + size_t session_key_len, int is_send, + int is_server) { static const u8 magic2[84] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, @@ -417,6 +416,8 @@ int get_asymetric_start_key(const u8 *master_key, u8 *session_key, } +#ifndef CONFIG_NO_RC4 + #define PWBLOCK_LEN 516 /** @@ -436,10 +437,8 @@ int encrypt_pw_block_with_password_hash( os_memset(pw_block, 0, PWBLOCK_LEN); - if (utf8_to_ucs2(password, password_len, pw_block, 512, &ucs2_len) < 0) - return -1; - - if (ucs2_len > 256) + if (utf8_to_ucs2(password, password_len, pw_block, 512, &ucs2_len) < 0 + || ucs2_len > 256) return -1; offset = (256 - ucs2_len) * 2; @@ -484,18 +483,23 @@ int new_password_encrypted_with_old_nt_password_hash( return 0; } +#endif /* CONFIG_NO_RC4 */ + /** * nt_password_hash_encrypted_with_block - NtPasswordHashEncryptedWithBlock() - RFC 2759, Sect 8.13 * @password_hash: 16-octer PasswordHash (IN) * @block: 16-octet Block (IN) * @cypher: 16-octer Cypher (OUT) + * Returns: 0 on success, -1 on failure */ -void nt_password_hash_encrypted_with_block(const u8 *password_hash, - const u8 *block, u8 *cypher) +int nt_password_hash_encrypted_with_block(const u8 *password_hash, + const u8 *block, u8 *cypher) { - des_encrypt(password_hash, block, cypher); - des_encrypt(password_hash + 8, block + 7, cypher + 8); + if (des_encrypt(password_hash, block, cypher) < 0 || + des_encrypt(password_hash + 8, block + 7, cypher + 8) < 0) + return -1; + return 0; } @@ -518,10 +522,10 @@ int old_nt_password_hash_encrypted_with_new_nt_password_hash( if (nt_password_hash(old_password, old_password_len, old_password_hash) || nt_password_hash(new_password, new_password_len, - new_password_hash)) + new_password_hash) || + nt_password_hash_encrypted_with_block(old_password_hash, + new_password_hash, + encrypted_password_hash)) return -1; - nt_password_hash_encrypted_with_block(old_password_hash, - new_password_hash, - encrypted_password_hash); return 0; } diff --git a/components/wpa_supplicant/src/crypto/ms_funcs.h b/components/wpa_supplicant/src/crypto/ms_funcs.h index dadb7d9321..b8d55f0532 100644 --- a/components/wpa_supplicant/src/crypto/ms_funcs.h +++ b/components/wpa_supplicant/src/crypto/ms_funcs.h @@ -1,7 +1,9 @@ /* - * WPA Supplicant / shared MSCHAPV2 helper functions - * + * WPA Supplicant / shared MSCHAPV2 helper functions / RFC 2433 / RFC 2759 + * Copyright (c) 2004-2009, Jouni Malinen * + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef MS_FUNCS_H @@ -11,7 +13,6 @@ int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge, const u8 *username, size_t username_len, const u8 *password, size_t password_len, u8 *response); - int generate_nt_response_pwhash(const u8 *auth_challenge, const u8 *peer_challenge, const u8 *username, size_t username_len, @@ -30,8 +31,10 @@ int generate_authenticator_response_pwhash( int nt_challenge_response(const u8 *challenge, const u8 *password, size_t password_len, u8 *response); -void challenge_response(const u8 *challenge, const u8 *password_hash, - u8 *response); +int challenge_response(const u8 *challenge, const u8 *password_hash, + u8 *response); +int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge, + const u8 *username, size_t username_len, u8 *challenge); int nt_password_hash(const u8 *password, size_t password_len, u8 *password_hash); int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash); @@ -40,18 +43,15 @@ int get_master_key(const u8 *password_hash_hash, const u8 *nt_response, int get_asymetric_start_key(const u8 *master_key, u8 *session_key, size_t session_key_len, int is_send, int is_server); -int encrypt_pw_block_with_password_hash( - const u8 *password, size_t password_len, - const u8 *password_hash, u8 *pw_block); -int __must_check encry_pw_block_with_password_hash( +int __must_check encrypt_pw_block_with_password_hash( const u8 *password, size_t password_len, const u8 *password_hash, u8 *pw_block); int __must_check new_password_encrypted_with_old_nt_password_hash( const u8 *new_password, size_t new_password_len, const u8 *old_password, size_t old_password_len, u8 *encrypted_pw_block); -void nt_password_hash_encrypted_with_block(const u8 *password_hash, - const u8 *block, u8 *cypher); +int nt_password_hash_encrypted_with_block(const u8 *password_hash, + const u8 *block, u8 *cypher); int old_nt_password_hash_encrypted_with_new_nt_password_hash( const u8 *new_password, size_t new_password_len, const u8 *old_password, size_t old_password_len, diff --git a/components/wpa_supplicant/src/crypto/random.h b/components/wpa_supplicant/src/crypto/random.h index cbfa8773fd..d13e1c4929 100644 --- a/components/wpa_supplicant/src/crypto/random.h +++ b/components/wpa_supplicant/src/crypto/random.h @@ -2,21 +2,13 @@ * Random number generator * Copyright (c) 2010-2011, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef RANDOM_H #define RANDOM_H -#define CONFIG_NO_RANDOM_POOL - #ifdef CONFIG_NO_RANDOM_POOL #define random_init(e) do { } while (0) #define random_deinit() do { } while (0) @@ -29,6 +21,8 @@ void random_init(const char *entropy_file); void random_deinit(void); void random_add_randomness(const void *buf, size_t len); int random_get_bytes(void *buf, size_t len); +int random_pool_ready(void); +void random_mark_pool_ready(void); #endif /* CONFIG_NO_RANDOM_POOL */ #endif /* RANDOM_H */ diff --git a/components/wpa_supplicant/src/crypto/rc4.c b/components/wpa_supplicant/src/crypto/rc4.c index e76532e972..98ae269a63 100644 --- a/components/wpa_supplicant/src/crypto/rc4.c +++ b/components/wpa_supplicant/src/crypto/rc4.c @@ -2,25 +2,18 @@ * RC4 stream cipher * Copyright (c) 2002-2005, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "crypto.h" #define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0) -int -rc4_skip(const u8 *key, size_t keylen, size_t skip, +int rc4_skip(const u8 *key, size_t keylen, size_t skip, u8 *data, size_t data_len) { u32 i, j, k; diff --git a/components/wpa_supplicant/src/crypto/sha1-internal.c b/components/wpa_supplicant/src/crypto/sha1-internal.c index f69a9f913d..ffa04df017 100644 --- a/components/wpa_supplicant/src/crypto/sha1-internal.c +++ b/components/wpa_supplicant/src/crypto/sha1-internal.c @@ -2,35 +2,24 @@ * SHA1 hash implementation and interface functions * Copyright (c) 2003-2005, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "sha1.h" #include "sha1_i.h" #include "md5.h" #include "crypto.h" -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/sha1.h" -#endif - typedef struct SHA1Context SHA1_CTX; void SHA1Transform(u32 state[5], const unsigned char buffer[64]); - -#ifndef USE_MBEDTLS_CRYPTO +#ifdef CONFIG_CRYPTO_INTERNAL /** * sha1_vector - SHA-1 hash for data vector * @num_elem: Number of elements in the data vector @@ -39,61 +28,22 @@ void SHA1Transform(u32 state[5], const unsigned char buffer[64]); * @mac: Buffer for the hash * Returns: 0 on success, -1 of failure */ -int -sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) +int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { SHA1_CTX ctx; size_t i; + if (TEST_FAIL()) + return -1; + SHA1Init(&ctx); for (i = 0; i < num_elem; i++) SHA1Update(&ctx, addr[i], len[i]); SHA1Final(mac, &ctx); return 0; } -#else -/** - * sha1_vector - SHA-1 hash for data vector - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash - * Returns: 0 on success, -1 of failure - */ -int -sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -{ - mbedtls_sha1_context ctx; - size_t i; - int ret; +#endif /* CONFIG_CRYPTO_INTERNAL */ - mbedtls_sha1_init( &ctx ); - - if ((ret = mbedtls_sha1_starts_ret( &ctx)) != 0) { - goto exit; - } - - - for (i = 0; i < num_elem; i++) { - if ((ret = mbedtls_sha1_update_ret(&ctx, addr[i], len[i])) != 0) { - goto exit; - } - } - - if ((ret = mbedtls_sha1_finish_ret( &ctx, mac)) != 0) { - goto exit; - } - -exit: - mbedtls_sha1_free( &ctx ); - - if (ret) { - return -1; - } - - return 0; -} -#endif /* ===== start - public domain SHA1 implementation ===== */ @@ -223,8 +173,7 @@ void SHAPrintContext(SHA1_CTX *context, char *msg) /* Hash a single 512-bit block. This is the core of the algorithm. */ -void -SHA1Transform(u32 state[5], const unsigned char buffer[64]) +void SHA1Transform(u32 state[5], const unsigned char buffer[64]) { u32 a, b, c, d, e; typedef union { @@ -275,15 +224,14 @@ SHA1Transform(u32 state[5], const unsigned char buffer[64]) /* Wipe variables */ a = b = c = d = e = 0; #ifdef SHA1HANDSOFF - os_memset(block, 0, 64); + forced_memzero(block, 64); #endif } /* SHA1Init - Initialize new context */ -void -SHA1Init(SHA1_CTX* context) +void SHA1Init(SHA1_CTX* context) { /* SHA1 initialization constants */ context->state[0] = 0x67452301; @@ -297,8 +245,7 @@ SHA1Init(SHA1_CTX* context) /* Run your data through this. */ -void -SHA1Update(SHA1_CTX* context, const void *_data, u32 len) +void SHA1Update(SHA1_CTX* context, const void *_data, u32 len) { u32 i, j; const unsigned char *data = _data; @@ -328,8 +275,7 @@ SHA1Update(SHA1_CTX* context, const void *_data, u32 len) /* Add padding and return the message digest. */ -void -SHA1Final(unsigned char digest[20], SHA1_CTX* context) +void SHA1Final(unsigned char digest[20], SHA1_CTX* context) { u32 i; unsigned char finalcount[8]; @@ -351,10 +297,10 @@ SHA1Final(unsigned char digest[20], SHA1_CTX* context) 255); } /* Wipe variables */ - i = 0; os_memset(context->buffer, 0, 64); os_memset(context->state, 0, 20); os_memset(context->count, 0, 8); - os_memset(finalcount, 0, 8); + forced_memzero(finalcount, sizeof(finalcount)); } + /* ===== end - public domain SHA1 implementation ===== */ diff --git a/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c b/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c index c8d4de6d51..8effe2fe06 100644 --- a/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c +++ b/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c @@ -2,79 +2,18 @@ * SHA1-based key derivation function (PBKDF2) for IEEE 802.11i * Copyright (c) 2003-2005, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" -#include "utils/common.h" +#include "includes.h" + +#include "common.h" #include "sha1.h" -#include "md5.h" -#include "crypto.h" -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/pkcs5.h" - -/** - * pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i - * @passphrase: ASCII passphrase - * @ssid: SSID - * @ssid_len: SSID length in bytes - * @iterations: Number of iterations to run - * @buf: Buffer for the generated key - * @buflen: Length of the buffer in bytes - * Returns: 0 on success, -1 of failure - * - * This function is used to derive PSK for WPA-PSK. For this protocol, - * iterations is set to 4096 and buflen to 32. This function is described in - * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0. - */ -int -pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, u8 *buf, size_t buflen) -{ - - mbedtls_md_context_t sha1_ctx; - const mbedtls_md_info_t *info_sha1; - int ret; - - mbedtls_md_init( &sha1_ctx ); - - info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); - if (info_sha1 == NULL) { - ret = -1; - goto exit; - } - - if ((ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0) { - ret = -1; - goto exit; - } - - ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, (const unsigned char*) passphrase, os_strlen(passphrase) , (const unsigned char*) ssid, - ssid_len, iterations, 32, buf ); - if (ret != 0) { - ret = -1; - goto exit; - } - -exit: - mbedtls_md_free( &sha1_ctx ); - - return ret; -} -#else - -static int -pbkdf2_sha1_f(const char *passphrase, const char *ssid, - size_t ssid_len, int iterations, unsigned int count, - u8 *digest) +static int pbkdf2_sha1_f(const char *passphrase, const u8 *ssid, + size_t ssid_len, int iterations, unsigned int count, + u8 *digest) { unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN]; int i, j; @@ -83,7 +22,7 @@ pbkdf2_sha1_f(const char *passphrase, const char *ssid, size_t len[2]; size_t passphrase_len = os_strlen(passphrase); - addr[0] = (u8 *) ssid; + addr[0] = ssid; len[0] = ssid_len; addr[1] = count_buf; len[1] = 4; @@ -130,8 +69,7 @@ pbkdf2_sha1_f(const char *passphrase, const char *ssid, * iterations is set to 4096 and buflen to 32. This function is described in * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0. */ -int -pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, +int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, int iterations, u8 *buf, size_t buflen) { unsigned int count = 0; @@ -152,4 +90,3 @@ pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, return 0; } -#endif diff --git a/components/wpa_supplicant/src/crypto/sha1-prf.c b/components/wpa_supplicant/src/crypto/sha1-prf.c new file mode 100644 index 0000000000..13851494fb --- /dev/null +++ b/components/wpa_supplicant/src/crypto/sha1-prf.c @@ -0,0 +1,67 @@ +/* + * SHA1-based PRF + * Copyright (c) 2003-2005, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "sha1.h" +#include "crypto.h" + + +/** + * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) + * @key: Key for PRF + * @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 of failure + * + * This function is used to derive new, cryptographically separate keys from a + * given key (e.g., PMK in IEEE 802.11i). + */ +int sha1_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) +{ + u8 counter = 0; + size_t pos, plen; + u8 hash[SHA1_MAC_LEN]; + size_t label_len = os_strlen(label) + 1; + const unsigned char *addr[3]; + size_t len[3]; + + addr[0] = (u8 *) label; + len[0] = label_len; + addr[1] = data; + len[1] = data_len; + addr[2] = &counter; + len[2] = 1; + + pos = 0; + while (pos < buf_len) { + plen = buf_len - pos; + if (plen >= SHA1_MAC_LEN) { + if (hmac_sha1_vector(key, key_len, 3, addr, len, + &buf[pos])) + return -1; + pos += SHA1_MAC_LEN; + } else { + if (hmac_sha1_vector(key, key_len, 3, addr, len, + hash)) + return -1; + os_memcpy(&buf[pos], hash, plen); + break; + } + counter++; + } + forced_memzero(hash, sizeof(hash)); + + return 0; +} diff --git a/components/wpa_supplicant/src/crypto/sha1-tlsprf.c b/components/wpa_supplicant/src/crypto/sha1-tlsprf.c index bd6ec7a554..5e8d15920c 100644 --- a/components/wpa_supplicant/src/crypto/sha1-tlsprf.c +++ b/components/wpa_supplicant/src/crypto/sha1-tlsprf.c @@ -6,9 +6,9 @@ * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "sha1.h" #include "md5.h" @@ -92,10 +92,10 @@ int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label, SHA1_pos++; } - os_memset(A_MD5, 0, MD5_MAC_LEN); - os_memset(P_MD5, 0, MD5_MAC_LEN); - os_memset(A_SHA1, 0, SHA1_MAC_LEN); - os_memset(P_SHA1, 0, SHA1_MAC_LEN); + forced_memzero(A_MD5, MD5_MAC_LEN); + forced_memzero(P_MD5, MD5_MAC_LEN); + forced_memzero(A_SHA1, SHA1_MAC_LEN); + forced_memzero(P_SHA1, SHA1_MAC_LEN); return 0; } diff --git a/components/wpa_supplicant/src/crypto/sha1.c b/components/wpa_supplicant/src/crypto/sha1.c index 20910eeec6..76d7a68f26 100644 --- a/components/wpa_supplicant/src/crypto/sha1.c +++ b/components/wpa_supplicant/src/crypto/sha1.c @@ -2,19 +2,13 @@ * SHA1 hash implementation and interface functions * Copyright (c) 2003-2005, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "sha1.h" #include "crypto.h" @@ -29,14 +23,14 @@ * @mac: Buffer for the hash (20 bytes) * Returns: 0 on success, -1 on failure */ -int -hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, +int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ unsigned char tk[20]; const u8 *_addr[6]; size_t _len[6], i; + int ret; if (num_elem > 5) { /* @@ -91,7 +85,10 @@ hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, _len[0] = 64; _addr[1] = mac; _len[1] = SHA1_MAC_LEN; - return sha1_vector(2, _addr, _len, mac); + ret = sha1_vector(2, _addr, _len, mac); + forced_memzero(k_pad, sizeof(k_pad)); + forced_memzero(tk, sizeof(tk)); + return ret; } @@ -104,62 +101,8 @@ hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, * @mac: Buffer for the hash (20 bytes) * Returns: 0 on success, -1 of failure */ -int -hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, +int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac) { return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac); } - -/** - * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) - * @key: Key for PRF - * @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 of failure - * - * This function is used to derive new, cryptographically separate keys from a - * given key (e.g., PMK in IEEE 802.11i). - */ -int -sha1_prf(const u8 *key, size_t key_len, const char *label, - const u8 *data, size_t data_len, u8 *buf, size_t buf_len) -{ - u8 counter = 0; - size_t pos, plen; - u8 hash[SHA1_MAC_LEN]; - size_t label_len = os_strlen(label) + 1; - const unsigned char *addr[3]; - size_t len[3]; - - addr[0] = (u8 *) label; - len[0] = label_len; - addr[1] = data; - len[1] = data_len; - addr[2] = &counter; - len[2] = 1; - - pos = 0; - while (pos < buf_len) { - plen = buf_len - pos; - if (plen >= SHA1_MAC_LEN) { - if (hmac_sha1_vector(key, key_len, 3, addr, len, - &buf[pos])) - return -1; - pos += SHA1_MAC_LEN; - } else { - if (hmac_sha1_vector(key, key_len, 3, addr, len, - hash)) - return -1; - os_memcpy(&buf[pos], hash, plen); - break; - } - counter++; - } - - return 0; -} diff --git a/components/wpa_supplicant/src/crypto/sha1.h b/components/wpa_supplicant/src/crypto/sha1.h index 65e3958fc6..933cd81b95 100644 --- a/components/wpa_supplicant/src/crypto/sha1.h +++ b/components/wpa_supplicant/src/crypto/sha1.h @@ -2,14 +2,8 @@ * SHA1 hash implementation and interface functions * Copyright (c) 2003-2009, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef SHA1_H @@ -17,17 +11,17 @@ #define SHA1_MAC_LEN 20 -int hmac_sha1_vector(const uint8_t *key, size_t key_len, size_t num_elem, - const uint8_t *addr[], const size_t *len, uint8_t *mac); -int hmac_sha1(const uint8_t *key, size_t key_len, const uint8_t *data, size_t data_len, - uint8_t *mac); -int sha1_prf(const uint8_t *key, size_t key_len, const char *label, - const uint8_t *data, size_t data_len, uint8_t *buf, size_t buf_len); -int sha1_t_prf(const uint8_t *key, size_t key_len, const char *label, - const uint8_t *seed, size_t seed_len, uint8_t *buf, size_t buf_len); -//int __must_check tls_prf(const uint8_t *secret, size_t secret_len, -// const char *label, const uint8_t *seed, size_t seed_len, -// uint8_t *out, size_t outlen); -int pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, uint8_t *buf, size_t buflen); +int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac); +int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, + u8 *mac); +int sha1_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len); +int sha1_t_prf(const u8 *key, size_t key_len, const char *label, + const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len); +int __must_check tls_prf_sha1_md5(const u8 *secret, size_t secret_len, + const char *label, const u8 *seed, + size_t seed_len, u8 *out, size_t outlen); +int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, + int iterations, u8 *buf, size_t buflen); #endif /* SHA1_H */ diff --git a/components/wpa_supplicant/src/crypto/sha1_i.h b/components/wpa_supplicant/src/crypto/sha1_i.h index ec2f82f75b..344387e973 100644 --- a/components/wpa_supplicant/src/crypto/sha1_i.h +++ b/components/wpa_supplicant/src/crypto/sha1_i.h @@ -2,14 +2,8 @@ * SHA1 internal definitions * Copyright (c) 2003-2005, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef SHA1_I_H diff --git a/components/wpa_supplicant/src/crypto/sha256-internal.c b/components/wpa_supplicant/src/crypto/sha256-internal.c index a4a04bf90d..ff1e2ba168 100644 --- a/components/wpa_supplicant/src/crypto/sha256-internal.c +++ b/components/wpa_supplicant/src/crypto/sha256-internal.c @@ -2,83 +2,17 @@ * SHA-256 hash implementation and interface functions * Copyright (c) 2003-2011, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ -/* - * Hardware crypto support Copyright 2017-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. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" -#ifdef USE_MBEDTLS_CRYPTO -#include "mbedtls/sha256.h" -#else /* USE_MBEDTLS_CRYPTO */ +#include "common.h" #include "sha256.h" #include "sha256_i.h" #include "crypto.h" -#endif /* USE_MBEDTLS_CRYPTO */ -#ifdef USE_MBEDTLS_CRYPTO -/** - * sha256_vector - SHA256 hash for data vector - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash - * Returns: 0 on success, -1 of failure - */ -int -sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, - u8 *mac) -{ - int ret = 0; - mbedtls_sha256_context ctx; - - mbedtls_sha256_init(&ctx); - - if (mbedtls_sha256_starts_ret(&ctx, 0) != 0) { - ret = -1; - goto out; - } - - for(size_t index = 0; index < num_elem; index++) { - if (mbedtls_sha256_update_ret(&ctx, addr[index], len[index]) != 0) { - ret = -1; - goto out; - } - } - - if (mbedtls_sha256_finish_ret(&ctx, mac) != 0) { - ret = -1; - goto out; - } - -out: - mbedtls_sha256_free(&ctx); - - return ret; -} -#else /* USE_MBEDTLS_CRYPTO */ /** * sha256_vector - SHA256 hash for data vector @@ -94,6 +28,9 @@ int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, struct sha256_state ctx; size_t i; + if (TEST_FAIL()) + return -1; + sha256_init(&ctx); for (i = 0; i < num_elem; i++) if (sha256_process(&ctx, addr[i], len[i])) @@ -288,6 +225,5 @@ int sha256_done(struct sha256_state *md, unsigned char *out) return 0; } -#endif /* USE_MBEDTLS_CRYPTO */ /* ===== end - public domain SHA256 implementation ===== */ diff --git a/components/wpa_supplicant/src/crypto/sha256-kdf.c b/components/wpa_supplicant/src/crypto/sha256-kdf.c index 420b81bcce..5a6b744552 100644 --- a/components/wpa_supplicant/src/crypto/sha256-kdf.c +++ b/components/wpa_supplicant/src/crypto/sha256-kdf.c @@ -6,10 +6,10 @@ * See README for more details. */ -#include "utils/includes.h" -#include "utils/common.h" +#include "includes.h" -#include "crypto/sha256.h" +#include "common.h" +#include "sha256.h" /** @@ -69,7 +69,7 @@ int hmac_sha256_kdf(const u8 *secret, size_t secret_len, if (iter == 255) { os_memset(out, 0, outlen); - os_memset(T, 0, SHA256_MAC_LEN); + forced_memzero(T, SHA256_MAC_LEN); return -1; } iter++; @@ -77,11 +77,11 @@ int hmac_sha256_kdf(const u8 *secret, size_t secret_len, if (hmac_sha256_vector(secret, secret_len, 4, addr, len, T) < 0) { os_memset(out, 0, outlen); - os_memset(T, 0, SHA256_MAC_LEN); + forced_memzero(T, SHA256_MAC_LEN); return -1; } } - os_memset(T, 0, SHA256_MAC_LEN); + forced_memzero(T, SHA256_MAC_LEN); return 0; } diff --git a/components/wpa_supplicant/src/crypto/sha256-prf.c b/components/wpa_supplicant/src/crypto/sha256-prf.c index 7d7d34635f..d665a9983c 100644 --- a/components/wpa_supplicant/src/crypto/sha256-prf.c +++ b/components/wpa_supplicant/src/crypto/sha256-prf.c @@ -6,9 +6,9 @@ * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "sha256.h" #include "crypto.h" @@ -102,7 +102,7 @@ int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, buf[pos - 1] &= mask; } - os_memset(hash, 0, sizeof(hash)); + forced_memzero(hash, sizeof(hash)); return 0; } diff --git a/components/wpa_supplicant/src/crypto/sha256-tlsprf.c b/components/wpa_supplicant/src/crypto/sha256-tlsprf.c index 0ba1b49163..9045cd36b4 100644 --- a/components/wpa_supplicant/src/crypto/sha256-tlsprf.c +++ b/components/wpa_supplicant/src/crypto/sha256-tlsprf.c @@ -6,9 +6,9 @@ * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "sha256.h" diff --git a/components/wpa_supplicant/src/crypto/sha256.c b/components/wpa_supplicant/src/crypto/sha256.c index b0f9ce3027..17af964ad0 100644 --- a/components/wpa_supplicant/src/crypto/sha256.c +++ b/components/wpa_supplicant/src/crypto/sha256.c @@ -1,35 +1,14 @@ /* * SHA-256 hash implementation and interface functions - * Copyright (c) 2003-2007, Jouni Malinen + * Copyright (c) 2003-2012, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ -/* - * 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 - * - * Hardware crypto support Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD - * - * 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. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "sha256.h" #include "crypto.h" @@ -52,7 +31,7 @@ int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *_addr[11]; size_t _len[11], i; - if (num_elem > 5) { + if (num_elem > 10) { /* * Fixed limit on the number of fragments to avoid having to * allocate memory (which could fail). @@ -108,6 +87,7 @@ int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, return sha256_vector(2, _addr, _len, mac); } + /** * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104) * @key: Key for HMAC operations diff --git a/components/wpa_supplicant/src/crypto/sha256.h b/components/wpa_supplicant/src/crypto/sha256.h index 96dd03a4c6..8054bbe5c5 100644 --- a/components/wpa_supplicant/src/crypto/sha256.h +++ b/components/wpa_supplicant/src/crypto/sha256.h @@ -1,15 +1,9 @@ /* * SHA256 hash implementation and interface functions - * Copyright (c) 2003-2006, Jouni Malinen + * Copyright (c) 2003-2016, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #ifndef SHA256_H @@ -18,20 +12,19 @@ #define SHA256_MAC_LEN 32 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *mac); + const u8 *addr[], const size_t *len, u8 *mac); int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, - size_t data_len, u8 *mac); + size_t data_len, u8 *mac); int sha256_prf(const u8 *key, size_t key_len, const char *label, - const u8 *data, size_t data_len, u8 *buf, size_t buf_len); + const u8 *data, size_t data_len, u8 *buf, size_t buf_len); int sha256_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); int tls_prf_sha256(const u8 *secret, size_t secret_len, - const char *label, const u8 *seed, size_t seed_len, - u8 *out, size_t outlen); - + const char *label, const u8 *seed, size_t seed_len, + u8 *out, size_t outlen); int hmac_sha256_kdf(const u8 *secret, size_t secret_len, - const char *label, const u8 *seed, size_t seed_len, - u8 *out, size_t outlen); + const char *label, const u8 *seed, size_t seed_len, + u8 *out, size_t outlen); #endif /* SHA256_H */ diff --git a/components/wpa_supplicant/src/crypto/sha384-tlsprf.c b/components/wpa_supplicant/src/crypto/sha384-tlsprf.c index 196b988977..9ff96ac2c7 100644 --- a/components/wpa_supplicant/src/crypto/sha384-tlsprf.c +++ b/components/wpa_supplicant/src/crypto/sha384-tlsprf.c @@ -6,9 +6,9 @@ * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" -#include "utils/common.h" +#include "common.h" #include "sha384.h" diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 88c34b0d64..be793e4728 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -1459,7 +1459,7 @@ failed: #endif return -1; } - if (aes_unwrap(sm->ptk.kek, maxkeylen / 8, + if (aes_unwrap(sm->ptk.kek, 16, maxkeylen / 8, (const u8 *) (key + 1), gd->gtk)) { #ifdef DEBUG_PRINT wpa_printf(MSG_DEBUG, "WPA: AES unwrap " @@ -1703,7 +1703,7 @@ failed: return -1; } */ - if (aes_unwrap(sm->ptk.kek, keydatalen / 8, + if (aes_unwrap(sm->ptk.kek, 16, keydatalen / 8, (u8 *) (key + 1), buf)) { #ifdef DEBUG_PRINT wpa_printf(MSG_DEBUG, "WPA: AES unwrap failed - " @@ -2216,7 +2216,7 @@ wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len) if (strlen((char *)esp_wifi_sta_get_prof_password_internal()) == 64) { hexstr2bin((char *)esp_wifi_sta_get_prof_password_internal(), esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN); } else { - pbkdf2_sha1((char *)esp_wifi_sta_get_prof_password_internal(), (char *)sta_ssid->ssid, (size_t)sta_ssid->len, + pbkdf2_sha1((char *)esp_wifi_sta_get_prof_password_internal(), sta_ssid->ssid, (size_t)sta_ssid->len, 4096, esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN); } esp_wifi_sta_update_ap_info_internal(); diff --git a/components/wpa_supplicant/src/tls/bignum.c b/components/wpa_supplicant/src/tls/bignum.c index 7f2bd7eb04..3e4d0156da 100644 --- a/components/wpa_supplicant/src/tls/bignum.c +++ b/components/wpa_supplicant/src/tls/bignum.c @@ -2,25 +2,17 @@ * Big number math * Copyright (c) 2006, Jouni Malinen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ -#include "utils/includes.h" -#include "utils/common.h" -#include "utils/wpabuf.h" -#include "utils/wpa_debug.h" -#include "tls/bignum.h" +#include "includes.h" + +#include "common.h" +#include "bignum.h" -#define CONFIG_INTERNAL_LIBTOMMATH #ifdef CONFIG_INTERNAL_LIBTOMMATH -#include "tls/libtommath.h" +#include "libtommath.h" #else /* CONFIG_INTERNAL_LIBTOMMATH */ #include #endif /* CONFIG_INTERNAL_LIBTOMMATH */ @@ -35,10 +27,9 @@ * bignum_init - Allocate memory for bignum * Returns: Pointer to allocated bignum or %NULL on failure */ -struct bignum * -bignum_init(void) +struct bignum * bignum_init(void) { - struct bignum *n = (struct bignum *)os_zalloc(sizeof(mp_int)); + struct bignum *n = os_zalloc(sizeof(mp_int)); if (n == NULL) return NULL; if (mp_init((mp_int *) n) != MP_OKAY) { @@ -53,8 +44,7 @@ bignum_init(void) * bignum_deinit - Free bignum * @n: Bignum from bignum_init() */ -void -bignum_deinit(struct bignum *n) +void bignum_deinit(struct bignum *n) { if (n) { mp_clear((mp_int *) n); @@ -68,8 +58,7 @@ bignum_deinit(struct bignum *n) * @n: Bignum from bignum_init() * Returns: Length of n if written to a binary buffer */ -size_t -bignum_get_unsigned_bin_len(struct bignum *n) +size_t bignum_get_unsigned_bin_len(struct bignum *n) { return mp_unsigned_bin_size((mp_int *) n); } @@ -83,8 +72,7 @@ bignum_get_unsigned_bin_len(struct bignum *n) * enough. Set to used buffer length on success if not %NULL. * Returns: 0 on success, -1 on failure */ -int -bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len) +int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len) { size_t need = mp_unsigned_bin_size((mp_int *) n); if (len && need > *len) { @@ -108,8 +96,7 @@ bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len) * @len: Length of buf in octets * Returns: 0 on success, -1 on failure */ -int -bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len) +int bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len) { if (mp_read_unsigned_bin((mp_int *) n, (u8 *) buf, len) != MP_OKAY) { wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); @@ -125,21 +112,19 @@ bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len) * @b: Bignum from bignum_init() * Returns: 0 on success, -1 on failure */ -int -bignum_cmp(const struct bignum *a, const struct bignum *b) +int bignum_cmp(const struct bignum *a, const struct bignum *b) { return mp_cmp((mp_int *) a, (mp_int *) b); } /** - * bignum_cmd_d - Compare bignum to standard integer + * bignum_cmp_d - Compare bignum to standard integer * @a: Bignum from bignum_init() * @b: Small integer - * Returns: 0 on success, -1 on failure + * Returns: -1 if a < b, 0 if a == b, 1 if a > b */ -int -bignum_cmp_d(const struct bignum *a, unsigned long b) +int bignum_cmp_d(const struct bignum *a, unsigned long b) { return mp_cmp_d((mp_int *) a, b); } @@ -152,8 +137,7 @@ bignum_cmp_d(const struct bignum *a, unsigned long b) * @c: Bignum from bignum_init(); used to store the result of a + b * Returns: 0 on success, -1 on failure */ -int -bignum_add(const struct bignum *a, const struct bignum *b, +int bignum_add(const struct bignum *a, const struct bignum *b, struct bignum *c) { if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { @@ -171,8 +155,7 @@ bignum_add(const struct bignum *a, const struct bignum *b, * @c: Bignum from bignum_init(); used to store the result of a - b * Returns: 0 on success, -1 on failure */ -int -bignum_sub(const struct bignum *a, const struct bignum *b, +int bignum_sub(const struct bignum *a, const struct bignum *b, struct bignum *c) { if (mp_sub((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { @@ -190,8 +173,7 @@ bignum_sub(const struct bignum *a, const struct bignum *b, * @c: Bignum from bignum_init(); used to store the result of a * b * Returns: 0 on success, -1 on failure */ -int -bignum_mul(const struct bignum *a, const struct bignum *b, +int bignum_mul(const struct bignum *a, const struct bignum *b, struct bignum *c) { if (mp_mul((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { @@ -210,8 +192,7 @@ bignum_mul(const struct bignum *a, const struct bignum *b, * @d: Bignum from bignum_init(); used to store the result of a * b (mod c) * Returns: 0 on success, -1 on failure */ -int -bignum_mulmod(const struct bignum *a, const struct bignum *b, +int bignum_mulmod(const struct bignum *a, const struct bignum *b, const struct bignum *c, struct bignum *d) { if (mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) @@ -231,8 +212,7 @@ bignum_mulmod(const struct bignum *a, const struct bignum *b, * @d: Bignum from bignum_init(); used to store the result of a^b (mod c) * Returns: 0 on success, -1 on failure */ -int -bignum_exptmod(const struct bignum *a, const struct bignum *b, +int bignum_exptmod(const struct bignum *a, const struct bignum *b, const struct bignum *c, struct bignum *d) { if (mp_exptmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) diff --git a/components/wpa_supplicant/src/tls/rsa.c b/components/wpa_supplicant/src/tls/rsa.c index e1eff7f097..1b01f5843d 100644 --- a/components/wpa_supplicant/src/tls/rsa.c +++ b/components/wpa_supplicant/src/tls/rsa.c @@ -1,17 +1,18 @@ /* * RSA - * Copyright (c) 2006, Jouni Malinen + * Copyright (c) 2006-2014, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. */ -#include "utils/includes.h" +#include "includes.h" + +#include "common.h" +#include "asn1.h" +#include "bignum.h" +#include "rsa.h" -#include "utils/common.h" -#include "tls/asn1.h" -#include "tls/bignum.h" -#include "tls/rsa.h" struct crypto_rsa_key { int private_key; /* whether private key is set */ @@ -64,7 +65,7 @@ crypto_rsa_import_public_key(const u8 *buf, size_t len) struct asn1_hdr hdr; const u8 *pos, *end; - key = (struct crypto_rsa_key *)os_zalloc(sizeof(*key)); + key = os_zalloc(sizeof(*key)); if (key == NULL) return NULL; @@ -115,6 +116,29 @@ error: } +struct crypto_rsa_key * +crypto_rsa_import_public_key_parts(const u8 *n, size_t n_len, + const u8 *e, size_t e_len) +{ + struct crypto_rsa_key *key; + + key = os_zalloc(sizeof(*key)); + if (key == NULL) + return NULL; + + key->n = bignum_init(); + key->e = bignum_init(); + if (key->n == NULL || key->e == NULL || + bignum_set_unsigned_bin(key->n, n, n_len) < 0 || + bignum_set_unsigned_bin(key->e, e, e_len) < 0) { + crypto_rsa_free(key); + return NULL; + } + + return key; +} + + /** * crypto_rsa_import_private_key - Import an RSA private key * @buf: Key buffer (DER encoded RSA private key) @@ -129,7 +153,7 @@ crypto_rsa_import_private_key(const u8 *buf, size_t len) struct asn1_hdr hdr; const u8 *pos, *end; - key = (struct crypto_rsa_key *)os_zalloc(sizeof(*key)); + key = os_zalloc(sizeof(*key)); if (key == NULL) return NULL; @@ -261,7 +285,7 @@ int crypto_rsa_exptmod(const u8 *in, size_t inlen, u8 *out, size_t *outlen, if (use_private) { /* - * Decrypt (or sign) using Chinese remainer theorem to speed + * Decrypt (or sign) using Chinese remainder theorem to speed * up calculation. This is equivalent to tmp = tmp^d mod n * (which would require more CPU to calculate directly). * @@ -321,7 +345,6 @@ int crypto_rsa_exptmod(const u8 *in, size_t inlen, u8 *out, size_t *outlen, ret = 0; error: - bignum_deinit(tmp); bignum_deinit(a); bignum_deinit(b); diff --git a/components/wpa_supplicant/src/tls/rsa.h b/components/wpa_supplicant/src/tls/rsa.h index c236a9df44..b65818ee15 100644 --- a/components/wpa_supplicant/src/tls/rsa.h +++ b/components/wpa_supplicant/src/tls/rsa.h @@ -14,6 +14,9 @@ struct crypto_rsa_key; struct crypto_rsa_key * crypto_rsa_import_public_key(const u8 *buf, size_t len); struct crypto_rsa_key * +crypto_rsa_import_public_key_parts(const u8 *n, size_t n_len, + const u8 *e, size_t e_len); +struct crypto_rsa_key * crypto_rsa_import_private_key(const u8 *buf, size_t len); size_t crypto_rsa_get_modulus_len(struct crypto_rsa_key *key); int crypto_rsa_exptmod(const u8 *in, size_t inlen, u8 *out, size_t *outlen, diff --git a/components/wpa_supplicant/src/utils/common.c b/components/wpa_supplicant/src/utils/common.c index 47305b0cdb..1c619f5cc6 100644 --- a/components/wpa_supplicant/src/utils/common.c +++ b/components/wpa_supplicant/src/utils/common.c @@ -547,3 +547,8 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len); return ssid_txt; } + +void * __hide_aliasing_typecast(void *foo) +{ + return foo; +} diff --git a/components/wpa_supplicant/src/utils/common.h b/components/wpa_supplicant/src/utils/common.h index 144487b7da..0596b6ab4f 100644 --- a/components/wpa_supplicant/src/utils/common.h +++ b/components/wpa_supplicant/src/utils/common.h @@ -441,6 +441,9 @@ struct wpa_freq_range_list { }; #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#ifndef TEST_FAIL +#define TEST_FAIL() 0 +#endif void wpa_bin_clear_free(void *bin, size_t len); int int_array_len(const int *a); diff --git a/components/wpa_supplicant/src/utils/includes.h b/components/wpa_supplicant/src/utils/includes.h index 2d84d57333..7e4f5660a7 100644 --- a/components/wpa_supplicant/src/utils/includes.h +++ b/components/wpa_supplicant/src/utils/includes.h @@ -21,6 +21,10 @@ #include "supplicant_opt.h" +#define AES_SMALL_TABLES +#define CONFIG_NO_RANDOM_POOL +#define CONFIG_INTERNAL_LIBTOMMATH + /* Include possible build time configuration before including anything else */ #ifndef __ets__ #include diff --git a/components/wpa_supplicant/test/test_crypto.c b/components/wpa_supplicant/test/test_crypto.c index 0c17b0bddf..19399a6c6d 100644 --- a/components/wpa_supplicant/test/test_crypto.c +++ b/components/wpa_supplicant/test/test_crypto.c @@ -18,6 +18,8 @@ #include #include "unity.h" #include +#include "utils/common.h" +#include "utils/includes.h" #include "crypto/crypto.h" #include "mbedtls/ecp.h" diff --git a/components/wpa_supplicant/test/test_dpp.c b/components/wpa_supplicant/test/test_dpp.c index b2da8869c9..6070842dc0 100644 --- a/components/wpa_supplicant/test/test_dpp.c +++ b/components/wpa_supplicant/test/test_dpp.c @@ -20,6 +20,8 @@ #include #include "unity.h" #include +#include "utils/common.h" +#include "utils/includes.h" #include "crypto/crypto.h" #include "../src/common/defs.h" #include "../src/common/dpp.h" diff --git a/components/wpa_supplicant/test/test_sae.c b/components/wpa_supplicant/test/test_sae.c index 52ac9d9320..e0d99825e9 100644 --- a/components/wpa_supplicant/test/test_sae.c +++ b/components/wpa_supplicant/test/test_sae.c @@ -21,6 +21,8 @@ #include #include "unity.h" #include +#include "utils/common.h" +#include "utils/includes.h" #include "crypto/crypto.h" #include "../src/common/sae.h" #include "utils/wpabuf.h"