mirror of
https://github.com/espressif/esp-idf.git
synced 2025-11-15 15:00:02 +01:00
Merge remote-tracking branch 'origin/master' into feature/github-7022
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
#include "utils/wpa_debug.h"
|
||||
#include "ap/hostapd.h"
|
||||
#include "ap/wpa_auth_i.h"
|
||||
#include "esp_supplicant/esp_wifi_driver.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "esp_wifi_types.h"
|
||||
|
||||
void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "crypto/sha256.h"
|
||||
#include "crypto/random.h"
|
||||
|
||||
#include "esp_supplicant/esp_wifi_driver.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_private/wifi.h"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "scan.h"
|
||||
#include "bss.h"
|
||||
#ifdef ESP_SUPPLICANT
|
||||
#include "esp_supplicant/esp_wifi_driver.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#endif
|
||||
|
||||
#define MAX_BSS_COUNT 20
|
||||
@@ -123,6 +123,7 @@ static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
|
||||
if (bss == wpa_s->current_bss)
|
||||
return 1;
|
||||
|
||||
#ifndef ESP_SUPPLICANT
|
||||
if (wpa_s->current_bss &&
|
||||
(bss->ssid_len != wpa_s->current_bss->ssid_len ||
|
||||
os_memcmp(bss->ssid, wpa_s->current_bss->ssid,
|
||||
@@ -131,6 +132,8 @@ static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
|
||||
|
||||
return !is_zero_ether_addr(bss->bssid) && wpa_s->current_bss->bssid &&
|
||||
(os_memcmp(bss->bssid, wpa_s->current_bss->bssid, ETH_ALEN) == 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "ieee802_11_defs.h"
|
||||
#include "esp_supplicant/esp_wifi_driver.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
|
||||
struct element {
|
||||
u8 id;
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
#include "rrm.h"
|
||||
#include "scan.h"
|
||||
#include <sys/errno.h>
|
||||
#include "esp_supplicant/esp_common_i.h"
|
||||
#ifdef ESP_SUPPLICANT
|
||||
#include "esp_common_i.h"
|
||||
#endif
|
||||
|
||||
static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx)
|
||||
{
|
||||
|
||||
@@ -754,6 +754,10 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
|
||||
if (wpa_s->wnm_dissoc_timer) {
|
||||
/* TODO: mark current BSS less preferred for
|
||||
* selection */
|
||||
#ifdef ESP_SUPPLICANT
|
||||
os_memset(wpa_s->next_scan_bssid, 0, ETH_ALEN);
|
||||
wpa_s->next_scan_chan = 0;
|
||||
#endif
|
||||
wpa_printf(MSG_DEBUG, "Trying to find another BSS");
|
||||
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "esp_supplicant/esp_wifi_driver.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#ifndef WPA_COMMON_H
|
||||
#define WPA_COMMON_H
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,17 +199,12 @@ 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) {
|
||||
if (os_memcmp_const(x, t, M) != 0) {
|
||||
wpa_printf(MSG_DEBUG, "CCM: Auth mismatch");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -1019,7 +1066,7 @@ void crypto_free_buffer(unsigned char *buf);
|
||||
* @crypto_ec_get_priv_key_der: get private key in der format
|
||||
* @key: key structure
|
||||
* @key_data: key data in charater buffer
|
||||
* @key_len = key lenght of charater buffer
|
||||
* @key_len = key length of charater buffer
|
||||
* Return : 0 if success
|
||||
*/
|
||||
int crypto_ec_get_priv_key_der(struct crypto_key *key, unsigned char **key_data, int *key_len);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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]);
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ===== */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ===== */
|
||||
|
||||
@@ -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
|
||||
|
||||
67
components/wpa_supplicant/src/crypto/sha1-prf.c
Normal file
67
components/wpa_supplicant/src/crypto/sha1-prf.c
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ===== */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
92
components/wpa_supplicant/src/crypto/sha384-internal.c
Normal file
92
components/wpa_supplicant/src/crypto/sha384-internal.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* SHA-384 hash implementation and interface functions
|
||||
* Copyright (c) 2015, Pali Rohár <pali.rohar@gmail.com>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "sha384_i.h"
|
||||
#include "crypto.h"
|
||||
|
||||
|
||||
/**
|
||||
* 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 of failure
|
||||
*/
|
||||
int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
|
||||
u8 *mac)
|
||||
{
|
||||
struct sha384_state ctx;
|
||||
size_t i;
|
||||
|
||||
sha384_init(&ctx);
|
||||
for (i = 0; i < num_elem; i++)
|
||||
if (sha384_process(&ctx, addr[i], len[i]))
|
||||
return -1;
|
||||
if (sha384_done(&ctx, mac))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ===== start - public domain SHA384 implementation ===== */
|
||||
|
||||
/* This is based on SHA384 implementation in LibTomCrypt that was released into
|
||||
* public domain by Tom St Denis. */
|
||||
|
||||
#define CONST64(n) n ## ULL
|
||||
|
||||
/**
|
||||
Initialize the hash state
|
||||
@param md The hash state you wish to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void sha384_init(struct sha384_state *md)
|
||||
{
|
||||
md->curlen = 0;
|
||||
md->length = 0;
|
||||
md->state[0] = CONST64(0xcbbb9d5dc1059ed8);
|
||||
md->state[1] = CONST64(0x629a292a367cd507);
|
||||
md->state[2] = CONST64(0x9159015a3070dd17);
|
||||
md->state[3] = CONST64(0x152fecd8f70e5939);
|
||||
md->state[4] = CONST64(0x67332667ffc00b31);
|
||||
md->state[5] = CONST64(0x8eb44a8768581511);
|
||||
md->state[6] = CONST64(0xdb0c2e0d64f98fa7);
|
||||
md->state[7] = CONST64(0x47b5481dbefa4fa4);
|
||||
}
|
||||
|
||||
int sha384_process(struct sha384_state *md, const unsigned char *in,
|
||||
unsigned long inlen)
|
||||
{
|
||||
return sha512_process(md, in, inlen);
|
||||
}
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
@param md The hash state
|
||||
@param out [out] The destination of the hash (48 bytes)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha384_done(struct sha384_state *md, unsigned char *out)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
|
||||
if (md->curlen >= sizeof(md->buf))
|
||||
return -1;
|
||||
|
||||
if (sha512_done(md, buf) != 0)
|
||||
return -1;
|
||||
|
||||
os_memcpy(out, buf, 48);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ===== end - public domain SHA384 implementation ===== */
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
23
components/wpa_supplicant/src/crypto/sha384_i.h
Normal file
23
components/wpa_supplicant/src/crypto/sha384_i.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SHA-384 internal definitions
|
||||
* Copyright (c) 2015, Pali Rohár <pali.rohar@gmail.com>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef SHA384_I_H
|
||||
#define SHA384_I_H
|
||||
|
||||
#include "sha512_i.h"
|
||||
|
||||
#define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
#define sha384_state sha512_state
|
||||
|
||||
void sha384_init(struct sha384_state *md);
|
||||
int sha384_process(struct sha384_state *md, const unsigned char *in,
|
||||
unsigned long inlen);
|
||||
int sha384_done(struct sha384_state *md, unsigned char *out);
|
||||
|
||||
#endif /* SHA384_I_H */
|
||||
270
components/wpa_supplicant/src/crypto/sha512-internal.c
Normal file
270
components/wpa_supplicant/src/crypto/sha512-internal.c
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* SHA-512 hash implementation and interface functions
|
||||
* Copyright (c) 2015, Pali Rohár <pali.rohar@gmail.com>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "sha512_i.h"
|
||||
#include "crypto.h"
|
||||
|
||||
|
||||
/**
|
||||
* 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 of failure
|
||||
*/
|
||||
int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
|
||||
u8 *mac)
|
||||
{
|
||||
struct sha512_state ctx;
|
||||
size_t i;
|
||||
|
||||
sha512_init(&ctx);
|
||||
for (i = 0; i < num_elem; i++)
|
||||
if (sha512_process(&ctx, addr[i], len[i]))
|
||||
return -1;
|
||||
if (sha512_done(&ctx, mac))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ===== start - public domain SHA512 implementation ===== */
|
||||
|
||||
/* This is based on SHA512 implementation in LibTomCrypt that was released into
|
||||
* public domain by Tom St Denis. */
|
||||
|
||||
#define CONST64(n) n ## ULL
|
||||
|
||||
/* the K array */
|
||||
static const u64 K[80] = {
|
||||
CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
|
||||
CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
|
||||
CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
|
||||
CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
|
||||
CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
|
||||
CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
|
||||
CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
|
||||
CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
|
||||
CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
|
||||
CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
|
||||
CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
|
||||
CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
|
||||
CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
|
||||
CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
|
||||
CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
|
||||
CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
|
||||
CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
|
||||
CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
|
||||
CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
|
||||
CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
|
||||
CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
|
||||
CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
|
||||
CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
|
||||
CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
|
||||
CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
|
||||
CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
|
||||
CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
|
||||
CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
|
||||
CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
|
||||
CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
|
||||
CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
|
||||
CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
|
||||
CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
|
||||
CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
|
||||
CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
|
||||
CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
|
||||
CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
|
||||
CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
|
||||
CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
|
||||
CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
/* Various logical functions */
|
||||
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define Maj(x,y,z) (((x | y) & z) | (x & y))
|
||||
#define S(x, n) ROR64c(x, n)
|
||||
#define R(x, n) (((x) & CONST64(0xFFFFFFFFFFFFFFFF)) >> ((u64) n))
|
||||
#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
|
||||
#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
|
||||
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
|
||||
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#define ROR64c(x, y) \
|
||||
( ((((x) & CONST64(0xFFFFFFFFFFFFFFFF)) >> ((u64) (y) & CONST64(63))) | \
|
||||
((x) << ((u64) (64 - ((y) & CONST64(63)))))) & \
|
||||
CONST64(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
/* compress 1024-bits */
|
||||
static int sha512_compress(struct sha512_state *md, unsigned char *buf)
|
||||
{
|
||||
u64 S[8], t0, t1;
|
||||
u64 *W;
|
||||
int i;
|
||||
|
||||
W = os_malloc(80 * sizeof(u64));
|
||||
if (!W)
|
||||
return -1;
|
||||
|
||||
/* copy state into S */
|
||||
for (i = 0; i < 8; i++) {
|
||||
S[i] = md->state[i];
|
||||
}
|
||||
|
||||
/* copy the state into 1024-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++)
|
||||
W[i] = WPA_GET_BE64(buf + (8 * i));
|
||||
|
||||
/* fill W[16..79] */
|
||||
for (i = 16; i < 80; i++) {
|
||||
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
|
||||
W[i - 16];
|
||||
}
|
||||
|
||||
/* Compress */
|
||||
for (i = 0; i < 80; i++) {
|
||||
t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
|
||||
t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
|
||||
S[7] = S[6];
|
||||
S[6] = S[5];
|
||||
S[5] = S[4];
|
||||
S[4] = S[3] + t0;
|
||||
S[3] = S[2];
|
||||
S[2] = S[1];
|
||||
S[1] = S[0];
|
||||
S[0] = t0 + t1;
|
||||
}
|
||||
|
||||
/* feedback */
|
||||
for (i = 0; i < 8; i++) {
|
||||
md->state[i] = md->state[i] + S[i];
|
||||
}
|
||||
|
||||
os_free(W);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize the hash state
|
||||
@param md The hash state you wish to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void sha512_init(struct sha512_state *md)
|
||||
{
|
||||
md->curlen = 0;
|
||||
md->length = 0;
|
||||
md->state[0] = CONST64(0x6a09e667f3bcc908);
|
||||
md->state[1] = CONST64(0xbb67ae8584caa73b);
|
||||
md->state[2] = CONST64(0x3c6ef372fe94f82b);
|
||||
md->state[3] = CONST64(0xa54ff53a5f1d36f1);
|
||||
md->state[4] = CONST64(0x510e527fade682d1);
|
||||
md->state[5] = CONST64(0x9b05688c2b3e6c1f);
|
||||
md->state[6] = CONST64(0x1f83d9abfb41bd6b);
|
||||
md->state[7] = CONST64(0x5be0cd19137e2179);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Process a block of memory though the hash
|
||||
@param md The hash state
|
||||
@param in The data to hash
|
||||
@param inlen The length of the data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha512_process(struct sha512_state *md, const unsigned char *in,
|
||||
unsigned long inlen)
|
||||
{
|
||||
unsigned long n;
|
||||
|
||||
if (md->curlen >= sizeof(md->buf))
|
||||
return -1;
|
||||
|
||||
while (inlen > 0) {
|
||||
if (md->curlen == 0 && inlen >= SHA512_BLOCK_SIZE) {
|
||||
if (sha512_compress(md, (unsigned char *) in) < 0)
|
||||
return -1;
|
||||
md->length += SHA512_BLOCK_SIZE * 8;
|
||||
in += SHA512_BLOCK_SIZE;
|
||||
inlen -= SHA512_BLOCK_SIZE;
|
||||
} else {
|
||||
n = MIN(inlen, (SHA512_BLOCK_SIZE - md->curlen));
|
||||
os_memcpy(md->buf + md->curlen, in, n);
|
||||
md->curlen += n;
|
||||
in += n;
|
||||
inlen -= n;
|
||||
if (md->curlen == SHA512_BLOCK_SIZE) {
|
||||
if (sha512_compress(md, md->buf) < 0)
|
||||
return -1;
|
||||
md->length += 8 * SHA512_BLOCK_SIZE;
|
||||
md->curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
@param md The hash state
|
||||
@param out [out] The destination of the hash (64 bytes)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha512_done(struct sha512_state *md, unsigned char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (md->curlen >= sizeof(md->buf))
|
||||
return -1;
|
||||
|
||||
/* increase the length of the message */
|
||||
md->length += md->curlen * CONST64(8);
|
||||
|
||||
/* append the '1' bit */
|
||||
md->buf[md->curlen++] = (unsigned char) 0x80;
|
||||
|
||||
/* if the length is currently above 112 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->curlen > 112) {
|
||||
while (md->curlen < 128) {
|
||||
md->buf[md->curlen++] = (unsigned char) 0;
|
||||
}
|
||||
sha512_compress(md, md->buf);
|
||||
md->curlen = 0;
|
||||
}
|
||||
|
||||
/* pad up to 120 bytes of zeroes
|
||||
* note: that from 112 to 120 is the 64 MSB of the length. We assume
|
||||
* that you won't hash > 2^64 bits of data... :-)
|
||||
*/
|
||||
while (md->curlen < 120) {
|
||||
md->buf[md->curlen++] = (unsigned char) 0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
WPA_PUT_BE64(md->buf + 120, md->length);
|
||||
sha512_compress(md, md->buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 8; i++)
|
||||
WPA_PUT_BE64(out + (8 * i), md->state[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ===== end - public domain SHA512 implementation ===== */
|
||||
25
components/wpa_supplicant/src/crypto/sha512_i.h
Normal file
25
components/wpa_supplicant/src/crypto/sha512_i.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SHA-512 internal definitions
|
||||
* Copyright (c) 2015, Pali Rohár <pali.rohar@gmail.com>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef SHA512_I_H
|
||||
#define SHA512_I_H
|
||||
|
||||
#define SHA512_BLOCK_SIZE 128
|
||||
|
||||
struct sha512_state {
|
||||
u64 length, state[8];
|
||||
u32 curlen;
|
||||
u8 buf[SHA512_BLOCK_SIZE];
|
||||
};
|
||||
|
||||
void sha512_init(struct sha512_state *md);
|
||||
int sha512_process(struct sha512_state *md, const unsigned char *in,
|
||||
unsigned long inlen);
|
||||
int sha512_done(struct sha512_state *md, unsigned char *out);
|
||||
|
||||
#endif /* SHA512_I_H */
|
||||
@@ -121,6 +121,10 @@ static int tls_mbedtls_read(void *ctx, unsigned char *buf, size_t len)
|
||||
struct wpabuf *local_buf;
|
||||
size_t data_len = len;
|
||||
|
||||
if (data->in_data == NULL) {
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
|
||||
if (len > wpabuf_len(data->in_data)) {
|
||||
wpa_printf(MSG_ERROR, "don't have suffient data\n");
|
||||
data_len = wpabuf_len(data->in_data);
|
||||
@@ -466,6 +470,10 @@ static int tls_create_mbedtls_handle(const struct tls_connection_params *params,
|
||||
wpa_printf(MSG_ERROR, "mbedtls_ssl_setup returned -0x%x", -ret);
|
||||
goto exit;
|
||||
}
|
||||
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
|
||||
/* Disable BEAST attack countermeasures for Windows 2008 interoperability */
|
||||
mbedtls_ssl_conf_cbc_record_splitting(&tls->conf, MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED);
|
||||
#endif
|
||||
|
||||
/* Enable debug prints in case supplicant's prints are enabled */
|
||||
#if defined(DEBUG_PRINT) && defined(CONFIG_MBEDTLS_DEBUG) && defined(ESPRESSIF_USE)
|
||||
@@ -556,56 +564,26 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx,
|
||||
if (wpabuf_len(in_data)) {
|
||||
conn->tls_io_data.in_data = wpabuf_dup(in_data);
|
||||
}
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "%s:%d", __func__, __LINE__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Multiple reads */
|
||||
while (conn->tls_io_data.in_data) {
|
||||
while (tls->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER) {
|
||||
if (tls->ssl.state == MBEDTLS_SSL_CLIENT_CERTIFICATE) {
|
||||
/* Read random data before session completes, not present after handshake */
|
||||
if (tls->ssl.handshake) {
|
||||
os_memcpy(conn->randbytes, tls->ssl.handshake->randbytes,
|
||||
TLS_RANDOM_LEN * 2);
|
||||
}
|
||||
}
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* State machine just started, get client hello */
|
||||
if (tls->ssl.state == MBEDTLS_SSL_CLIENT_HELLO) {
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "%s:%d", __func__, __LINE__);
|
||||
if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
wpa_printf(MSG_INFO, "%s: ret is %d line:%d", __func__, ret, __LINE__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Already read sever data till hello done */
|
||||
if (tls->ssl.state == MBEDTLS_SSL_CLIENT_CERTIFICATE) {
|
||||
/* Read random data before session completes, not present after handshake */
|
||||
if (tls->ssl.handshake) {
|
||||
os_memcpy(conn->randbytes, tls->ssl.handshake->randbytes,
|
||||
TLS_RANDOM_LEN * 2);
|
||||
}
|
||||
|
||||
/* trigger state machine multiple times to reach till finish */
|
||||
while (tls->ssl.state <= MBEDTLS_SSL_CLIENT_FINISHED) {
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Trigger state machine till handshake is complete or error occures */
|
||||
if (tls->ssl.state == MBEDTLS_SSL_FLUSH_BUFFERS) {
|
||||
while (tls->ssl.state <= MBEDTLS_SSL_HANDSHAKE_OVER) {
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!conn->tls_io_data.out_data) {
|
||||
wpa_printf(MSG_INFO, "application data is null, adding one byte for ack");
|
||||
u8 *dummy = os_zalloc(1);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "eap_peer/eap_config.h"
|
||||
#include "eap_peer/eap.h"
|
||||
#include "eap_peer/eap_tls.h"
|
||||
#include "esp_supplicant/esp_wifi_driver.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#ifdef EAP_PEER_METHOD
|
||||
#include "eap_peer/eap_methods.h"
|
||||
#endif
|
||||
|
||||
@@ -1,399 +0,0 @@
|
||||
/**
|
||||
* Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_wifi_types.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "drivers/driver.h"
|
||||
#include "common/bss.h"
|
||||
#include "common/rrm.h"
|
||||
#include "common/wnm_sta.h"
|
||||
#include "common/wpa_supplicant_i.h"
|
||||
#include "esp_supplicant/esp_scan_i.h"
|
||||
#include "esp_supplicant/esp_common_i.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "esp_rrm.h"
|
||||
#include "esp_wnm.h"
|
||||
|
||||
struct wpa_supplicant g_wpa_supp;
|
||||
|
||||
static void *s_supplicant_task_hdl = NULL;
|
||||
static void *s_supplicant_evt_queue = NULL;
|
||||
static void *s_supplicant_api_lock = NULL;
|
||||
|
||||
static int esp_handle_action_frm(u8 *frame, size_t len,
|
||||
u8 *sender, u32 rssi, u8 channel)
|
||||
{
|
||||
struct ieee_mgmt_frame *frm = os_malloc(sizeof(struct ieee_mgmt_frame) + len);
|
||||
|
||||
if (!frm) {
|
||||
wpa_printf(MSG_ERROR, "memory allocation failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memcpy(frm->sender, sender, ETH_ALEN);
|
||||
frm->len = len;
|
||||
frm->channel = channel;
|
||||
frm->rssi = rssi;
|
||||
|
||||
os_memcpy(frm->payload, frame, len);
|
||||
if (esp_supplicant_post_evt(SIG_SUPPLICANT_RX_ACTION, (u32)frm) != 0) {
|
||||
os_free(frm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void esp_rx_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender,
|
||||
u8 *payload, size_t len, u32 rssi)
|
||||
{
|
||||
if (payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) {
|
||||
/* neighbor report parsing */
|
||||
wpas_rrm_process_neighbor_rep(wpa_s, payload + 1, len - 1);
|
||||
} else if (payload[0] == WLAN_RRM_RADIO_MEASUREMENT_REQUEST) {
|
||||
/* Beacon measurement */
|
||||
wpas_rrm_handle_radio_measurement_request(wpa_s, NULL,
|
||||
sender, payload + 1, len - 1);
|
||||
} else if (payload[0] == WLAN_RRM_LINK_MEASUREMENT_REQUEST) {
|
||||
/* Link measurement */
|
||||
wpas_rrm_handle_link_measurement_request(wpa_s, NULL,
|
||||
payload + 1, len - 1, rssi);
|
||||
}
|
||||
}
|
||||
|
||||
static int esp_mgmt_rx_action(u8 *sender, u8 *payload, size_t len, u8 channel, u32 rssi)
|
||||
{
|
||||
u8 category;
|
||||
u8 bssid[ETH_ALEN];
|
||||
struct wpa_supplicant *wpa_s = &g_wpa_supp;
|
||||
int ret = esp_wifi_get_assoc_bssid_internal(bssid);
|
||||
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_INFO, "STA not associated");
|
||||
return -1;
|
||||
}
|
||||
|
||||
category = *payload++;
|
||||
len--;
|
||||
if (category == WLAN_ACTION_WNM) {
|
||||
ieee802_11_rx_wnm_action(wpa_s, sender, payload, len);
|
||||
} else if (category == WLAN_ACTION_RADIO_MEASUREMENT) {
|
||||
esp_rx_rrm_frame(wpa_s, sender, payload, len, rssi);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void esp_btm_rrm_task(void *pvParameters)
|
||||
{
|
||||
supplicant_event_t *evt;
|
||||
bool task_del = false;
|
||||
|
||||
while(1) {
|
||||
if (xQueueReceive(s_supplicant_evt_queue, &evt, portMAX_DELAY) != pdTRUE)
|
||||
continue;
|
||||
|
||||
/* event validation failed */
|
||||
if (evt->id >= SIG_SUPPLICANT_MAX) {
|
||||
os_free(evt);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (evt->id) {
|
||||
case SIG_SUPPLICANT_RX_ACTION:
|
||||
{
|
||||
struct ieee_mgmt_frame *frm = (struct ieee_mgmt_frame *)evt->data;
|
||||
esp_mgmt_rx_action(frm->sender, frm->payload, frm->len, frm->channel, frm->rssi);
|
||||
os_free(frm);
|
||||
break;
|
||||
}
|
||||
|
||||
case SIG_SUPPLICANT_SCAN_DONE:
|
||||
esp_supplicant_handle_scan_done_evt();
|
||||
break;
|
||||
case SIG_SUPPLICANT_DEL_TASK:
|
||||
task_del = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
os_free(evt);
|
||||
|
||||
if (task_del)
|
||||
break;
|
||||
}
|
||||
|
||||
vQueueDelete(s_supplicant_evt_queue);
|
||||
s_supplicant_evt_queue = NULL;
|
||||
|
||||
if (s_supplicant_api_lock) {
|
||||
vSemaphoreDelete(s_supplicant_api_lock);
|
||||
s_supplicant_api_lock = NULL;
|
||||
}
|
||||
|
||||
/* At this point, we completed */
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void esp_clear_bssid_flag(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
wifi_config_t *config;
|
||||
|
||||
/* Reset only if btm is enabled */
|
||||
if (esp_wifi_is_btm_enabled_internal(WIFI_IF_STA) == false)
|
||||
return;
|
||||
|
||||
config = os_zalloc(sizeof(wifi_config_t));
|
||||
|
||||
if (!config) {
|
||||
wpa_printf(MSG_ERROR, "failed to allocate memory");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_wifi_get_config(WIFI_IF_STA, config);
|
||||
config->sta.bssid_set = 0;
|
||||
esp_wifi_set_config(WIFI_IF_STA, config);
|
||||
os_free(config);
|
||||
wpa_printf(MSG_DEBUG, "cleared bssid flag");
|
||||
}
|
||||
|
||||
static void esp_register_action_frame(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
wpa_s->type &= ~WLAN_FC_STYPE_ACTION;
|
||||
/* subtype is defined only for action frame */
|
||||
wpa_s->subtype = 0;
|
||||
|
||||
/* current supported features in supplicant: rrm and btm */
|
||||
if (esp_wifi_is_rm_enabled_internal(WIFI_IF_STA))
|
||||
wpa_s->subtype = 1 << WLAN_ACTION_RADIO_MEASUREMENT;
|
||||
if (esp_wifi_is_btm_enabled_internal(WIFI_IF_STA))
|
||||
wpa_s->subtype |= 1 << WLAN_ACTION_WNM;
|
||||
|
||||
if (wpa_s->subtype)
|
||||
wpa_s->type |= 1 << WLAN_FC_STYPE_ACTION;
|
||||
|
||||
esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype);
|
||||
}
|
||||
|
||||
static void esp_supplicant_sta_conn_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 *ie;
|
||||
struct wpa_supplicant *wpa_s = &g_wpa_supp;
|
||||
int ret = esp_wifi_get_assoc_bssid_internal(bssid);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "Not able to get connected bssid");
|
||||
return;
|
||||
}
|
||||
struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, bssid);
|
||||
if (!bss) {
|
||||
wpa_printf(MSG_INFO, "connected bss entry not present in scan cache");
|
||||
return;
|
||||
}
|
||||
wpa_s->current_bss = bss;
|
||||
ie = (u8 *)bss;
|
||||
ie += sizeof(struct wpa_bss);
|
||||
ieee802_11_parse_elems(wpa_s, ie, bss->ie_len);
|
||||
wpa_bss_flush(wpa_s);
|
||||
/* Register for action frames */
|
||||
esp_register_action_frame(wpa_s);
|
||||
/* clear set bssid flag */
|
||||
esp_clear_bssid_flag(wpa_s);
|
||||
}
|
||||
|
||||
static void esp_supplicant_sta_disconn_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = &g_wpa_supp;
|
||||
wpas_rrm_reset(wpa_s);
|
||||
if (wpa_s->current_bss) {
|
||||
wpa_s->current_bss = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = &g_wpa_supp;
|
||||
|
||||
s_supplicant_evt_queue = xQueueCreate(3, sizeof(supplicant_event_t));
|
||||
xTaskCreate(esp_btm_rrm_task, "btm_rrm_t", SUPPLICANT_TASK_STACK_SIZE, NULL, 2, s_supplicant_task_hdl);
|
||||
|
||||
s_supplicant_api_lock = xSemaphoreCreateRecursiveMutex();
|
||||
if (!s_supplicant_api_lock) {
|
||||
wpa_printf(MSG_ERROR, "esp_supplicant_common_init: failed to create Supplicant API lock");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_scan_init(wpa_s);
|
||||
wpas_rrm_reset(wpa_s);
|
||||
wpas_clear_beacon_rep_data(wpa_s);
|
||||
|
||||
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED,
|
||||
&esp_supplicant_sta_conn_handler, NULL);
|
||||
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
|
||||
&esp_supplicant_sta_disconn_handler, NULL);
|
||||
|
||||
wpa_s->type = 0;
|
||||
wpa_s->subtype = 0;
|
||||
wpa_cb->wpa_sta_rx_mgmt = esp_ieee80211_handle_rx_frm;
|
||||
}
|
||||
|
||||
int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb,
|
||||
void *cb_ctx)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = &g_wpa_supp;
|
||||
struct wpa_ssid_value wpa_ssid = {0};
|
||||
struct wifi_ssid *ssid = esp_wifi_sta_get_prof_ssid_internal();
|
||||
os_memcpy(wpa_ssid.ssid, ssid->ssid, ssid->len);
|
||||
wpa_ssid.ssid_len = ssid->len;
|
||||
wpas_rrm_send_neighbor_rep_request(wpa_s, &wpa_ssid, 0, 0, cb, cb_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason,
|
||||
const char *btm_candidates,
|
||||
int cand_list)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = &g_wpa_supp;
|
||||
return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason, btm_candidates, cand_list);
|
||||
}
|
||||
|
||||
void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_bss *bss, char *ssid)
|
||||
{
|
||||
wifi_config_t *config = os_zalloc(sizeof(wifi_config_t));
|
||||
|
||||
if (!config) {
|
||||
wpa_printf(MSG_ERROR, "failed to allocate memory");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_wifi_get_config(WIFI_IF_STA, config);
|
||||
/* We only support roaming in same ESS, therefore only bssid setting is needed */
|
||||
os_memcpy(config->sta.bssid, bss->bssid, ETH_ALEN);
|
||||
config->sta.bssid_set = 1;
|
||||
esp_wifi_internal_issue_disconnect(WIFI_REASON_ROAMING);
|
||||
esp_wifi_set_config(WIFI_IF_STA, config);
|
||||
os_free(config);
|
||||
esp_wifi_connect();
|
||||
}
|
||||
|
||||
void esp_set_rm_enabled_ie(void)
|
||||
{
|
||||
uint8_t rmm_ie[5] = {0};
|
||||
uint8_t rrm_ie_len = 5;
|
||||
uint8_t *pos = rmm_ie;
|
||||
|
||||
*pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT;
|
||||
|
||||
*pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
|
||||
#ifdef SCAN_CACHE_SUPPORTED
|
||||
WLAN_RRM_CAPS_BEACON_REPORT_TABLE |
|
||||
#endif
|
||||
WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE;
|
||||
|
||||
/* set rm enabled IE if enabled in driver */
|
||||
if (esp_wifi_is_rm_enabled_internal(WIFI_IF_STA)) {
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_RM_ENABLED_CAPS, rmm_ie, rrm_ie_len, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void esp_get_tx_power(uint8_t *tx_power)
|
||||
{
|
||||
#define DEFAULT_MAX_TX_POWER 19 /* max tx power is 19.5 dbm */
|
||||
s8 power;
|
||||
/* esp sends management frames at max tx power configured */
|
||||
int ret = esp_wifi_get_max_tx_power(&power);
|
||||
if (ret != 0) {
|
||||
wpa_printf(MSG_ERROR, "failed to get tx power");
|
||||
*tx_power = DEFAULT_MAX_TX_POWER;
|
||||
return;
|
||||
}
|
||||
*tx_power = power/4;
|
||||
#undef DEFAULT_MAX_TX_POWER
|
||||
}
|
||||
|
||||
int wpa_drv_send_action(struct wpa_supplicant *wpa_s,
|
||||
unsigned int channel,
|
||||
unsigned int wait,
|
||||
const u8 *data, size_t data_len,
|
||||
int no_cck)
|
||||
{
|
||||
int ret = 0;
|
||||
wifi_mgmt_frm_req_t *req = os_zalloc(sizeof(*req) + data_len);;
|
||||
if (!req)
|
||||
return -1;
|
||||
|
||||
if (!wpa_s->current_bss) {
|
||||
wpa_printf(MSG_ERROR, "STA not associated, return");
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
req->ifx = WIFI_IF_STA;
|
||||
req->subtype = WLAN_FC_STYPE_ACTION;
|
||||
req->data_len = data_len;
|
||||
os_memcpy(req->data, data, req->data_len);
|
||||
|
||||
if (esp_wifi_send_mgmt_frm_internal(req) != 0) {
|
||||
wpa_printf(MSG_ERROR, "action frame sending failed");
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
wpa_printf(MSG_INFO, "action frame sent");
|
||||
|
||||
cleanup:
|
||||
os_free(req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data)
|
||||
{
|
||||
supplicant_event_t *evt = os_zalloc(sizeof(supplicant_event_t));
|
||||
if (evt == NULL) {
|
||||
return -1;
|
||||
}
|
||||
evt->id = evt_id;
|
||||
evt->data = data;
|
||||
|
||||
SUPPLICANT_API_LOCK();
|
||||
if (xQueueSend(s_supplicant_evt_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) {
|
||||
SUPPLICANT_API_UNLOCK();
|
||||
os_free(evt);
|
||||
return -1;
|
||||
}
|
||||
SUPPLICANT_API_UNLOCK();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esp_ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender,
|
||||
u32 rssi, u8 channel, u64 current_tsf)
|
||||
{
|
||||
if (type == WLAN_FC_STYPE_BEACON || type == WLAN_FC_STYPE_PROBE_RESP) {
|
||||
return esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf);
|
||||
} else if (type == WLAN_FC_STYPE_ACTION) {
|
||||
return esp_handle_action_frm(frame, len, sender, rssi, channel);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef ESP_COMMON_I_H
|
||||
#define ESP_COMMON_I_H
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
struct wpa_funcs;
|
||||
|
||||
#ifdef ROAMING_SUPPORT
|
||||
struct ieee_mgmt_frame {
|
||||
u8 sender[ETH_ALEN];
|
||||
u8 channel;
|
||||
u32 rssi;
|
||||
size_t len;
|
||||
u8 payload[0];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
uint32_t data;
|
||||
} supplicant_event_t;
|
||||
|
||||
#define SUPPLICANT_API_LOCK() xSemaphoreTakeRecursive(s_supplicant_api_lock, portMAX_DELAY)
|
||||
#define SUPPLICANT_API_UNLOCK() xSemaphoreGiveRecursive(s_supplicant_api_lock)
|
||||
|
||||
#define SUPPLICANT_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD)
|
||||
enum SIG_SUPPLICANT {
|
||||
SIG_SUPPLICANT_RX_ACTION,
|
||||
SIG_SUPPLICANT_SCAN_DONE,
|
||||
SIG_SUPPLICANT_DEL_TASK,
|
||||
SIG_SUPPLICANT_MAX,
|
||||
};
|
||||
|
||||
int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data);
|
||||
int esp_ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender,
|
||||
u32 rssi, u8 channel, u64 current_tsf);
|
||||
void esp_set_rm_enabled_ie(void);
|
||||
void esp_get_tx_power(uint8_t *tx_power);
|
||||
void esp_supplicant_common_init(struct wpa_funcs *wpa_cb);
|
||||
#else
|
||||
|
||||
#include "esp_rrm.h"
|
||||
#include "esp_wnm.h"
|
||||
|
||||
static inline void esp_set_rm_enabled_ie(void) {}
|
||||
static inline int esp_ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender,
|
||||
u32 rssi, u8 channel, u64 current_tsf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb,
|
||||
void *cb_ctx)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason,
|
||||
const char *btm_candidates,
|
||||
int cand_list)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,661 +0,0 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_dpp_i.h"
|
||||
#include "esp_dpp.h"
|
||||
#include "esp_wpa.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
|
||||
static void *s_dpp_task_hdl = NULL;
|
||||
static void *s_dpp_evt_queue = NULL;
|
||||
static void *s_dpp_api_lock = NULL;
|
||||
|
||||
static bool s_dpp_stop_listening;
|
||||
static int s_dpp_auth_retries;
|
||||
struct esp_dpp_context_t s_dpp_ctx;
|
||||
static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action;
|
||||
|
||||
#define DPP_API_LOCK() xSemaphoreTakeRecursive(s_dpp_api_lock, portMAX_DELAY)
|
||||
#define DPP_API_UNLOCK() xSemaphoreGiveRecursive(s_dpp_api_lock)
|
||||
|
||||
struct action_rx_param {
|
||||
u8 sa[ETH_ALEN];
|
||||
u32 channel;
|
||||
u32 frm_len;
|
||||
u32 vendor_data_len;
|
||||
struct ieee80211_action *action_frm;
|
||||
};
|
||||
|
||||
static int esp_dpp_post_evt(uint32_t evt_id, uint32_t data)
|
||||
{
|
||||
DPP_API_LOCK();
|
||||
|
||||
dpp_event_t *evt = os_zalloc(sizeof(dpp_event_t));
|
||||
if (evt == NULL) {
|
||||
DPP_API_UNLOCK();
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
evt->id = evt_id;
|
||||
evt->data = data;
|
||||
if ( xQueueSend(s_dpp_evt_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) {
|
||||
DPP_API_UNLOCK();
|
||||
os_free(evt);
|
||||
return ESP_ERR_DPP_FAILURE;
|
||||
}
|
||||
DPP_API_UNLOCK();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void esp_dpp_call_cb(esp_supp_dpp_event_t evt, void *data)
|
||||
{
|
||||
s_dpp_ctx.dpp_event_cb(evt, data);
|
||||
}
|
||||
|
||||
void esp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len,
|
||||
uint8_t channel, uint32_t wait_time_ms)
|
||||
{
|
||||
wifi_action_tx_req_t *req = os_zalloc(sizeof(*req) + len);;
|
||||
if (!req) {
|
||||
return;
|
||||
}
|
||||
|
||||
req->ifx = ESP_IF_WIFI_STA;
|
||||
memcpy(req->dest_mac, dest_mac, ETH_ALEN);
|
||||
req->no_ack = false;
|
||||
req->data_len = len;
|
||||
req->rx_cb = s_action_rx_cb;
|
||||
memcpy(req->data, buf, req->data_len);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: Mgmt Tx - MAC:" MACSTR ", Channel-%d, WaitT-%d",
|
||||
MAC2STR(dest_mac), channel, wait_time_ms);
|
||||
|
||||
if (ESP_OK != esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_REQ, channel,
|
||||
wait_time_ms, req)) {
|
||||
wpa_printf(MSG_ERROR, "DPP: Failed to perfrm offchannel operation");
|
||||
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
|
||||
os_free(req);
|
||||
return;
|
||||
}
|
||||
|
||||
os_free(req);
|
||||
}
|
||||
|
||||
static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_data)
|
||||
{
|
||||
size_t len = rx_param->vendor_data_len - 2;
|
||||
const u8 *r_bootstrap, *i_bootstrap;
|
||||
u16 r_bootstrap_len, i_bootstrap_len;
|
||||
struct dpp_bootstrap_info *own_bi;
|
||||
int rc;
|
||||
|
||||
wpa_printf(MSG_INFO, "DPP: Authentication Request from " MACSTR, MAC2STR(rx_param->sa));
|
||||
|
||||
r_bootstrap = dpp_get_attr(dpp_data, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
|
||||
&r_bootstrap_len);
|
||||
if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
|
||||
wpa_printf(MSG_INFO, "DPP: Missing or invalid Responder Bootstrapping Key Hash attribute");
|
||||
rc = ESP_ERR_DPP_INVALID_ATTR;
|
||||
goto fail;
|
||||
}
|
||||
wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash", r_bootstrap, r_bootstrap_len);
|
||||
|
||||
i_bootstrap = dpp_get_attr(dpp_data, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
|
||||
&i_bootstrap_len);
|
||||
if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
|
||||
wpa_printf(MSG_INFO, "DPP: Missing or invalid Initiator Bootstrapping Key Hash attribute");
|
||||
rc = ESP_ERR_DPP_INVALID_ATTR;
|
||||
goto fail;
|
||||
}
|
||||
wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash", i_bootstrap, i_bootstrap_len);
|
||||
|
||||
own_bi = dpp_bootstrap_get_id(s_dpp_ctx.dpp_global, s_dpp_ctx.id);
|
||||
/* Try to find own and peer bootstrapping key matches based on the
|
||||
* received hash values */
|
||||
if (os_memcmp(own_bi->pubkey_hash, r_bootstrap, SHA256_MAC_LEN)) {
|
||||
wpa_printf(MSG_INFO, "DPP: No matching own bootstrapping key found as responder - ignore message");
|
||||
rc = ESP_ERR_DPP_INVALID_ATTR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
s_dpp_ctx.dpp_auth = dpp_auth_req_rx(NULL, DPP_CAPAB_ENROLLEE, 0, NULL,
|
||||
own_bi, rx_param->channel,
|
||||
(const u8 *)&rx_param->action_frm->u.public_action.v, dpp_data, len);
|
||||
os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN);
|
||||
|
||||
esp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg),
|
||||
wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg),
|
||||
rx_param->channel, OFFCHAN_TX_WAIT_TIME);
|
||||
return;
|
||||
fail:
|
||||
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)rc);
|
||||
}
|
||||
|
||||
static void gas_query_req_tx(struct dpp_authentication *auth)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
int supp_op_classes[] = {81, 0};
|
||||
|
||||
buf = dpp_build_conf_req_helper(auth, NULL, 0, NULL,
|
||||
supp_op_classes);
|
||||
if (!buf) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: No configuration request data available");
|
||||
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (chan %u)",
|
||||
MAC2STR(auth->peer_mac_addr), auth->curr_chan);
|
||||
|
||||
esp_send_action_frame(auth->peer_mac_addr, wpabuf_head(buf), wpabuf_len(buf),
|
||||
auth->curr_chan, OFFCHAN_TX_WAIT_TIME);
|
||||
}
|
||||
|
||||
static int esp_dpp_handle_config_obj(struct dpp_authentication *auth,
|
||||
struct dpp_config_obj *conf)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = &s_dpp_ctx.wifi_cfg;
|
||||
|
||||
if (conf->ssid_len) {
|
||||
os_memcpy(wifi_cfg->sta.ssid, conf->ssid, conf->ssid_len);
|
||||
}
|
||||
|
||||
if (dpp_akm_legacy(conf->akm)) {
|
||||
if (conf->passphrase[0])
|
||||
os_memcpy(wifi_cfg->sta.password, conf->passphrase,
|
||||
sizeof(wifi_cfg->sta.password));
|
||||
if (conf->akm == DPP_AKM_PSK_SAE) {
|
||||
wifi_cfg->sta.pmf_cfg.capable = true;
|
||||
wifi_cfg->sta.pmf_cfg.required = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->connector) {
|
||||
/* TODO: Save the Connector and consider using a command
|
||||
* to fetch the value instead of sending an event with
|
||||
* it. The Connector could end up being larger than what
|
||||
* most clients are ready to receive as an event
|
||||
* message. */
|
||||
wpa_printf(MSG_INFO, DPP_EVENT_CONNECTOR "%s",
|
||||
conf->connector);
|
||||
}
|
||||
s_dpp_stop_listening = false;
|
||||
esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_CANCEL, 0, 0, NULL);
|
||||
esp_dpp_call_cb(ESP_SUPP_DPP_CFG_RECVD, wifi_cfg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void esp_dpp_rx_auth_conf(struct action_rx_param *rx_param, uint8_t *dpp_data)
|
||||
{
|
||||
struct dpp_authentication *auth = s_dpp_ctx.dpp_auth;
|
||||
struct ieee80211_public_action *public_action =
|
||||
&rx_param->action_frm->u.public_action;
|
||||
size_t len = rx_param->vendor_data_len - 2;
|
||||
int rc;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
|
||||
MAC2STR(rx_param->sa));
|
||||
|
||||
if (!auth) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: No DPP Authentication in progress - drop");
|
||||
rc = ESP_ERR_DPP_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (os_memcmp(rx_param->sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
|
||||
MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
|
||||
rc = ESP_ERR_DPP_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (dpp_auth_conf_rx(auth, (const u8 *)&public_action->v,
|
||||
dpp_data, len) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
|
||||
rc = ESP_ERR_DPP_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Send GAS Query Req */
|
||||
gas_query_req_tx(auth);
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)rc);
|
||||
}
|
||||
|
||||
static void esp_dpp_rx_auth(struct action_rx_param *rx_param)
|
||||
{
|
||||
uint8_t crypto_suit, type;
|
||||
uint8_t *tmp;
|
||||
|
||||
tmp = rx_param->action_frm->u.public_action.v.pa_vendor_spec.vendor_data;
|
||||
crypto_suit = tmp[0];
|
||||
type = tmp[1];
|
||||
|
||||
if (crypto_suit != 1) {
|
||||
wpa_printf(MSG_ERROR, "DPP: Unsupported crypto suit");
|
||||
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case DPP_PA_AUTHENTICATION_REQ:
|
||||
esp_dpp_rx_auth_req(rx_param, &tmp[2]);
|
||||
break;
|
||||
case DPP_PA_AUTHENTICATION_CONF:
|
||||
esp_dpp_rx_auth_conf(rx_param, &tmp[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gas_query_resp_rx(struct action_rx_param *rx_param)
|
||||
{
|
||||
struct dpp_authentication *auth = s_dpp_ctx.dpp_auth;
|
||||
uint8_t *pos = rx_param->action_frm->u.public_action.v.pa_gas_resp.data;
|
||||
uint8_t *resp = &pos[10];
|
||||
int i, res;
|
||||
|
||||
if (pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 &&
|
||||
WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1) {
|
||||
if (dpp_conf_resp_rx(auth, resp, rx_param->vendor_data_len - 2) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < auth->num_conf_obj; i++) {
|
||||
res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[i]);
|
||||
if (res < 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
fail:
|
||||
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE);
|
||||
}
|
||||
|
||||
static void esp_dpp_rx_action(struct action_rx_param *rx_param)
|
||||
{
|
||||
if (rx_param->action_frm->category == WLAN_ACTION_PUBLIC) {
|
||||
struct ieee80211_public_action *public_action =
|
||||
&rx_param->action_frm->u.public_action;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: Rx Public Action frame: action - %d",
|
||||
public_action->action);
|
||||
|
||||
if (public_action->action == WLAN_PA_VENDOR_SPECIFIC &&
|
||||
WPA_GET_BE24(public_action->v.pa_vendor_spec.oui) == OUI_WFA &&
|
||||
public_action->v.pa_vendor_spec.wfa_stype == DPP_OUI_TYPE) {
|
||||
|
||||
rx_param->vendor_data_len = rx_param->frm_len -
|
||||
(size_t)(public_action->v.pa_vendor_spec.vendor_data -
|
||||
(u8 *)rx_param->action_frm);
|
||||
|
||||
if (!s_dpp_stop_listening) {
|
||||
esp_supp_dpp_stop_listen();
|
||||
}
|
||||
|
||||
esp_dpp_rx_auth(rx_param);
|
||||
} else if (public_action->action == WLAN_PA_GAS_INITIAL_RESP &&
|
||||
public_action->v.pa_gas_resp.type == WLAN_EID_ADV_PROTO &&
|
||||
public_action->v.pa_gas_resp.length == 8 &&
|
||||
public_action->v.pa_gas_resp.status_code == 0) {
|
||||
|
||||
rx_param->vendor_data_len = rx_param->frm_len -
|
||||
(size_t)(public_action->v.pa_gas_resp.data +
|
||||
public_action->v.pa_gas_resp.length -
|
||||
(u8 *)rx_param->action_frm);
|
||||
|
||||
gas_query_resp_rx(rx_param);
|
||||
}
|
||||
}
|
||||
|
||||
os_free(rx_param->action_frm);
|
||||
os_free(rx_param);
|
||||
}
|
||||
|
||||
static void esp_dpp_task(void *pvParameters )
|
||||
{
|
||||
dpp_event_t *evt;
|
||||
bool task_del = false;
|
||||
|
||||
for (;;) {
|
||||
if (xQueueReceive(s_dpp_evt_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt->id < SIG_DPP_MAX) {
|
||||
DPP_API_LOCK();
|
||||
} else {
|
||||
os_free(evt);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (evt->id) {
|
||||
case SIG_DPP_DEL_TASK:
|
||||
task_del = true;
|
||||
break;
|
||||
|
||||
case SIG_DPP_BOOTSTRAP_GEN: {
|
||||
char *command = (char *)evt->data;
|
||||
const char *uri;
|
||||
|
||||
s_dpp_ctx.id = dpp_bootstrap_gen(s_dpp_ctx.dpp_global, command);
|
||||
uri = dpp_bootstrap_get_uri(s_dpp_ctx.dpp_global, s_dpp_ctx.id);
|
||||
|
||||
esp_dpp_call_cb(ESP_SUPP_DPP_URI_READY, (void *)uri);
|
||||
os_free(command);
|
||||
}
|
||||
break;
|
||||
|
||||
case SIG_DPP_RX_ACTION: {
|
||||
esp_dpp_rx_action((struct action_rx_param *)evt->data);
|
||||
}
|
||||
break;
|
||||
|
||||
case SIG_DPP_LISTEN_NEXT_CHANNEL: {
|
||||
struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params;
|
||||
static int counter;
|
||||
int channel;
|
||||
|
||||
channel = p->chan_list[counter++ % p->num_chan];
|
||||
esp_wifi_remain_on_channel(ESP_IF_WIFI_STA, WIFI_ROC_REQ, channel,
|
||||
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
os_free(evt);
|
||||
DPP_API_UNLOCK();
|
||||
|
||||
if (task_del) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vQueueDelete(s_dpp_evt_queue);
|
||||
s_dpp_evt_queue = NULL;
|
||||
|
||||
if (s_dpp_api_lock) {
|
||||
vSemaphoreDelete(s_dpp_api_lock);
|
||||
s_dpp_api_lock = NULL;
|
||||
}
|
||||
|
||||
/* At this point, we completed */
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel)
|
||||
{
|
||||
struct ieee80211_hdr *rx_hdr = (struct ieee80211_hdr *)hdr;
|
||||
struct action_rx_param *rx_param;
|
||||
int ret = ESP_ERR_NOT_SUPPORTED;
|
||||
|
||||
if (WLAN_FC_GET_STYPE(rx_hdr->frame_control) == WLAN_FC_STYPE_ACTION) {
|
||||
rx_param = os_zalloc(sizeof(struct action_rx_param));
|
||||
if (!rx_param) {
|
||||
wpa_printf(MSG_ERROR, "Failed to allocate memory for Rx Action");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
os_memcpy(rx_param->sa, rx_hdr->addr2, ETH_ALEN);
|
||||
rx_param->channel = channel;
|
||||
rx_param->action_frm = os_zalloc(len);
|
||||
if (!rx_param->action_frm) {
|
||||
wpa_printf(MSG_ERROR, "Failed to allocate memory for Rx Action");
|
||||
os_free(rx_param);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
rx_param->frm_len = len;
|
||||
os_memcpy(rx_param->action_frm, payload, len);
|
||||
|
||||
ret = esp_dpp_post_evt(SIG_DPP_RX_ACTION, (u32)rx_param);
|
||||
if (ESP_OK != ret) {
|
||||
wpa_printf(MSG_ERROR, "Failed to post event to DPP Task(status=%d)", ret);
|
||||
os_free(rx_param->action_frm);
|
||||
os_free(rx_param);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void offchan_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
if (event_id == WIFI_EVENT_ACTION_TX_STATUS) {
|
||||
wifi_event_action_tx_status_t *evt =
|
||||
(wifi_event_action_tx_status_t *)event_data;
|
||||
wpa_printf(MSG_DEBUG, "Mgmt Tx Status - %d, Cookie - 0x%x",
|
||||
evt->status, (uint32_t)evt->context);
|
||||
|
||||
if (evt->status) {
|
||||
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
|
||||
}
|
||||
|
||||
} else if (event_id == WIFI_EVENT_ROC_DONE) {
|
||||
wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data;
|
||||
|
||||
if (!s_dpp_stop_listening && evt->context == (uint32_t)s_action_rx_cb) {
|
||||
esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *esp_dpp_parse_chan_list(const char *chan_list)
|
||||
{
|
||||
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
|
||||
char *uri_channels = os_zalloc(14 * 6 + 1);
|
||||
const char *pos = chan_list;
|
||||
const char *pos2;
|
||||
char *pos3 = uri_channels;
|
||||
params->num_chan = 0;
|
||||
|
||||
os_memcpy(pos3, " chan=", strlen(" chan="));
|
||||
pos3 += strlen(" chan=");
|
||||
|
||||
while (pos && *pos) {
|
||||
int channel;
|
||||
int len = strlen(chan_list);
|
||||
|
||||
pos2 = pos;
|
||||
while (*pos2 >= '0' && *pos2 <= '9') {
|
||||
pos2++;
|
||||
}
|
||||
if (*pos2 == ',' || *pos2 == ' ' || *pos2 == '\0') {
|
||||
channel = atoi(pos);
|
||||
if (channel < 1 || channel > 14) {
|
||||
os_free(uri_channels);
|
||||
return NULL;
|
||||
}
|
||||
params->chan_list[params->num_chan++] = channel;
|
||||
os_memcpy(pos3, "81/", strlen("81/"));
|
||||
pos3 += strlen("81/");
|
||||
os_memcpy(pos3, pos, (pos2 - pos));
|
||||
pos3 += (pos2 - pos);
|
||||
*pos3++ = ',';
|
||||
|
||||
pos = pos2 + 1;
|
||||
}
|
||||
while (*pos == ',' || *pos == ' ' || *pos == '\0') {
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (((int)(pos - chan_list) >= len)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(pos3 - 1) = ' ';
|
||||
|
||||
return uri_channels;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type,
|
||||
const char *key, const char *uri_info)
|
||||
{
|
||||
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
|
||||
char *uri_chan_list = esp_dpp_parse_chan_list(chan_list);
|
||||
char *command = os_zalloc(1200);
|
||||
int ret;
|
||||
|
||||
if (!uri_chan_list || !command || params->num_chan >= 14 || params->num_chan == 0) {
|
||||
wpa_printf(MSG_ERROR, "Invalid Channel list - %s", chan_list);
|
||||
if (command) {
|
||||
os_free(command);
|
||||
}
|
||||
ret = ESP_ERR_DPP_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (type != DPP_BOOTSTRAP_QR_CODE) {
|
||||
wpa_printf(MSG_INFO, "Bootstrap type %d not supported", type);
|
||||
os_free(command);
|
||||
ret = ESP_ERR_NOT_SUPPORTED;
|
||||
goto fail;
|
||||
}
|
||||
params->type = type;
|
||||
esp_wifi_get_mac(ESP_IF_WIFI_STA, params->mac);
|
||||
|
||||
if (uri_info) {
|
||||
params->info_len = strlen(uri_info);
|
||||
if (params->info_len) {
|
||||
params->info = os_zalloc(params->info_len + 1);
|
||||
if (!params->info) {
|
||||
os_free(command);
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto fail;
|
||||
}
|
||||
os_memcpy(params->info, uri_info, params->info_len);
|
||||
}
|
||||
}
|
||||
|
||||
if (key) {
|
||||
params->key_len = strlen(key);
|
||||
if (params->key_len) {
|
||||
char prefix[] = "30310201010420";
|
||||
char postfix[] = "a00a06082a8648ce3d030107";
|
||||
|
||||
params->key = os_zalloc(params->key_len +
|
||||
sizeof(prefix) + sizeof(postfix));
|
||||
if (!params->key) {
|
||||
os_free(command);
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto fail;
|
||||
}
|
||||
sprintf(params->key, "%s%s%s", prefix, key, postfix);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(command, "type=qrcode mac=" MACSTR "%s%s%s%s%s",
|
||||
MAC2STR(params->mac), uri_chan_list,
|
||||
params->key_len ? "key=" : "",
|
||||
params->key_len ? params->key : "",
|
||||
params->info_len ? " info=" : "",
|
||||
params->info_len ? params->info : "");
|
||||
|
||||
ret = esp_dpp_post_evt(SIG_DPP_BOOTSTRAP_GEN, (u32)command);
|
||||
if (ret != ESP_OK) {
|
||||
os_free(command);
|
||||
if (params->info) {
|
||||
os_free(params->info);
|
||||
params->info = NULL;
|
||||
}
|
||||
if (params->key) {
|
||||
os_free(params->key);
|
||||
params->key = NULL;
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = ESP_OK;
|
||||
fail:
|
||||
if (uri_chan_list) {
|
||||
os_free(uri_chan_list);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_supp_dpp_start_listen(void)
|
||||
{
|
||||
if (esp_wifi_get_user_init_flag_internal() == 0) {
|
||||
wpa_printf(MSG_ERROR, "DPP: ROC not possible before wifi is started");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
|
||||
}
|
||||
|
||||
void esp_supp_dpp_stop_listen(void)
|
||||
{
|
||||
s_dpp_stop_listening = true;
|
||||
esp_wifi_remain_on_channel(ESP_IF_WIFI_STA, WIFI_ROC_CANCEL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb)
|
||||
{
|
||||
struct dpp_global_config cfg = {0};
|
||||
|
||||
os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx));
|
||||
s_dpp_ctx.dpp_event_cb = cb;
|
||||
|
||||
cfg.cb_ctx = &s_dpp_ctx;
|
||||
cfg.msg_ctx = &s_dpp_ctx;
|
||||
s_dpp_ctx.dpp_global = dpp_global_init(&cfg);
|
||||
|
||||
s_dpp_stop_listening = false;
|
||||
s_dpp_evt_queue = xQueueCreate(3, sizeof(dpp_event_t));
|
||||
xTaskCreate(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 2, s_dpp_task_hdl);
|
||||
|
||||
s_dpp_api_lock = xSemaphoreCreateRecursiveMutex();
|
||||
if (!s_dpp_api_lock) {
|
||||
wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API lock");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS,
|
||||
&offchan_event_handler, NULL);
|
||||
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ROC_DONE,
|
||||
&offchan_event_handler, NULL);
|
||||
|
||||
wpa_printf(MSG_INFO, "esp_dpp_task prio:%d, stack:%d\n", 2, DPP_TASK_STACK_SIZE);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_supp_dpp_deinit(void)
|
||||
{
|
||||
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
|
||||
|
||||
if (params->info) {
|
||||
os_free(params->info);
|
||||
params->info = NULL;
|
||||
}
|
||||
if (params->key) {
|
||||
os_free(params->key);
|
||||
params->key = NULL;
|
||||
}
|
||||
|
||||
s_dpp_auth_retries = 0;
|
||||
dpp_global_deinit(s_dpp_ctx.dpp_global);
|
||||
esp_dpp_post_evt(SIG_DPP_DEL_TASK, 0);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
#ifndef ESP_DPP_I_H
|
||||
#define ESP_DPP_I_H
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
|
||||
#include "common/dpp.h"
|
||||
#include "esp_dpp.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
|
||||
#define DPP_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD)
|
||||
|
||||
enum SIG_DPP {
|
||||
SIG_DPP_RESET = 0,
|
||||
SIG_DPP_BOOTSTRAP_GEN,
|
||||
SIG_DPP_RX_ACTION,
|
||||
SIG_DPP_LISTEN_NEXT_CHANNEL,
|
||||
SIG_DPP_DEL_TASK,
|
||||
SIG_DPP_MAX,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
uint32_t data;
|
||||
} dpp_event_t;
|
||||
|
||||
#define BOOTSTRAP_ROC_WAIT_TIME 500
|
||||
#define OFFCHAN_TX_WAIT_TIME 500
|
||||
|
||||
struct dpp_bootstrap_params_t {
|
||||
enum dpp_bootstrap_type type;
|
||||
uint8_t chan_list[14];
|
||||
uint8_t num_chan;
|
||||
uint8_t mac[6];
|
||||
uint32_t key_len;
|
||||
char *key;
|
||||
uint32_t info_len;
|
||||
char *info;
|
||||
};
|
||||
|
||||
struct esp_dpp_context_t {
|
||||
struct dpp_bootstrap_params_t bootstrap_params;
|
||||
struct dpp_authentication *dpp_auth;
|
||||
int gas_dialog_token;
|
||||
esp_supp_dpp_event_cb_t dpp_event_cb;
|
||||
struct dpp_global *dpp_global;
|
||||
wifi_config_t wifi_cfg;
|
||||
int id;
|
||||
};
|
||||
|
||||
int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel);
|
||||
|
||||
#endif /* ESP_DPP_I_H */
|
||||
@@ -1,158 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/eapol_common.h"
|
||||
#include "ap/wpa_auth.h"
|
||||
#include "ap/ap_config.h"
|
||||
#include "utils/wpa_debug.h"
|
||||
#include "ap/hostapd.h"
|
||||
#include "ap/wpa_auth_i.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "esp_wifi_types.h"
|
||||
|
||||
void *hostap_init(void)
|
||||
{
|
||||
struct wifi_ssid *ssid = esp_wifi_ap_get_prof_ap_ssid_internal();
|
||||
struct hostapd_data *hapd = NULL;
|
||||
struct wpa_auth_config *auth_conf;
|
||||
u8 mac[6];
|
||||
u16 spp_attrubute = 0;
|
||||
u8 pairwise_cipher;
|
||||
|
||||
hapd = (struct hostapd_data *)os_zalloc(sizeof(struct hostapd_data));
|
||||
|
||||
if (hapd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hapd->conf = (struct hostapd_bss_config *)os_zalloc(sizeof(struct hostapd_bss_config));
|
||||
|
||||
if (hapd->conf == NULL) {
|
||||
os_free(hapd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auth_conf = (struct wpa_auth_config *)os_zalloc(sizeof(struct wpa_auth_config));
|
||||
|
||||
if (auth_conf == NULL) {
|
||||
os_free(hapd->conf);
|
||||
os_free(hapd);
|
||||
hapd = NULL;
|
||||
return NULL;
|
||||
}
|
||||
if (esp_wifi_ap_get_prof_authmode_internal() == WIFI_AUTH_WPA_PSK) {
|
||||
auth_conf->wpa = WPA_PROTO_WPA;
|
||||
}
|
||||
if (esp_wifi_ap_get_prof_authmode_internal() == WIFI_AUTH_WPA2_PSK) {
|
||||
auth_conf->wpa = WPA_PROTO_RSN;
|
||||
}
|
||||
if (esp_wifi_ap_get_prof_authmode_internal() == WIFI_AUTH_WPA_WPA2_PSK) {
|
||||
auth_conf->wpa = WPA_PROTO_RSN | WPA_PROTO_WPA;
|
||||
}
|
||||
|
||||
pairwise_cipher = esp_wifi_ap_get_prof_pairwise_cipher_internal();
|
||||
/* TKIP is compulsory in WPA Mode */
|
||||
if (auth_conf->wpa == WPA_PROTO_WPA && pairwise_cipher == WIFI_CIPHER_TYPE_CCMP) {
|
||||
pairwise_cipher = WIFI_CIPHER_TYPE_TKIP_CCMP;
|
||||
}
|
||||
if (pairwise_cipher == WIFI_CIPHER_TYPE_TKIP) {
|
||||
auth_conf->wpa_group = WPA_CIPHER_TKIP;
|
||||
auth_conf->wpa_pairwise = WPA_CIPHER_TKIP;
|
||||
auth_conf->rsn_pairwise = WPA_CIPHER_TKIP;
|
||||
} else if (pairwise_cipher == WIFI_CIPHER_TYPE_CCMP) {
|
||||
auth_conf->wpa_group = WPA_CIPHER_CCMP;
|
||||
auth_conf->wpa_pairwise = WPA_CIPHER_CCMP;
|
||||
auth_conf->rsn_pairwise = WPA_CIPHER_CCMP;
|
||||
} else {
|
||||
auth_conf->wpa_group = WPA_CIPHER_TKIP;
|
||||
auth_conf->wpa_pairwise = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP;
|
||||
auth_conf->rsn_pairwise = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP;
|
||||
}
|
||||
|
||||
auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
|
||||
auth_conf->eapol_version = EAPOL_VERSION;
|
||||
|
||||
spp_attrubute = esp_wifi_get_spp_attrubute_internal(WIFI_IF_AP);
|
||||
auth_conf->spp_sup.capable = ((spp_attrubute & WPA_CAPABILITY_SPP_CAPABLE) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_CAP_DISABLE);
|
||||
auth_conf->spp_sup.require = ((spp_attrubute & WPA_CAPABILITY_SPP_REQUIRED) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_REQ_DISABLE);
|
||||
|
||||
memcpy(hapd->conf->ssid.ssid, ssid->ssid, ssid->len);
|
||||
hapd->conf->ssid.ssid_len = ssid->len;
|
||||
hapd->conf->ssid.wpa_passphrase = (char *)os_zalloc(64);
|
||||
if (hapd->conf->ssid.wpa_passphrase == NULL) {
|
||||
os_free(auth_conf);
|
||||
os_free(hapd->conf);
|
||||
os_free(hapd);
|
||||
hapd = NULL;
|
||||
return NULL;
|
||||
}
|
||||
memcpy(hapd->conf->ssid.wpa_passphrase, esp_wifi_ap_get_prof_password_internal(), strlen((char *)esp_wifi_ap_get_prof_password_internal()));
|
||||
|
||||
hapd->conf->ap_max_inactivity = 5 * 60;
|
||||
hostapd_setup_wpa_psk(hapd->conf);
|
||||
|
||||
esp_wifi_get_macaddr_internal(WIFI_IF_AP, mac);
|
||||
|
||||
hapd->wpa_auth = wpa_init(mac, auth_conf, NULL);
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_WPA, hapd->wpa_auth->wpa_ie, (uint16_t)hapd->wpa_auth->wpa_ie_len, 0);
|
||||
os_free(auth_conf);
|
||||
|
||||
return (void *)hapd;
|
||||
}
|
||||
|
||||
bool hostap_deinit(void *data)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *)data;
|
||||
|
||||
if (hapd == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hapd->wpa_auth->wpa_ie != NULL) {
|
||||
os_free(hapd->wpa_auth->wpa_ie);
|
||||
}
|
||||
|
||||
if (hapd->wpa_auth->group != NULL) {
|
||||
os_free(hapd->wpa_auth->group);
|
||||
}
|
||||
|
||||
if (hapd->wpa_auth != NULL) {
|
||||
os_free(hapd->wpa_auth);
|
||||
}
|
||||
|
||||
if (hapd->conf->ssid.wpa_psk != NULL) {
|
||||
os_free(hapd->conf->ssid.wpa_psk);
|
||||
}
|
||||
|
||||
if (hapd->conf->ssid.wpa_passphrase != NULL) {
|
||||
os_free(hapd->conf->ssid.wpa_passphrase);
|
||||
}
|
||||
|
||||
if (hapd->conf != NULL) {
|
||||
os_free(hapd->conf);
|
||||
}
|
||||
|
||||
if (hapd != NULL) {
|
||||
os_free(hapd);
|
||||
}
|
||||
|
||||
esp_wifi_unset_appie_internal(WIFI_APPIE_WPA);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ESP_HOSTAP_H
|
||||
#define ESP_HOSTAP_H
|
||||
|
||||
void *hostap_init(void);
|
||||
bool hostap_deinit(void *data);
|
||||
|
||||
#endif /* ESP_HOSTAP_H */
|
||||
@@ -1,271 +0,0 @@
|
||||
/**
|
||||
* Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/wpa_supplicant_i.h"
|
||||
#include "utils/wpa_debug.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "esp_wifi_types.h"
|
||||
#include "drivers/driver.h"
|
||||
#include "common/scan.h"
|
||||
#include "common/bss.h"
|
||||
#include "common/rrm.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "esp_supplicant/esp_common_i.h"
|
||||
#include "common/wnm_sta.h"
|
||||
|
||||
extern struct wpa_supplicant g_wpa_supp;
|
||||
|
||||
static void esp_scan_done_event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = &g_wpa_supp;
|
||||
if (!wpa_s->scanning) {
|
||||
/* update last scan time */
|
||||
wpa_s->scan_start_tsf = esp_wifi_get_tsf_time(WIFI_IF_STA);
|
||||
wpa_printf(MSG_DEBUG, "scan not triggered by supplicant, ignore");
|
||||
return;
|
||||
}
|
||||
wpa_s->type &= ~(1 << WLAN_FC_STYPE_BEACON) & ~(1 << WLAN_FC_STYPE_PROBE_RESP);
|
||||
esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype);
|
||||
esp_supplicant_post_evt(SIG_SUPPLICANT_SCAN_DONE, 0);
|
||||
|
||||
}
|
||||
|
||||
static void esp_supp_handle_wnm_scan_done(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
struct wpa_bss *bss = wpa_bss_get_next_bss(wpa_s, wpa_s->current_bss);
|
||||
|
||||
if (wpa_s->wnm_neighbor_report_elements) {
|
||||
wnm_scan_process(wpa_s, 1);
|
||||
} else if (wpa_s->wnm_dissoc_timer) {
|
||||
if (wpa_s->num_bss == 1) {
|
||||
wpa_printf(MSG_INFO, "not able to find another candidate, do nothing");
|
||||
return;
|
||||
}
|
||||
/* this is a already matched bss */
|
||||
if (bss) {
|
||||
wnm_bss_tm_connect(wpa_s, bss, NULL, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_supp_scan_done_cleanup(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
uint16_t number = 1;
|
||||
wifi_ap_record_t ap_records;
|
||||
|
||||
wpa_s->scanning = 0;
|
||||
wpa_s->scan_reason = 0;
|
||||
/* clean scan list from net80211 */
|
||||
esp_wifi_scan_get_ap_records(&number, &ap_records);
|
||||
}
|
||||
|
||||
void esp_supplicant_handle_scan_done_evt(void)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = &g_wpa_supp;
|
||||
|
||||
wpa_printf(MSG_INFO, "scan done received");
|
||||
/* Check which module started this, call the respective function */
|
||||
if (wpa_s->scan_reason == REASON_RRM_BEACON_REPORT) {
|
||||
wpas_beacon_rep_scan_process(wpa_s, wpa_s->scan_start_tsf);
|
||||
} else if (wpa_s->scan_reason == REASON_WNM_BSS_TRANS_REQ) {
|
||||
esp_supp_handle_wnm_scan_done(wpa_s);
|
||||
}
|
||||
esp_supp_scan_done_cleanup(wpa_s);
|
||||
wpa_bss_update_end(wpa_s);
|
||||
#ifndef SCAN_CACHE_SUPPORTED
|
||||
wpa_bss_flush(wpa_s);
|
||||
#endif
|
||||
}
|
||||
|
||||
void esp_scan_init(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
wpa_s->scanning = 0;
|
||||
wpa_bss_init(wpa_s);
|
||||
wpa_s->last_scan_res = NULL;
|
||||
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_SCAN_DONE,
|
||||
&esp_scan_done_event_handler, NULL);
|
||||
}
|
||||
|
||||
void esp_scan_deinit(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
wpa_bss_deinit(wpa_s);
|
||||
}
|
||||
|
||||
int esp_handle_beacon_probe(u8 type, u8 *frame, size_t len, u8 *sender,
|
||||
u32 rssi, u8 channel, u64 current_tsf)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = &g_wpa_supp;
|
||||
struct os_reltime now;
|
||||
struct wpa_scan_res *res;
|
||||
u8 *ptr;
|
||||
|
||||
if (len < 12) {
|
||||
wpa_printf(MSG_ERROR, "beacon/probe is having short len=%d\n", len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = os_zalloc(sizeof(struct wpa_scan_res) + len - 12);
|
||||
if (!res) {
|
||||
wpa_printf(MSG_ERROR, "failed to allocate memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = (u8 *)res;
|
||||
os_get_time(&now);
|
||||
os_memcpy(res->bssid, sender, ETH_ALEN);
|
||||
res->tsf = WPA_GET_LE64(frame);
|
||||
frame += 8;
|
||||
len -= 8;
|
||||
|
||||
if ((wpa_s->scan_start_tsf == 0) &&
|
||||
wpa_s->current_bss &&
|
||||
(os_memcmp(wpa_s->current_bss, sender, ETH_ALEN) == 0)) {
|
||||
wpa_s->scan_start_tsf = res->tsf;
|
||||
os_memcpy(wpa_s->tsf_bssid, sender, ETH_ALEN);
|
||||
}
|
||||
res->beacon_int = WPA_GET_LE16(frame);
|
||||
|
||||
frame += 2;
|
||||
len -= 2;
|
||||
res->caps = WPA_GET_LE16(frame);
|
||||
frame += 2;
|
||||
len -= 2;
|
||||
|
||||
res->chan = channel;
|
||||
res->noise = 0;
|
||||
res->level = rssi;
|
||||
os_memcpy(res->tsf_bssid, wpa_s->tsf_bssid, ETH_ALEN);
|
||||
res->parent_tsf = current_tsf - wpa_s->scan_start_tsf;
|
||||
if (type == WLAN_FC_STYPE_PROBE_RESP)
|
||||
res->ie_len = len;
|
||||
else if (type == WLAN_FC_STYPE_BEACON)
|
||||
res->beacon_ie_len = len;
|
||||
|
||||
ptr += sizeof(struct wpa_scan_res);
|
||||
|
||||
/* update rest of the frame */
|
||||
os_memcpy(ptr, frame, len);
|
||||
wpa_bss_update_scan_res(wpa_s, res, &now);
|
||||
os_free(res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int esp_issue_scan(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_driver_scan_params *scan_params)
|
||||
{
|
||||
wifi_scan_config_t *params = NULL;
|
||||
int ret = 0;
|
||||
u64 scan_start_tsf = esp_wifi_get_tsf_time(WIFI_IF_STA);
|
||||
|
||||
/* TODO: Directly try to connect if scan results are recent */
|
||||
if ((scan_start_tsf - wpa_s->scan_start_tsf) > 100000) {
|
||||
wpa_printf(MSG_DEBUG, "flushing old scan cache %llu",
|
||||
(scan_start_tsf - wpa_s->scan_start_tsf));
|
||||
wpa_bss_flush(wpa_s);
|
||||
}
|
||||
|
||||
esp_wifi_get_macaddr_internal(WIFI_IF_STA, wpa_s->tsf_bssid);
|
||||
|
||||
if (scan_params) {
|
||||
params = os_zalloc(sizeof(wifi_scan_config_t));
|
||||
if (!params) {
|
||||
wpa_printf(MSG_ERROR, "failed to allocate memory");
|
||||
return -1;
|
||||
}
|
||||
if (scan_params->num_ssids) {
|
||||
params->ssid = os_zalloc(scan_params->ssids[0].ssid_len + 1);
|
||||
if (!params->ssid) {
|
||||
wpa_printf(MSG_ERROR, "failed to allocate memory");
|
||||
return -1;
|
||||
}
|
||||
os_memcpy(params->ssid, scan_params->ssids[0].ssid, scan_params->ssids[0].ssid_len);
|
||||
params->scan_type = WIFI_SCAN_TYPE_ACTIVE;
|
||||
} else
|
||||
params->scan_type = WIFI_SCAN_TYPE_PASSIVE;
|
||||
|
||||
if (scan_params->bssid) {
|
||||
params->bssid = os_zalloc(ETH_ALEN);
|
||||
if (!params->bssid) {
|
||||
wpa_printf(MSG_ERROR, "failed to allocate memory");
|
||||
return -1;
|
||||
}
|
||||
os_memcpy(params->bssid, scan_params->bssid, ETH_ALEN);
|
||||
}
|
||||
if (scan_params->channel) {
|
||||
params->channel = scan_params->channel;
|
||||
}
|
||||
|
||||
if (scan_params->duration) {
|
||||
params->scan_time.passive = scan_params->duration;
|
||||
params->scan_time.active.min = scan_params->duration;
|
||||
params->scan_time.active.max = scan_params->duration;
|
||||
}
|
||||
}
|
||||
|
||||
wpa_s->scan_start_tsf = scan_start_tsf;
|
||||
/* Register frames to come to supplicant when we park on channel */
|
||||
wpa_s->type |= (1 << WLAN_FC_STYPE_BEACON) | (1 << WLAN_FC_STYPE_PROBE_RESP);
|
||||
esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype);
|
||||
|
||||
/* issue scan */
|
||||
if (esp_wifi_scan_start(params, false) < 0) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
wpa_s->scanning = 1;
|
||||
wpa_bss_update_start(wpa_s);
|
||||
wpa_printf(MSG_INFO, "scan issued at time=%llu", wpa_s->scan_start_tsf);
|
||||
|
||||
cleanup:
|
||||
if (params->ssid)
|
||||
os_free(params->ssid);
|
||||
if (params->bssid)
|
||||
os_free(params->bssid);
|
||||
os_free(params);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* wpa_supplicant_trigger_scan - Request driver to start a scan
|
||||
* @wpa_s: Pointer to wpa_supplicant data
|
||||
* @params: Scan parameters
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_driver_scan_params *params)
|
||||
{
|
||||
return esp_issue_scan(wpa_s, params);
|
||||
}
|
||||
|
||||
void wpa_scan_results_free(struct wpa_scan_results *res)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (res == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < res->num; i++)
|
||||
os_free(res->res[i]);
|
||||
os_free(res->res);
|
||||
os_free(res);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef ESP_SCAN_I_H
|
||||
#define ESP_SCAN_I_H
|
||||
void esp_scan_init(struct wpa_supplicant *wpa_s);
|
||||
void esp_scan_deinit(struct wpa_supplicant *wpa_s);
|
||||
int esp_handle_beacon_probe(u8 type, u8 *frame, size_t len, u8 *sender,
|
||||
u32 rssi, u8 channel, u64 current_tsf);
|
||||
|
||||
void esp_supplicant_handle_scan_done_evt(void);
|
||||
#endif
|
||||
@@ -1,269 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESP_WIFI_DRIVER_H_
|
||||
#define _ESP_WIFI_DRIVER_H_
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi.h"
|
||||
|
||||
#if CONFIG_NEWLIB_NANO_FORMAT
|
||||
#define TASK_STACK_SIZE_ADD 0
|
||||
#else
|
||||
#define TASK_STACK_SIZE_ADD 512
|
||||
#endif
|
||||
|
||||
#define WPA2_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD)
|
||||
#define WPS_TASK_STACK_SIZE (12288 + TASK_STACK_SIZE_ADD)
|
||||
|
||||
enum wpa_alg{
|
||||
WIFI_WPA_ALG_NONE = 0,
|
||||
WIFI_WPA_ALG_WEP40 = 1,
|
||||
WIFI_WPA_ALG_TKIP = 2,
|
||||
WIFI_WPA_ALG_CCMP = 3,
|
||||
WIFI_WAPI_ALG_SMS4 = 4,
|
||||
WIFI_WPA_ALG_WEP104 = 5,
|
||||
WIFI_WPA_ALG_WEP = 6,
|
||||
WIFI_WPA_ALG_IGTK = 7,
|
||||
WIFI_WPA_ALG_PMK = 8,
|
||||
WIFI_WPA_ALG_GCMP = 9,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
WIFI_APPIE_PROBEREQ = 0,
|
||||
WIFI_APPIE_ASSOC_REQ,
|
||||
WIFI_APPIE_ASSOC_RESP,
|
||||
WIFI_APPIE_WPA,
|
||||
WIFI_APPIE_RSN,
|
||||
WIFI_APPIE_WPS_PR,
|
||||
WIFI_APPIE_WPS_AR,
|
||||
WIFI_APPIE_MESH_QUICK,
|
||||
WIFI_APPIE_FREQ_ERROR,
|
||||
WIFI_APPIE_ESP_MANUFACTOR,
|
||||
WIFI_APPIE_COUNTRY,
|
||||
WIFI_APPIE_MAX,
|
||||
} wifi_appie_t;
|
||||
|
||||
/* wifi_appie_t is in rom code and can't be changed anymore, use wifi_appie_ram_t for new app IEs */
|
||||
typedef enum {
|
||||
WIFI_APPIE_RM_ENABLED_CAPS = WIFI_APPIE_MAX,
|
||||
WIFI_APPIE_RAM_MAX,
|
||||
} wifi_appie_ram_t;
|
||||
|
||||
enum {
|
||||
NONE_AUTH = 0x01,
|
||||
WPA_AUTH_UNSPEC = 0x02,
|
||||
WPA_AUTH_PSK = 0x03,
|
||||
WPA2_AUTH_ENT = 0x04,
|
||||
WPA2_AUTH_PSK = 0x05,
|
||||
WPA_AUTH_CCKM = 0x06,
|
||||
WPA2_AUTH_CCKM = 0x07,
|
||||
WPA2_AUTH_PSK_SHA256= 0x08,
|
||||
WPA3_AUTH_PSK = 0x09,
|
||||
WPA2_AUTH_ENT_SHA256= 0x0a,
|
||||
WAPI_AUTH_PSK = 0x0b,
|
||||
WAPI_AUTH_CERT = 0x0c,
|
||||
WPA2_AUTH_INVALID = 0x0d,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
WPA2_ENT_EAP_STATE_NOT_START,
|
||||
WPA2_ENT_EAP_STATE_IN_PROGRESS,
|
||||
WPA2_ENT_EAP_STATE_SUCCESS,
|
||||
WPA2_ENT_EAP_STATE_FAIL,
|
||||
} wpa2_ent_eap_state_t;
|
||||
|
||||
struct wifi_appie {
|
||||
uint16_t ie_len;
|
||||
uint8_t ie_data[];
|
||||
};
|
||||
|
||||
struct wifi_ssid {
|
||||
int len;
|
||||
uint8_t ssid[32];
|
||||
};
|
||||
|
||||
struct wps_scan_ie {
|
||||
uint8_t *bssid;
|
||||
uint8_t chan;
|
||||
uint16_t capinfo;
|
||||
uint8_t *ssid;
|
||||
uint8_t *wpa;
|
||||
uint8_t *rsn;
|
||||
uint8_t *wps;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int proto;
|
||||
int pairwise_cipher;
|
||||
int group_cipher;
|
||||
int key_mgmt;
|
||||
int capabilities;
|
||||
size_t num_pmkid;
|
||||
const u8 *pmkid;
|
||||
int mgmt_group_cipher;
|
||||
} wifi_wpa_ie_t;
|
||||
|
||||
struct wpa_funcs {
|
||||
bool (*wpa_sta_init)(void);
|
||||
bool (*wpa_sta_deinit)(void);
|
||||
void (*wpa_sta_connect)(uint8_t *bssid);
|
||||
void (*wpa_sta_disconnected_cb)(uint8_t reason_code);
|
||||
int (*wpa_sta_rx_eapol)(u8 *src_addr, u8 *buf, u32 len);
|
||||
bool (*wpa_sta_in_4way_handshake)(void);
|
||||
void *(*wpa_ap_init)(void);
|
||||
bool (*wpa_ap_deinit)(void *data);
|
||||
bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len);
|
||||
bool (*wpa_ap_remove)(void *sm);
|
||||
uint8_t *(*wpa_ap_get_wpa_ie)(uint8_t *len);
|
||||
bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len);
|
||||
void (*wpa_ap_get_peer_spp_msg)(void *sm, bool *spp_cap, bool *spp_req);
|
||||
char *(*wpa_config_parse_string)(const char *value, size_t *len);
|
||||
int (*wpa_parse_wpa_ie)(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data);
|
||||
int (*wpa_config_bss)(u8 *bssid);
|
||||
int (*wpa_michael_mic_failure)(u16 is_unicast);
|
||||
uint8_t *(*wpa3_build_sae_msg)(uint8_t *bssid, uint32_t type, size_t *len);
|
||||
int (*wpa3_parse_sae_msg)(uint8_t *buf, size_t len, uint32_t type, uint16_t status);
|
||||
int (*wpa_sta_rx_mgmt)(u8 type, u8 *frame, size_t len, u8 *sender, u32 rssi, u8 channel, u64 current_tsf);
|
||||
};
|
||||
|
||||
struct wpa2_funcs {
|
||||
int (*wpa2_sm_rx_eapol)(u8 *src_addr, u8 *buf, u32 len, u8 *bssid);
|
||||
int (*wpa2_start)(void);
|
||||
u8 (*wpa2_get_state)(void);
|
||||
int (*wpa2_init)(void);
|
||||
void (*wpa2_deinit)(void);
|
||||
};
|
||||
|
||||
struct wps_funcs {
|
||||
bool (*wps_parse_scan_result)(struct wps_scan_ie *scan);
|
||||
int (*wifi_station_wps_start)(void);
|
||||
int (*wps_sm_rx_eapol)(u8 *src_addr, u8 *buf, u32 len);
|
||||
int (*wps_start_pending)(void);
|
||||
};
|
||||
|
||||
typedef esp_err_t (*wifi_wpa2_fn_t)(void *);
|
||||
typedef struct {
|
||||
wifi_wpa2_fn_t fn;
|
||||
void *param;
|
||||
} wifi_wpa2_param_t;
|
||||
|
||||
#define IS_WPS_REGISTRAR(type) (((type)>WPS_TYPE_MAX)?(((type)<WPS_TYPE_MAX)?true:false):false)
|
||||
#define IS_WPS_ENROLLEE(type) (((type)>WPS_TYPE_DISABLE)?(((type)<WPS_TYPE_MAX)?true:false):false)
|
||||
|
||||
typedef enum wps_status {
|
||||
WPS_STATUS_DISABLE = 0,
|
||||
WPS_STATUS_SCANNING,
|
||||
WPS_STATUS_PENDING,
|
||||
WPS_STATUS_SUCCESS,
|
||||
WPS_STATUS_MAX,
|
||||
} WPS_STATUS_t;
|
||||
|
||||
#define WIFI_TXCB_EAPOL_ID 3
|
||||
typedef void(*wifi_tx_cb_t)(void *);
|
||||
typedef int (*wifi_ipc_fn_t)(void *);
|
||||
typedef struct {
|
||||
wifi_ipc_fn_t fn;
|
||||
void *arg;
|
||||
uint32_t arg_size;
|
||||
} wifi_ipc_config_t;
|
||||
|
||||
#define WPA_IGTK_LEN 16
|
||||
typedef struct {
|
||||
uint8_t keyid[2];
|
||||
uint8_t pn[6];
|
||||
uint8_t igtk[WPA_IGTK_LEN];
|
||||
} wifi_wpa_igtk_t;
|
||||
|
||||
typedef struct {
|
||||
wifi_interface_t ifx;
|
||||
uint8_t subtype;
|
||||
uint32_t data_len;
|
||||
uint8_t data[0];
|
||||
} wifi_mgmt_frm_req_t;
|
||||
|
||||
uint8_t *esp_wifi_ap_get_prof_pmk_internal(void);
|
||||
struct wifi_ssid *esp_wifi_ap_get_prof_ap_ssid_internal(void);
|
||||
uint8_t esp_wifi_ap_get_prof_authmode_internal(void);
|
||||
uint8_t esp_wifi_sta_get_prof_authmode_internal(void);
|
||||
uint8_t *esp_wifi_ap_get_prof_password_internal(void);
|
||||
struct wifi_ssid *esp_wifi_sta_get_prof_ssid_internal(void);
|
||||
uint8_t esp_wifi_sta_get_reset_param_internal(void);
|
||||
uint8_t esp_wifi_sta_get_pairwise_cipher_internal(void);
|
||||
uint8_t esp_wifi_sta_get_group_cipher_internal(void);
|
||||
bool esp_wifi_sta_prof_is_wpa_internal(void);
|
||||
int esp_wifi_get_macaddr_internal(uint8_t if_index, uint8_t *macaddr);
|
||||
int esp_wifi_set_appie_internal(uint8_t type, uint8_t *ie, uint16_t len, uint8_t flag);
|
||||
int esp_wifi_unset_appie_internal(uint8_t type);
|
||||
struct wifi_appie *esp_wifi_get_appie_internal(uint8_t type);
|
||||
void *esp_wifi_get_hostap_private_internal(void); //1
|
||||
uint8_t *esp_wifi_sta_get_prof_password_internal(void);
|
||||
void esp_wifi_deauthenticate_internal(u8 reason_code);
|
||||
uint16_t esp_wifi_get_spp_attrubute_internal(uint8_t ifx);
|
||||
bool esp_wifi_sta_is_running_internal(void);
|
||||
bool esp_wifi_auth_done_internal(void);
|
||||
int esp_wifi_set_ap_key_internal(int alg, const u8 *addr, int idx, u8 *key, size_t key_len);
|
||||
int esp_wifi_get_sta_hw_key_idx_internal(int key_idx);
|
||||
int esp_wifi_set_sta_key_internal(int alg, u8 *addr, int key_idx, int set_tx,
|
||||
u8 *seq, size_t seq_len, u8 *key, size_t key_len, int key_entry_valid);
|
||||
int esp_wifi_get_sta_key_internal(uint8_t *ifx, int *alg, u8 *addr, int *key_idx,
|
||||
u8 *key, size_t key_len, int key_entry_valid);
|
||||
bool esp_wifi_wpa_ptk_init_done_internal(uint8_t *mac);
|
||||
uint8_t esp_wifi_sta_set_reset_param_internal(uint8_t reset_flag);
|
||||
uint8_t esp_wifi_get_sta_gtk_index_internal(void);
|
||||
void esp_wifi_set_sta_gtk_index_internal(u8 valid, u8 index);
|
||||
int esp_wifi_register_tx_cb_internal(wifi_tx_cb_t fn, u8 id);
|
||||
int esp_wifi_register_wpa_cb_internal(struct wpa_funcs *cb);
|
||||
int esp_wifi_unregister_wpa_cb_internal(void);
|
||||
int esp_wifi_get_assoc_bssid_internal(uint8_t *bssid);
|
||||
bool esp_wifi_sta_is_ap_notify_completed_rsne_internal(void);
|
||||
int esp_wifi_ap_deauth_internal(uint8_t *mac, uint32_t reason);
|
||||
int esp_wifi_ipc_internal(wifi_ipc_config_t *cfg, bool sync);
|
||||
int esp_wifi_register_wpa2_cb_internal(struct wpa2_funcs *cb);
|
||||
int esp_wifi_unregister_wpa2_cb_internal(void);
|
||||
bool esp_wifi_sta_prof_is_wpa2_internal(void);
|
||||
bool esp_wifi_sta_prof_is_wpa3_internal(void);
|
||||
bool esp_wifi_sta_prof_is_wapi_internal(void);
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_disable_internal(wifi_wpa2_param_t *param);
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_enable_internal(wifi_wpa2_param_t *param);
|
||||
esp_err_t esp_wifi_set_wpa2_ent_state_internal(wpa2_ent_eap_state_t state);
|
||||
int esp_wifi_get_wps_type_internal(void);
|
||||
int esp_wifi_set_wps_type_internal(uint32_t type);
|
||||
int esp_wifi_get_wps_status_internal(void);
|
||||
int esp_wifi_set_wps_status_internal(uint32_t status);
|
||||
int esp_wifi_disarm_sta_connection_timer_internal(void);
|
||||
bool esp_wifi_get_sniffer_internal(void);
|
||||
int esp_wifi_set_wps_cb_internal(struct wps_funcs *wps_cb);
|
||||
bool esp_wifi_enable_sta_privacy_internal(void);
|
||||
uint8_t esp_wifi_get_user_init_flag_internal(void);
|
||||
esp_err_t esp_wifi_internal_supplicant_header_md5_check(const char *md5);
|
||||
int esp_wifi_sta_update_ap_info_internal(void);
|
||||
uint8_t *esp_wifi_sta_get_ap_info_prof_pmk_internal(void);
|
||||
esp_err_t esp_wifi_set_wps_start_flag_internal(bool start);
|
||||
uint16_t esp_wifi_sta_pmf_enabled(void);
|
||||
wifi_cipher_type_t esp_wifi_sta_get_mgmt_group_cipher(void);
|
||||
int esp_wifi_set_igtk_internal(uint8_t if_index, const wifi_wpa_igtk_t *igtk);
|
||||
esp_err_t esp_wifi_internal_issue_disconnect(uint8_t reason_code);
|
||||
bool esp_wifi_skip_supp_pmkcaching(void);
|
||||
bool esp_wifi_is_rm_enabled_internal(uint8_t if_index);
|
||||
bool esp_wifi_is_btm_enabled_internal(uint8_t if_index);
|
||||
esp_err_t esp_wifi_register_mgmt_frame_internal(uint32_t type, uint32_t subtype);
|
||||
esp_err_t esp_wifi_send_mgmt_frm_internal(const wifi_mgmt_frm_req_t *req);
|
||||
uint8_t esp_wifi_ap_get_prof_pairwise_cipher_internal(void);
|
||||
esp_err_t esp_wifi_action_tx_req(uint8_t type, uint8_t channel,
|
||||
uint32_t wait_time_ms, const wifi_action_tx_req_t *req);
|
||||
esp_err_t esp_wifi_remain_on_channel(uint8_t ifx, uint8_t type, uint8_t channel,
|
||||
uint32_t wait_time_ms, wifi_action_rx_cb_t rx_cb);
|
||||
|
||||
#endif /* _ESP_WIFI_DRIVER_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,235 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
|
||||
#include "common/sae.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "rsn_supp/wpa.h"
|
||||
|
||||
static struct sae_data g_sae_data;
|
||||
static struct wpabuf *g_sae_token = NULL;
|
||||
static struct wpabuf *g_sae_commit = NULL;
|
||||
static struct wpabuf *g_sae_confirm = NULL;
|
||||
int g_allowed_groups[] = { IANA_SECP256R1, 0 };
|
||||
|
||||
static esp_err_t wpa3_build_sae_commit(u8 *bssid)
|
||||
{
|
||||
int default_group = IANA_SECP256R1;
|
||||
u32 len = 0;
|
||||
u8 own_addr[ETH_ALEN];
|
||||
const u8 *pw;
|
||||
|
||||
if (wpa_sta_cur_pmksa_matches_akm()) {
|
||||
wpa_printf(MSG_INFO, "wpa3: Skip SAE and use cached PMK instead");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (g_sae_commit) {
|
||||
wpabuf_free(g_sae_commit);
|
||||
g_sae_commit = NULL;
|
||||
}
|
||||
|
||||
if (g_sae_token) {
|
||||
len = wpabuf_len(g_sae_token);
|
||||
goto reuse_data;
|
||||
}
|
||||
|
||||
memset(&g_sae_data, 0, sizeof(g_sae_data));
|
||||
if (sae_set_group(&g_sae_data, default_group)) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: could not set SAE group %d", default_group);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_wifi_get_macaddr_internal(WIFI_IF_STA, own_addr);
|
||||
if (!bssid) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: cannot prepare SAE commit with no BSSID!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
pw = (const u8 *)esp_wifi_sta_get_prof_password_internal();
|
||||
if (sae_prepare_commit(own_addr, bssid, pw, strlen((const char *)pw), NULL, &g_sae_data) < 0) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to prepare SAE commit!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
reuse_data:
|
||||
len += SAE_COMMIT_MAX_LEN;
|
||||
g_sae_commit = wpabuf_alloc(len);
|
||||
if (!g_sae_commit) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to allocate buffer for commit msg");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (sae_write_commit(&g_sae_data, g_sae_commit, g_sae_token, NULL) != ESP_OK) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to write SAE commit msg");
|
||||
wpabuf_free(g_sae_commit);
|
||||
g_sae_commit = NULL;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (g_sae_token) {
|
||||
wpabuf_free(g_sae_token);
|
||||
g_sae_token = NULL;
|
||||
}
|
||||
g_sae_data.state = SAE_COMMITTED;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t wpa3_build_sae_confirm(void)
|
||||
{
|
||||
if (g_sae_data.state != SAE_COMMITTED)
|
||||
return ESP_FAIL;
|
||||
|
||||
if (g_sae_confirm) {
|
||||
wpabuf_free(g_sae_confirm);
|
||||
g_sae_confirm = NULL;
|
||||
}
|
||||
|
||||
g_sae_confirm = wpabuf_alloc(SAE_COMMIT_MAX_LEN);
|
||||
if (!g_sae_confirm) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to allocate buffer for confirm msg");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (sae_write_confirm(&g_sae_data, g_sae_confirm) != ESP_OK) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to write SAE confirm msg");
|
||||
wpabuf_free(g_sae_confirm);
|
||||
g_sae_confirm = NULL;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
g_sae_data.state = SAE_CONFIRMED;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_wpa3_free_sae_data(void)
|
||||
{
|
||||
if (g_sae_commit) {
|
||||
wpabuf_free(g_sae_commit);
|
||||
g_sae_commit = NULL;
|
||||
}
|
||||
|
||||
if (g_sae_confirm) {
|
||||
wpabuf_free(g_sae_confirm);
|
||||
g_sae_confirm = NULL;
|
||||
}
|
||||
sae_clear_data(&g_sae_data);
|
||||
}
|
||||
|
||||
static u8 *wpa3_build_sae_msg(u8 *bssid, u32 sae_msg_type, size_t *sae_msg_len)
|
||||
{
|
||||
u8 *buf = NULL;
|
||||
|
||||
switch (sae_msg_type) {
|
||||
case SAE_MSG_COMMIT:
|
||||
if (ESP_OK != wpa3_build_sae_commit(bssid))
|
||||
return NULL;
|
||||
*sae_msg_len = wpabuf_len(g_sae_commit);
|
||||
buf = wpabuf_mhead_u8(g_sae_commit);
|
||||
break;
|
||||
case SAE_MSG_CONFIRM:
|
||||
if (ESP_OK != wpa3_build_sae_confirm())
|
||||
return NULL;
|
||||
*sae_msg_len = wpabuf_len(g_sae_confirm);
|
||||
buf = wpabuf_mhead_u8(g_sae_confirm);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int wpa3_parse_sae_commit(u8 *buf, u32 len, u16 status)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (g_sae_data.state != SAE_COMMITTED) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to parse SAE commit in state(%d)!",
|
||||
g_sae_data.state);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (status == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ) {
|
||||
if (g_sae_token)
|
||||
wpabuf_free(g_sae_token);
|
||||
g_sae_token = wpabuf_alloc_copy(buf + 2, len - 2);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ret = sae_parse_commit(&g_sae_data, buf, len, NULL, 0, g_allowed_groups);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: could not parse commit(%d)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sae_process_commit(&g_sae_data);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: could not process commit(%d)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int wpa3_parse_sae_confirm(u8 *buf, u32 len)
|
||||
{
|
||||
if (g_sae_data.state != SAE_CONFIRMED) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to parse SAE commit in state(%d)!",
|
||||
g_sae_data.state);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (sae_check_confirm(&g_sae_data, buf, len) != ESP_OK) {
|
||||
wpa_printf(MSG_ERROR, "wpa3: failed to parse SAE confirm");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
g_sae_data.state = SAE_ACCEPTED;
|
||||
|
||||
wpa_set_pmk(g_sae_data.pmk, g_sae_data.pmkid, true);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int wpa3_parse_sae_msg(u8 *buf, size_t len, u32 sae_msg_type, u16 status)
|
||||
{
|
||||
int ret = ESP_OK;
|
||||
|
||||
switch (sae_msg_type) {
|
||||
case SAE_MSG_COMMIT:
|
||||
ret = wpa3_parse_sae_commit(buf, len, status);
|
||||
break;
|
||||
case SAE_MSG_CONFIRM:
|
||||
ret = wpa3_parse_sae_confirm(buf, len);
|
||||
esp_wpa3_free_sae_data();
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_ERROR, "wpa3: Invalid SAE msg type(%d)!", sae_msg_type);
|
||||
ret = ESP_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb)
|
||||
{
|
||||
wpa_cb->wpa3_build_sae_msg = wpa3_build_sae_msg;
|
||||
wpa_cb->wpa3_parse_sae_msg = wpa3_parse_sae_msg;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ESP_WPA3_H
|
||||
#define ESP_WPA3_H
|
||||
|
||||
#include "esp_wifi_driver.h"
|
||||
|
||||
#ifdef CONFIG_WPA3_SAE
|
||||
|
||||
void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb);
|
||||
void esp_wpa3_free_sae_data(void);
|
||||
|
||||
#else /* CONFIG_WPA3_SAE */
|
||||
|
||||
static inline void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb)
|
||||
{
|
||||
wpa_cb->wpa3_build_sae_msg = NULL;
|
||||
wpa_cb->wpa3_parse_sae_msg = NULL;
|
||||
}
|
||||
|
||||
static inline void esp_wpa3_free_sae_data(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WPA3_SAE */
|
||||
#endif /* ESP_WPA3_H */
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
* This file define the ESP supplicant internal error code
|
||||
*/
|
||||
|
||||
#define WPA_ERR_INVALID_BSSID -2
|
||||
@@ -1,272 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "rsn_supp/wpa.h"
|
||||
#include "rsn_supp/wpa_i.h"
|
||||
#include "common/eapol_common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "rsn_supp/wpa_ie.h"
|
||||
#include "ap/wpa_auth.h"
|
||||
#include "ap/wpa_auth_i.h"
|
||||
#include "ap/ap_config.h"
|
||||
#include "ap/hostapd.h"
|
||||
#include "esp_wpas_glue.h"
|
||||
#include "esp_hostap.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "crypto/aes_wrap.h"
|
||||
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#include "esp_wpa3_i.h"
|
||||
#include "esp_wpa2.h"
|
||||
#include "esp_common_i.h"
|
||||
|
||||
void wpa_install_key(enum wpa_alg alg, u8 *addr, int key_idx, int set_tx,
|
||||
u8 *seq, size_t seq_len, u8 *key, size_t key_len, int key_entry_valid)
|
||||
{
|
||||
esp_wifi_set_sta_key_internal(alg, addr, key_idx, set_tx, seq, seq_len, key, key_len, key_entry_valid);
|
||||
}
|
||||
|
||||
int wpa_get_key(uint8_t *ifx, int *alg, u8 *addr, int *key_idx,
|
||||
u8 *key, size_t key_len, int key_entry_valid)
|
||||
{
|
||||
return esp_wifi_get_sta_key_internal(ifx, alg, addr, key_idx, key, key_len, key_entry_valid);
|
||||
}
|
||||
|
||||
/**
|
||||
* eapol_sm_notify_eap_success - Notification of external EAP success trigger
|
||||
* @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
|
||||
* @success: %TRUE = set success, %FALSE = clear success
|
||||
*
|
||||
* Notify the EAPOL state machine that external event has forced EAP state to
|
||||
* success (success = %TRUE). This can be cleared by setting success = %FALSE.
|
||||
*
|
||||
* This function is called to update EAP state when WPA-PSK key handshake has
|
||||
* been completed successfully since WPA-PSK does not use EAP state machine.
|
||||
*/
|
||||
|
||||
/* fix buf for tx for now */
|
||||
#define WPA_TX_MSG_BUFF_MAXLEN 200
|
||||
|
||||
void wpa_sendto_wrapper(void *buffer, u16 len)
|
||||
{
|
||||
esp_wifi_internal_tx(0, buffer, len);
|
||||
}
|
||||
|
||||
void wpa_deauthenticate(u8 reason_code)
|
||||
{
|
||||
esp_wifi_deauthenticate_internal(reason_code);
|
||||
}
|
||||
|
||||
void wpa_config_profile(void)
|
||||
{
|
||||
if (esp_wifi_sta_prof_is_wpa_internal()) {
|
||||
wpa_set_profile(WPA_PROTO_WPA, esp_wifi_sta_get_prof_authmode_internal());
|
||||
} else if (esp_wifi_sta_prof_is_wpa2_internal() || esp_wifi_sta_prof_is_wpa3_internal()) {
|
||||
wpa_set_profile(WPA_PROTO_RSN, esp_wifi_sta_get_prof_authmode_internal());
|
||||
} else if (esp_wifi_sta_prof_is_wapi_internal()) {
|
||||
wpa_set_profile(WPA_PROTO_WAPI, esp_wifi_sta_get_prof_authmode_internal());
|
||||
} else {
|
||||
WPA_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
int wpa_config_bss(uint8_t *bssid)
|
||||
{
|
||||
int ret = 0;
|
||||
struct wifi_ssid *ssid = esp_wifi_sta_get_prof_ssid_internal();
|
||||
u8 mac[6];
|
||||
|
||||
esp_wifi_get_macaddr_internal(0, mac);
|
||||
ret = wpa_set_bss((char *)mac, (char *)bssid, esp_wifi_sta_get_pairwise_cipher_internal(), esp_wifi_sta_get_group_cipher_internal(),
|
||||
(char *)esp_wifi_sta_get_prof_password_internal(), ssid->ssid, ssid->len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wpa_config_assoc_ie(u8 proto, u8 *assoc_buf, u32 assoc_wpa_ie_len)
|
||||
{
|
||||
if (proto == BIT(0)) {
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_WPA, assoc_buf, assoc_wpa_ie_len, 1);
|
||||
} else {
|
||||
esp_wifi_set_appie_internal(WIFI_APPIE_RSN, assoc_buf, assoc_wpa_ie_len, 1);
|
||||
}
|
||||
esp_set_rm_enabled_ie();
|
||||
}
|
||||
|
||||
void wpa_neg_complete(void)
|
||||
{
|
||||
esp_wifi_auth_done_internal();
|
||||
}
|
||||
|
||||
bool wpa_attach(void)
|
||||
{
|
||||
bool ret = true;
|
||||
ret = wpa_sm_init(NULL, wpa_sendto_wrapper,
|
||||
wpa_config_assoc_ie, wpa_install_key, wpa_get_key, wpa_deauthenticate, wpa_neg_complete);
|
||||
if(ret) {
|
||||
ret = (esp_wifi_register_tx_cb_internal(eapol_txcb, WIFI_TXCB_EAPOL_ID) == ESP_OK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t *wpa_ap_get_wpa_ie(uint8_t *ie_len)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *)esp_wifi_get_hostap_private_internal();
|
||||
|
||||
if (!hapd || !hapd->wpa_auth || !hapd->wpa_auth->wpa_ie) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*ie_len = hapd->wpa_auth->wpa_ie_len;
|
||||
return hapd->wpa_auth->wpa_ie;
|
||||
}
|
||||
|
||||
bool wpa_ap_rx_eapol(void *hapd_data, void *sm_data, u8 *data, size_t data_len)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *)hapd_data;
|
||||
struct wpa_state_machine *sm = (struct wpa_state_machine *)sm_data;
|
||||
|
||||
if (!hapd || !sm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wpa_receive(hapd->wpa_auth, sm, data, data_len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wpa_ap_get_peer_spp_msg(void *sm_data, bool *spp_cap, bool *spp_req)
|
||||
{
|
||||
struct wpa_state_machine *sm = (struct wpa_state_machine *)sm_data;
|
||||
|
||||
if (!sm) {
|
||||
return;
|
||||
}
|
||||
|
||||
*spp_cap = sm->spp_sup.capable;
|
||||
*spp_req = sm->spp_sup.require;
|
||||
}
|
||||
|
||||
bool wpa_deattach(void)
|
||||
{
|
||||
esp_wifi_sta_wpa2_ent_disable();
|
||||
wpa_sm_deinit();
|
||||
return true;
|
||||
}
|
||||
|
||||
void wpa_sta_connect(uint8_t *bssid)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
wpa_config_profile();
|
||||
ret = wpa_config_bss(bssid);
|
||||
WPA_ASSERT(ret == 0);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
int wpa_parse_wpa_ie_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data)
|
||||
{
|
||||
struct wpa_ie_data ie;
|
||||
int ret = 0;
|
||||
|
||||
ret = wpa_parse_wpa_ie(wpa_ie, wpa_ie_len, &ie);
|
||||
data->proto = ie.proto;
|
||||
data->pairwise_cipher = cipher_type_map_supp_to_public(ie.pairwise_cipher);
|
||||
data->group_cipher = cipher_type_map_supp_to_public(ie.group_cipher);
|
||||
data->key_mgmt = ie.key_mgmt;
|
||||
data->capabilities = ie.capabilities;
|
||||
data->pmkid = ie.pmkid;
|
||||
data->mgmt_group_cipher = cipher_type_map_supp_to_public(ie.mgmt_group_cipher);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wpa_sta_disconnected_cb(uint8_t reason_code)
|
||||
{
|
||||
switch (reason_code) {
|
||||
case WIFI_REASON_UNSPECIFIED:
|
||||
case WIFI_REASON_AUTH_EXPIRE:
|
||||
case WIFI_REASON_NOT_AUTHED:
|
||||
case WIFI_REASON_NOT_ASSOCED:
|
||||
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
|
||||
case WIFI_REASON_INVALID_PMKID:
|
||||
case WIFI_REASON_AUTH_FAIL:
|
||||
case WIFI_REASON_ASSOC_FAIL:
|
||||
case WIFI_REASON_CONNECTION_FAIL:
|
||||
case WIFI_REASON_HANDSHAKE_TIMEOUT:
|
||||
esp_wpa3_free_sae_data();
|
||||
wpa_sta_clear_curr_pmksa();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ROAMING_SUPPORT
|
||||
static inline void esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
|
||||
{
|
||||
wpa_cb->wpa_sta_rx_mgmt = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int esp_supplicant_init(void)
|
||||
{
|
||||
int ret = ESP_OK;
|
||||
struct wpa_funcs *wpa_cb;
|
||||
|
||||
wpa_cb = (struct wpa_funcs *)os_malloc(sizeof(struct wpa_funcs));
|
||||
if (!wpa_cb) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
wpa_cb->wpa_sta_init = wpa_attach;
|
||||
wpa_cb->wpa_sta_deinit = wpa_deattach;
|
||||
wpa_cb->wpa_sta_rx_eapol = wpa_sm_rx_eapol;
|
||||
wpa_cb->wpa_sta_connect = wpa_sta_connect;
|
||||
wpa_cb->wpa_sta_disconnected_cb = wpa_sta_disconnected_cb;
|
||||
wpa_cb->wpa_sta_in_4way_handshake = wpa_sta_in_4way_handshake;
|
||||
|
||||
wpa_cb->wpa_ap_join = wpa_ap_join;
|
||||
wpa_cb->wpa_ap_remove = wpa_ap_remove;
|
||||
wpa_cb->wpa_ap_get_wpa_ie = wpa_ap_get_wpa_ie;
|
||||
wpa_cb->wpa_ap_rx_eapol = wpa_ap_rx_eapol;
|
||||
wpa_cb->wpa_ap_get_peer_spp_msg = wpa_ap_get_peer_spp_msg;
|
||||
wpa_cb->wpa_ap_init = hostap_init;
|
||||
wpa_cb->wpa_ap_deinit = hostap_deinit;
|
||||
|
||||
wpa_cb->wpa_config_parse_string = wpa_config_parse_string;
|
||||
wpa_cb->wpa_parse_wpa_ie = wpa_parse_wpa_ie_wrapper;
|
||||
wpa_cb->wpa_config_bss = NULL;//wpa_config_bss;
|
||||
wpa_cb->wpa_michael_mic_failure = wpa_michael_mic_failure;
|
||||
esp_wifi_register_wpa3_cb(wpa_cb);
|
||||
esp_supplicant_common_init(wpa_cb);
|
||||
|
||||
esp_wifi_register_wpa_cb_internal(wpa_cb);
|
||||
|
||||
#if CONFIG_WPA_WAPI_PSK
|
||||
ret = esp_wifi_internal_wapi_init();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int esp_supplicant_deinit(void)
|
||||
{
|
||||
return esp_wifi_unregister_wpa_cb_internal();
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifdef ESP_SUPPLICANT
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "common/eapol_common.h"
|
||||
#include "rsn_supp/wpa.h"
|
||||
#include "rsn_supp/pmksa_cache.h"
|
||||
|
||||
u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
|
||||
const void *data, u16 data_len,
|
||||
size_t *msg_len, void **data_pos)
|
||||
{
|
||||
void *buffer;
|
||||
struct ieee802_1x_hdr *hdr;
|
||||
|
||||
*msg_len = sizeof(struct ieee802_1x_hdr) + data_len;
|
||||
|
||||
buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr));
|
||||
|
||||
if (buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX: reserve l2_ethhdr is enough */
|
||||
hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
|
||||
|
||||
hdr->version = sm->eapol_version;
|
||||
hdr->type = type;
|
||||
hdr->length = host_to_be16(data_len);
|
||||
|
||||
if (data) {
|
||||
memcpy(hdr + 1, data, data_len);
|
||||
} else {
|
||||
memset(hdr + 1, 0, data_len);
|
||||
}
|
||||
|
||||
if (data_pos) {
|
||||
*data_pos = hdr + 1;
|
||||
}
|
||||
|
||||
return (u8 *) hdr;
|
||||
}
|
||||
|
||||
void wpa_sm_free_eapol(u8 *buffer)
|
||||
{
|
||||
buffer = buffer - sizeof(struct l2_ethhdr);
|
||||
os_free(buffer);
|
||||
}
|
||||
|
||||
void wpa_sm_deauthenticate(struct wpa_sm *sm, u8 reason_code)
|
||||
{
|
||||
|
||||
/*only need send deauth frame when associated*/
|
||||
if (WPA_SM_STATE(sm) >= WPA_ASSOCIATED) {
|
||||
pmksa_cache_clear_current(sm);
|
||||
sm->wpa_deauthenticate(reason_code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mlme_setprotection - MLME-SETPROTECTION.request primitive
|
||||
* @priv: Private driver interface data
|
||||
* @addr: Address of the station for which to set protection (may be
|
||||
* %NULL for group keys)
|
||||
* @protect_type: MLME_SETPROTECTION_PROTECT_TYPE_*
|
||||
* @key_type: MLME_SETPROTECTION_KEY_TYPE_*
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This is an optional function that can be used to set the driver to
|
||||
* require protection for Tx and/or Rx frames. This uses the layer
|
||||
* interface defined in IEEE 802.11i-2004 clause 10.3.22.1
|
||||
* (MLME-SETPROTECTION.request). Many drivers do not use explicit
|
||||
* set protection operation; instead, they set protection implicitly
|
||||
* based on configured keys.
|
||||
*/
|
||||
int wpa_sm_mlme_setprotection(struct wpa_sm *sm, const u8 *addr,
|
||||
int protect_type, int key_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*use above two functions to get wpa_ie and rsn_ie, then don't need wpa_sm_get_beacon_ie function
|
||||
*/
|
||||
int wpa_sm_get_beacon_ie(struct wpa_sm *sm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* wpa_supplicant_disassociate - Disassociate the current connection
|
||||
* @wpa_s: Pointer to wpa_supplicant data
|
||||
* @reason_code: IEEE 802.11 reason code for the disassociate frame
|
||||
*
|
||||
* This function is used to request %wpa_supplicant to disassociate with the
|
||||
* current AP.
|
||||
*/
|
||||
void wpa_sm_disassociate(struct wpa_sm *sm, int reason_code)
|
||||
{
|
||||
/*check if need clear internal state and data value*/
|
||||
}
|
||||
#endif
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef WPAS_GLUE_H
|
||||
#define WPAS_GLUE_H
|
||||
|
||||
u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
|
||||
const void *data, u16 data_len,
|
||||
size_t *msg_len, void **data_pos);
|
||||
|
||||
int wpa_sm_mlme_setprotection(struct wpa_sm *sm, const u8 *addr,
|
||||
int protect_type, int key_type);
|
||||
|
||||
void wpa_sm_deauthenticate(struct wpa_sm *sm, u8 reason_code);
|
||||
|
||||
void wpa_sm_disassociate(struct wpa_sm *sm, int reason_code);
|
||||
|
||||
int wpa_sm_get_beacon_ie(struct wpa_sm *sm);
|
||||
|
||||
void wpa_sm_free_eapol(u8 *buffer);
|
||||
|
||||
#endif /* WPAS_GLUE_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,8 +21,8 @@
|
||||
#include "common/eapol_common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "rsn_supp/wpa_ie.h"
|
||||
#include "esp_supplicant/esp_wpas_glue.h"
|
||||
#include "esp_supplicant/esp_wifi_driver.h"
|
||||
#include "esp_wpas_glue.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/sha1.h"
|
||||
@@ -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 - "
|
||||
@@ -2081,7 +2081,7 @@ bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func,
|
||||
|
||||
spp_attrubute = esp_wifi_get_spp_attrubute_internal(WIFI_IF_STA);
|
||||
sm->spp_sup.capable = ((spp_attrubute & WPA_CAPABILITY_SPP_CAPABLE) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_CAP_DISABLE);
|
||||
sm->spp_sup.require = ((spp_attrubute & WPA_CAPABILITY_SPP_REQUIRED) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_REQ_DISABLE);
|
||||
sm->spp_sup.require = ((spp_attrubute & WPA_CAPABILITY_SPP_REQUIRED) ? SPP_AMSDU_REQ_ENABLE : SPP_AMSDU_REQ_DISABLE);
|
||||
|
||||
wpa_sm_set_state(WPA_INACTIVE);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1376,7 +1376,7 @@ static int x509_sha1_oid(struct asn1_oid *oid)
|
||||
oid->oid[5] == 26 /* id-sha1 */;
|
||||
}
|
||||
|
||||
static int x509_sha256_oid(struct asn1_oid *oid)
|
||||
static int x509_sha2_oid(struct asn1_oid *oid)
|
||||
{
|
||||
return oid->len == 9 &&
|
||||
oid->oid[0] == 2 /* joint-iso-itu-t */ &&
|
||||
@@ -1386,11 +1386,31 @@ static int x509_sha256_oid(struct asn1_oid *oid)
|
||||
oid->oid[4] == 101 /* gov */ &&
|
||||
oid->oid[5] == 3 /* csor */ &&
|
||||
oid->oid[6] == 4 /* nistAlgorithm */ &&
|
||||
oid->oid[7] == 2 /* hashAlgs */ &&
|
||||
oid->oid[7] == 2 /* hashAlgs */;
|
||||
}
|
||||
|
||||
|
||||
static int x509_sha256_oid(struct asn1_oid *oid)
|
||||
{
|
||||
return x509_sha2_oid(oid) &&
|
||||
oid->oid[8] == 1 /* sha256 */;
|
||||
}
|
||||
|
||||
|
||||
static int x509_sha384_oid(struct asn1_oid *oid)
|
||||
{
|
||||
return x509_sha2_oid(oid) &&
|
||||
oid->oid[8] == 2 /* sha384 */;
|
||||
}
|
||||
|
||||
|
||||
static int x509_sha512_oid(struct asn1_oid *oid)
|
||||
{
|
||||
return x509_sha2_oid(oid) &&
|
||||
oid->oid[8] == 3 /* sha512 */;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* x509_certificate_parse - Parse a X.509 certificate in DER format
|
||||
* @buf: Pointer to the X.509 certificate in DER format
|
||||
@@ -1515,7 +1535,7 @@ int x509_certificate_check_signature(struct x509_certificate *issuer,
|
||||
size_t data_len;
|
||||
struct asn1_hdr hdr;
|
||||
struct asn1_oid oid;
|
||||
u8 hash[32];
|
||||
u8 hash[64];
|
||||
size_t hash_len;
|
||||
|
||||
if (!x509_pkcs_oid(&cert->signature.oid) ||
|
||||
@@ -1627,6 +1647,32 @@ int x509_certificate_check_signature(struct x509_certificate *issuer,
|
||||
goto skip_digest_oid;
|
||||
}
|
||||
|
||||
if (x509_sha384_oid(&oid)) {
|
||||
if (cert->signature.oid.oid[6] !=
|
||||
12 /* sha384WithRSAEncryption */) {
|
||||
wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA384 "
|
||||
"does not match with certificate "
|
||||
"signatureAlgorithm (%lu)",
|
||||
cert->signature.oid.oid[6]);
|
||||
os_free(data);
|
||||
return -1;
|
||||
}
|
||||
goto skip_digest_oid;
|
||||
}
|
||||
|
||||
if (x509_sha512_oid(&oid)) {
|
||||
if (cert->signature.oid.oid[6] !=
|
||||
13 /* sha512WithRSAEncryption */) {
|
||||
wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA512 "
|
||||
"does not match with certificate "
|
||||
"signatureAlgorithm (%lu)",
|
||||
cert->signature.oid.oid[6]);
|
||||
os_free(data);
|
||||
return -1;
|
||||
}
|
||||
goto skip_digest_oid;
|
||||
}
|
||||
|
||||
if (!x509_digest_oid(&oid)) {
|
||||
wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm");
|
||||
os_free(data);
|
||||
@@ -1692,9 +1738,21 @@ skip_digest_oid:
|
||||
wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA256)",
|
||||
hash, hash_len);
|
||||
break;
|
||||
case 2: /* md2WithRSAEncryption */
|
||||
case 12: /* sha384WithRSAEncryption */
|
||||
sha384_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len,
|
||||
hash);
|
||||
hash_len = 48;
|
||||
wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA384)",
|
||||
hash, hash_len);
|
||||
break;
|
||||
case 13: /* sha512WithRSAEncryption */
|
||||
sha512_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len,
|
||||
hash);
|
||||
hash_len = 64;
|
||||
wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA512)",
|
||||
hash, hash_len);
|
||||
break;
|
||||
case 2: /* md2WithRSAEncryption */
|
||||
default:
|
||||
wpa_printf(MSG_INFO, "X509: Unsupported certificate signature "
|
||||
"algorithm (%lu)", cert->signature.oid.oid[6]);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg, wps_key_mode_t mode)
|
||||
{
|
||||
struct wpabuf *pubkey;
|
||||
struct wpabuf *pubkey = NULL;
|
||||
|
||||
if (mode != WPS_CALC_KEY_NO_CALC) {
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
|
||||
u8 id, u8 len, const u8 *pos)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "WPS: WFA subelement id=%u len=%u",
|
||||
wpa_printf(MSG_MSGDUMP, "WPS: WFA subelement id=%u len=%u",
|
||||
id, len);
|
||||
switch (id) {
|
||||
case WFA_ELEM_VERSION2:
|
||||
@@ -128,44 +128,9 @@ static int wps_parse_vendor_ext(struct wps_parse_attr *attr, const u8 *pos,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 wps_ignore_null_padding_in_attr(const u8 *pos, u16 type, u16 attr_data_len)
|
||||
{
|
||||
u16 len = attr_data_len;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
#ifdef CONFIG_WPA_WPS_WARS
|
||||
/*
|
||||
* Some AP's keep NULL-padding at the end of some variable length WPS Attributes.
|
||||
* This is not as par the WPS2.0 specs, but to avoid interop issues, ignore the
|
||||
* padding by reducing the attribute length by 1.
|
||||
*/
|
||||
switch (type) {
|
||||
case ATTR_MANUFACTURER:
|
||||
case ATTR_MODEL_NAME:
|
||||
case ATTR_MODEL_NUMBER:
|
||||
case ATTR_SERIAL_NUMBER:
|
||||
case ATTR_DEV_NAME:
|
||||
case ATTR_SSID:
|
||||
case ATTR_NETWORK_KEY:
|
||||
if (pos[len - 1] == 0)
|
||||
len--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
||||
const u8 *pos, u16 attr_data_len)
|
||||
const u8 *pos, u16 len)
|
||||
{
|
||||
u16 len;
|
||||
|
||||
len = wps_ignore_null_padding_in_attr(pos, type, attr_data_len);
|
||||
|
||||
switch (type) {
|
||||
case ATTR_VERSION:
|
||||
if (len != 1) {
|
||||
@@ -617,7 +582,7 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
|
||||
pos += 2;
|
||||
len = WPA_GET_BE16(pos);
|
||||
pos += 2;
|
||||
wpa_printf(MSG_DEBUG, "WPS: attr type=0x%x len=%u",
|
||||
wpa_printf(MSG_MSGDUMP, "WPS: attr type=0x%x len=%u",
|
||||
type, len);
|
||||
if (len > end - pos) {
|
||||
wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
|
||||
|
||||
@@ -25,8 +25,6 @@ extern int wps_testing_dummy_cred;
|
||||
|
||||
#endif /* CONFIG_WPS_TESTING */
|
||||
|
||||
#define CONFIG_WPS_STRICT
|
||||
|
||||
/* Diffie-Hellman 1536-bit MODP Group; RFC 3526, Group 5 */
|
||||
#define WPS_DH_GROUP 5
|
||||
|
||||
@@ -310,7 +308,8 @@ enum wps_dev_subcateg {
|
||||
WPS_DEV_GAMING_XBOX = 1,
|
||||
WPS_DEV_GAMING_XBOX360 = 2,
|
||||
WPS_DEV_GAMING_PLAYSTATION = 3,
|
||||
WPS_DEV_PHONE_WINDOWS_MOBILE = 1
|
||||
WPS_DEV_PHONE_WINDOWS_MOBILE = 1,
|
||||
WPS_DEV_PHONE_SINGLE_MODE = 2,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "wps/wps.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_WPS_STRICT
|
||||
|
||||
#ifndef WPS_STRICT_ALL
|
||||
#define WPS_STRICT_WPS2
|
||||
#endif /* WPS_STRICT_ALL */
|
||||
@@ -95,7 +97,6 @@ static int wps_validate_response_type(const u8 *response_type, int mandatory)
|
||||
|
||||
static int valid_config_methods(u16 val, int wps2)
|
||||
{
|
||||
#ifndef CONFIG_WPA_WPS_WARS
|
||||
if (wps2) {
|
||||
if (!(val & 0x6000) && (val & WPS_CONFIG_DISPLAY)) {
|
||||
wpa_printf(MSG_INFO, "WPS-STRICT: Display flag "
|
||||
@@ -109,7 +110,6 @@ static int valid_config_methods(u16 val, int wps2)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2363,3 +2363,4 @@ _out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user