Merge branch 'feature/crypto_porting_v4.3' into 'release/v4.3'

wpa_supplicant: Rewrite Crypto APIs based on MbedTLS (backport V4.3)

See merge request espressif/esp-idf!14181
This commit is contained in:
Jiang Jiang Jian 2021-06-30 11:46:03 +00:00
commit 3a0b4628ce
74 changed files with 2059 additions and 1756 deletions

View File

@ -316,6 +316,7 @@ menu "Wi-Fi"
config ESP32_WIFI_ENABLE_WPA3_SAE
bool "Enable WPA3-Personal"
default y
depends on WPA_MBEDTLS_CRYPTO
help
Select this option to allow the device to establish a WPA3-Personal connection with eligible AP's.
PMF (Protected Management Frames) is a prerequisite feature for a WPA3 connection, it needs to be

View File

@ -642,6 +642,13 @@ menu "mbedTLS"
This option is generally faster than CCM.
config MBEDTLS_NIST_KW_C
bool "NIST key wrapping (KW) and KW padding (KWP)"
default n
depends on MBEDTLS_AES_C
help
Enable NIST key wrapping and key wrapping padding.
endmenu # Symmetric Ciphers
config MBEDTLS_RIPEMD160_C

View File

@ -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)

View File

@ -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)

View File

@ -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"

View File

@ -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 \

View File

@ -28,6 +28,7 @@
#define MSG_INFO ESP_LOG_INFO
#define MSG_DEBUG ESP_LOG_DEBUG
#define MSG_MSGDUMP ESP_LOG_VERBOSE
#define MSG_EXCESSIVE ESP_LOG_VERBOSE
#else
enum { MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR };

View File

@ -19,6 +19,7 @@
#include <stdio.h>
#include <stdlib.h>
#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 */

View File

@ -21,6 +21,7 @@
#define USE_MBEDTLS_CRYPTO 1
#else
#define CONFIG_TLS_INTERNAL_CLIENT
#define CONFIG_CRYPTO_INTERNAL
#define CONFIG_TLSV12
#endif

View File

@ -29,6 +29,7 @@
#include <sys/time.h>
#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

View File

@ -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);

View File

@ -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

View File

@ -3,40 +3,16 @@
*
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
* 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 */

View File

@ -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;
}

View File

@ -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
}

View File

@ -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 <j@w1.fi>
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* 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);

View File

@ -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 <j@w1.fi>
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* 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);

View File

@ -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 <j@w1.fi>
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* 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 */
};

View File

@ -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;

View File

@ -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];

View File

@ -1,81 +1,44 @@
/*
* AES key unwrap (128-bit KEK, RFC3394)
* AES key unwrap (RFC3394)
*
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
* 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.
*

View File

@ -1,55 +1,34 @@
/*
* AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
* AES Key Wrap Algorithm (RFC3394)
*
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
* 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.
*

View File

@ -2,14 +2,8 @@
* AES functions
* Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
*
* 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 */

View File

@ -1,15 +1,9 @@
/*
* AES (Rijndael) cipher
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* 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)

View File

@ -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 <j@w1.fi>
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* 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 */

View File

@ -1,244 +0,0 @@
/*
* Big number math
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* 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 <tommath.h>
#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;
}

View File

@ -1,38 +0,0 @@
/*
* Big number math
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* 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 */

View File

@ -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);

View File

@ -1,15 +1,9 @@
/*
* WPA Supplicant / wrapper functions for crypto libraries
* Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
* Wrapper functions for crypto libraries
* Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi>
*
* 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

View File

@ -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;
}

View File

@ -2,83 +2,91 @@
* Crypto wrapper for internal crypto implementation - modexp
* Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
*
* 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 */

View File

@ -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

View File

@ -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)
{
}

View File

@ -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;

View File

