mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
ci(wpa_supplicant): Add UT for supplicant crypto
This commit is contained in:
@@ -633,7 +633,7 @@ menu "Wi-Fi"
|
||||
config ESP_WIFI_P256_ACCEL
|
||||
bool "Enable P-256 crypto acceleration"
|
||||
depends on ESP_WIFI_MBEDTLS_CRYPTO
|
||||
default y
|
||||
default n
|
||||
help
|
||||
Enable Espressif-specific P-256 acceleration in the WPA supplicant
|
||||
crypto layer. This reduces SAE and DPP latency on supported targets
|
||||
|
||||
@@ -604,6 +604,12 @@ static void p256_fast_point_from_affine(p256_fast_jac_point *p,
|
||||
os_memcpy(p->Z, one_mont, sizeof(p->Z));
|
||||
}
|
||||
|
||||
#define P256_WINDOW_BITS 4U
|
||||
#define P256_WINDOW_ENTRY_COUNT (1U << P256_WINDOW_BITS)
|
||||
#define P256_WINDOW_PRECOMP_COUNT (P256_WINDOW_ENTRY_COUNT - 1U)
|
||||
#define P256_WINDOW_BATCH_COUNT (P256_WINDOW_PRECOMP_COUNT - 1U)
|
||||
#define P256_SCALAR_WINDOW_COUNT ((P256_WORDS * 32U) / P256_WINDOW_BITS)
|
||||
|
||||
static void p256_fast_point_double(p256_fast_jac_point *r)
|
||||
{
|
||||
u32 z2[P256_WORDS], y2[P256_WORDS], y4[P256_WORDS];
|
||||
@@ -739,7 +745,7 @@ static int p256_fast_points_batch_to_affine_mont(
|
||||
const p256_fast_jac_point *points, size_t num,
|
||||
u32(*xs)[P256_WORDS], u32(*ys)[P256_WORDS])
|
||||
{
|
||||
u32 prefix[14][P256_WORDS];
|
||||
u32 prefix[P256_WINDOW_BATCH_COUNT][P256_WORDS];
|
||||
u32 prod_std[P256_WORDS], inv_std[P256_WORDS];
|
||||
u32 running_inv[P256_WORDS], inv_z[P256_WORDS];
|
||||
u32 tmp[P256_WORDS];
|
||||
@@ -789,9 +795,9 @@ static int p256_fast_points_batch_to_affine_mont(
|
||||
}
|
||||
|
||||
struct p256_window4_scratch {
|
||||
p256_fast_jac_point precomp[15];
|
||||
u32 table_x[16][P256_WORDS];
|
||||
u32 table_y[16][P256_WORDS];
|
||||
p256_fast_jac_point precomp[P256_WINDOW_PRECOMP_COUNT];
|
||||
u32 table_x[P256_WINDOW_ENTRY_COUNT][P256_WORDS];
|
||||
u32 table_y[P256_WINDOW_ENTRY_COUNT][P256_WORDS];
|
||||
};
|
||||
|
||||
static int crypto_ec_point_mul_p256_window4_core(const mbedtls_ecp_group *grp,
|
||||
@@ -846,14 +852,15 @@ static int crypto_ec_point_mul_p256_window4_core(const mbedtls_ecp_group *grp,
|
||||
p256_fast_point_from_affine(&scratch->precomp[0], x_mont, y_mont, one_mont);
|
||||
os_memcpy(&scratch->precomp[1], &scratch->precomp[0], sizeof(scratch->precomp[1]));
|
||||
p256_fast_point_double(&scratch->precomp[1]);
|
||||
for (window = 2; window < 15; window++) {
|
||||
for (window = 2; window < P256_WINDOW_PRECOMP_COUNT; window++) {
|
||||
os_memcpy(&scratch->precomp[window], &scratch->precomp[window - 1],
|
||||
sizeof(scratch->precomp[window]));
|
||||
p256_fast_point_add_mixed(&scratch->precomp[window], x_mont, y_mont,
|
||||
one_mont);
|
||||
}
|
||||
|
||||
if (p256_fast_points_batch_to_affine_mont(&scratch->precomp[1], 14,
|
||||
if (p256_fast_points_batch_to_affine_mont(&scratch->precomp[1],
|
||||
P256_WINDOW_BATCH_COUNT,
|
||||
&scratch->table_x[2],
|
||||
&scratch->table_y[2]) != 0) {
|
||||
ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
@@ -862,14 +869,17 @@ static int crypto_ec_point_mul_p256_window4_core(const mbedtls_ecp_group *grp,
|
||||
|
||||
p256_fast_point_set_zero(r);
|
||||
|
||||
for (window = 63; window >= 0; window--) {
|
||||
u32 idx = p256_words_get_window(scalar, (unsigned) window * 4, 4);
|
||||
for (window = P256_SCALAR_WINDOW_COUNT - 1; window >= 0; window--) {
|
||||
u32 idx = p256_words_get_window(scalar,
|
||||
(unsigned) window * P256_WINDOW_BITS,
|
||||
P256_WINDOW_BITS);
|
||||
|
||||
if (started) {
|
||||
p256_fast_point_double(r);
|
||||
p256_fast_point_double(r);
|
||||
p256_fast_point_double(r);
|
||||
p256_fast_point_double(r);
|
||||
unsigned int dbl;
|
||||
|
||||
for (dbl = 0; dbl < P256_WINDOW_BITS; dbl++) {
|
||||
p256_fast_point_double(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == 0U) {
|
||||
@@ -1001,9 +1011,7 @@ static int crypto_ec_point_mul_fast(const mbedtls_ecp_group *grp,
|
||||
if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ESP_WIFI_P256_SOFT_ACCEL
|
||||
#elif ESP_WIFI_P256_SOFT_ACCEL
|
||||
if (crypto_ec_is_p256_group(grp)) {
|
||||
return crypto_ec_point_mul_p256_jacobian_fast(grp, p, k, res);
|
||||
}
|
||||
@@ -1152,7 +1160,6 @@ struct crypto_bignum *crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
|
||||
(const struct crypto_bignum *) &grp->P,
|
||||
(struct crypto_bignum *) &temp));
|
||||
|
||||
#if CONFIG_ESP_WIFI_P256_ACCEL
|
||||
if (mbedtls_ecp_group_a_is_minus_3(grp)) {
|
||||
/*
|
||||
* For NIST P-curves used in SAE, a == -3. Compute (-3x + b) mod p
|
||||
@@ -1178,11 +1185,6 @@ struct crypto_bignum *crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
|
||||
&grp->A));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&temp2, &temp2, &grp->P));
|
||||
}
|
||||
#else
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&temp2, (const mbedtls_mpi *) x,
|
||||
&grp->A));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&temp2, &temp2, &grp->P));
|
||||
#endif
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&temp2, &temp2, &grp->B));
|
||||
while (mbedtls_mpi_cmp_mpi(&temp2, &grp->P) >= 0) {
|
||||
|
||||
@@ -44,6 +44,42 @@ struct dpp_global {
|
||||
|
||||
extern struct dpp_curve_params dpp_curves[];
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
u64 dpp_last_auth_req_parse_us;
|
||||
u64 dpp_last_auth_resp_form_us;
|
||||
u64 dpp_last_auth_req_total_us;
|
||||
|
||||
static u64 dpp_time_us(void)
|
||||
{
|
||||
struct os_reltime now;
|
||||
|
||||
if (os_get_reltime(&now) < 0)
|
||||
return 0;
|
||||
|
||||
return ((u64) now.sec * 1000000) + now.usec;
|
||||
}
|
||||
|
||||
static void dpp_auth_req_set_timing(struct dpp_authentication *auth,
|
||||
u64 start_us, u64 parse_done_us)
|
||||
{
|
||||
u64 end_us;
|
||||
|
||||
if (!auth || !start_us || !parse_done_us || parse_done_us < start_us)
|
||||
return;
|
||||
|
||||
end_us = dpp_time_us();
|
||||
if (!end_us || end_us < parse_done_us)
|
||||
return;
|
||||
|
||||
auth->auth_req_parse_us = parse_done_us - start_us;
|
||||
auth->auth_resp_form_us = end_us - parse_done_us;
|
||||
auth->auth_req_total_us = end_us - start_us;
|
||||
dpp_last_auth_req_parse_us = auth->auth_req_parse_us;
|
||||
dpp_last_auth_resp_form_us = auth->auth_resp_form_us;
|
||||
dpp_last_auth_req_total_us = auth->auth_req_total_us;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define TRANSACTION_ID_ATTR_SET_LEN 5
|
||||
#define CONNECTOR_ATTR_SET_LEN 4
|
||||
|
||||
@@ -1707,6 +1743,13 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
||||
u16 i_capab_len;
|
||||
u16 i_bootstrap_len;
|
||||
struct dpp_authentication *auth = NULL;
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
u64 start_us = dpp_time_us();
|
||||
u64 parse_done_us = 0;
|
||||
dpp_last_auth_req_parse_us = 0;
|
||||
dpp_last_auth_resp_form_us = 0;
|
||||
dpp_last_auth_req_total_us = 0;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
if (dpp_test == DPP_TEST_STOP_AT_AUTH_REQ) {
|
||||
@@ -1892,9 +1935,15 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: Mutual authentication required with QR Codes, but peer info is not yet available - request more time");
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
parse_done_us = dpp_time_us();
|
||||
#endif
|
||||
if (dpp_auth_build_resp_status(auth,
|
||||
DPP_STATUS_RESPONSE_PENDING) < 0)
|
||||
goto fail;
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
dpp_auth_req_set_timing(auth, start_us, parse_done_us);
|
||||
#endif
|
||||
i_bootstrap = dpp_get_attr(attr_start, attr_len,
|
||||
DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
|
||||
&i_bootstrap_len);
|
||||
@@ -1912,8 +1961,14 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
||||
"%s", hex);
|
||||
return auth;
|
||||
}
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
parse_done_us = dpp_time_us();
|
||||
#endif
|
||||
if (dpp_auth_build_resp_ok(auth) < 0)
|
||||
goto fail;
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
dpp_auth_req_set_timing(auth, start_us, parse_done_us);
|
||||
#endif
|
||||
|
||||
return auth;
|
||||
|
||||
@@ -1926,8 +1981,14 @@ not_compatible:
|
||||
auth->configurator = 0;
|
||||
auth->peer_protocol_key = pi;
|
||||
pi = NULL;
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
parse_done_us = dpp_time_us();
|
||||
#endif
|
||||
if (dpp_auth_build_resp_status(auth, DPP_STATUS_NOT_COMPATIBLE) < 0)
|
||||
goto fail;
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
dpp_auth_req_set_timing(auth, start_us, parse_done_us);
|
||||
#endif
|
||||
|
||||
auth->remove_on_tx_status = 1;
|
||||
return auth;
|
||||
|
||||
@@ -317,8 +317,19 @@ struct dpp_authentication {
|
||||
char *groups_override;
|
||||
unsigned int ignore_netaccesskey_mismatch:1;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
u64 auth_req_parse_us;
|
||||
u64 auth_resp_form_us;
|
||||
u64 auth_req_total_us;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
extern u64 dpp_last_auth_req_parse_us;
|
||||
extern u64 dpp_last_auth_resp_form_us;
|
||||
extern u64 dpp_last_auth_req_total_us;
|
||||
#endif
|
||||
|
||||
struct dpp_configurator {
|
||||
struct dl_list list;
|
||||
unsigned int id;
|
||||
|
||||
@@ -7,7 +7,7 @@ idf_component_register(SRCS
|
||||
"test_sae.c"
|
||||
"test_wpa_supplicant_main.c"
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES wpa_supplicant mbedtls esp_wifi esp_event unity
|
||||
PRIV_REQUIRES wpa_supplicant mbedtls esp_wifi esp_event unity esp_psram esp_timer
|
||||
WHOLE_ARCHIVE)
|
||||
|
||||
idf_component_get_property(esp_supplicant_dir wpa_supplicant COMPONENT_DIR)
|
||||
@@ -23,3 +23,7 @@ target_include_directories(${COMPONENT_LIB} PRIVATE ${esp_supplicant_dir}/src)
|
||||
add_definitions(-DWIFI_SUPPLICANT_MD5=\"${WIFI_SUPPLICANT_MD5}\")
|
||||
add_definitions(-DCONFIG_WPA3_SAE)
|
||||
add_definitions(-DCONFIG_DPP)
|
||||
|
||||
if(CONFIG_ESP_WIFI_TESTING_OPTIONS)
|
||||
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_TESTING_OPTIONS)
|
||||
endif()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -14,12 +14,211 @@
|
||||
#include "utils/includes.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
#include "esp_timer.h"
|
||||
#include "mbedtls/ecdh.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/pk.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_wpa_supplicant_common.h"
|
||||
|
||||
typedef struct crypto_bignum crypto_bignum;
|
||||
|
||||
static const uint8_t test_secp256r1_prime[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
static const uint8_t test_p256_bignum_vals[][32] = {
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xca, 0xfe, 0xba, 0xbe, 0x88, 0x99, 0xaa, 0xbb,
|
||||
0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe,
|
||||
0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0
|
||||
},
|
||||
{
|
||||
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
|
||||
0x0f, 0xed, 0xcb, 0xa9, 0x87, 0x65, 0x43, 0x21,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
||||
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10
|
||||
},
|
||||
{
|
||||
0xa5, 0x5a, 0xa5, 0x5a, 0xa5, 0x5a, 0xa5, 0x5a,
|
||||
0x5a, 0xa5, 0x5a, 0xa5, 0x5a, 0xa5, 0x5a, 0xa5,
|
||||
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
|
||||
0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0
|
||||
}
|
||||
};
|
||||
|
||||
static const uint8_t test_p256_scalar_seeds[][32] = {
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xca, 0xfe, 0xba, 0xbe, 0x88, 0x99, 0xaa, 0xbb,
|
||||
0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe,
|
||||
0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0
|
||||
},
|
||||
{
|
||||
0xa5, 0x5a, 0xa5, 0x5a, 0xa5, 0x5a, 0xa5, 0x5a,
|
||||
0x5a, 0xa5, 0x5a, 0xa5, 0x5a, 0xa5, 0x5a, 0xa5,
|
||||
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
|
||||
0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0
|
||||
},
|
||||
{
|
||||
0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78,
|
||||
0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0,
|
||||
0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
|
||||
0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned int test_p256_point_multipliers[] = { 7, 13 };
|
||||
static const unsigned int test_small_exponents[] = { 0, 1, 2, 3 };
|
||||
|
||||
static int test_mbedtls_rng(void *ctx, unsigned char *buf, size_t len)
|
||||
{
|
||||
(void) ctx;
|
||||
return os_get_random(buf, len) == 0 ? 0 : MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||
}
|
||||
|
||||
static void test_load_valid_p256_scalar(const mbedtls_ecp_group *grp,
|
||||
const uint8_t *seed, size_t seed_len,
|
||||
mbedtls_mpi *scalar)
|
||||
{
|
||||
mbedtls_mpi range;
|
||||
|
||||
mbedtls_mpi_init(&range);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_sub_int(&range, &grp->N, 1));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_read_binary(scalar, seed, seed_len));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_mod_mpi(scalar, scalar, &range));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_add_int(scalar, scalar, 1));
|
||||
mbedtls_mpi_free(&range);
|
||||
}
|
||||
|
||||
static void test_make_p256_affine_point(mbedtls_ecp_group *grp,
|
||||
unsigned int multiplier,
|
||||
mbedtls_ecp_point *point)
|
||||
{
|
||||
mbedtls_mpi k;
|
||||
|
||||
mbedtls_mpi_init(&k);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_lset(&k, multiplier));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ecp_mul(grp, point, &k, &grp->G,
|
||||
test_mbedtls_rng, NULL));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_cmp_int(&point->MBEDTLS_PRIVATE(Z), 1));
|
||||
mbedtls_mpi_free(&k);
|
||||
}
|
||||
|
||||
static int test_legendre_reference(const mbedtls_mpi *a, const mbedtls_mpi *p)
|
||||
{
|
||||
mbedtls_mpi a_mod, exp, res, one, pm1;
|
||||
int legendre = -2;
|
||||
|
||||
mbedtls_mpi_init(&a_mod);
|
||||
mbedtls_mpi_init(&exp);
|
||||
mbedtls_mpi_init(&res);
|
||||
mbedtls_mpi_init(&one);
|
||||
mbedtls_mpi_init(&pm1);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_mod_mpi(&a_mod, a, p));
|
||||
if (mbedtls_mpi_cmp_int(&a_mod, 0) == 0) {
|
||||
legendre = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_copy(&exp, p));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_sub_int(&exp, &exp, 1));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_shift_r(&exp, 1));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_exp_mod(&res, &a_mod, &exp, p, NULL));
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_lset(&one, 1));
|
||||
if (mbedtls_mpi_cmp_mpi(&res, &one) == 0) {
|
||||
legendre = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_copy(&pm1, p));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_sub_int(&pm1, &pm1, 1));
|
||||
if (mbedtls_mpi_cmp_mpi(&res, &pm1) == 0) {
|
||||
legendre = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
TEST_FAIL_MESSAGE("Unexpected Legendre reference result");
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&a_mod);
|
||||
mbedtls_mpi_free(&exp);
|
||||
mbedtls_mpi_free(&res);
|
||||
mbedtls_mpi_free(&one);
|
||||
mbedtls_mpi_free(&pm1);
|
||||
return legendre;
|
||||
}
|
||||
|
||||
static void test_print_crypto_timing(const char *label,
|
||||
int64_t generic_total_us, size_t generic_ops,
|
||||
int64_t api_total_us, size_t api_ops)
|
||||
{
|
||||
long long generic_avg = generic_ops ? (long long)(generic_total_us / (int64_t) generic_ops) : 0;
|
||||
long long api_avg = api_ops ? (long long)(api_total_us / (int64_t) api_ops) : 0;
|
||||
|
||||
printf("%s timing(us): generic_avg=%lld api_avg=%lld generic_total=%lld api_total=%lld ops=%u\n",
|
||||
label, generic_avg, api_avg,
|
||||
(long long) generic_total_us, (long long) api_total_us,
|
||||
(unsigned int) api_ops);
|
||||
}
|
||||
|
||||
static int test_mbedtls_ecdh(const struct crypto_ec_key *key_own,
|
||||
const struct crypto_ec_key *key_peer,
|
||||
u8 *secret, size_t *secret_len)
|
||||
{
|
||||
mbedtls_ecdh_context ctx;
|
||||
mbedtls_pk_context *own = (mbedtls_pk_context *) key_own;
|
||||
mbedtls_pk_context *peer = (mbedtls_pk_context *) key_peer;
|
||||
int ret = -1;
|
||||
|
||||
mbedtls_ecdh_init(&ctx);
|
||||
|
||||
if (mbedtls_ecdh_get_params(&ctx, mbedtls_pk_ec(*own),
|
||||
MBEDTLS_ECDH_OURS) != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mbedtls_ecdh_get_params(&ctx, mbedtls_pk_ec(*peer),
|
||||
MBEDTLS_ECDH_THEIRS) != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mbedtls_ecdh_calc_secret(&ctx, secret_len, secret, 66,
|
||||
test_mbedtls_rng, NULL) != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
mbedtls_ecdh_free(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_mbedtls_key_gen_p256(mbedtls_pk_context *kctx)
|
||||
{
|
||||
mbedtls_pk_init(kctx);
|
||||
|
||||
if (mbedtls_pk_setup(kctx,
|
||||
mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(*kctx),
|
||||
test_mbedtls_rng, NULL) != 0) {
|
||||
mbedtls_pk_free(kctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]")
|
||||
{
|
||||
set_leak_threshold(300);
|
||||
@@ -203,6 +402,38 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]")
|
||||
|
||||
}
|
||||
|
||||
{ /** BN mul mod on secp256r1 prime */
|
||||
uint8_t val[32];
|
||||
uint8_t one[32] = {0};
|
||||
crypto_bignum *bn1, *bn2, *bn3, *mulmod;
|
||||
|
||||
one[0] = 1;
|
||||
os_memcpy(val, test_secp256r1_prime, sizeof(val));
|
||||
val[31]--;
|
||||
|
||||
mulmod = crypto_bignum_init();
|
||||
TEST_ASSERT_NOT_NULL(mulmod);
|
||||
|
||||
bn1 = crypto_bignum_init_set(val, sizeof(val));
|
||||
TEST_ASSERT_NOT_NULL(bn1);
|
||||
|
||||
bn2 = crypto_bignum_init_set(val, sizeof(val));
|
||||
TEST_ASSERT_NOT_NULL(bn2);
|
||||
|
||||
bn3 = crypto_bignum_init_set(test_secp256r1_prime,
|
||||
sizeof(test_secp256r1_prime));
|
||||
TEST_ASSERT_NOT_NULL(bn3);
|
||||
|
||||
TEST_ASSERT(crypto_bignum_mulmod(bn1, bn2, bn3, mulmod) == 0);
|
||||
TEST_ASSERT(crypto_bignum_to_bin(mulmod, val, sizeof(val), 0) == 1);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(one, val, 1);
|
||||
|
||||
crypto_bignum_deinit(bn1, 1);
|
||||
crypto_bignum_deinit(bn2, 1);
|
||||
crypto_bignum_deinit(bn3, 1);
|
||||
crypto_bignum_deinit(mulmod, 1);
|
||||
}
|
||||
|
||||
{ /** BN exp mod*/
|
||||
uint8_t buf1[32], buf2[32], buf3[32], buf4[32], buf5[32];
|
||||
|
||||
@@ -273,6 +504,84 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]")
|
||||
crypto_bignum_deinit(bn2, 1);
|
||||
|
||||
}
|
||||
|
||||
{ /** BN Legendre symbol test on secp256r1 prime */
|
||||
uint8_t val[32] = {0};
|
||||
crypto_bignum *bn_val, *bn_p;
|
||||
|
||||
bn_p = crypto_bignum_init_set(test_secp256r1_prime,
|
||||
sizeof(test_secp256r1_prime));
|
||||
TEST_ASSERT_NOT_NULL(bn_p);
|
||||
|
||||
val[31] = 1;
|
||||
bn_val = crypto_bignum_init_set(val, sizeof(val));
|
||||
TEST_ASSERT_NOT_NULL(bn_val);
|
||||
TEST_ASSERT(crypto_bignum_legendre(bn_val, bn_p) == 1);
|
||||
crypto_bignum_deinit(bn_val, 1);
|
||||
|
||||
os_memset(val, 0, sizeof(val));
|
||||
val[31] = 3;
|
||||
bn_val = crypto_bignum_init_set(val, sizeof(val));
|
||||
TEST_ASSERT_NOT_NULL(bn_val);
|
||||
TEST_ASSERT(crypto_bignum_legendre(bn_val, bn_p) == -1);
|
||||
crypto_bignum_deinit(bn_val, 1);
|
||||
|
||||
os_memset(val, 0, sizeof(val));
|
||||
bn_val = crypto_bignum_init_set(val, sizeof(val));
|
||||
TEST_ASSERT_NOT_NULL(bn_val);
|
||||
TEST_ASSERT(crypto_bignum_legendre(bn_val, bn_p) == 0);
|
||||
crypto_bignum_deinit(bn_val, 1);
|
||||
|
||||
crypto_bignum_deinit(bn_p, 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test secp256r1 fast bignum paths against mbedtls reference", "[wpa_crypto]")
|
||||
{
|
||||
crypto_bignum *bn_p;
|
||||
int i;
|
||||
|
||||
set_leak_threshold(620);
|
||||
|
||||
bn_p = crypto_bignum_init_set(test_secp256r1_prime,
|
||||
sizeof(test_secp256r1_prime));
|
||||
TEST_ASSERT_NOT_NULL(bn_p);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_p256_bignum_vals); i++) {
|
||||
crypto_bignum *bn_a = crypto_bignum_init_set(test_p256_bignum_vals[i], sizeof(test_p256_bignum_vals[i]));
|
||||
crypto_bignum *bn_b = crypto_bignum_init_set(
|
||||
test_p256_bignum_vals[(i + 1) % ARRAY_SIZE(test_p256_bignum_vals)],
|
||||
sizeof(test_p256_bignum_vals[0]));
|
||||
crypto_bignum *bn_mul = crypto_bignum_init();
|
||||
mbedtls_mpi ref_mul;
|
||||
int ref_legendre;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(bn_a);
|
||||
TEST_ASSERT_NOT_NULL(bn_b);
|
||||
TEST_ASSERT_NOT_NULL(bn_mul);
|
||||
|
||||
mbedtls_mpi_init(&ref_mul);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_mul_mpi(&ref_mul,
|
||||
(const mbedtls_mpi *) bn_a,
|
||||
(const mbedtls_mpi *) bn_b));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_mod_mpi(&ref_mul, &ref_mul,
|
||||
(const mbedtls_mpi *) bn_p));
|
||||
|
||||
TEST_ASSERT_EQUAL(0, crypto_bignum_mulmod(bn_a, bn_b, bn_p, bn_mul));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_cmp_mpi((const mbedtls_mpi *) bn_mul,
|
||||
&ref_mul));
|
||||
|
||||
ref_legendre = test_legendre_reference((const mbedtls_mpi *) bn_a,
|
||||
(const mbedtls_mpi *) bn_p);
|
||||
TEST_ASSERT_EQUAL(ref_legendre, crypto_bignum_legendre(bn_a, bn_p));
|
||||
|
||||
mbedtls_mpi_free(&ref_mul);
|
||||
crypto_bignum_deinit(bn_a, 1);
|
||||
crypto_bignum_deinit(bn_b, 1);
|
||||
crypto_bignum_deinit(bn_mul, 1);
|
||||
}
|
||||
|
||||
crypto_bignum_deinit(bn_p, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -536,3 +845,385 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Test secp256r1 point multiply against mbedtls reference", "[wpa_crypto]")
|
||||
{
|
||||
struct crypto_ec *e;
|
||||
struct crypto_ec_point *p = NULL;
|
||||
struct crypto_ec_point *res = NULL;
|
||||
mbedtls_ecp_point ref;
|
||||
int i, j;
|
||||
|
||||
set_leak_threshold(620);
|
||||
|
||||
e = crypto_ec_init(19);
|
||||
TEST_ASSERT_NOT_NULL(e);
|
||||
|
||||
p = crypto_ec_point_init(e);
|
||||
TEST_ASSERT_NOT_NULL(p);
|
||||
res = crypto_ec_point_init(e);
|
||||
TEST_ASSERT_NOT_NULL(res);
|
||||
mbedtls_ecp_point_init(&ref);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_p256_point_multipliers); i++) {
|
||||
test_make_p256_affine_point((mbedtls_ecp_group *) e,
|
||||
test_p256_point_multipliers[i],
|
||||
(mbedtls_ecp_point *) p);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(test_p256_scalar_seeds); j++) {
|
||||
mbedtls_mpi scalar;
|
||||
|
||||
mbedtls_mpi_init(&scalar);
|
||||
test_load_valid_p256_scalar((const mbedtls_ecp_group *) e,
|
||||
test_p256_scalar_seeds[j],
|
||||
sizeof(test_p256_scalar_seeds[j]),
|
||||
&scalar);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, crypto_ec_point_mul(e, p,
|
||||
(struct crypto_bignum *) &scalar,
|
||||
res));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ecp_mul((mbedtls_ecp_group *) e,
|
||||
&ref, &scalar,
|
||||
(const mbedtls_ecp_point *) p,
|
||||
test_mbedtls_rng, NULL));
|
||||
TEST_ASSERT_EQUAL(0, crypto_ec_point_cmp(e, res,
|
||||
(const struct crypto_ec_point *) &ref));
|
||||
|
||||
mbedtls_mpi_free(&scalar);
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_ecp_point_free(&ref);
|
||||
crypto_ec_point_deinit(p, 1);
|
||||
crypto_ec_point_deinit(res, 1);
|
||||
crypto_ec_deinit(e);
|
||||
}
|
||||
|
||||
TEST_CASE("Measure secp256r1 bignum API timings against mbedtls reference", "[wpa_crypto]")
|
||||
{
|
||||
const unsigned int loops = 64;
|
||||
crypto_bignum *bn_p;
|
||||
int64_t generic_total_us = 0;
|
||||
int64_t api_total_us = 0;
|
||||
size_t ops = 0;
|
||||
int i, loop;
|
||||
|
||||
set_leak_threshold(700);
|
||||
|
||||
bn_p = crypto_bignum_init_set(test_secp256r1_prime,
|
||||
sizeof(test_secp256r1_prime));
|
||||
TEST_ASSERT_NOT_NULL(bn_p);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_p256_bignum_vals); i++) {
|
||||
crypto_bignum *bn_a = crypto_bignum_init_set(test_p256_bignum_vals[i],
|
||||
sizeof(test_p256_bignum_vals[i]));
|
||||
crypto_bignum *bn_b = crypto_bignum_init_set(
|
||||
test_p256_bignum_vals[(i + 1) % ARRAY_SIZE(test_p256_bignum_vals)],
|
||||
sizeof(test_p256_bignum_vals[0]));
|
||||
crypto_bignum *bn_mul = crypto_bignum_init();
|
||||
mbedtls_mpi ref_mul;
|
||||
int ref_legendre;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(bn_a);
|
||||
TEST_ASSERT_NOT_NULL(bn_b);
|
||||
TEST_ASSERT_NOT_NULL(bn_mul);
|
||||
|
||||
mbedtls_mpi_init(&ref_mul);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_mul_mpi(&ref_mul,
|
||||
(const mbedtls_mpi *) bn_a,
|
||||
(const mbedtls_mpi *) bn_b));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_mod_mpi(&ref_mul, &ref_mul,
|
||||
(const mbedtls_mpi *) bn_p));
|
||||
TEST_ASSERT_EQUAL(0, crypto_bignum_mulmod(bn_a, bn_b, bn_p, bn_mul));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_cmp_mpi((const mbedtls_mpi *) bn_mul,
|
||||
&ref_mul));
|
||||
ref_legendre = test_legendre_reference((const mbedtls_mpi *) bn_a,
|
||||
(const mbedtls_mpi *) bn_p);
|
||||
TEST_ASSERT_EQUAL(ref_legendre, crypto_bignum_legendre(bn_a, bn_p));
|
||||
|
||||
for (loop = 0; loop < loops; loop++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_mul_mpi(&ref_mul,
|
||||
(const mbedtls_mpi *) bn_a,
|
||||
(const mbedtls_mpi *) bn_b));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_mod_mpi(&ref_mul, &ref_mul,
|
||||
(const mbedtls_mpi *) bn_p));
|
||||
generic_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
for (loop = 0; loop < loops; loop++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
TEST_ASSERT_EQUAL(0, crypto_bignum_mulmod(bn_a, bn_b, bn_p, bn_mul));
|
||||
api_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
ops += loops;
|
||||
mbedtls_mpi_free(&ref_mul);
|
||||
crypto_bignum_deinit(bn_a, 1);
|
||||
crypto_bignum_deinit(bn_b, 1);
|
||||
crypto_bignum_deinit(bn_mul, 1);
|
||||
}
|
||||
|
||||
test_print_crypto_timing("secp256r1 mulmod", generic_total_us, ops,
|
||||
api_total_us, ops);
|
||||
|
||||
generic_total_us = 0;
|
||||
api_total_us = 0;
|
||||
ops = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_small_exponents); i++) {
|
||||
crypto_bignum *bn_exp = crypto_bignum_init_uint(test_small_exponents[i]);
|
||||
char label[48];
|
||||
|
||||
TEST_ASSERT_NOT_NULL(bn_exp);
|
||||
|
||||
generic_total_us = 0;
|
||||
api_total_us = 0;
|
||||
ops = 0;
|
||||
|
||||
for (loop = 0; loop < ARRAY_SIZE(test_p256_bignum_vals); loop++) {
|
||||
crypto_bignum *bn_a = crypto_bignum_init_set(test_p256_bignum_vals[loop],
|
||||
sizeof(test_p256_bignum_vals[loop]));
|
||||
crypto_bignum *bn_res = crypto_bignum_init();
|
||||
mbedtls_mpi ref_res;
|
||||
int iter;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(bn_a);
|
||||
TEST_ASSERT_NOT_NULL(bn_res);
|
||||
|
||||
mbedtls_mpi_init(&ref_res);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_exp_mod(&ref_res,
|
||||
(const mbedtls_mpi *) bn_a,
|
||||
(const mbedtls_mpi *) bn_exp,
|
||||
(const mbedtls_mpi *) bn_p,
|
||||
NULL));
|
||||
TEST_ASSERT_EQUAL(0, crypto_bignum_exptmod(bn_a, bn_exp, bn_p,
|
||||
bn_res));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_cmp_mpi((const mbedtls_mpi *) bn_res,
|
||||
&ref_res));
|
||||
|
||||
for (iter = 0; iter < loops; iter++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_mpi_exp_mod(&ref_res,
|
||||
(const mbedtls_mpi *) bn_a,
|
||||
(const mbedtls_mpi *) bn_exp,
|
||||
(const mbedtls_mpi *) bn_p,
|
||||
NULL));
|
||||
generic_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
for (iter = 0; iter < loops; iter++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
TEST_ASSERT_EQUAL(0, crypto_bignum_exptmod(bn_a, bn_exp, bn_p,
|
||||
bn_res));
|
||||
api_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
ops += loops;
|
||||
mbedtls_mpi_free(&ref_res);
|
||||
crypto_bignum_deinit(bn_a, 1);
|
||||
crypto_bignum_deinit(bn_res, 1);
|
||||
}
|
||||
|
||||
snprintf(label, sizeof(label), "secp256r1 exptmod e=%u",
|
||||
test_small_exponents[i]);
|
||||
test_print_crypto_timing(label, generic_total_us, ops,
|
||||
api_total_us, ops);
|
||||
crypto_bignum_deinit(bn_exp, 1);
|
||||
}
|
||||
|
||||
generic_total_us = 0;
|
||||
api_total_us = 0;
|
||||
ops = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_p256_bignum_vals); i++) {
|
||||
crypto_bignum *bn_a = crypto_bignum_init_set(test_p256_bignum_vals[i],
|
||||
sizeof(test_p256_bignum_vals[i]));
|
||||
TEST_ASSERT_NOT_NULL(bn_a);
|
||||
|
||||
TEST_ASSERT_EQUAL(test_legendre_reference((const mbedtls_mpi *) bn_a,
|
||||
(const mbedtls_mpi *) bn_p),
|
||||
crypto_bignum_legendre(bn_a, bn_p));
|
||||
|
||||
for (loop = 0; loop < loops; loop++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
(void) test_legendre_reference((const mbedtls_mpi *) bn_a,
|
||||
(const mbedtls_mpi *) bn_p);
|
||||
generic_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
for (loop = 0; loop < loops; loop++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
(void) crypto_bignum_legendre(bn_a, bn_p);
|
||||
api_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
ops += loops;
|
||||
crypto_bignum_deinit(bn_a, 1);
|
||||
}
|
||||
|
||||
test_print_crypto_timing("secp256r1 legendre", generic_total_us, ops,
|
||||
api_total_us, ops);
|
||||
|
||||
crypto_bignum_deinit(bn_p, 1);
|
||||
}
|
||||
|
||||
TEST_CASE("Measure secp256r1 EC API timings against mbedtls reference", "[wpa_crypto]")
|
||||
{
|
||||
const unsigned int point_mul_loops = 4;
|
||||
const unsigned int key_gen_loops = 4;
|
||||
const unsigned int ecdh_loops = 4;
|
||||
struct crypto_ec *e;
|
||||
struct crypto_ec_point *p = NULL;
|
||||
struct crypto_ec_point *res = NULL;
|
||||
mbedtls_ecp_point ref;
|
||||
int64_t generic_total_us = 0;
|
||||
int64_t api_total_us = 0;
|
||||
size_t ops = 0;
|
||||
int i, j, loop;
|
||||
|
||||
set_leak_threshold(900);
|
||||
|
||||
e = crypto_ec_init(19);
|
||||
TEST_ASSERT_NOT_NULL(e);
|
||||
|
||||
p = crypto_ec_point_init(e);
|
||||
TEST_ASSERT_NOT_NULL(p);
|
||||
res = crypto_ec_point_init(e);
|
||||
TEST_ASSERT_NOT_NULL(res);
|
||||
mbedtls_ecp_point_init(&ref);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_p256_point_multipliers); i++) {
|
||||
test_make_p256_affine_point((mbedtls_ecp_group *) e,
|
||||
test_p256_point_multipliers[i],
|
||||
(mbedtls_ecp_point *) p);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(test_p256_scalar_seeds); j++) {
|
||||
mbedtls_mpi scalar;
|
||||
|
||||
mbedtls_mpi_init(&scalar);
|
||||
test_load_valid_p256_scalar((const mbedtls_ecp_group *) e,
|
||||
test_p256_scalar_seeds[j],
|
||||
sizeof(test_p256_scalar_seeds[j]),
|
||||
&scalar);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, crypto_ec_point_mul(e, p,
|
||||
(struct crypto_bignum *) &scalar,
|
||||
res));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ecp_mul((mbedtls_ecp_group *) e,
|
||||
&ref, &scalar,
|
||||
(const mbedtls_ecp_point *) p,
|
||||
test_mbedtls_rng, NULL));
|
||||
TEST_ASSERT_EQUAL(0, crypto_ec_point_cmp(e, res,
|
||||
(const struct crypto_ec_point *) &ref));
|
||||
|
||||
for (loop = 0; loop < point_mul_loops; loop++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ecp_mul((mbedtls_ecp_group *) e,
|
||||
&ref, &scalar,
|
||||
(const mbedtls_ecp_point *) p,
|
||||
test_mbedtls_rng, NULL));
|
||||
generic_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
for (loop = 0; loop < point_mul_loops; loop++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
TEST_ASSERT_EQUAL(0, crypto_ec_point_mul(e, p,
|
||||
(struct crypto_bignum *) &scalar,
|
||||
res));
|
||||
api_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
ops += point_mul_loops;
|
||||
mbedtls_mpi_free(&scalar);
|
||||
}
|
||||
}
|
||||
|
||||
test_print_crypto_timing("secp256r1 point_mul", generic_total_us, ops,
|
||||
api_total_us, ops);
|
||||
|
||||
generic_total_us = 0;
|
||||
api_total_us = 0;
|
||||
|
||||
for (loop = 0; loop < key_gen_loops; loop++) {
|
||||
mbedtls_pk_context kctx;
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
TEST_ASSERT_EQUAL(0, test_mbedtls_key_gen_p256(&kctx));
|
||||
generic_total_us += esp_timer_get_time() - start_us;
|
||||
mbedtls_pk_free(&kctx);
|
||||
}
|
||||
|
||||
for (loop = 0; loop < key_gen_loops; loop++) {
|
||||
struct crypto_ec_key *key;
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
|
||||
key = crypto_ec_key_gen(19);
|
||||
TEST_ASSERT_NOT_NULL(key);
|
||||
api_total_us += esp_timer_get_time() - start_us;
|
||||
crypto_ec_key_deinit(key);
|
||||
}
|
||||
|
||||
test_print_crypto_timing("secp256r1 key_gen", generic_total_us, key_gen_loops,
|
||||
api_total_us, key_gen_loops);
|
||||
|
||||
{
|
||||
struct crypto_ec_key *key_own = crypto_ec_key_gen(19);
|
||||
struct crypto_ec_key *key_peer = crypto_ec_key_gen(19);
|
||||
u8 secret_generic[66];
|
||||
u8 secret_api[66];
|
||||
size_t secret_generic_len = 0;
|
||||
size_t secret_api_len = 0;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(key_own);
|
||||
TEST_ASSERT_NOT_NULL(key_peer);
|
||||
TEST_ASSERT_EQUAL(0, test_mbedtls_ecdh(key_own, key_peer,
|
||||
secret_generic,
|
||||
&secret_generic_len));
|
||||
TEST_ASSERT_EQUAL(0, crypto_ecdh(key_own, key_peer,
|
||||
secret_api, &secret_api_len));
|
||||
TEST_ASSERT_EQUAL(secret_generic_len, secret_api_len);
|
||||
TEST_ASSERT_EQUAL_MEMORY(secret_generic, secret_api, secret_api_len);
|
||||
|
||||
generic_total_us = 0;
|
||||
api_total_us = 0;
|
||||
|
||||
for (loop = 0; loop < ecdh_loops; loop++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
size_t secret_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(0, test_mbedtls_ecdh(key_own, key_peer,
|
||||
secret_generic,
|
||||
&secret_len));
|
||||
generic_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
for (loop = 0; loop < ecdh_loops; loop++) {
|
||||
int64_t start_us = esp_timer_get_time();
|
||||
size_t secret_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(0, crypto_ecdh(key_own, key_peer,
|
||||
secret_api, &secret_len));
|
||||
api_total_us += esp_timer_get_time() - start_us;
|
||||
}
|
||||
|
||||
test_print_crypto_timing("secp256r1 ecdh", generic_total_us, ecdh_loops,
|
||||
api_total_us, ecdh_loops);
|
||||
|
||||
crypto_ec_key_deinit(key_own);
|
||||
crypto_ec_key_deinit(key_peer);
|
||||
}
|
||||
|
||||
mbedtls_ecp_point_free(&ref);
|
||||
crypto_ec_point_deinit(p, 1);
|
||||
crypto_ec_point_deinit(res, 1);
|
||||
crypto_ec_deinit(e);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
#include "unity.h"
|
||||
#include <string.h>
|
||||
#include "utils/common.h"
|
||||
@@ -18,8 +19,16 @@
|
||||
#include "common/dpp.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "test_wpa_supplicant_common.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_TESTING_OPTIONS
|
||||
static unsigned int dpp_test_task_stack_high_watermark_bytes(void)
|
||||
{
|
||||
return (unsigned int)(uxTaskGetStackHighWaterMark(NULL) *
|
||||
sizeof(StackType_t));
|
||||
}
|
||||
|
||||
struct dpp_global {
|
||||
void *msg_ctx;
|
||||
struct dl_list bootstrap; /* struct dpp_bootstrap_info */
|
||||
@@ -32,9 +41,46 @@ extern u8 dpp_nonce_override[DPP_MAX_NONCE_LEN];
|
||||
extern size_t dpp_nonce_override_len;
|
||||
#define MAX_FRAME_SIZE 1200
|
||||
|
||||
static void dpp_test_clear_overrides(void)
|
||||
{
|
||||
dpp_protocol_key_override_len = 0;
|
||||
dpp_nonce_override_len = 0;
|
||||
os_memset(dpp_protocol_key_override, 0, sizeof(dpp_protocol_key_override));
|
||||
os_memset(dpp_nonce_override, 0, sizeof(dpp_nonce_override));
|
||||
}
|
||||
|
||||
static u32 dpp_test_prod_limit_us(void)
|
||||
{
|
||||
#if CONFIG_MBEDTLS_HARDWARE_ECC
|
||||
return 200000;
|
||||
#else
|
||||
return 425000;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int dpp_test_leak_threshold(void)
|
||||
{
|
||||
return 800;
|
||||
}
|
||||
|
||||
static void dpp_test_log_auth_timing(const char *label,
|
||||
const struct dpp_authentication *auth)
|
||||
{
|
||||
TEST_ASSERT_NOT_NULL(auth);
|
||||
|
||||
ESP_LOGI("DPP Test",
|
||||
"%s timing(us): parse=%llu response_form=%llu total=%llu",
|
||||
label,
|
||||
(unsigned long long) auth->auth_req_parse_us,
|
||||
(unsigned long long) auth->auth_resp_form_us,
|
||||
(unsigned long long) auth->auth_req_total_us);
|
||||
ESP_LOGI("DPP Test", "%s task stack high watermark(bytes): %u",
|
||||
label, dpp_test_task_stack_high_watermark_bytes());
|
||||
}
|
||||
|
||||
TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]")
|
||||
{
|
||||
set_leak_threshold(130);
|
||||
set_leak_threshold(dpp_test_leak_threshold());
|
||||
/* Global variables */
|
||||
char command[1200] = {0};
|
||||
const u8 *frame;
|
||||
@@ -66,6 +112,10 @@ TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]")
|
||||
sprintf(command, "type=qrcode key=%s", key);
|
||||
id = dpp_bootstrap_gen(dpp, command);
|
||||
uri = dpp_bootstrap_get_uri(dpp, id);
|
||||
if (uri == NULL) {
|
||||
ESP_LOGE("DPP Test", "Failed to get URI from bootstrap id");
|
||||
TEST_ASSERT(0);
|
||||
}
|
||||
printf("uri is =%s\n", uri);
|
||||
printf("is be =%s\n", bootstrap_info);
|
||||
TEST_ASSERT((strcmp(uri, bootstrap_info) == 0));
|
||||
@@ -129,6 +179,9 @@ TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]")
|
||||
len -= 26;
|
||||
auth_instance = dpp_auth_req_rx(NULL, 1, 0, NULL,
|
||||
dpp_bootstrap_get_id(dpp, id), 2412, frame, frame + 6, len - 6);
|
||||
TEST_ASSERT_NOT_NULL(auth_instance);
|
||||
TEST_ASSERT_NOT_NULL(auth_instance->resp_msg);
|
||||
dpp_test_log_auth_timing("Vector responder", auth_instance);
|
||||
|
||||
/* auth response u8 */
|
||||
hex_len = os_strlen(auth_resp);
|
||||
@@ -172,7 +225,118 @@ TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]")
|
||||
{
|
||||
dpp_auth_deinit(auth_instance);
|
||||
dpp_global_deinit(dpp);
|
||||
dpp_test_clear_overrides();
|
||||
}
|
||||
ESP_LOGI("DPP Test", "Test case passed");
|
||||
}
|
||||
|
||||
TEST_CASE("Test DPP responder p256 production timing", "[wpa_dpp][performance]")
|
||||
{
|
||||
struct dpp_global_config dpp_conf;
|
||||
struct dpp_global *dpp = NULL;
|
||||
struct dpp_bootstrap_info *responder_bi = NULL;
|
||||
struct dpp_bootstrap_info *initiator_bi = NULL;
|
||||
struct dpp_authentication *initiator_auth = NULL;
|
||||
struct dpp_authentication *responder_auth = NULL;
|
||||
struct wpabuf *conf = NULL;
|
||||
const u8 *frame;
|
||||
size_t len;
|
||||
int responder_id;
|
||||
int initiator_id;
|
||||
u32 limit_us = dpp_test_prod_limit_us();
|
||||
u64 total_us = 0;
|
||||
const char *failure = NULL;
|
||||
|
||||
set_leak_threshold(dpp_test_leak_threshold());
|
||||
os_memset(&dpp_conf, 0, sizeof(dpp_conf));
|
||||
dpp = dpp_global_init(&dpp_conf);
|
||||
if (!dpp) {
|
||||
TEST_FAIL_MESSAGE("Failed to initialize DPP global context");
|
||||
}
|
||||
|
||||
responder_id = dpp_bootstrap_gen(dpp, "type=qrcode curve=P-256");
|
||||
if (responder_id <= 0) {
|
||||
failure = "Failed to generate responder bootstrap";
|
||||
goto cleanup;
|
||||
}
|
||||
initiator_id = dpp_bootstrap_gen(dpp, "type=qrcode curve=P-256");
|
||||
if (initiator_id <= 0) {
|
||||
failure = "Failed to generate initiator bootstrap";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
responder_bi = dpp_bootstrap_get_id(dpp, responder_id);
|
||||
initiator_bi = dpp_bootstrap_get_id(dpp, initiator_id);
|
||||
if (!responder_bi || !initiator_bi) {
|
||||
failure = "Failed to resolve bootstrap info";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dpp_test_clear_overrides();
|
||||
initiator_auth = dpp_auth_init(NULL, responder_bi, initiator_bi,
|
||||
DPP_CAPAB_CONFIGURATOR, 2412, NULL, 0);
|
||||
if (!initiator_auth || !initiator_auth->req_msg) {
|
||||
failure = "Failed to initialize DPP initiator authentication";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
frame = wpabuf_head_u8(initiator_auth->req_msg) + 2;
|
||||
len = wpabuf_len(initiator_auth->req_msg) - 2;
|
||||
responder_auth = dpp_auth_req_rx(NULL, DPP_CAPAB_ENROLLEE, 0,
|
||||
NULL, responder_bi, 2412,
|
||||
frame, frame + DPP_HDR_LEN,
|
||||
len - DPP_HDR_LEN);
|
||||
if (!responder_auth || !responder_auth->resp_msg) {
|
||||
failure = "Failed to process DPP authentication request";
|
||||
goto cleanup;
|
||||
}
|
||||
dpp_test_log_auth_timing("Production responder", responder_auth);
|
||||
total_us = responder_auth->auth_req_total_us;
|
||||
if (limit_us) {
|
||||
ESP_LOGI("DPP Test",
|
||||
"Production responder timing gate(us): total=%llu limit=%" PRIu32,
|
||||
(unsigned long long) total_us,
|
||||
limit_us);
|
||||
}
|
||||
|
||||
frame = wpabuf_head_u8(responder_auth->resp_msg) + 2;
|
||||
len = wpabuf_len(responder_auth->resp_msg) - 2;
|
||||
conf = dpp_auth_resp_rx(initiator_auth, frame, frame + DPP_HDR_LEN,
|
||||
len - DPP_HDR_LEN);
|
||||
if (!conf) {
|
||||
failure = "Failed to process DPP authentication response";
|
||||
goto cleanup;
|
||||
}
|
||||
if (initiator_auth->auth_success != 1) {
|
||||
failure = "Initiator authentication did not complete successfully";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
frame = wpabuf_head_u8(conf) + 2;
|
||||
len = wpabuf_len(conf) - 2;
|
||||
if (dpp_auth_conf_rx(responder_auth, frame, frame + DPP_HDR_LEN,
|
||||
len - DPP_HDR_LEN) != 0) {
|
||||
failure = "Failed to process DPP authentication confirmation";
|
||||
goto cleanup;
|
||||
}
|
||||
if (responder_auth->auth_success != 1) {
|
||||
failure = "Responder authentication did not complete successfully";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
wpabuf_free(conf);
|
||||
dpp_auth_deinit(responder_auth);
|
||||
dpp_auth_deinit(initiator_auth);
|
||||
dpp_global_deinit(dpp);
|
||||
dpp_test_clear_overrides();
|
||||
|
||||
if (failure) {
|
||||
TEST_FAIL_MESSAGE(failure);
|
||||
}
|
||||
if (limit_us) {
|
||||
TEST_ASSERT_MESSAGE(total_us <= limit_us,
|
||||
"DPP responder production timing regression");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -20,9 +20,41 @@
|
||||
#include "utils/wpabuf.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_wpa_supplicant_common.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
typedef struct crypto_bignum crypto_bignum;
|
||||
|
||||
static unsigned int test_task_stack_high_watermark_bytes(void)
|
||||
{
|
||||
return (unsigned int)(uxTaskGetStackHighWaterMark(NULL) *
|
||||
sizeof(StackType_t));
|
||||
}
|
||||
|
||||
static int sae_commit_parse_limit_us(void)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
return 400000;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
return 300000;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
return 380000;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
return 340000;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5
|
||||
return 130000;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
return 180000;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C61
|
||||
return 200000;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
return 230000;
|
||||
#else
|
||||
return 230000;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct wpabuf *wpabuf_alloc2(size_t len)
|
||||
{
|
||||
struct wpabuf *buf = (struct wpabuf *)os_zalloc(sizeof(struct wpabuf) + len);
|
||||
@@ -233,26 +265,52 @@ TEST_CASE("Test SAE functionality with ECC group", "[wpa3_sae]")
|
||||
u8 pwd[] = "ESP32-WPA3";
|
||||
struct wpabuf *buf;
|
||||
int default_groups[] = { IANA_SECP256R1, 0 };
|
||||
int64_t start_us;
|
||||
int64_t total_start_us;
|
||||
int64_t total_us;
|
||||
int64_t prepare_us;
|
||||
int64_t write_us;
|
||||
int64_t parse_us;
|
||||
int64_t formation_us;
|
||||
int limit_us = sae_commit_parse_limit_us();
|
||||
|
||||
memset(&sae, 0, sizeof(sae));
|
||||
total_start_us = esp_timer_get_time();
|
||||
|
||||
TEST_ASSERT(sae_set_group(&sae, IANA_SECP256R1) == 0);
|
||||
|
||||
start_us = esp_timer_get_time();
|
||||
TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd, strlen((const char *)pwd), &sae) == 0);
|
||||
prepare_us = esp_timer_get_time() - start_us;
|
||||
|
||||
buf = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
|
||||
|
||||
TEST_ASSERT(buf != NULL);
|
||||
|
||||
start_us = esp_timer_get_time();
|
||||
sae_write_commit(&sae, buf, NULL, NULL);// No anti-clogging token
|
||||
write_us = esp_timer_get_time() - start_us;
|
||||
formation_us = prepare_us + write_us;
|
||||
|
||||
/* Parsing commit created by self will be detected as reflection attack*/
|
||||
start_us = esp_timer_get_time();
|
||||
TEST_ASSERT(sae_parse_commit(&sae,
|
||||
wpabuf_mhead(buf), buf->used, NULL, 0, default_groups, 0) == SAE_SILENTLY_DISCARD);
|
||||
parse_us = esp_timer_get_time() - start_us;
|
||||
|
||||
wpabuf_free2(buf);
|
||||
sae_clear_temp_data(&sae);
|
||||
sae_clear_data(&sae);
|
||||
total_us = esp_timer_get_time() - total_start_us;
|
||||
|
||||
ESP_LOGI("SAE Test",
|
||||
"Commit/parse timing(us): prepare=%lld write=%lld formation=%lld parse=%lld total=%lld limit=%d",
|
||||
(long long) prepare_us, (long long) write_us,
|
||||
(long long) formation_us, (long long) parse_us,
|
||||
(long long) total_us, limit_us);
|
||||
ESP_LOGI("SAE Test", "Task stack high watermark(bytes): %u",
|
||||
test_task_stack_high_watermark_bytes());
|
||||
TEST_ASSERT_MESSAGE(total_us <= limit_us, "SAE commit/parse timing regression");
|
||||
|
||||
}
|
||||
ESP_LOGI("SAE Test", "=========== Complete ============");
|
||||
|
||||
@@ -32,7 +32,7 @@ static void check_leak(size_t before_free, size_t after_free, const char *type)
|
||||
{
|
||||
ssize_t delta = after_free - before_free;
|
||||
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d, threshold %d)\n", type, before_free, after_free, delta, leak_threshold);
|
||||
TEST_ASSERT_MESSAGE(delta > leak_threshold, "memory leak");
|
||||
TEST_ASSERT_MESSAGE(delta >= leak_threshold, "memory leak");
|
||||
}
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
||||
CONFIG_ESP_WIFI_TESTING_OPTIONS=y
|
||||
CONFIG_ESP_WIFI_DEBUG_PRINT=y
|
||||
CONFIG_ESP_WIFI_DPP_SUPPORT=y
|
||||
CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y
|
||||
CONFIG_ESP_WIFI_P256_ACCEL=y
|
||||
|
||||
Reference in New Issue
Block a user