Skip to content

Commit

Permalink
Merge branch 'feature/pbkdf2_fast_implementation' into 'master'
Browse files Browse the repository at this point in the history
esp_wifi: Port fast_pbkdf2 implementation to calculate PMK

See merge request espressif/esp-idf!24287
  • Loading branch information
jack0c committed Sep 12, 2023
2 parents c3bd8ab + eafc34b commit 62720ff
Show file tree
Hide file tree
Showing 9 changed files with 478 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitlab/ci/target-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,7 @@ UT_S2_SDSPI:

UT_C2:
extends: .unit_test_esp32c2_template
parallel: 2
tags:
- ESP32C2_IDF
- UT_T1_1
Expand All @@ -1419,6 +1420,7 @@ UT_C3_SDSPI:

UT_C6:
extends: .unit_test_esp32c6_template
parallel: 2
tags:
- ESP32C6_IDF
- UT_T1_1
Expand Down
18 changes: 18 additions & 0 deletions components/mbedtls/port/include/sha1_alt.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ typedef struct {
esp_mbedtls_sha1_mode mode;
} mbedtls_sha1_context;

/**
* \brief Set the SHA-1 mode for a mbedtls_sha1_context.
*
* \param ctx The SHA-1 context structure.
* \param mode The SHA-1 mode to be set. It can be one of the following:
* - ESP_MBEDTLS_SHA1_UNUSED: Indicates that the first block hasn't been processed yet.
* - ESP_MBEDTLS_SHA1_HARDWARE: Specifies the use of hardware SHA engine for SHA-1 calculations.
* - ESP_MBEDTLS_SHA1_SOFTWARE: Specifies the use of software-based SHA-1 calculations.
*
* \return None.
*/
static inline void esp_mbedtls_set_sha1_mode(mbedtls_sha1_context *ctx, esp_mbedtls_sha1_mode mode)
{
if (ctx) {
ctx->mode = mode;
}
}

#elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME

typedef enum {
Expand Down
2 changes: 2 additions & 0 deletions components/wpa_supplicant/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ endif()

if(CONFIG_ESP_WIFI_MBEDTLS_CRYPTO)
set(crypto_src
"esp_supplicant/src/crypto/fastpbkdf2.c"
"esp_supplicant/src/crypto/crypto_mbedtls.c"
"esp_supplicant/src/crypto/crypto_mbedtls-bignum.c"
"esp_supplicant/src/crypto/crypto_mbedtls-rsa.c"
Expand Down Expand Up @@ -229,6 +230,7 @@ target_compile_definitions(${COMPONENT_LIB} PRIVATE
CONFIG_IEEE80211W
CONFIG_SHA256
CONFIG_NO_RADIUS
CONFIG_FAST_PBKDF2
)

if(CONFIG_ESP_WIFI_ENABLE_WPA3_SAE)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -36,6 +36,10 @@
#include "crypto.h"
#include "mbedtls/esp_config.h"

#ifdef CONFIG_FAST_PBKDF2
#include "fastpbkdf2.h"
#endif

static int digest_vector(mbedtls_md_type_t md_type, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
Expand Down Expand Up @@ -745,16 +749,22 @@ int crypto_mod_exp(const uint8_t *base, size_t base_len,
int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
int iterations, u8 *buf, size_t buflen)
{
#ifdef CONFIG_FAST_PBKDF2
fastpbkdf2_hmac_sha1((const u8 *) passphrase, os_strlen(passphrase),
ssid, ssid_len, iterations, buf, buflen);
return 0;
#else
int ret = mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, (const u8 *) passphrase,
os_strlen(passphrase) , ssid,
ssid_len, iterations, 32, buf);
ssid_len, iterations, buflen, buf);
if (ret != 0) {
ret = -1;
goto cleanup;
}

cleanup:
return ret;
#endif
}

#ifdef MBEDTLS_DES_C
Expand Down
325 changes: 325 additions & 0 deletions components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* SPDX-FileCopyrightText: 2015 Joseph Birr-Pixton <[email protected]>
*
* SPDX-License-Identifier: CC0-1.0
*/

/*
* fastpbkdf2 - Faster PBKDF2-HMAC calculation
* Written in 2015 by Joseph Birr-Pixton <[email protected]>
*
* To the extent possible under law, the author(s) have dedicated all
* copyright and related and neighboring rights to this software to the
* public domain worldwide. This software is distributed without any
* warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication
* along with this software. If not, see
* <http://creativecommons.org/publicdomain/zero/1.0/>.
*/

#ifndef FASTPBKDF2_H
#define FASTPBKDF2_H

#include <stdlib.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/** Calculates PBKDF2-HMAC-SHA1.
*
* @p npw bytes at @p pw are the password input.
* @p nsalt bytes at @p salt are the salt input.
* @p iterations is the PBKDF2 iteration count and must be non-zero.
* @p nout bytes of output are written to @p out. @p nout must be non-zero.
*
* This function cannot fail; it does not report errors.
*/
void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw,
const uint8_t *salt, size_t nsalt,
uint32_t iterations,
uint8_t *out, size_t nout);
#ifdef __cplusplus
}
#endif