@ -28,9 +28,27 @@
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/md.h"
#include "mbedtls/aes.h"
#include "mbedtls/bignum.h"
#include "mbedtls/pkcs5.h"
#include "mbedtls/cmac.h"
#include "mbedtls/nist_kw.h"
#include "mbedtls/des.h"
#include "mbedtls/ccm.h"
#include "mbedtls/arc4.h"
int mbedtls_hmac_vector(mbedtls_md_type_t md_type, const u8 *key, size_t key_len,
size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
#include "common.h"
#include "utils/wpabuf.h"
#include "dh_group5.h"
#include "sha1.h"
#include "sha256.h"
#include "md5.h"
#include "aes_wrap.h"
#include "crypto.h"
#include "mbedtls/esp_config.h"
static int digest_vector(mbedtls_md_type_t md_type, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
size_t i;
const mbedtls_md_info_t *md_info;
@ -39,16 +57,169 @@ int mbedtls_hmac_vector(mbedtls_md_type_t md_type, const u8 *key, size_t key_len
mbedtls_md_init(&md_ctx);
if((md_info = mbedtls_md_info_from_type(md_type)) == NULL )
md_info = mbedtls_md_info_from_type(md_type);
if (!md_info) {
wpa_printf(MSG_ERROR, "mbedtls_md_info_from_type() failed");
return -1;
}
if ((ret = mbedtls_md_setup( &md_ctx, md_info, 1)) != 0)
ret = mbedtls_md_setup(&md_ctx, md_info, 0);
if (ret != 0) {
wpa_printf(MSG_ERROR, "mbedtls_md_setup() returned error");
goto cleanup;
}
ret = mbedtls_md_starts(&md_ctx);
if (ret != 0) {
wpa_printf(MSG_ERROR, "mbedtls_md_starts returned error");
goto cleanup;
}
for (i = 0; i < num_elem; i++) {
ret = mbedtls_md_update(&md_ctx, addr[i], len[i]);
if (ret != 0) {
wpa_printf(MSG_ERROR, "mbedtls_md_update ret=%d", ret);
goto cleanup;
}
}
ret = mbedtls_md_finish(&md_ctx, mac);
cleanup:
mbedtls_md_free(&md_ctx);
return ret;
}
int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
u8 *mac)
{
return digest_vector(MBEDTLS_MD_SHA256, num_elem, addr, len, mac);
}
int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
u8 *mac)
{
return digest_vector(MBEDTLS_MD_SHA384, num_elem, addr, len, mac);
}
int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
{
return digest_vector(MBEDTLS_MD_SHA1, num_elem, addr, len, mac);
}
int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
{
return digest_vector(MBEDTLS_MD_MD5, num_elem, addr, len, mac);
}
#ifdef MBEDTLS_MD4_C
int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
{
return digest_vector(MBEDTLS_MD_MD4, num_elem, addr, len, mac);
}
#endif
struct crypto_hash {
mbedtls_md_context_t ctx;
};
struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
size_t key_len)
{
struct crypto_hash *ctx;
mbedtls_md_type_t md_type;
const mbedtls_md_info_t *md_info;
int ret;
switch (alg) {
case CRYPTO_HASH_ALG_HMAC_MD5:
md_type = MBEDTLS_MD_MD5;
break;
case CRYPTO_HASH_ALG_HMAC_SHA1:
md_type = MBEDTLS_MD_SHA1;
break;
case CRYPTO_HASH_ALG_HMAC_SHA256:
md_type = MBEDTLS_MD_SHA256;
break;
default:
return NULL;
}
ctx = os_zalloc(sizeof(*ctx));
if (ctx == NULL) {
return NULL;
}
mbedtls_md_init(&ctx->ctx);
md_info = mbedtls_md_info_from_type(md_type);
if (!md_info) {
os_free(ctx);
return NULL;
}
ret = mbedtls_md_setup(&ctx->ctx, md_info, 1);
if (ret != 0) {
os_free(ctx);
return NULL;
}
mbedtls_md_hmac_starts(&ctx->ctx, key, key_len);
return ctx;
}
void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
{
if (ctx == NULL) {
return;
}
mbedtls_md_hmac_update(&ctx->ctx, data, len);
}
int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
{
if (ctx == NULL) {
return -2;
}
if (mac == NULL || len == NULL) {
mbedtls_md_free(&ctx->ctx);
bin_clear_free(ctx, sizeof(*ctx));
return 0;
}
mbedtls_md_hmac_finish(&ctx->ctx, mac);
mbedtls_md_free(&ctx->ctx);
bin_clear_free(ctx, sizeof(*ctx));
return 0;
}
static int hmac_vector(mbedtls_md_type_t md_type,
const u8 *key, size_t key_len,
size_t num_elem, const u8 *addr[],
const size_t *len, u8 *mac)
{
size_t i;
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
int ret;
mbedtls_md_init(&md_ctx);
md_info = mbedtls_md_info_from_type(md_type);
if (!md_info) {
return -1;
}
ret = mbedtls_md_setup(&md_ctx, md_info, 1);
if (ret != 0) {
return(ret);
}
mbedtls_md_hmac_starts(&md_ctx, key, key_len);
for( i = 0; i < num_elem; i++)
for (i = 0; i < num_elem; i++) {
mbedtls_md_hmac_update(&md_ctx, addr[i], len[i]);
}
mbedtls_md_hmac_finish(&md_ctx, mac);
@ -60,8 +231,8 @@ int mbedtls_hmac_vector(mbedtls_md_type_t md_type, const u8 *key, size_t key_len
int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
return mbedtls_hmac_vector(MBEDTLS_MD_SHA384, key, key_len, num_elem, addr,
len, mac);
return hmac_vector(MBEDTLS_MD_SHA384, key, key_len, num_elem, addr,
len, mac);
}
@ -70,3 +241,672 @@ int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
{
return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
}
int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
return hmac_vector(MBEDTLS_MD_SHA256, key, key_len, num_elem, addr,
len, mac);
}
int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
size_t data_len, u8 *mac)
{
return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
}
int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
return hmac_vector(MBEDTLS_MD_MD5, key, key_len,
num_elem, addr, len, mac);
}
int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
u8 *mac)
{
return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
}
int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
return hmac_vector(MBEDTLS_MD_SHA1, key, key_len, num_elem, addr,
len, mac);
}
int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
u8 *mac)
{
return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
}
static void *aes_crypt_init(int mode, const u8 *key, size_t len)
{
int ret = -1;
mbedtls_aes_context *aes = os_malloc(sizeof(*aes));
if (!aes) {
return NULL;
}
mbedtls_aes_init(aes);
if (mode == MBEDTLS_AES_ENCRYPT) {
ret = mbedtls_aes_setkey_enc(aes, key, len * 8);
} else if (mode == MBEDTLS_AES_DECRYPT){
ret = mbedtls_aes_setkey_dec(aes, key, len * 8);
}
if (ret < 0) {
mbedtls_aes_free(aes);
os_free(aes);
wpa_printf(MSG_ERROR, "%s: mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec failed", __func__);
return NULL;
}
return (void *) aes;
}
static int aes_crypt(void *ctx, int mode, const u8 *in, u8 *out)
{
return mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx,
mode, in, out);
}
static void aes_crypt_deinit(void *ctx)
{
mbedtls_aes_free((mbedtls_aes_context *)ctx);
os_free(ctx);
}
void *aes_encrypt_init(const u8 *key, size_t len)
{
return aes_crypt_init(MBEDTLS_AES_ENCRYPT, key, len);
}
int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
{
return aes_crypt(ctx, MBEDTLS_AES_ENCRYPT, plain, crypt);
}
void aes_encrypt_deinit(void *ctx)
{
return aes_crypt_deinit(ctx);
}
void * aes_decrypt_init(const u8 *key, size_t len)
{
return aes_crypt_init(MBEDTLS_AES_DECRYPT, key, len);
}
int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
{
return aes_crypt(ctx, MBEDTLS_AES_DECRYPT, crypt, plain);
}
void aes_decrypt_deinit(void *ctx)
{
return aes_crypt_deinit(ctx);
}
int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
{
int ret = 0;
mbedtls_aes_context ctx;
u8 cbc[MBEDTLS_AES_BLOCK_SIZE];
mbedtls_aes_init(&ctx);
ret = mbedtls_aes_setkey_enc(&ctx, key, 128);
if (ret < 0) {
mbedtls_aes_free(&ctx);
return ret;
}
os_memcpy(cbc, iv, MBEDTLS_AES_BLOCK_SIZE);
ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT,
data_len, cbc, data, data);
mbedtls_aes_free(&ctx);
return ret;
}
int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
{
int ret = 0;
mbedtls_aes_context ctx;
u8 cbc[MBEDTLS_AES_BLOCK_SIZE];
mbedtls_aes_init(&ctx);
ret = mbedtls_aes_setkey_dec(&ctx, key, 128);
if (ret < 0) {
mbedtls_aes_free(&ctx);
return ret;
}
os_memcpy(cbc, iv, MBEDTLS_AES_BLOCK_SIZE);
ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT,
data_len, cbc, data, data);
mbedtls_aes_free(&ctx);
return ret;
}
struct crypto_cipher {
mbedtls_cipher_context_t ctx_enc;
mbedtls_cipher_context_t ctx_dec;
};
static int crypto_init_cipher_ctx(mbedtls_cipher_context_t *ctx,
const mbedtls_cipher_info_t *cipher_info,
const u8 *iv, const u8 *key,
mbedtls_operation_t operation)
{
mbedtls_cipher_init(ctx);
int ret;
ret = mbedtls_cipher_setup(ctx, cipher_info);
if (ret != 0) {
return -1;
}
if (mbedtls_cipher_setkey(ctx, key, cipher_info->key_bitlen,
operation) != 0) {
wpa_printf(MSG_ERROR, "mbedtls_cipher_setkey returned error");
return -1;
}
if (mbedtls_cipher_set_iv(ctx, iv, cipher_info->iv_size) != 0) {
wpa_printf(MSG_ERROR, "mbedtls_cipher_set_iv returned error");
return -1;
}
if (mbedtls_cipher_reset(ctx) != 0) {
wpa_printf(MSG_ERROR, "mbedtls_cipher_reset() returned error");
return -1;
}
return 0;
}
static mbedtls_cipher_type_t alg_to_mbedtls_cipher(enum crypto_cipher_alg alg,
size_t key_len)
{
switch (alg) {
#ifdef MBEDTLS_ARC4_C
case CRYPTO_CIPHER_ALG_RC4:
return MBEDTLS_CIPHER_ARC4_128;
#endif
case CRYPTO_CIPHER_ALG_AES:
if (key_len == 16) {
return MBEDTLS_CIPHER_AES_128_CBC;
}
if (key_len == 24) {
return MBEDTLS_CIPHER_AES_192_CBC;
}
if (key_len == 32) {
return MBEDTLS_CIPHER_AES_256_CBC;
}
break;
#ifdef MBEDTLS_DES_C
case CRYPTO_CIPHER_ALG_3DES:
return MBEDTLS_CIPHER_DES_EDE3_CBC;
case CRYPTO_CIPHER_ALG_DES:
return MBEDTLS_CIPHER_DES_CBC;
#endif
default:
break;
}
return MBEDTLS_CIPHER_NONE;
}
struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg,
const u8 *iv, const u8 *key,
size_t key_len)
{
struct crypto_cipher *ctx;
mbedtls_cipher_type_t cipher_type;
const mbedtls_cipher_info_t *cipher_info;
ctx = (struct crypto_cipher *)os_zalloc(sizeof(*ctx));
if (!ctx) {
return NULL;
}
cipher_type = alg_to_mbedtls_cipher(alg, key_len);
if (cipher_type == MBEDTLS_CIPHER_NONE) {
goto cleanup;
}
cipher_info = mbedtls_cipher_info_from_type(cipher_type);
if (cipher_info == NULL) {
goto cleanup;
}
/* Init both ctx encryption/decryption */
if (crypto_init_cipher_ctx(&ctx->ctx_enc, cipher_info, iv, key,
MBEDTLS_ENCRYPT) < 0) {
goto cleanup;
}
if (crypto_init_cipher_ctx(&ctx->ctx_dec, cipher_info, iv, key,
MBEDTLS_DECRYPT) < 0) {
goto cleanup;
}
return ctx;
cleanup:
os_free(ctx);
return NULL;
}
#if 0
int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
u8 *crypt, size_t len)
{
int ret;
size_t olen = 1200;
ret = mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen);
if (ret != 0) {
return -1;
}
ret = mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen);
if (ret != 0) {
return -1;
}
return 0;
}
int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
u8 *plain, size_t len)
{
int ret;
size_t olen = 1200;
ret = mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen);
if (ret != 0) {
return -1;
}
ret = mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen);
if (ret != 0) {
return -1;
}
return 0;
}
#endif
void crypto_cipher_deinit(struct crypto_cipher *ctx)
{
mbedtls_cipher_free(&ctx->ctx_enc);
mbedtls_cipher_free(&ctx->ctx_dec);
os_free(ctx);
}
int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce,
u8 *data, size_t data_len)
{
int ret;
mbedtls_aes_context ctx;
uint8_t stream_block[MBEDTLS_AES_BLOCK_SIZE];
size_t offset = 0;
mbedtls_aes_init(&ctx);
ret = mbedtls_aes_setkey_enc(&ctx, key, key_len * 8);
if (ret < 0) {
goto cleanup;
}
ret = mbedtls_aes_crypt_ctr(&ctx, data_len, &offset, (u8 *)nonce,
stream_block, data, data);
cleanup:
mbedtls_aes_free(&ctx);
return ret;
}
int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
u8 *data, size_t data_len)
{
return aes_ctr_encrypt(key, 16, nonce, data, data_len);
}
#ifdef MBEDTLS_NIST_KW_C
int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
{
mbedtls_nist_kw_context ctx;
size_t olen;
int ret = 0;
mbedtls_nist_kw_init(&ctx);
ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
kek, kek_len * 8, 1);
if (ret != 0) {
return ret;
}
ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain,
n * 8, cipher, &olen, (n + 1) * 8);
mbedtls_nist_kw_free(&ctx);
return ret;
}
int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
u8 *plain)
{
mbedtls_nist_kw_context ctx;
size_t olen;
int ret = 0;
mbedtls_nist_kw_init(&ctx);
ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
kek, kek_len * 8, 0);
if (ret != 0) {
return ret;
}
ret = mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher,
(n + 1) * 8, plain, &olen, (n * 8));
mbedtls_nist_kw_free(&ctx);
return ret;
}
#endif
int crypto_mod_exp(const uint8_t *base, size_t base_len,
const uint8_t *power, size_t power_len,
const uint8_t *modulus, size_t modulus_len,
uint8_t *result, size_t *result_len)
{
mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result, bn_rinv;
int ret = 0;
mbedtls_mpi_init(&bn_base);
mbedtls_mpi_init(&bn_exp);
mbedtls_mpi_init(&bn_modulus);
mbedtls_mpi_init(&bn_result);
mbedtls_mpi_init(&bn_rinv);
mbedtls_mpi_read_binary(&bn_base, base, base_len);
mbedtls_mpi_read_binary(&bn_exp, power, power_len);
mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len);
ret = mbedtls_mpi_exp_mod(&bn_result, &bn_base, &bn_exp, &bn_modulus,
&bn_rinv);
if (ret < 0) {
mbedtls_mpi_free(&bn_base);
mbedtls_mpi_free(&bn_exp);
mbedtls_mpi_free(&bn_modulus);
mbedtls_mpi_free(&bn_result);
mbedtls_mpi_free(&bn_rinv);
return ret;
}
ret = mbedtls_mpi_write_binary(&bn_result, result, *result_len);
mbedtls_mpi_free(&bn_base);
mbedtls_mpi_free(&bn_exp);
mbedtls_mpi_free(&bn_modulus);
mbedtls_mpi_free(&bn_result);
mbedtls_mpi_free(&bn_rinv);
return ret;
}
int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
int iterations, u8 *buf, size_t buflen)
{
mbedtls_md_context_t sha1_ctx;
const mbedtls_md_info_t *info_sha1;
int ret;
mbedtls_md_init(&sha1_ctx);
info_sha1 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
if (info_sha1 == NULL) {
ret = -1;
goto cleanup;
}
if ((ret = mbedtls_md_setup(&sha1_ctx, info_sha1, 1)) != 0) {
ret = -1;
goto cleanup;
}
ret = mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx, (const u8 *) passphrase,
os_strlen(passphrase) , ssid,
ssid_len, iterations, 32, buf);
if (ret != 0) {
ret = -1;
goto cleanup;
}
cleanup:
mbedtls_md_free(&sha1_ctx);
return ret;
}
#ifdef MBEDTLS_DES_C
int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
{
int ret;
mbedtls_des_context des;
u8 pkey[8], next, tmp;
int i;
/* Add parity bits to the key */
next = 0;
for (i = 0; i < 7; i++) {
tmp = key[i];
pkey[i] = (tmp >> i) | next | 1;
next = tmp << (7 - i);
}
pkey[i] = next | 1;
mbedtls_des_init(&des);
ret = mbedtls_des_setkey_enc(&des, pkey);
if (ret < 0) {
return ret;
}
ret = mbedtls_des_crypt_ecb(&des, clear, cypher);
mbedtls_des_free(&des);
return ret;
}
#endif
/* Only enable this if all other ciphers are using MbedTLS implementation */
#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_CMAC_C) && defined(MBEDTLS_NIST_KW_C)
int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce,
size_t M, const u8 *plain, size_t plain_len,
const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth)
{
int ret;
mbedtls_ccm_context ccm;
mbedtls_ccm_init(&ccm);
ret = mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES,
key, key_len * 8);
if (ret < 0) {
wpa_printf(MSG_ERROR, "mbedtls_ccm_setkey failed");
goto cleanup;
}
ret = mbedtls_ccm_encrypt_and_tag(&ccm, plain_len, nonce, 13, aad,
aad_len, plain, crypt, auth, M);
cleanup:
mbedtls_ccm_free(&ccm);
return ret;
}
int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce,
size_t M, const u8 *crypt, size_t crypt_len,
const u8 *aad, size_t aad_len, const u8 *auth,
u8 *plain)
{
int ret;
mbedtls_ccm_context ccm;
mbedtls_ccm_init(&ccm);
ret = mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES,
key, key_len * 8);
if (ret < 0) {
goto cleanup;;
}
ret = mbedtls_ccm_star_auth_decrypt(&ccm, crypt_len,
nonce, 13, aad, aad_len,
crypt, plain, auth, M);
cleanup:
mbedtls_ccm_free(&ccm);
return ret;
}
#endif
#ifdef MBEDTLS_ARC4_C
int rc4_skip(const u8 *key, size_t keylen, size_t skip,
u8 *data, size_t data_len)
{
int ret;
unsigned char skip_buf_in[16];
unsigned char skip_buf_out[16];
mbedtls_arc4_context ctx;
unsigned char *obuf = os_malloc(data_len);
if (!obuf) {
wpa_printf(MSG_ERROR, "%s:memory allocation failed", __func__);
return -1;
}
mbedtls_arc4_init(&ctx);
mbedtls_arc4_setup(&ctx, key, keylen);
while (skip >= sizeof(skip_buf_in)) {
size_t len = skip;
if (len > sizeof(skip_buf_in)) {
len = sizeof(skip_buf_in);
}
if ((ret = mbedtls_arc4_crypt(&ctx, len, skip_buf_in,
skip_buf_out)) != 0) {
wpa_printf(MSG_ERROR, "rc4 encryption failed");
return -1;
}
os_memcpy(skip_buf_in, skip_buf_out, 16);
skip -= len;
}
mbedtls_arc4_crypt(&ctx, data_len, data, obuf);
memcpy(data, obuf, data_len);
os_free(obuf);
return 0;
}
#endif
#ifdef MBEDTLS_CMAC_C
int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
const mbedtls_cipher_info_t *cipher_info;
int i, ret = 0;
mbedtls_cipher_type_t cipher_type;
mbedtls_cipher_context_t ctx;
switch (key_len) {
case 16:
cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
break;
case 24:
cipher_type = MBEDTLS_CIPHER_AES_192_ECB;
break;
case 32:
cipher_type = MBEDTLS_CIPHER_AES_256_ECB;
break;
default:
cipher_type = MBEDTLS_CIPHER_NONE;
break;
}
cipher_info = mbedtls_cipher_info_from_type(cipher_type);
if (cipher_info == NULL) {
/* Failing at this point must be due to a build issue */
ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
goto cleanup;
}
if (key == NULL || mac == NULL) {
return -1;
}
mbedtls_cipher_init(&ctx);
ret = mbedtls_cipher_setup(&ctx, cipher_info);
if (ret != 0) {
goto cleanup;
}
ret = mbedtls_cipher_cmac_starts(&ctx, key, key_len * 8);
if (ret != 0) {
goto cleanup;
}
for (i = 0 ; i < num_elem; i++) {
ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]);
if (ret != 0) {
goto cleanup;
}
}
ret = mbedtls_cipher_cmac_finish(&ctx, mac);
cleanup:
mbedtls_cipher_free(&ctx);
return(ret);
}
int omac1_aes_128_vector(const u8 *key, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
}
int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
{
return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
}
#endif
int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
u8 *pubkey)
{
size_t pubkey_len, pad;
if (os_get_random(privkey, prime_len) < 0) {
return -1;
}
if (os_memcmp(privkey, prime, prime_len) > 0) {
/* Make sure private value is smaller than prime */
privkey[0] = 0;
}
pubkey_len = prime_len;
if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len,
pubkey, &pubkey_len) < 0) {
return -1;
}
if (pubkey_len < prime_len) {
pad = prime_len - pubkey_len;
os_memmove(pubkey + pad, pubkey, pubkey_len);
os_memset(pubkey, 0, pad);
}
return 0;
}

