From ad7cb5f5c1c5c22828ba613658f896dca81beb90 Mon Sep 17 00:00:00 2001 From: "kapil.gupta" Date: Mon, 14 Sep 2020 13:51:25 +0530 Subject: [PATCH] wpa_supplicant: Write Crypto API based on mbedtls This commit add following crypto changes 1. Update current crypto code with upstream supplicant code 2. Add a proper porting layer to use mbedtls APIs for all the crypto operations used by supplicant. Internal crypto will be used when USE_MBEDLTS flag is disabled in supplicant's menuconfig. This commit also removes the clutter in crypto files due to partial porting of some APIs to mbedtls, all the code from those files have been removed and rewritten in a generic way, this is inspired from current upstream code. This also reduces the lib size significantly, supplicant's lib size reduces around ~567kb after this change(NB: lib size doesn't indicate reduction in final bin size). --- components/mbedtls/Kconfig | 7 + .../mbedtls/port/include/mbedtls/esp_config.h | 15 + components/wpa_supplicant/CMakeLists.txt | 96 +- components/wpa_supplicant/Kconfig | 4 +- components/wpa_supplicant/component.mk | 42 +- components/wpa_supplicant/port/include/os.h | 24 + components/wpa_supplicant/port/os_xtensa.c | 8 + components/wpa_supplicant/src/ap/wpa_auth.c | 2 +- .../wpa_supplicant/src/common/wpa_common.c | 1 + .../wpa_supplicant/src/crypto/aes-cbc.c | 108 +-- .../wpa_supplicant/src/crypto/aes-ccm.c | 29 +- .../wpa_supplicant/src/crypto/aes-ctr.c | 28 +- .../src/crypto/aes-internal-dec.c | 33 +- .../src/crypto/aes-internal-enc.c | 33 +- .../wpa_supplicant/src/crypto/aes-internal.c | 44 +- .../wpa_supplicant/src/crypto/aes-omac1.c | 10 +- .../wpa_supplicant/src/crypto/aes-siv.c | 10 +- .../wpa_supplicant/src/crypto/aes-unwrap.c | 75 +- .../wpa_supplicant/src/crypto/aes-wrap.c | 66 +- components/wpa_supplicant/src/crypto/aes.h | 23 +- components/wpa_supplicant/src/crypto/aes_i.h | 22 +- .../wpa_supplicant/src/crypto/aes_wrap.h | 55 +- components/wpa_supplicant/src/crypto/bignum.c | 244 ----- components/wpa_supplicant/src/crypto/bignum.h | 38 - components/wpa_supplicant/src/crypto/ccmp.c | 35 +- components/wpa_supplicant/src/crypto/crypto.h | 167 ++-- .../src/crypto/crypto_internal-cipher.c | 83 +- .../src/crypto/crypto_internal-modexp.c | 141 +-- .../src/crypto/crypto_internal-rsa.c | 39 +- .../src/crypto/crypto_internal.c | 135 ++- .../src/crypto/crypto_mbedtls-bignum.c | 8 +- .../src/crypto/crypto_mbedtls.c | 848 +++++++++++++++++- .../wpa_supplicant/src/crypto/crypto_ops.c | 30 +- .../wpa_supplicant/src/crypto/des-internal.c | 15 +- .../wpa_supplicant/src/crypto/dh_group5.c | 34 +- .../wpa_supplicant/src/crypto/dh_group5.h | 15 +- .../wpa_supplicant/src/crypto/dh_groups.c | 42 +- .../wpa_supplicant/src/crypto/dh_groups.h | 10 +- .../wpa_supplicant/src/crypto/md4-internal.c | 242 +++-- .../wpa_supplicant/src/crypto/md5-internal.c | 38 +- components/wpa_supplicant/src/crypto/md5.c | 26 +- components/wpa_supplicant/src/crypto/md5.h | 28 +- components/wpa_supplicant/src/crypto/md5_i.h | 10 +- .../wpa_supplicant/src/crypto/ms_funcs.c | 116 +-- .../wpa_supplicant/src/crypto/ms_funcs.h | 22 +- components/wpa_supplicant/src/crypto/random.h | 14 +- components/wpa_supplicant/src/crypto/rc4.c | 17 +- .../wpa_supplicant/src/crypto/sha1-internal.c | 88 +- .../wpa_supplicant/src/crypto/sha1-pbkdf2.c | 83 +- .../wpa_supplicant/src/crypto/sha1-prf.c | 67 ++ .../wpa_supplicant/src/crypto/sha1-tlsprf.c | 12 +- components/wpa_supplicant/src/crypto/sha1.c | 79 +- components/wpa_supplicant/src/crypto/sha1.h | 36 +- components/wpa_supplicant/src/crypto/sha1_i.h | 10 +- .../src/crypto/sha256-internal.c | 78 +- .../wpa_supplicant/src/crypto/sha256-kdf.c | 12 +- .../wpa_supplicant/src/crypto/sha256-prf.c | 6 +- .../wpa_supplicant/src/crypto/sha256-tlsprf.c | 4 +- components/wpa_supplicant/src/crypto/sha256.c | 34 +- components/wpa_supplicant/src/crypto/sha256.h | 27 +- .../wpa_supplicant/src/crypto/sha384-tlsprf.c | 4 +- components/wpa_supplicant/src/rsn_supp/wpa.c | 6 +- components/wpa_supplicant/src/tls/bignum.c | 64 +- components/wpa_supplicant/src/utils/common.h | 3 + .../wpa_supplicant/src/utils/includes.h | 4 + components/wpa_supplicant/test/test_crypto.c | 2 + components/wpa_supplicant/test/test_dpp.c | 2 + components/wpa_supplicant/test/test_sae.c | 2 + 68 files changed, 2009 insertions(+), 1746 deletions(-) delete mode 100644 components/wpa_supplicant/src/crypto/bignum.c delete mode 100644 components/wpa_supplicant/src/crypto/bignum.h create mode 100644 components/wpa_supplicant/src/crypto/sha1-prf.c diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index ed0e62e9b8..1c4232f508 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -637,6 +637,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 799e3e7153..3b35a84c8d 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 56e286573a..21dd7bafb3 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 c81e71993b..e951d4841e 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/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/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..a58ab9dd25 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,666 @@ 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); +} + +void *aes_crypt_init(const u8 *key, size_t len) +{ + mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); + if (!aes) { + return NULL; + } + mbedtls_aes_init(aes); + + if (mbedtls_aes_setkey_enc(aes, key, len * 8) < 0) { + mbedtls_aes_free(aes); + os_free(aes); + wpa_printf(MSG_ERROR, "%s: mbedtls_aes_setkey_enc failed", __func__); + return NULL; + } + + return (void *) aes; +} + +int aes_crypt(void *ctx, int mode, const u8 *in, u8 *out) +{ + return mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, + mode, in, out); +} + +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(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(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..1a87c82d5a 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.c" #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/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"