#endif
68 changes: 68 additions & 0 deletions components/wpa_supplicant/test/test_fast_pbkdf2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "string.h"
#include <inttypes.h>
#include "unity.h"
#include "utils/common.h"
#include "mbedtls/pkcs5.h"
#include "crypto/sha1.h"

#if SOC_WIFI_SUPPORTED

#define PMK_LEN 32

TEST_CASE("Test pbkdf2", "[crypto-pbkdf2]")
{
uint8_t PMK[PMK_LEN];
uint8_t ssid_len;
uint8_t passphrase_len;
uint8_t ssid[MAX_SSID_LEN];
uint8_t passphrase[MAX_PASSPHRASE_LEN];
uint8_t expected_pmk1[PMK_LEN] =
{0xe7, 0x90, 0xd0, 0x65, 0x67, 0xf0, 0xbf, 0xca, 0xca, 0x10, 0x88, 0x0b, 0x85, 0xb2, 0x33, 0xe5,
0xe1, 0xd5, 0xe5, 0xb8, 0xd0, 0xfd, 0x94, 0x60, 0x56, 0x95, 0x5e, 0x41, 0x5a, 0x7f, 0xfa, 0xfa};

uint8_t expected_pmk[PMK_LEN];

/* Compare Fast PBKDF output with expected output*/
pbkdf2_sha1("espressif", (uint8_t *)"espressif", strlen("espressif"), 4096, PMK, PMK_LEN);
TEST_ASSERT(memcmp(PMK, expected_pmk1, PMK_LEN) == 0);

/* Compare fast PBKDF output with mbedtls pbkdf2 function's output */
pbkdf2_sha1("espressif2", (uint8_t *)"espressif2", strlen("espressif2"), 4096, PMK, PMK_LEN);
mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, (const unsigned char *) "espressif2",
strlen("espressif2") , (const unsigned char *)"espressif2",
strlen("espressif2"), 4096, PMK_LEN, expected_pmk);
TEST_ASSERT(memcmp(PMK, expected_pmk, PMK_LEN) == 0);

/* Calculate PMK using random ssid and passphrase and compare */
os_memset(ssid, 0, MAX_SSID_LEN);
os_memset(passphrase, 0, MAX_PASSPHRASE_LEN);
ssid_len = os_random();
ssid_len %= MAX_SSID_LEN;

os_get_random(ssid, ssid_len);

passphrase_len = os_random();
passphrase_len %= MAX_PASSPHRASE_LEN;

os_get_random(passphrase, passphrase_len);
pbkdf2_sha1((char *)passphrase, ssid, ssid_len, 4096, PMK, PMK_LEN);
mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, (const unsigned char *) passphrase,
strlen((char *)passphrase) , (const unsigned char *)ssid,
ssid_len, 4096, PMK_LEN, expected_pmk);

/* Dump values if fails */
if (memcmp(PMK, expected_pmk, PMK_LEN) != 0) {
ESP_LOG_BUFFER_HEXDUMP("passphrase", passphrase, passphrase_len, ESP_LOG_INFO);
ESP_LOG_BUFFER_HEXDUMP("ssid", ssid, ssid_len, ESP_LOG_INFO);
ESP_LOG_BUFFER_HEXDUMP("PMK", PMK, PMK_LEN, ESP_LOG_INFO);
ESP_LOG_BUFFER_HEXDUMP("expected_pmk", expected_pmk, PMK_LEN, ESP_LOG_INFO);
}
TEST_ASSERT(memcmp(PMK, expected_pmk, PMK_LEN) == 0);
}

#endif /* SOC_WIFI_SUPPORTED */
2 changes: 2 additions & 0 deletions docs/en/COPYRIGHT.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ These third party libraries can be included into the application (firmware) prod

* `wpa_supplicant`_ Copyright (c) 2003-2022 Jouni Malinen <[email protected]> and contributors and licensed under the BSD license.

* :component_file:`Fast PBKDF2 <wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c>` Copyright (c) 2015 Joseph Birr-Pixton and licensed under CC0 Public Domain Dedication license.

* `FreeBSD net80211`_ Copyright (c) 2004-2008 Sam Leffler, Errno Consulting and licensed under the BSD license.

* `argtable3`_ argument parsing library Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann and licensed under 3-clause BSD license. argtable3 also includes the following software components. For details, please see argtable3 :component_file:`LICENSE file<console/argtable3/LICENSE>`.
Expand Down
1 change: 1 addition & 0 deletions tools/ci/check_copyright_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ ignore:
- components/http_parser/
- components/wpa_supplicant/src/
- '!components/wpa_supplicant/esp_supplicant/'
- components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2*
- components/bt/host/bluedroid/
- '!components/bt/host/bluedroid/api/'
- '!components/bt/host/bluedroid/btc/'
Expand Down

0 comments on commit 62720ff

Please sign in to comment.