View File

@ -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,

View File

@ -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]);
}*/
}

View File

@ -1,43 +1,41 @@
/*
* Diffie-Hellman group 5 operations
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
* Copyright (c) 2009, 2012, Jouni Malinen <j@w1.fi>
*
* 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)
{
}

View File

@ -1,23 +1,16 @@
/*
* Diffie-Hellman group 5 operations
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
* Copyright (c) 2009, 2012, Jouni Malinen <j@w1.fi>
*
* 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);

View File

@ -2,25 +2,17 @@
* Diffie-Hellman groups
* Copyright (c) 2007, Jouni Malinen <j@w1.fi>
*
* 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);

View File

@ -2,14 +2,8 @@
* Diffie-Hellman groups
* Copyright (c) 2007, Jouni Malinen <j@w1.fi>
*
* 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

View File

@ -1,31 +1,39 @@
/*
* MD4 hash implementation
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* 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<<s | 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<<s | 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 ===== */

View File

@ -2,19 +2,13 @@
* MD5 hash implementation and interface functions
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* 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;

View File

@ -2,19 +2,13 @@
* MD5 hash implementation and interface functions
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* 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);

View File

@ -2,14 +2,8 @@
* MD5 hash implementation and interface functions
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
*
* 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 */

View File

@ -2,14 +2,8 @@
* MD5 internal definitions
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* 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

