diff --git a/components/wpa_supplicant/src/crypto/aes-cbc.c b/components/wpa_supplicant/src/crypto/aes-cbc.c index 188c167f..03d7a68b 100644 --- a/components/wpa_supplicant/src/crypto/aes-cbc.c +++ b/components/wpa_supplicant/src/crypto/aes-cbc.c @@ -12,16 +12,30 @@ * * See README and COPYING for more details. */ - -#include "sdkconfig.h" - -#ifndef CONFIG_ESP_AES +/* + * 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 "crypto/aes.h" -#include "crypto/aes_wrap.h" +#include "aes.h" +#include "aes_wrap.h" + +#ifdef USE_MBEDTLS_CRYPTO +#include "mbedtls/aes.h" /** * aes_128_cbc_encrypt - AES-128 CBC encryption @@ -31,7 +45,70 @@ * @data_len: Length of data in bytes (must be divisible by 16) * Returns: 0 on success, -1 on failure */ -int +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) { void *ctx; @@ -65,7 +142,7 @@ 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 +int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) { void *ctx; @@ -90,52 +167,4 @@ aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) aes_decrypt_deinit(ctx); return 0; } - -#else /* CONFIG_ESP_AES */ - -#include -#include "esp_aes.h" - -#ifndef AES_BLOCK_SIZE -#define AES_BLOCK_SIZE 16 -#endif - -int aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, size_t data_len) -{ - int ret; - esp_aes_t ctx; - uint8_t iv_tmp[AES_BLOCK_SIZE]; - - ret = esp_aes_set_encrypt_key(&ctx, key, 128); - if (ret) - return ret; - - memcpy(iv_tmp, iv, AES_BLOCK_SIZE); - - ret = esp_aes_encrypt_cbc(&ctx, data, data_len, data, data_len, iv_tmp); - if (ret) - return ret; - - return 0; -} - -int aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, size_t data_len) -{ - int ret; - esp_aes_t ctx; - uint8_t iv_tmp[AES_BLOCK_SIZE]; - - ret = esp_aes_set_decrypt_key(&ctx, key, 128); - if (ret) - return ret; - - memcpy(iv_tmp, iv, AES_BLOCK_SIZE); - - ret = esp_aes_decrypt_cbc(&ctx, data, data_len, data, data_len, iv_tmp); - if (ret) - return ret; - - return 0; -} - -#endif /* CONFIG_ESP_AES */ +#endif /* USE_MBEDTLS_CRYPTO */ diff --git a/components/wpa_supplicant/src/crypto/aes-unwrap.c b/components/wpa_supplicant/src/crypto/aes-unwrap.c index 7f4c5b69..090c2a90 100644 --- a/components/wpa_supplicant/src/crypto/aes-unwrap.c +++ b/components/wpa_supplicant/src/crypto/aes-unwrap.c @@ -12,16 +12,31 @@ * * See README and COPYING for more details. */ - -#include "sdkconfig.h" - -#ifndef CONFIG_ESP_AES +/* + * 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 "crypto/aes.h" -#include "crypto/aes_wrap.h" +#ifdef USE_MBEDTLS_CRYPTO +#include "mbedtls/aes.h" +#else /* USE_MBEDTLS_CRYPTO */ +#include "aes.h" +#include "aes_wrap.h" +#endif /* USE_MBEDTLS_CRYPTO */ /** * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394) @@ -37,16 +52,30 @@ aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain) { u8 a[8], *r, b[16]; 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 */ /* 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); if (ctx == NULL) return -1; +#endif /* USE_MBEDTLS_CRYPTO */ /* 2) Compute intermediate values. * For j = 5 to 0 @@ -62,13 +91,21 @@ aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain) b[7] ^= n * j + i; 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. * @@ -82,58 +119,3 @@ aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain) return 0; } - -#else -#include -#include "esp_aes.h" - -int aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain) -{ - int ret; - uint8_t a[8], *r, b[16]; - esp_aes_t ctx; - - /* 1) Initialize variables. */ - memcpy(a, cipher, 8); - r = plain; - memcpy(r, cipher + 8, 8 * n); - - ret = esp_aes_set_decrypt_key(&ctx, kek, 128); - if (ret) - return ret; - - /* 2) Compute intermediate values. - * For j = 5 to 0 - * For i = n to 1 - * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i - * A = MSB(64, B) - * R[i] = LSB(64, B) - */ - for (int j = 5; j >= 0; j--) { - r = plain + (n - 1) * 8; - for (int i = n; i >= 1; i--) { - memcpy(b, a, 8); - b[7] ^= n * j + i; - - memcpy(b + 8, r, 8); - esp_aes_decrypt_ecb(&ctx, b, b); - memcpy(a, b, 8); - memcpy(r, b + 8, 8); - r -= 8; - } - } - - /* 3) Output results. - * - * These are already in @plain due to the location of temporary - * variables. Just verify that the IV matches with the expected value. - */ - for (int i = 0; i < 8; i++) { - if (a[i] != 0xa6) - return -1; - } - - return 0; -} - -#endif /* CONFIG_ESP_AES */ diff --git a/components/wpa_supplicant/src/crypto/aes-wrap.c b/components/wpa_supplicant/src/crypto/aes-wrap.c index d37a43db..42e60660 100644 --- a/components/wpa_supplicant/src/crypto/aes-wrap.c +++ b/components/wpa_supplicant/src/crypto/aes-wrap.c @@ -6,16 +6,30 @@ * This software may be distributed under the terms of the BSD license. * See README for more details. */ - -#include "sdkconfig.h" - -#ifndef CONFIG_ESP_AES +/* + * 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 "crypto/aes.h" -#include "crypto/aes_wrap.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) @@ -30,7 +44,12 @@ int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher) { u8 *a, *r, b[16]; 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 */ a = cipher; r = cipher + 8; @@ -39,9 +58,18 @@ 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); if (ctx == NULL) return -1; +#endif /* USE_MBEDTLS_CRYPTO */ /* 2) Calculate intermediate values. * For j = 0 to 5 @@ -55,14 +83,24 @@ 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; 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. * @@ -72,54 +110,3 @@ int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher) return 0; } -#else -#include -#include "esp_aes.h" - -int aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher) -{ - int ret; - uint8_t *a, *r, b[16]; - esp_aes_t ctx; - - a = cipher; - r = cipher + 8; - - /* 1) Initialize variables. */ - memset(a, 0xa6, 8); - memcpy(r, plain, 8 * n); - - ret = esp_aes_set_encrypt_key(&ctx, kek, 128); - if (ret) - return ret; - - /* 2) Calculate intermediate values. - * For j = 0 to 5 - * For i=1 to n - * B = AES(K, A | R[i]) - * A = MSB(64, B) ^ t where t = (n*j)+i - * R[i] = LSB(64, B) - */ - for (int j = 0; j <= 5; j++) { - r = cipher + 8; - for (int i = 1; i <= n; i++) { - memcpy(b, a, 8); - memcpy(b + 8, r, 8); - esp_aes_encrypt_ecb(&ctx, b, b); - memcpy(a, b, 8); - a[7] ^= n * j + i; - memcpy(r, b + 8, 8); - r += 8; - } - } - - /* 3) Output the results. - * - * These are already in @cipher due to the location of temporary - * variables. - */ - - return 0; -} - -#endif /* CONFIG_ESP_AES */ diff --git a/components/wpa_supplicant/src/crypto/aes_wrap.h b/components/wpa_supplicant/src/crypto/aes_wrap.h index 6c3541ca..4ee77e97 100644 --- a/components/wpa_supplicant/src/crypto/aes_wrap.h +++ b/components/wpa_supplicant/src/crypto/aes_wrap.h @@ -24,12 +24,19 @@ 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 omac1_aes_vector(const u8 *key, size_t key_len, + 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); 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); 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, @@ -44,11 +51,4 @@ 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 fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher); -int __must_check fast_aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain); -int __must_check fast_aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, - size_t data_len); -int __must_check fast_aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, - size_t data_len); - #endif /* AES_WRAP_H */ diff --git a/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c b/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c index 81327775..9ca428cf 100644 --- a/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c +++ b/components/wpa_supplicant/src/crypto/crypto_internal-cipher.c @@ -5,20 +5,32 @@ * This software may be distributed under the terms of the BSD license. * See README for more details. */ - -//#include "utils/includes.h" +/* + * 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 "crypto/crypto.h" -#include "crypto/aes.h" +#include "utils/includes.h" +#include "crypto.h" +#include "aes.h" #if defined(CONFIG_DES) || defined(CONFIG_DES3) -#include "crypto/des_i.h" +#include "des_i.h" #endif - -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; -#endif - +#ifdef USE_MBEDTLS_CRYPTO +#include "mbedtls/aes.h" +#endif /* USE_MBEDTLS_CRYPTO */ struct crypto_cipher { enum crypto_cipher_alg alg; @@ -30,8 +42,13 @@ 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 { @@ -72,6 +89,12 @@ 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); @@ -83,6 +106,7 @@ 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 @@ -134,8 +158,14 @@ 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; @@ -201,7 +231,13 @@ 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); @@ -253,8 +289,13 @@ 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: diff --git a/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c b/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c index 2bf67df3..8d9d7fe8 100644 --- a/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c +++ b/components/wpa_supplicant/src/crypto/crypto_internal-modexp.c @@ -11,14 +11,72 @@ * * 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. + */ #include "utils/includes.h" #include "utils/common.h" +#ifdef USE_MBEDTLS_CRYPTO +#include "mbedtls/bignum.h" +#else /* USE_MBEDTLS_CRYPTO */ #include "bignum.h" -#include "crypto/crypto.h" +#endif /* USE_MBEDTLS_CRYPTO */ +#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) +{ + 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; +} +#else /* USE_MBEDTLS_CRYPTO */ int crypto_mod_exp(const u8 *base, size_t base_len, const u8 *power, size_t power_len, @@ -54,3 +112,4 @@ 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 58554e17..ec27b6d9 100644 --- a/components/wpa_supplicant/src/crypto/crypto_internal-rsa.c +++ b/components/wpa_supplicant/src/crypto/crypto_internal-rsa.c @@ -7,15 +7,17 @@ */ #include "utils/common.h" -#include "crypto/crypto.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; @@ -27,7 +29,6 @@ struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len) crypto_rsa_import_public_key(key, len); } - struct crypto_private_key * crypto_private_key_import(const u8 *key, size_t len, const char *passwd) @@ -108,3 +109,4 @@ int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key, 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 352d741b..8d6af0c9 100644 --- a/components/wpa_supplicant/src/crypto/crypto_internal.c +++ b/components/wpa_supplicant/src/crypto/crypto_internal.c @@ -5,29 +5,44 @@ * 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 "crypto/crypto.h" -#include "crypto/sha1_i.h" -#include "crypto/md5_i.h" - -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#include "crypto.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; union { struct MD5Context md5; -#ifndef CONFIG_ESP_SHA - struct SHA1Context sha1; -#else - SHA1_CTX sha1; -#endif + 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 */ } u; u8 key[64]; @@ -58,7 +73,12 @@ 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 */ case CRYPTO_HASH_ALG_HMAC_MD5: @@ -102,9 +122,17 @@ 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; } @@ -116,8 +144,14 @@ 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: @@ -146,7 +180,11 @@ 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 */ default: @@ -195,7 +233,12 @@ 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 */ case CRYPTO_HASH_ALG_HMAC_MD5: @@ -247,17 +290,31 @@ 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: diff --git a/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c b/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c index ec710014..79e1bc38 100644 --- a/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c +++ b/components/wpa_supplicant/src/crypto/sha1-pbkdf2.c @@ -14,14 +14,67 @@ #include "utils/includes.h" #include "utils/common.h" -#include "crypto/sha1.h" -#include "crypto/md5.h" -#include "crypto/crypto.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) + size_t ssid_len, int iterations, unsigned int count, + u8 *digest) { unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN]; int i, j; @@ -99,3 +152,4 @@ pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, return 0; } +#endif