View File

@ -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;
}

View File

@ -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 <j@w1.fi>
*
* 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,

View File

@ -2,21 +2,13 @@
* Random number generator
* Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
*
* 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 */

View File

@ -2,25 +2,18 @@
* RC4 stream cipher
* Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
*
* 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;

View File

@ -2,35 +2,24 @@
* SHA1 hash implementation and interface functions
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* 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 ===== */

View File

@ -2,79 +2,18 @@
* SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* 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

View File

@ -0,0 +1,67 @@
/*
* SHA1-based PRF
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "includes.h"
#include "common.h"
#include "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;
}

View File

@ -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;
}

View File

@ -2,19 +2,13 @@
* SHA1 hash implementation and interface functions
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* 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;
}

View File

@ -2,14 +2,8 @@
* SHA1 hash implementation and interface functions
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
*
* 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 */

View File

@ -2,14 +2,8 @@
* SHA1 internal definitions
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* 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

View File

@ -2,83 +2,17 @@
* SHA-256 hash implementation and interface functions
* Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi>
*
* 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 ===== */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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"

View File

@ -1,35 +1,14 @@
/*
* SHA-256 hash implementation and interface functions
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* 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

View File

@ -1,15 +1,9 @@
/*
* SHA256 hash implementation and interface functions
* Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
* Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi>
*
* 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 */

View File

@ -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"

View File

@ -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();

View File

@ -2,25 +2,17 @@
* Big number math
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/includes.h"
#include "utils/common.h"
#include "utils/wpabuf.h"
#include "utils/wpa_debug.h"
#include "tls/bignum.h"
#include "includes.h"
#include "common.h"
#include "bignum.h"
#define CONFIG_INTERNAL_LIBTOMMATH
#ifdef CONFIG_INTERNAL_LIBTOMMATH
#include "tls/libtommath.h"
#include "libtommath.h"
#else /* CONFIG_INTERNAL_LIBTOMMATH */
#include <tommath.h>
#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)

View File

@ -1,17 +1,18 @@
/*
* RSA
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
* Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/includes.h"
#include "includes.h"
#include "common.h"
#include "asn1.h"
#include "bignum.h"
#include "rsa.h"
#include "utils/common.h"
#include "tls/asn1.h"
#include "tls/bignum.h"
#include "tls/rsa.h"
struct crypto_rsa_key {
int private_key; /* whether private key is set */
@ -64,7 +65,7 @@ crypto_rsa_import_public_key(const u8 *buf, size_t len)
struct asn1_hdr hdr;
const u8 *pos, *end;
key = (struct crypto_rsa_key *)os_zalloc(sizeof(*key));
key = os_zalloc(sizeof(*key));
if (key == NULL)
return NULL;
@ -115,6 +116,29 @@ error:
}
struct crypto_rsa_key *
crypto_rsa_import_public_key_parts(const u8 *n, size_t n_len,
const u8 *e, size_t e_len)
{
struct crypto_rsa_key *key;
key = os_zalloc(sizeof(*key));
if (key == NULL)
return NULL;
key->n = bignum_init();
key->e = bignum_init();
if (key->n == NULL || key->e == NULL ||
bignum_set_unsigned_bin(key->n, n, n_len) < 0 ||
bignum_set_unsigned_bin(key->e, e, e_len) < 0) {
crypto_rsa_free(key);
return NULL;
}
return key;
}
/**
* crypto_rsa_import_private_key - Import an RSA private key
* @buf: Key buffer (DER encoded RSA private key)
@ -129,7 +153,7 @@ crypto_rsa_import_private_key(const u8 *buf, size_t len)
struct asn1_hdr hdr;
const u8 *pos, *end;
key = (struct crypto_rsa_key *)os_zalloc(sizeof(*key));
key = os_zalloc(sizeof(*key));
if (key == NULL)
return NULL;
@ -261,7 +285,7 @@ int crypto_rsa_exptmod(const u8 *in, size_t inlen, u8 *out, size_t *outlen,
if (use_private) {
/*
* Decrypt (or sign) using Chinese remainer theorem to speed
* Decrypt (or sign) using Chinese remainder theorem to speed
* up calculation. This is equivalent to tmp = tmp^d mod n
* (which would require more CPU to calculate directly).
*
@ -321,7 +345,6 @@ int crypto_rsa_exptmod(const u8 *in, size_t inlen, u8 *out, size_t *outlen,
ret = 0;
error:
bignum_deinit(tmp);
bignum_deinit(a);
bignum_deinit(b);

View File

@ -14,6 +14,9 @@ struct crypto_rsa_key;
struct crypto_rsa_key *
crypto_rsa_import_public_key(const u8 *buf, size_t len);
struct crypto_rsa_key *
crypto_rsa_import_public_key_parts(const u8 *n, size_t n_len,
const u8 *e, size_t e_len);
struct crypto_rsa_key *
crypto_rsa_import_private_key(const u8 *buf, size_t len);
size_t crypto_rsa_get_modulus_len(struct crypto_rsa_key *key);
int crypto_rsa_exptmod(const u8 *in, size_t inlen, u8 *out, size_t *outlen,

View File

@ -547,3 +547,8 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
return ssid_txt;
}
void * __hide_aliasing_typecast(void *foo)
{
return foo;
}

View File

@ -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);

View File

@ -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 <stdlib.h>

View File

@ -18,6 +18,8 @@
#include <time.h>
#include "unity.h"
#include <string.h>
#include "utils/common.h"
#include "utils/includes.h"
#include "crypto/crypto.h"
#include "mbedtls/ecp.h"

View File

@ -20,6 +20,8 @@
#include <time.h>
#include "unity.h"
#include <string.h>
#include "utils/common.h"
#include "utils/includes.h"
#include "crypto/crypto.h"
#include "../src/common/defs.h"
#include "../src/common/dpp.h"

View File

@ -21,6 +21,8 @@
#include <time.h>
#include "unity.h"
#include <string.h>
#include "utils/common.h"
#include "utils/includes.h"
#include "crypto/crypto.h"
#include "../src/common/sae.h"
#include "utils/wpabuf.h"