From edef8d5fae3d0140e39588f112135d7a79e855cb Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Tue, 4 Jul 2023 14:33:40 +0530 Subject: [PATCH 1/8] fix(mbedtls): Fix the port for the mbedtls_internal_shaX_process API - Also added the fix to update intermediate SHA state in the mbedtls_shaX_update API --- components/mbedtls/port/sha/dma/esp_sha1.c | 42 ++++++---- components/mbedtls/port/sha/dma/esp_sha256.c | 42 ++++++---- components/mbedtls/port/sha/dma/esp_sha512.c | 63 ++++++++++----- .../port/sha/parallel_engine/esp_sha1.c | 79 ++++++++++--------- .../port/sha/parallel_engine/esp_sha256.c | 70 +++++++++------- .../port/sha/parallel_engine/esp_sha512.c | 70 +++++++++------- 6 files changed, 224 insertions(+), 142 deletions(-) diff --git a/components/mbedtls/port/sha/dma/esp_sha1.c b/components/mbedtls/port/sha/dma/esp_sha1.c index 91b011f386..d6082bf449 100644 --- a/components/mbedtls/port/sha/dma/esp_sha1.c +++ b/components/mbedtls/port/sha/dma/esp_sha1.c @@ -110,6 +110,17 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) } #endif +static void esp_internal_sha_update_state(mbedtls_sha1_context *ctx) +{ + if (ctx->sha_state == ESP_SHA1_STATE_INIT) { + ctx->first_block = true; + ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS; + } else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) { + ctx->first_block = false; + esp_sha_write_digest_state(ctx->mode, ctx->state); + } +} + static int esp_internal_sha1_dma_process(mbedtls_sha1_context *ctx, const uint8_t *data, size_t len, uint8_t *buf, size_t buf_len) @@ -119,9 +130,17 @@ static int esp_internal_sha1_dma_process(mbedtls_sha1_context *ctx, int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) { - int ret; + int ret = -1; esp_sha_acquire_hardware(); + esp_internal_sha_update_state(ctx); + ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; + } + + esp_sha_read_digest_state(ctx->mode, ctx->state); esp_sha_release_hardware(); return ret; } @@ -136,7 +155,6 @@ void mbedtls_sha1_process( mbedtls_sha1_context *ctx, int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) { - int ret; size_t fill; uint32_t left, len, local_len = 0; @@ -167,25 +185,19 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp if ( len || local_len) { esp_sha_acquire_hardware(); - if (ctx->sha_state == ESP_SHA1_STATE_INIT) { - ctx->first_block = true; - ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS; - } else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) { - ctx->first_block = false; - esp_sha_write_digest_state(SHA1, ctx->state); + esp_internal_sha_update_state(ctx); + + int ret = esp_internal_sha1_dma_process(ctx, input, len, ctx->buffer, local_len); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; } - ret = esp_internal_sha1_dma_process(ctx, input, len, ctx->buffer, local_len); - esp_sha_read_digest_state(SHA1, ctx->state); esp_sha_release_hardware(); - if (ret != 0) { - return ret; - } - } if ( ilen > 0 ) { @@ -216,7 +228,7 @@ static const unsigned char sha1_padding[64] = { */ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] ) { - int ret; + int ret = -1; uint32_t last, padn; uint32_t high, low; unsigned char msglen[8]; diff --git a/components/mbedtls/port/sha/dma/esp_sha256.c b/components/mbedtls/port/sha/dma/esp_sha256.c index 307b338498..12bf5223ae 100644 --- a/components/mbedtls/port/sha/dma/esp_sha256.c +++ b/components/mbedtls/port/sha/dma/esp_sha256.c @@ -125,11 +125,30 @@ void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, #endif +static void esp_internal_sha_update_state(mbedtls_sha256_context *ctx) +{ + if (ctx->sha_state == ESP_SHA256_STATE_INIT) { + ctx->first_block = true; + ctx->sha_state = ESP_SHA256_STATE_IN_PROCESS; + } else if (ctx->sha_state == ESP_SHA256_STATE_IN_PROCESS) { + ctx->first_block = false; + esp_sha_write_digest_state(ctx->mode, ctx->state); + } +} + int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) { - int ret; + int ret = -1; esp_sha_acquire_hardware(); + esp_internal_sha_update_state(ctx); + ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; + } + + esp_sha_read_digest_state(ctx->mode, ctx->state); esp_sha_release_hardware(); return ret; @@ -149,7 +168,6 @@ void mbedtls_sha256_process( mbedtls_sha256_context *ctx, int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen ) { - int ret = 0; size_t fill; uint32_t left, len, local_len = 0; @@ -181,24 +199,18 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char if ( len || local_len) { esp_sha_acquire_hardware(); + esp_internal_sha_update_state(ctx); - if (ctx->sha_state == ESP_SHA256_STATE_INIT) { - ctx->first_block = true; - ctx->sha_state = ESP_SHA256_STATE_IN_PROCESS; - } else if (ctx->sha_state == ESP_SHA256_STATE_IN_PROCESS) { - ctx->first_block = false; - esp_sha_write_digest_state(ctx->mode, ctx->state); + int ret = esp_sha_dma(ctx->mode, input, len, ctx->buffer, local_len, ctx->first_block); + + if (ret != 0) { + esp_sha_release_hardware(); + return ret; } - ret = esp_sha_dma(ctx->mode, input, len, ctx->buffer, local_len, ctx->first_block); - esp_sha_read_digest_state(ctx->mode, ctx->state); esp_sha_release_hardware(); - - if (ret != 0) { - return ret; - } } if ( ilen > 0 ) { @@ -229,7 +241,7 @@ static const unsigned char sha256_padding[64] = { */ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] ) { - int ret; + int ret = -1; uint32_t last, padn; uint32_t high, low; unsigned char msglen[8]; diff --git a/components/mbedtls/port/sha/dma/esp_sha512.c b/components/mbedtls/port/sha/dma/esp_sha512.c index fa4465d0f8..b8d5eda119 100644 --- a/components/mbedtls/port/sha/dma/esp_sha512.c +++ b/components/mbedtls/port/sha/dma/esp_sha512.c @@ -146,6 +146,26 @@ void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, } #endif +static int esp_internal_sha_update_state(mbedtls_sha512_context *ctx) +{ + if (ctx->sha_state == ESP_SHA512_STATE_INIT) { + if (ctx->mode == SHA2_512T) { + int ret = -1; + if ((ret = esp_sha_512_t_init_hash(ctx->t_val)) != 0) { + return ret; + } + ctx->first_block = false; + } else { + ctx->first_block = true; + } + ctx->sha_state = ESP_SHA512_STATE_IN_PROCESS; + } else if (ctx->sha_state == ESP_SHA512_STATE_IN_PROCESS) { + ctx->first_block = false; + esp_sha_write_digest_state(ctx->mode, ctx->state); + } + return 0; +} + static int esp_internal_sha512_dma_process(mbedtls_sha512_context *ctx, const uint8_t *data, size_t len, uint8_t *buf, size_t buf_len) @@ -159,9 +179,22 @@ static int esp_internal_sha512_dma_process(mbedtls_sha512_context *ctx, int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) { - int ret; + int ret = -1; esp_sha_acquire_hardware(); + + ret = esp_internal_sha_update_state(ctx); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; + } + ret = esp_internal_sha512_dma_process(ctx, data, 128, 0, 0); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; + } + + esp_sha_read_digest_state(ctx->mode, ctx->state); esp_sha_release_hardware(); return ret; @@ -182,7 +215,6 @@ void mbedtls_sha512_process( mbedtls_sha512_context *ctx, int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input, size_t ilen ) { - int ret; size_t fill; unsigned int left, len, local_len = 0; @@ -214,31 +246,24 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char esp_sha_acquire_hardware(); - if (ctx->sha_state == ESP_SHA512_STATE_INIT) { + int ret = esp_internal_sha_update_state(ctx); - if (ctx->mode == SHA2_512T) { - esp_sha_512_t_init_hash(ctx->t_val); - ctx->first_block = false; - } else { - ctx->first_block = true; - } - ctx->sha_state = ESP_SHA512_STATE_IN_PROCESS; - - } else if (ctx->sha_state == ESP_SHA512_STATE_IN_PROCESS) { - ctx->first_block = false; - esp_sha_write_digest_state(ctx->mode, ctx->state); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; } ret = esp_internal_sha512_dma_process(ctx, input, len, ctx->buffer, local_len); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; + } + esp_sha_read_digest_state(ctx->mode, ctx->state); esp_sha_release_hardware(); - if (ret != 0) { - return ret; - } - } @@ -275,7 +300,7 @@ static const unsigned char sha512_padding[128] = { */ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] ) { - int ret; + int ret = -1; size_t last, padn; uint64_t high, low; unsigned char msglen[16]; diff --git a/components/mbedtls/port/sha/parallel_engine/esp_sha1.c b/components/mbedtls/port/sha/parallel_engine/esp_sha1.c index 4700daf553..edd9211c5f 100644 --- a/components/mbedtls/port/sha/parallel_engine/esp_sha1.c +++ b/components/mbedtls/port/sha/parallel_engine/esp_sha1.c @@ -142,39 +142,6 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) } #endif -static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ); - -int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) -{ - bool first_block = false; - if (ctx->mode == ESP_MBEDTLS_SHA1_UNUSED) { - /* try to use hardware for this digest */ - if (esp_sha_try_lock_engine(SHA1)) { - ctx->mode = ESP_MBEDTLS_SHA1_HARDWARE; - first_block = true; - } else { - ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE; - } - } - - if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) { - esp_sha_block(SHA1, data, first_block); - } else { - mbedtls_sha1_software_process(ctx, data); - } - - return 0; -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_sha1_process( mbedtls_sha1_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_sha1_process( ctx, data ); -} -#endif - - static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) { uint32_t temp, W[16], A, B, C, D, E; @@ -331,12 +298,46 @@ static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsi ctx->state[4] += E; } + +static int esp_internal_sha1_parallel_engine_process( mbedtls_sha1_context *ctx, const unsigned char data[64], bool read_digest ) +{ + bool first_block = false; + + if (ctx->mode == ESP_MBEDTLS_SHA1_UNUSED) { + /* try to use hardware for this digest */ + if (esp_sha_try_lock_engine(SHA1)) { + ctx->mode = ESP_MBEDTLS_SHA1_HARDWARE; + first_block = true; + } else { + ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE; + } + } + + if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) { + esp_sha_block(SHA1, data, first_block); + if (read_digest) { + esp_sha_read_digest_state(SHA1, ctx->state); + } + } else { + mbedtls_sha1_software_process(ctx, data); + } + + return 0; +} + + +int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) +{ + return esp_internal_sha1_parallel_engine_process(ctx, data, true); +} + + /* * SHA-1 process buffer */ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) { - int ret; + int ret = -1; size_t fill; uint32_t left; @@ -357,7 +358,7 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp if ( left && ilen >= fill ) { memcpy( (void *) (ctx->buffer + left), input, fill ); - if ( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) { + if ( ( ret = esp_internal_sha1_parallel_engine_process( ctx, ctx->buffer, false ) ) != 0 ) { return ret; } @@ -367,7 +368,7 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp } while ( ilen >= 64 ) { - if ( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) { + if ( ( ret = esp_internal_sha1_parallel_engine_process( ctx, input, false ) ) != 0 ) { return ret; } @@ -375,6 +376,10 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp ilen -= 64; } + if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) { + esp_sha_read_digest_state(SHA1, ctx->state); + } + if ( ilen > 0 ) { memcpy( (void *) (ctx->buffer + left), input, ilen ); } @@ -403,7 +408,7 @@ static const unsigned char sha1_padding[64] = { */ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] ) { - int ret; + int ret = -1; uint32_t last, padn; uint32_t high, low; unsigned char msglen[8]; diff --git a/components/mbedtls/port/sha/parallel_engine/esp_sha256.c b/components/mbedtls/port/sha/parallel_engine/esp_sha256.c index c29ffebb7d..5043f8b8ce 100644 --- a/components/mbedtls/port/sha/parallel_engine/esp_sha256.c +++ b/components/mbedtls/port/sha/parallel_engine/esp_sha256.c @@ -203,30 +203,6 @@ static const uint32_t K[] = { d += temp1; h = temp1 + temp2; \ } -static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ); - -int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) -{ - bool first_block = false; - - if (ctx->mode == ESP_MBEDTLS_SHA256_UNUSED) { - /* try to use hardware for this digest */ - if (!ctx->is224 && esp_sha_try_lock_engine(SHA2_256)) { - ctx->mode = ESP_MBEDTLS_SHA256_HARDWARE; - first_block = true; - } else { - ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE; - } - } - - if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) { - esp_sha_block(SHA2_256, data, first_block); - } else { - mbedtls_sha256_software_process(ctx, data); - } - - return 0; -} #if !defined(MBEDTLS_DEPRECATED_REMOVED) void mbedtls_sha256_process( mbedtls_sha256_context *ctx, @@ -292,13 +268,47 @@ static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const } } + +static int esp_internal_sha256_parallel_engine_process( mbedtls_sha256_context *ctx, const unsigned char data[64], bool read_digest ) +{ + bool first_block = false; + + if (ctx->mode == ESP_MBEDTLS_SHA256_UNUSED) { + /* try to use hardware for this digest */ + if (!ctx->is224 && esp_sha_try_lock_engine(SHA2_256)) { + ctx->mode = ESP_MBEDTLS_SHA256_HARDWARE; + first_block = true; + } else { + ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE; + } + } + + if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) { + esp_sha_block(SHA2_256, data, first_block); + if (read_digest) { + esp_sha_read_digest_state(SHA2_256, ctx->state); + } + } else { + mbedtls_sha256_software_process(ctx, data); + } + + return 0; +} + + +int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) +{ + return esp_internal_sha256_parallel_engine_process(ctx, data, true); +} + + /* * SHA-256 process buffer */ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen ) { - int ret; + int ret = -1; size_t fill; uint32_t left; @@ -319,7 +329,7 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char if ( left && ilen >= fill ) { memcpy( (void *) (ctx->buffer + left), input, fill ); - if ( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) { + if ( ( ret = esp_internal_sha256_parallel_engine_process( ctx, ctx->buffer, false ) ) != 0 ) { return ret; } @@ -329,7 +339,7 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char } while ( ilen >= 64 ) { - if ( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) { + if ( ( ret = esp_internal_sha256_parallel_engine_process( ctx, input, false ) ) != 0 ) { return ret; } @@ -337,6 +347,10 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char ilen -= 64; } + if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) { + esp_sha_read_digest_state(SHA2_256, ctx->state); + } + if ( ilen > 0 ) { memcpy( (void *) (ctx->buffer + left), input, ilen ); } @@ -365,7 +379,7 @@ static const unsigned char sha256_padding[64] = { */ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] ) { - int ret; + int ret = -1; uint32_t last, padn; uint32_t high, low; unsigned char msglen[8]; diff --git a/components/mbedtls/port/sha/parallel_engine/esp_sha512.c b/components/mbedtls/port/sha/parallel_engine/esp_sha512.c index fd9c354d15..e13eddda42 100644 --- a/components/mbedtls/port/sha/parallel_engine/esp_sha512.c +++ b/components/mbedtls/port/sha/parallel_engine/esp_sha512.c @@ -230,30 +230,6 @@ static const uint64_t K[80] = { UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) }; -static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ); - -int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) -{ - bool first_block = false; - - if (ctx->mode == ESP_MBEDTLS_SHA512_UNUSED) { - /* try to use hardware for this digest */ - if (esp_sha_try_lock_engine(sha_type(ctx))) { - ctx->mode = ESP_MBEDTLS_SHA512_HARDWARE; - first_block = true; - } else { - ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE; - } - } - - if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) { - esp_sha_block(sha_type(ctx), data, first_block); - } else { - mbedtls_sha512_software_process(ctx, data); - } - - return 0; -} #if !defined(MBEDTLS_DEPRECATED_REMOVED) void mbedtls_sha512_process( mbedtls_sha512_context *ctx, @@ -329,13 +305,47 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const ctx->state[7] += H; } + +static int esp_internal_sha512_parallel_engine_process( mbedtls_sha512_context *ctx, const unsigned char data[128], bool read_digest ) +{ + bool first_block = false; + + if (ctx->mode == ESP_MBEDTLS_SHA512_UNUSED) { + /* try to use hardware for this digest */ + if (esp_sha_try_lock_engine(sha_type(ctx))) { + ctx->mode = ESP_MBEDTLS_SHA512_HARDWARE; + first_block = true; + } else { + ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE; + } + } + + if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) { + esp_sha_block(sha_type(ctx), data, first_block); + if (read_digest) { + esp_sha_read_digest_state(sha_type(ctx), ctx->state); + } + } else { + mbedtls_sha512_software_process(ctx, data); + } + + return 0; +} + + +int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) +{ + return esp_internal_sha512_parallel_engine_process(ctx, data, true); +} + + /* * SHA-512 process buffer */ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input, size_t ilen ) { - int ret; + int ret = -1; size_t fill; unsigned int left; @@ -354,7 +364,7 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char if ( left && ilen >= fill ) { memcpy( (void *) (ctx->buffer + left), input, fill ); - if ( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) { + if ( ( ret = esp_internal_sha512_parallel_engine_process( ctx, ctx->buffer, false ) ) != 0 ) { return ret; } @@ -364,7 +374,7 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char } while ( ilen >= 128 ) { - if ( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) { + if ( ( ret = esp_internal_sha512_parallel_engine_process( ctx, input, false ) ) != 0 ) { return ret; } @@ -372,6 +382,10 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char ilen -= 128; } + if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) { + esp_sha_read_digest_state(sha_type(ctx), ctx->state); + } + if ( ilen > 0 ) { memcpy( (void *) (ctx->buffer + left), input, ilen ); } @@ -405,7 +419,7 @@ static const unsigned char sha512_padding[128] = { */ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] ) { - int ret; + int ret = -1; size_t last, padn; uint64_t high, low; unsigned char msglen[16]; From 9e61344890b9c3dcca7f35da346f6175cfd2e38b Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Tue, 4 Jul 2023 14:34:08 +0530 Subject: [PATCH 2/8] ci(mbedtls): added a test for the mbedtls_internal_shaX_process API --- components/mbedtls/test/test_sha.c | 88 +++++++++++++++++++++ components/soc/esp32/include/soc/soc_caps.h | 3 + 2 files changed, 91 insertions(+) diff --git a/components/mbedtls/test/test_sha.c b/components/mbedtls/test/test_sha.c index 063cdcf0a6..4f076a741c 100644 --- a/components/mbedtls/test/test_sha.c +++ b/components/mbedtls/test/test_sha.c @@ -141,4 +141,92 @@ TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]") #if SOC_SHA_SUPPORT_SHA512 TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_espsha, sha512_mbedtls, sizeof(sha512_espsha), "SHA512 results should match"); #endif + +#if CONFIG_MBEDTLS_HARDWARE_SHA + +TEST_CASE("Test mbedtls_internal_sha_process()", "[hw_crypto]") +{ + const size_t BUFFER_SZ = 128; + int ret; + unsigned char output[64] = { 0 }; + void *buffer = heap_caps_malloc(BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(buffer); + memset(buffer, 0xEE, BUFFER_SZ); + + mbedtls_sha1_context sha1_ctx; + + const uint8_t sha1_expected[20] = { 0x41, 0x63, 0x12, 0x5b, 0x9c, 0x68, 0x85, 0xc8, + 0x01, 0x40, 0xf4, 0x03, 0x5d, 0x0d, 0x84, 0x0e, + 0xa4, 0xae, 0x4d, 0xe9 }; + + mbedtls_sha1_init(&sha1_ctx); + mbedtls_sha1_starts(&sha1_ctx); + + ret = mbedtls_internal_sha1_process(&sha1_ctx, buffer); + TEST_ASSERT_EQUAL(0, ret); + + ret = mbedtls_internal_sha1_process(&sha1_ctx, buffer); + TEST_ASSERT_EQUAL(0, ret); + +#if SOC_SHA_ENDIANNESS_BE + for (int i = 0; i < sizeof(sha1_ctx.state)/sizeof(sha1_ctx.state[0]); i++) + { + *(uint32_t *)(output + i*4) = __builtin_bswap32(sha1_ctx.state[i]); + } +#else + memcpy(output, sha1_ctx.state, 20); +#endif + + // Check if the intermediate states are correct + TEST_ASSERT_EQUAL_HEX8_ARRAY(sha1_expected, output, sizeof(sha1_expected)); + + ret = mbedtls_sha1_finish(&sha1_ctx, output); + TEST_ASSERT_EQUAL(0, ret); + + mbedtls_sha1_free(&sha1_ctx); + +#if SOC_SHA_SUPPORT_SHA512 + mbedtls_sha512_context sha512_ctx; + + const uint8_t sha512_expected[64] = { 0x3c, 0x77, 0x5f, 0xb0, 0x3b, 0x25, 0x8d, 0x3b, + 0xa9, 0x28, 0xa2, 0x29, 0xf2, 0x14, 0x7d, 0xb3, + 0x64, 0x1e, 0x76, 0xd5, 0x0b, 0xbc, 0xdf, 0xb4, + 0x75, 0x1d, 0xe7, 0x7f, 0x62, 0x83, 0xdd, 0x78, + 0x6b, 0x0e, 0xa4, 0xd2, 0xbe, 0x51, 0x56, 0xd4, + 0xfe, 0x3b, 0xa3, 0x3a, 0xd7, 0xf6, 0xd3, 0xb3, + 0xe7, 0x9d, 0xb5, 0xe6, 0x76, 0x35, 0x2a, 0xae, + 0x07, 0x0a, 0x3a, 0x03, 0x44, 0xf0, 0xb8, 0xfe }; + + mbedtls_sha512_init(&sha512_ctx); + mbedtls_sha512_starts(&sha512_ctx, 0); + + ret = mbedtls_internal_sha512_process(&sha512_ctx, buffer); + TEST_ASSERT_EQUAL(0, ret); + + ret = mbedtls_internal_sha512_process(&sha512_ctx, buffer); + TEST_ASSERT_EQUAL(0, ret); + +#if SOC_SHA_ENDIANNESS_BE + for (int i = 0; i < sizeof(sha512_ctx.state)/sizeof(sha512_ctx.state[0]); i++) + { + *(uint64_t *)(output + i*8) = __builtin_bswap64(sha512_ctx.state[i]); + } +#else + memcpy(output, sha512_ctx.state, 64); +#endif + + // Check if the intermediate states are correct + TEST_ASSERT_EQUAL_HEX8_ARRAY(sha512_expected, output, sizeof(sha512_expected)); + + ret = mbedtls_sha512_finish(&sha512_ctx, output); + TEST_ASSERT_EQUAL(0, ret); + + mbedtls_sha512_free(&sha512_ctx); + +#endif + free(buffer); + +} +#endif + } diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 76222b0e31..1ed022077e 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -276,6 +276,9 @@ /* ESP32 style SHA engine, where multiple states can be stored in parallel */ #define SOC_SHA_SUPPORT_PARALLEL_ENG (1) +/* ESP32's SHA peripheral processes and stores data in big-endian format */ +#define SOC_SHA_ENDIANNESS_BE (1) + /* Supported HW algorithms */ #define SOC_SHA_SUPPORT_SHA1 (1) #define SOC_SHA_SUPPORT_SHA256 (1) From e8fcdc3ebfc2e27af019114579a5b30c3a01b08f Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 16 Jun 2023 16:49:59 +0530 Subject: [PATCH 3/8] change(esp_wifi): Copy fastpbkdf2 implementation Copy pbkdf2 implementation from https://github.com/ctz/fastpbkdf2(3c56895) --- .../wpa_supplicant/src/crypto/fastpbkdf2.c | 401 ++++++++++++++++++ .../wpa_supplicant/src/crypto/fastpbkdf2.h | 71 ++++ 2 files changed, 472 insertions(+) create mode 100644 components/wpa_supplicant/src/crypto/fastpbkdf2.c create mode 100644 components/wpa_supplicant/src/crypto/fastpbkdf2.h diff --git a/components/wpa_supplicant/src/crypto/fastpbkdf2.c b/components/wpa_supplicant/src/crypto/fastpbkdf2.c new file mode 100644 index 0000000000..90b42fac0e --- /dev/null +++ b/components/wpa_supplicant/src/crypto/fastpbkdf2.c @@ -0,0 +1,401 @@ +/* + * fast-pbkdf2 - Optimal PBKDF2-HMAC calculation + * Written in 2015 by Joseph Birr-Pixton + * + * 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 + * . + */ + +#include "fastpbkdf2.h" + +#include +#include +#if defined(__GNUC__) +#include +#endif + +#include + +/* --- MSVC doesn't support C99 --- */ +#ifdef _MSC_VER +#define restrict +#define _Pragma __pragma +#endif + +/* --- Common useful things --- */ +#define MIN(a, b) ((a) > (b)) ? (b) : (a) + +static inline void write32_be(uint32_t n, uint8_t out[4]) +{ +#if defined(__GNUC__) && __GNUC__ >= 4 && __BYTE_ORDER == __LITTLE_ENDIAN + *(uint32_t *)(out) = __builtin_bswap32(n); +#else + out[0] = (n >> 24) & 0xff; + out[1] = (n >> 16) & 0xff; + out[2] = (n >> 8) & 0xff; + out[3] = n & 0xff; +#endif +} + +static inline void write64_be(uint64_t n, uint8_t out[8]) +{ +#if defined(__GNUC__) && __GNUC__ >= 4 && __BYTE_ORDER == __LITTLE_ENDIAN + *(uint64_t *)(out) = __builtin_bswap64(n); +#else + write32_be((n >> 32) & 0xffffffff, out); + write32_be(n & 0xffffffff, out + 4); +#endif +} + +/* --- Optional OpenMP parallelisation of consecutive blocks --- */ +#ifdef WITH_OPENMP +# define OPENMP_PARALLEL_FOR _Pragma("omp parallel for") +#else +# define OPENMP_PARALLEL_FOR +#endif + +/* Prepare block (of blocksz bytes) to contain md padding denoting a msg-size + * message (in bytes). block has a prefix of used bytes. + * + * Message length is expressed in 32 bits (so suitable for sha1, sha256, sha512). */ +static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t msg) +{ + memset(block + used, 0, blocksz - used - 4); + block[used] = 0x80; + block += blocksz - 4; + write32_be((uint32_t) (msg * 8), block); +} + +/* Internal function/type names for hash-specific things. */ +#define HMAC_CTX(_name) HMAC_ ## _name ## _ctx +#define HMAC_INIT(_name) HMAC_ ## _name ## _init +#define HMAC_UPDATE(_name) HMAC_ ## _name ## _update +#define HMAC_FINAL(_name) HMAC_ ## _name ## _final + +#define PBKDF2_F(_name) pbkdf2_f_ ## _name +#define PBKDF2(_name) pbkdf2_ ## _name + +/* This macro expands to decls for the whole implementation for a given + * hash function. Arguments are: + * + * _name like 'sha1', added to symbol names + * _blocksz block size, in bytes + * _hashsz digest output, in bytes + * _ctx hash context type + * _init hash context initialisation function + * args: (_ctx *c) + * _update hash context update function + * args: (_ctx *c, const void *data, size_t ndata) + * _final hash context finish function + * args: (void *out, _ctx *c) + * _xform hash context raw block update function + * args: (_ctx *c, const void *data) + * _xcpy hash context raw copy function (only need copy hash state) + * args: (_ctx * restrict out, const _ctx *restrict in) + * _xtract hash context state extraction + * args: args (_ctx *restrict c, uint8_t *restrict out) + * _xxor hash context xor function (only need xor hash state) + * args: (_ctx *restrict out, const _ctx *restrict in) + * + * The resulting function is named PBKDF2(_name). + */ +#define DECL_PBKDF2(_name, _blocksz, _hashsz, _ctx, \ + _init, _update, _xform, _final, _xcpy, _xtract, _xxor) \ + typedef struct { \ + _ctx inner; \ + _ctx outer; \ + } HMAC_CTX(_name); \ + \ + static inline void HMAC_INIT(_name)(HMAC_CTX(_name) *ctx, \ + const uint8_t *key, size_t nkey) \ + { \ + /* Prepare key: */ \ + uint8_t k[_blocksz]; \ + \ + /* Shorten long keys. */ \ + if (nkey > _blocksz) \ + { \ + _init(&ctx->inner); \ + _update(&ctx->inner, key, nkey); \ + _final(k, &ctx->inner); \ + \ + key = k; \ + nkey = _hashsz; \ + } \ + \ + /* Standard doesn't cover case where blocksz < hashsz. */ \ + assert(nkey <= _blocksz); \ + \ + /* Right zero-pad short keys. */ \ + if (k != key) \ + memcpy(k, key, nkey); \ + if (_blocksz > nkey) \ + memset(k + nkey, 0, _blocksz - nkey); \ + \ + /* Start inner hash computation */ \ + uint8_t blk_inner[_blocksz]; \ + uint8_t blk_outer[_blocksz]; \ + \ + for (size_t i = 0; i < _blocksz; i++) \ + { \ + blk_inner[i] = 0x36 ^ k[i]; \ + blk_outer[i] = 0x5c ^ k[i]; \ + } \ + \ + _init(&ctx->inner); \ + _update(&ctx->inner, blk_inner, sizeof blk_inner); \ + \ + /* And outer. */ \ + _init(&ctx->outer); \ + _update(&ctx->outer, blk_outer, sizeof blk_outer); \ + } \ + \ + static inline void HMAC_UPDATE(_name)(HMAC_CTX(_name) *ctx, \ + const void *data, size_t ndata) \ + { \ + _update(&ctx->inner, data, ndata); \ + } \ + \ + static inline void HMAC_FINAL(_name)(HMAC_CTX(_name) *ctx, \ + uint8_t out[_hashsz]) \ + { \ + _final(out, &ctx->inner); \ + _update(&ctx->outer, out, _hashsz); \ + _final(out, &ctx->outer); \ + } \ + \ + \ + /* --- PBKDF2 --- */ \ + static inline void PBKDF2_F(_name)(const HMAC_CTX(_name) *startctx, \ + uint32_t counter, \ + const uint8_t *salt, size_t nsalt, \ + uint32_t iterations, \ + uint8_t *out) \ + { \ + uint8_t countbuf[4]; \ + write32_be(counter, countbuf); \ + \ + /* Prepare loop-invariant padding block. */ \ + uint8_t Ublock[_blocksz]; \ + md_pad(Ublock, _blocksz, _hashsz, _blocksz + _hashsz); \ + \ + /* First iteration: \ + * U_1 = PRF(P, S || INT_32_BE(i)) \ + */ \ + HMAC_CTX(_name) ctx = *startctx; \ + HMAC_UPDATE(_name)(&ctx, salt, nsalt); \ + HMAC_UPDATE(_name)(&ctx, countbuf, sizeof countbuf); \ + HMAC_FINAL(_name)(&ctx, Ublock); \ + _ctx result = ctx.outer; \ + \ + /* Subsequent iterations: \ + * U_c = PRF(P, U_{c-1}) \ + */ \ + for (uint32_t i = 1; i < iterations; i++) \ + { \ + /* Complete inner hash with previous U */ \ + _xcpy(&ctx.inner, &startctx->inner); \ + _xform(&ctx.inner, Ublock); \ + _xtract(&ctx.inner, Ublock); \ + /* Complete outer hash with inner output */ \ + _xcpy(&ctx.outer, &startctx->outer); \ + _xform(&ctx.outer, Ublock); \ + _xtract(&ctx.outer, Ublock); \ + _xxor(&result, &ctx.outer); \ + } \ + \ + /* Reform result into output buffer. */ \ + _xtract(&result, out); \ + } \ + \ + static inline void PBKDF2(_name)(const uint8_t *pw, size_t npw, \ + const uint8_t *salt, size_t nsalt, \ + uint32_t iterations, \ + uint8_t *out, size_t nout) \ + { \ + assert(iterations); \ + assert(out && nout); \ + \ + /* Starting point for inner loop. */ \ + HMAC_CTX(_name) ctx; \ + HMAC_INIT(_name)(&ctx, pw, npw); \ + \ + /* How many blocks do we need? */ \ + uint32_t blocks_needed = (uint32_t)(nout + _hashsz - 1) / _hashsz; \ + \ + OPENMP_PARALLEL_FOR \ + for (uint32_t counter = 1; counter <= blocks_needed; counter++) \ + { \ + uint8_t block[_hashsz]; \ + PBKDF2_F(_name)(&ctx, counter, salt, nsalt, iterations, block); \ + \ + size_t offset = (counter - 1) * _hashsz; \ + size_t taken = MIN(nout - offset, _hashsz); \ + memcpy(out + offset, block, taken); \ + } \ + } + +static inline void sha1_extract(SHA_CTX *restrict ctx, uint8_t *restrict out) +{ + write32_be(ctx->h0, out); + write32_be(ctx->h1, out + 4); + write32_be(ctx->h2, out + 8); + write32_be(ctx->h3, out + 12); + write32_be(ctx->h4, out + 16); +} + +static inline void sha1_cpy(SHA_CTX *restrict out, const SHA_CTX *restrict in) +{ + out->h0 = in->h0; + out->h1 = in->h1; + out->h2 = in->h2; + out->h3 = in->h3; + out->h4 = in->h4; +} + +static inline void sha1_xor(SHA_CTX *restrict out, const SHA_CTX *restrict in) +{ + out->h0 ^= in->h0; + out->h1 ^= in->h1; + out->h2 ^= in->h2; + out->h3 ^= in->h3; + out->h4 ^= in->h4; +} + +DECL_PBKDF2(sha1, + SHA_CBLOCK, + SHA_DIGEST_LENGTH, + SHA_CTX, + SHA1_Init, + SHA1_Update, + SHA1_Transform, + SHA1_Final, + sha1_cpy, + sha1_extract, + sha1_xor) + +static inline void sha256_extract(SHA256_CTX *restrict ctx, uint8_t *restrict out) +{ + write32_be(ctx->h[0], out); + write32_be(ctx->h[1], out + 4); + write32_be(ctx->h[2], out + 8); + write32_be(ctx->h[3], out + 12); + write32_be(ctx->h[4], out + 16); + write32_be(ctx->h[5], out + 20); + write32_be(ctx->h[6], out + 24); + write32_be(ctx->h[7], out + 28); +} + +static inline void sha256_cpy(SHA256_CTX *restrict out, const SHA256_CTX *restrict in) +{ + out->h[0] = in->h[0]; + out->h[1] = in->h[1]; + out->h[2] = in->h[2]; + out->h[3] = in->h[3]; + out->h[4] = in->h[4]; + out->h[5] = in->h[5]; + out->h[6] = in->h[6]; + out->h[7] = in->h[7]; +} + +static inline void sha256_xor(SHA256_CTX *restrict out, const SHA256_CTX *restrict in) +{ + out->h[0] ^= in->h[0]; + out->h[1] ^= in->h[1]; + out->h[2] ^= in->h[2]; + out->h[3] ^= in->h[3]; + out->h[4] ^= in->h[4]; + out->h[5] ^= in->h[5]; + out->h[6] ^= in->h[6]; + out->h[7] ^= in->h[7]; +} + +DECL_PBKDF2(sha256, + SHA256_CBLOCK, + SHA256_DIGEST_LENGTH, + SHA256_CTX, + SHA256_Init, + SHA256_Update, + SHA256_Transform, + SHA256_Final, + sha256_cpy, + sha256_extract, + sha256_xor) + +static inline void sha512_extract(SHA512_CTX *restrict ctx, uint8_t *restrict out) +{ + write64_be(ctx->h[0], out); + write64_be(ctx->h[1], out + 8); + write64_be(ctx->h[2], out + 16); + write64_be(ctx->h[3], out + 24); + write64_be(ctx->h[4], out + 32); + write64_be(ctx->h[5], out + 40); + write64_be(ctx->h[6], out + 48); + write64_be(ctx->h[7], out + 56); +} + +static inline void sha512_cpy(SHA512_CTX *restrict out, const SHA512_CTX *restrict in) +{ + out->h[0] = in->h[0]; + out->h[1] = in->h[1]; + out->h[2] = in->h[2]; + out->h[3] = in->h[3]; + out->h[4] = in->h[4]; + out->h[5] = in->h[5]; + out->h[6] = in->h[6]; + out->h[7] = in->h[7]; +} + +static inline void sha512_xor(SHA512_CTX *restrict out, const SHA512_CTX *restrict in) +{ + out->h[0] ^= in->h[0]; + out->h[1] ^= in->h[1]; + out->h[2] ^= in->h[2]; + out->h[3] ^= in->h[3]; + out->h[4] ^= in->h[4]; + out->h[5] ^= in->h[5]; + out->h[6] ^= in->h[6]; + out->h[7] ^= in->h[7]; +} + +DECL_PBKDF2(sha512, + SHA512_CBLOCK, + SHA512_DIGEST_LENGTH, + SHA512_CTX, + SHA512_Init, + SHA512_Update, + SHA512_Transform, + SHA512_Final, + sha512_cpy, + sha512_extract, + sha512_xor) + +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) +{ + PBKDF2(sha1)(pw, npw, salt, nsalt, iterations, out, nout); +} + +void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, + const uint8_t *salt, size_t nsalt, + uint32_t iterations, + uint8_t *out, size_t nout) +{ + PBKDF2(sha256)(pw, npw, salt, nsalt, iterations, out, nout); +} + +void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, + const uint8_t *salt, size_t nsalt, + uint32_t iterations, + uint8_t *out, size_t nout) +{ + PBKDF2(sha512)(pw, npw, salt, nsalt, iterations, out, nout); +} diff --git a/components/wpa_supplicant/src/crypto/fastpbkdf2.h b/components/wpa_supplicant/src/crypto/fastpbkdf2.h new file mode 100644 index 0000000000..0a7346ecac --- /dev/null +++ b/components/wpa_supplicant/src/crypto/fastpbkdf2.h @@ -0,0 +1,71 @@ +/* + * fastpbkdf2 - Faster PBKDF2-HMAC calculation + * Written in 2015 by Joseph Birr-Pixton + * + * 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 + * . + */ + +#ifndef FASTPBKDF2_H +#define FASTPBKDF2_H + +#include +#include + +#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); + +/** Calculates PBKDF2-HMAC-SHA256. + * + * @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_sha256(const uint8_t *pw, size_t npw, + const uint8_t *salt, size_t nsalt, + uint32_t iterations, + uint8_t *out, size_t nout); + +/** Calculates PBKDF2-HMAC-SHA512. + * + * @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_sha512(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 From 3e4f49606b098f002c36b083e79f628de459884f Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 16 Jun 2023 20:31:56 +0530 Subject: [PATCH 4/8] change(esp_wifi): Port fast_pbkdf2 implementation for mbedlts Add changes to use fast_pbkdf2 as default for PMK calculations. fast_pbkdf2 is significantly faster than current implementations for esp chips. Also removes unnecessary code for pbkdf-sha256 and pbkdf-sha512. --- components/mbedtls/port/include/sha1_alt.h | 18 ++ components/wpa_supplicant/CMakeLists.txt | 2 + .../src/crypto/crypto_mbedtls.c | 13 +- .../wpa_supplicant/src/crypto/fastpbkdf2.c | 248 ++++++------------ .../wpa_supplicant/src/crypto/fastpbkdf2.h | 35 +-- docs/en/COPYRIGHT.rst | 2 + 6 files changed, 126 insertions(+), 192 deletions(-) diff --git a/components/mbedtls/port/include/sha1_alt.h b/components/mbedtls/port/include/sha1_alt.h index f97c0e49b8..ce6391445c 100644 --- a/components/mbedtls/port/include/sha1_alt.h +++ b/components/mbedtls/port/include/sha1_alt.h @@ -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 typedef enum { diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index 505b89ba42..7b4c45f240 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -91,6 +91,7 @@ endif() if(CONFIG_WPA_MBEDTLS_CRYPTO) set(crypto_src + "src/crypto/fastpbkdf2.c" "src/crypto/crypto_mbedtls.c" "src/crypto/crypto_mbedtls-bignum.c" "src/crypto/crypto_mbedtls-ec.c") @@ -202,6 +203,7 @@ target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_IEEE80211W CONFIG_SHA256 CONFIG_WNM + CONFIG_FAST_PBKDF2 ) if(CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE) diff --git a/components/wpa_supplicant/src/crypto/crypto_mbedtls.c b/components/wpa_supplicant/src/crypto/crypto_mbedtls.c index cf37343cfa..544213e0a4 100644 --- a/components/wpa_supplicant/src/crypto/crypto_mbedtls.c +++ b/components/wpa_supplicant/src/crypto/crypto_mbedtls.c @@ -37,6 +37,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) { @@ -658,6 +662,12 @@ 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 + mbedtls_md_context_t sha1_ctx; const mbedtls_md_info_t *info_sha1; int ret; @@ -677,7 +687,7 @@ int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, ret = mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx, (const u8 *) passphrase, os_strlen(passphrase) , ssid, - ssid_len, iterations, 32, buf); + ssid_len, iterations, buflen, buf); if (ret != 0) { ret = -1; goto cleanup; @@ -686,6 +696,7 @@ int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, cleanup: mbedtls_md_free(&sha1_ctx); return ret; +#endif } #ifdef MBEDTLS_DES_C diff --git a/components/wpa_supplicant/src/crypto/fastpbkdf2.c b/components/wpa_supplicant/src/crypto/fastpbkdf2.c index 90b42fac0e..8ac2abbe56 100644 --- a/components/wpa_supplicant/src/crypto/fastpbkdf2.c +++ b/components/wpa_supplicant/src/crypto/fastpbkdf2.c @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2015 Joseph Birr-Pixton + * + * SPDX-License-Identifier: CC0-1.0 + */ + /* * fast-pbkdf2 - Optimal PBKDF2-HMAC calculation * Written in 2015 by Joseph Birr-Pixton @@ -11,7 +17,7 @@ * along with this software. If not, see * . */ - +#include "utils/common.h" #include "fastpbkdf2.h" #include @@ -20,7 +26,9 @@ #include #endif -#include +#include +#include "mbedtls/esp_config.h" +#include "utils/wpa_debug.h" /* --- MSVC doesn't support C99 --- */ #ifdef _MSC_VER @@ -29,7 +37,9 @@ #endif /* --- Common useful things --- */ +#ifndef MIN #define MIN(a, b) ((a) > (b)) ? (b) : (a) +#endif static inline void write32_be(uint32_t n, uint8_t out[4]) { @@ -43,23 +53,6 @@ static inline void write32_be(uint32_t n, uint8_t out[4]) #endif } -static inline void write64_be(uint64_t n, uint8_t out[8]) -{ -#if defined(__GNUC__) && __GNUC__ >= 4 && __BYTE_ORDER == __LITTLE_ENDIAN - *(uint64_t *)(out) = __builtin_bswap64(n); -#else - write32_be((n >> 32) & 0xffffffff, out); - write32_be(n & 0xffffffff, out + 4); -#endif -} - -/* --- Optional OpenMP parallelisation of consecutive blocks --- */ -#ifdef WITH_OPENMP -# define OPENMP_PARALLEL_FOR _Pragma("omp parallel for") -#else -# define OPENMP_PARALLEL_FOR -#endif - /* Prepare block (of blocksz bytes) to contain md padding denoting a msg-size * message (in bytes). block has a prefix of used bytes. * @@ -93,7 +86,7 @@ static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t ms * _update hash context update function * args: (_ctx *c, const void *data, size_t ndata) * _final hash context finish function - * args: (void *out, _ctx *c) + * args: (_ctx *c, void *out) * _xform hash context raw block update function * args: (_ctx *c, const void *data) * _xcpy hash context raw copy function (only need copy hash state) @@ -123,7 +116,7 @@ static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t ms { \ _init(&ctx->inner); \ _update(&ctx->inner, key, nkey); \ - _final(k, &ctx->inner); \ + _final(&ctx->inner, k); \ \ key = k; \ nkey = _hashsz; \ @@ -165,9 +158,9 @@ static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t ms static inline void HMAC_FINAL(_name)(HMAC_CTX(_name) *ctx, \ uint8_t out[_hashsz]) \ { \ - _final(out, &ctx->inner); \ + _final(&ctx->inner, out); \ _update(&ctx->outer, out, _hashsz); \ - _final(out, &ctx->outer); \ + _final(&ctx->outer, out); \ } \ \ \ @@ -229,7 +222,6 @@ static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t ms /* How many blocks do we need? */ \ uint32_t blocks_needed = (uint32_t)(nout + _hashsz - 1) / _hashsz; \ \ - OPENMP_PARALLEL_FOR \ for (uint32_t counter = 1; counter <= blocks_needed; counter++) \ { \ uint8_t block[_hashsz]; \ @@ -241,140 +233,88 @@ static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t ms } \ } -static inline void sha1_extract(SHA_CTX *restrict ctx, uint8_t *restrict out) +static inline void sha1_extract(mbedtls_sha1_context *restrict ctx, uint8_t *restrict out) { - write32_be(ctx->h0, out); - write32_be(ctx->h1, out + 4); - write32_be(ctx->h2, out + 8); - write32_be(ctx->h3, out + 12); - write32_be(ctx->h4, out + 16); +#if defined(MBEDTLS_SHA1_ALT) +#if CONFIG_IDF_TARGET_ESP32 + /* ESP32 stores internal SHA state in BE format similar to software */ + write32_be(ctx->state[0], out); + write32_be(ctx->state[1], out + 4); + write32_be(ctx->state[2], out + 8); + write32_be(ctx->state[3], out + 12); + write32_be(ctx->state[4], out + 16); +#else + *(uint32_t *)(out) = ctx->state[0]; + *(uint32_t *)(out + 4) = ctx->state[1]; + *(uint32_t *)(out + 8) = ctx->state[2]; + *(uint32_t *)(out + 12) = ctx->state[3]; + *(uint32_t *)(out + 16) = ctx->state[4]; +#endif +#else + write32_be(ctx->MBEDTLS_PRIVATE(state)[0], out); + write32_be(ctx->MBEDTLS_PRIVATE(state)[1], out + 4); + write32_be(ctx->MBEDTLS_PRIVATE(state)[2], out + 8); + write32_be(ctx->MBEDTLS_PRIVATE(state)[3], out + 12); + write32_be(ctx->MBEDTLS_PRIVATE(state)[4], out + 16); +#endif } -static inline void sha1_cpy(SHA_CTX *restrict out, const SHA_CTX *restrict in) +static inline void sha1_cpy(mbedtls_sha1_context *restrict out, const mbedtls_sha1_context *restrict in) { - out->h0 = in->h0; - out->h1 = in->h1; - out->h2 = in->h2; - out->h3 = in->h3; - out->h4 = in->h4; +#if defined(MBEDTLS_SHA1_ALT) + out->state[0] = in->state[0]; + out->state[1] = in->state[1]; + out->state[2] = in->state[2]; + out->state[3] = in->state[3]; + out->state[4] = in->state[4]; +#else + out->MBEDTLS_PRIVATE(state)[0] = in->MBEDTLS_PRIVATE(state)[0]; + out->MBEDTLS_PRIVATE(state)[1] = in->MBEDTLS_PRIVATE(state)[1]; + out->MBEDTLS_PRIVATE(state)[2] = in->MBEDTLS_PRIVATE(state)[2]; + out->MBEDTLS_PRIVATE(state)[3] = in->MBEDTLS_PRIVATE(state)[3]; + out->MBEDTLS_PRIVATE(state)[4] = in->MBEDTLS_PRIVATE(state)[4]; +#endif } -static inline void sha1_xor(SHA_CTX *restrict out, const SHA_CTX *restrict in) +static inline void sha1_xor(mbedtls_sha1_context *restrict out, const mbedtls_sha1_context *restrict in) { - out->h0 ^= in->h0; - out->h1 ^= in->h1; - out->h2 ^= in->h2; - out->h3 ^= in->h3; - out->h4 ^= in->h4; +#if defined(MBEDTLS_SHA1_ALT) + out->state[0] ^= in->state[0]; + out->state[1] ^= in->state[1]; + out->state[2] ^= in->state[2]; + out->state[3] ^= in->state[3]; + out->state[4] ^= in->state[4]; +#else + out->MBEDTLS_PRIVATE(state)[0] ^= in->MBEDTLS_PRIVATE(state)[0]; + out->MBEDTLS_PRIVATE(state)[1] ^= in->MBEDTLS_PRIVATE(state)[1]; + out->MBEDTLS_PRIVATE(state)[2] ^= in->MBEDTLS_PRIVATE(state)[2]; + out->MBEDTLS_PRIVATE(state)[3] ^= in->MBEDTLS_PRIVATE(state)[3]; + out->MBEDTLS_PRIVATE(state)[4] ^= in->MBEDTLS_PRIVATE(state)[4]; +#endif } -DECL_PBKDF2(sha1, - SHA_CBLOCK, - SHA_DIGEST_LENGTH, - SHA_CTX, - SHA1_Init, - SHA1_Update, - SHA1_Transform, - SHA1_Final, - sha1_cpy, - sha1_extract, - sha1_xor) - -static inline void sha256_extract(SHA256_CTX *restrict ctx, uint8_t *restrict out) +static int mbedtls_sha1_init_start(mbedtls_sha1_context *ctx) { - write32_be(ctx->h[0], out); - write32_be(ctx->h[1], out + 4); - write32_be(ctx->h[2], out + 8); - write32_be(ctx->h[3], out + 12); - write32_be(ctx->h[4], out + 16); - write32_be(ctx->h[5], out + 20); - write32_be(ctx->h[6], out + 24); - write32_be(ctx->h[7], out + 28); + mbedtls_sha1_init(ctx); + mbedtls_sha1_starts(ctx); +#if defined(CONFIG_IDF_TARGET_ESP32) && defined(MBEDTLS_SHA1_ALT) + /* Use software mode for esp32 since hardware can't give output more than 20 */ + esp_mbedtls_set_sha1_mode(ctx, ESP_MBEDTLS_SHA1_SOFTWARE); +#endif + return 0; } -static inline void sha256_cpy(SHA256_CTX *restrict out, const SHA256_CTX *restrict in) -{ - out->h[0] = in->h[0]; - out->h[1] = in->h[1]; - out->h[2] = in->h[2]; - out->h[3] = in->h[3]; - out->h[4] = in->h[4]; - out->h[5] = in->h[5]; - out->h[6] = in->h[6]; - out->h[7] = in->h[7]; -} - -static inline void sha256_xor(SHA256_CTX *restrict out, const SHA256_CTX *restrict in) -{ - out->h[0] ^= in->h[0]; - out->h[1] ^= in->h[1]; - out->h[2] ^= in->h[2]; - out->h[3] ^= in->h[3]; - out->h[4] ^= in->h[4]; - out->h[5] ^= in->h[5]; - out->h[6] ^= in->h[6]; - out->h[7] ^= in->h[7]; -} - -DECL_PBKDF2(sha256, - SHA256_CBLOCK, - SHA256_DIGEST_LENGTH, - SHA256_CTX, - SHA256_Init, - SHA256_Update, - SHA256_Transform, - SHA256_Final, - sha256_cpy, - sha256_extract, - sha256_xor) - -static inline void sha512_extract(SHA512_CTX *restrict ctx, uint8_t *restrict out) -{ - write64_be(ctx->h[0], out); - write64_be(ctx->h[1], out + 8); - write64_be(ctx->h[2], out + 16); - write64_be(ctx->h[3], out + 24); - write64_be(ctx->h[4], out + 32); - write64_be(ctx->h[5], out + 40); - write64_be(ctx->h[6], out + 48); - write64_be(ctx->h[7], out + 56); -} - -static inline void sha512_cpy(SHA512_CTX *restrict out, const SHA512_CTX *restrict in) -{ - out->h[0] = in->h[0]; - out->h[1] = in->h[1]; - out->h[2] = in->h[2]; - out->h[3] = in->h[3]; - out->h[4] = in->h[4]; - out->h[5] = in->h[5]; - out->h[6] = in->h[6]; - out->h[7] = in->h[7]; -} - -static inline void sha512_xor(SHA512_CTX *restrict out, const SHA512_CTX *restrict in) -{ - out->h[0] ^= in->h[0]; - out->h[1] ^= in->h[1]; - out->h[2] ^= in->h[2]; - out->h[3] ^= in->h[3]; - out->h[4] ^= in->h[4]; - out->h[5] ^= in->h[5]; - out->h[6] ^= in->h[6]; - out->h[7] ^= in->h[7]; -} - -DECL_PBKDF2(sha512, - SHA512_CBLOCK, - SHA512_DIGEST_LENGTH, - SHA512_CTX, - SHA512_Init, - SHA512_Update, - SHA512_Transform, - SHA512_Final, - sha512_cpy, - sha512_extract, - sha512_xor) +DECL_PBKDF2(sha1, // _name + 64, // _blocksz + 20, // _hashsz + mbedtls_sha1_context, // _ctx + mbedtls_sha1_init_start, // _init + mbedtls_sha1_update, // _update + mbedtls_internal_sha1_process, // _xform + mbedtls_sha1_finish, // _final + sha1_cpy, // _xcpy + sha1_extract, // _xtract + sha1_xor) // _xxor void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, @@ -383,19 +323,3 @@ void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, { PBKDF2(sha1)(pw, npw, salt, nsalt, iterations, out, nout); } - -void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, - const uint8_t *salt, size_t nsalt, - uint32_t iterations, - uint8_t *out, size_t nout) -{ - PBKDF2(sha256)(pw, npw, salt, nsalt, iterations, out, nout); -} - -void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, - const uint8_t *salt, size_t nsalt, - uint32_t iterations, - uint8_t *out, size_t nout) -{ - PBKDF2(sha512)(pw, npw, salt, nsalt, iterations, out, nout); -} diff --git a/components/wpa_supplicant/src/crypto/fastpbkdf2.h b/components/wpa_supplicant/src/crypto/fastpbkdf2.h index 0a7346ecac..60838942dd 100644 --- a/components/wpa_supplicant/src/crypto/fastpbkdf2.h +++ b/components/wpa_supplicant/src/crypto/fastpbkdf2.h @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2015 Joseph Birr-Pixton + * + * SPDX-License-Identifier: CC0-1.0 + */ + /* * fastpbkdf2 - Faster PBKDF2-HMAC calculation * Written in 2015 by Joseph Birr-Pixton @@ -35,35 +41,6 @@ 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); - -/** Calculates PBKDF2-HMAC-SHA256. - * - * @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_sha256(const uint8_t *pw, size_t npw, - const uint8_t *salt, size_t nsalt, - uint32_t iterations, - uint8_t *out, size_t nout); - -/** Calculates PBKDF2-HMAC-SHA512. - * - * @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_sha512(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 diff --git a/docs/en/COPYRIGHT.rst b/docs/en/COPYRIGHT.rst index 1c6b8d584e..256a6dbb71 100644 --- a/docs/en/COPYRIGHT.rst +++ b/docs/en/COPYRIGHT.rst @@ -25,6 +25,8 @@ These third party libraries can be included into the application (firmware) prod * `wpa_supplicant`_ Copyright (c) 2003-2005 Jouni Malinen and licensed under the BSD license. +* :component_file:`Fast PBKDF2 ` 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. * `JSMN`_ JSON Parser (components/jsmn) Copyright (c) 2010 Serge A. Zaitsev and licensed under the MIT license. From e9f29de687dd44b5d4c7216d90391510f266393a Mon Sep 17 00:00:00 2001 From: Shreyas Sheth Date: Thu, 24 Aug 2023 01:07:35 +0530 Subject: [PATCH 5/8] ci(wifi): Add test case for fast pbkdf2 verification --- .../wpa_supplicant/test/test_fast_pbkdf2.c | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 components/wpa_supplicant/test/test_fast_pbkdf2.c diff --git a/components/wpa_supplicant/test/test_fast_pbkdf2.c b/components/wpa_supplicant/test/test_fast_pbkdf2.c new file mode 100644 index 0000000000..ec08525d36 --- /dev/null +++ b/components/wpa_supplicant/test/test_fast_pbkdf2.c @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include "string.h" +#include +#include "unity.h" +#include "utils/common.h" +#include "mbedtls/pkcs5.h" +#include "crypto/sha1.h" + +#define MAX_PASSPHRASE_LEN 64 +#define MAX_SSID_LEN 32 +#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); + ESP_LOG_BUFFER_HEXDUMP("PMK", PMK, PMK_LEN, ESP_LOG_INFO); + ESP_LOG_BUFFER_HEXDUMP("expected_pmk", expected_pmk1, PMK_LEN, ESP_LOG_INFO); + + /* Compare fast PBKDF output with mbedtls pbkdf2 function's output */ + pbkdf2_sha1("espressif2", (uint8_t *)"espressif2", strlen("espressif2"), 4096, PMK, PMK_LEN); + mbedtls_md_context_t sha1_ctx; + const mbedtls_md_info_t *info_sha1; + mbedtls_md_init(&sha1_ctx); + info_sha1 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + mbedtls_md_setup(&sha1_ctx, info_sha1, 1); + mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx, (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); + ESP_LOG_BUFFER_HEXDUMP("PMK", PMK, PMK_LEN, ESP_LOG_INFO); + ESP_LOG_BUFFER_HEXDUMP("expected_pmk", expected_pmk, PMK_LEN, ESP_LOG_INFO); + /* 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_md_context_t sha1_ctx_1; + const mbedtls_md_info_t *info_sha1_1; + mbedtls_md_init(&sha1_ctx_1); + info_sha1_1 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + mbedtls_md_setup(&sha1_ctx_1, info_sha1_1, 1); + mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx_1, (const unsigned char *) passphrase, + strlen((char *)passphrase), (const unsigned char *)ssid, ssid_len, + 4096, PMK_LEN, expected_pmk1); + ESP_LOG_BUFFER_HEXDUMP("PMK", PMK, PMK_LEN, ESP_LOG_INFO); + ESP_LOG_BUFFER_HEXDUMP("expected_pmk", expected_pmk1, PMK_LEN, ESP_LOG_INFO); + TEST_ASSERT(memcmp(PMK, expected_pmk1, PMK_LEN) == 0); +} From a1b3ef5cefd2acad3e40b52cbd373618661b50f0 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Thu, 26 Oct 2023 10:59:56 +0530 Subject: [PATCH 6/8] fix(wpa_supplicant): implement sha1_finish for fastpbkdf2 --- .../wpa_supplicant/src/crypto/fastpbkdf2.c | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/components/wpa_supplicant/src/crypto/fastpbkdf2.c b/components/wpa_supplicant/src/crypto/fastpbkdf2.c index 8ac2abbe56..4f8fa2f804 100644 --- a/components/wpa_supplicant/src/crypto/fastpbkdf2.c +++ b/components/wpa_supplicant/src/crypto/fastpbkdf2.c @@ -30,6 +30,12 @@ #include "mbedtls/esp_config.h" #include "utils/wpa_debug.h" +#if (MBEDTLS_VERSION_NUMBER < 0x03000000) +#ifndef MBEDTLS_PRIVATE +#define MBEDTLS_PRIVATE(member) member +#endif +#endif + /* --- MSVC doesn't support C99 --- */ #ifdef _MSC_VER #define restrict @@ -304,6 +310,65 @@ static int mbedtls_sha1_init_start(mbedtls_sha1_context *ctx) return 0; } +#ifndef MBEDTLS_SHA1_ALT +static int sha1_finish(mbedtls_sha1_context *ctx, + unsigned char output[20]) +{ + int ret = -1; + uint32_t used; + uint32_t high, low; + + /* + * Add padding: 0x80 then 0x00 until 8 bytes remain for the length + */ + used = ctx->MBEDTLS_PRIVATE(total)[0] & 0x3F; + + ctx->MBEDTLS_PRIVATE(buffer)[used++] = 0x80; + + if (used <= 56) { + /* Enough room for padding + length in current block */ + memset(ctx->MBEDTLS_PRIVATE(buffer) + used, 0, 56 - used); + } else { + /* We'll need an extra block */ + memset(ctx->MBEDTLS_PRIVATE(buffer) + used, 0, 64 - used); + + if ((ret = mbedtls_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { + goto exit; + } + + memset(ctx->MBEDTLS_PRIVATE(buffer), 0, 56); + } + + /* + * Add message length + */ + high = (ctx->MBEDTLS_PRIVATE(total)[0] >> 29) + | (ctx->MBEDTLS_PRIVATE(total)[1] << 3); + low = (ctx->MBEDTLS_PRIVATE(total)[0] << 3); + + write32_be(high, ctx->MBEDTLS_PRIVATE(buffer) + 56); + write32_be(low, ctx->MBEDTLS_PRIVATE(buffer) + 60); + + if ((ret = mbedtls_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { + goto exit; + } + + /* + * Output final state + */ + write32_be(ctx->MBEDTLS_PRIVATE(state)[0], output); + write32_be(ctx->MBEDTLS_PRIVATE(state)[1], output + 4); + write32_be(ctx->MBEDTLS_PRIVATE(state)[2], output + 8); + write32_be(ctx->MBEDTLS_PRIVATE(state)[3], output + 12); + write32_be(ctx->MBEDTLS_PRIVATE(state)[4], output + 16); + + ret = 0; + +exit: + return ret; +} +#endif + DECL_PBKDF2(sha1, // _name 64, // _blocksz 20, // _hashsz @@ -311,7 +376,11 @@ DECL_PBKDF2(sha1, // _name mbedtls_sha1_init_start, // _init mbedtls_sha1_update, // _update mbedtls_internal_sha1_process, // _xform +#if defined(MBEDTLS_SHA1_ALT) mbedtls_sha1_finish, // _final +#else + sha1_finish, // _final +#endif sha1_cpy, // _xcpy sha1_extract, // _xtract sha1_xor) // _xxor From d6f65b147253cc8c501d28943b6d3191249cc7bd Mon Sep 17 00:00:00 2001 From: Shreyas Sheth Date: Mon, 27 Nov 2023 18:17:53 +0530 Subject: [PATCH 7/8] fix(wpa_supplicant): Remove deprecated mbedtls functions used in fast pbkdf2 and fix ci error --- components/mbedtls/test/test_sha.c | 13 +++++++------ components/wpa_supplicant/src/crypto/fastpbkdf2.c | 14 +++++++------- docs/en/COPYRIGHT.rst | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/components/mbedtls/test/test_sha.c b/components/mbedtls/test/test_sha.c index 4f076a741c..df157344d9 100644 --- a/components/mbedtls/test/test_sha.c +++ b/components/mbedtls/test/test_sha.c @@ -141,6 +141,7 @@ TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]") #if SOC_SHA_SUPPORT_SHA512 TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_espsha, sha512_mbedtls, sizeof(sha512_espsha), "SHA512 results should match"); #endif +} #if CONFIG_MBEDTLS_HARDWARE_SHA @@ -160,7 +161,8 @@ TEST_CASE("Test mbedtls_internal_sha_process()", "[hw_crypto]") 0xa4, 0xae, 0x4d, 0xe9 }; mbedtls_sha1_init(&sha1_ctx); - mbedtls_sha1_starts(&sha1_ctx); + ret = mbedtls_sha1_starts_ret(&sha1_ctx); + TEST_ASSERT_EQUAL(0, ret); ret = mbedtls_internal_sha1_process(&sha1_ctx, buffer); TEST_ASSERT_EQUAL(0, ret); @@ -180,7 +182,7 @@ TEST_CASE("Test mbedtls_internal_sha_process()", "[hw_crypto]") // Check if the intermediate states are correct TEST_ASSERT_EQUAL_HEX8_ARRAY(sha1_expected, output, sizeof(sha1_expected)); - ret = mbedtls_sha1_finish(&sha1_ctx, output); + ret = mbedtls_sha1_finish_ret(&sha1_ctx, output); TEST_ASSERT_EQUAL(0, ret); mbedtls_sha1_free(&sha1_ctx); @@ -198,7 +200,8 @@ TEST_CASE("Test mbedtls_internal_sha_process()", "[hw_crypto]") 0x07, 0x0a, 0x3a, 0x03, 0x44, 0xf0, 0xb8, 0xfe }; mbedtls_sha512_init(&sha512_ctx); - mbedtls_sha512_starts(&sha512_ctx, 0); + ret = mbedtls_sha512_starts_ret(&sha512_ctx, 0); + TEST_ASSERT_EQUAL(0, ret); ret = mbedtls_internal_sha512_process(&sha512_ctx, buffer); TEST_ASSERT_EQUAL(0, ret); @@ -218,7 +221,7 @@ TEST_CASE("Test mbedtls_internal_sha_process()", "[hw_crypto]") // Check if the intermediate states are correct TEST_ASSERT_EQUAL_HEX8_ARRAY(sha512_expected, output, sizeof(sha512_expected)); - ret = mbedtls_sha512_finish(&sha512_ctx, output); + ret = mbedtls_sha512_finish_ret(&sha512_ctx, output); TEST_ASSERT_EQUAL(0, ret); mbedtls_sha512_free(&sha512_ctx); @@ -228,5 +231,3 @@ TEST_CASE("Test mbedtls_internal_sha_process()", "[hw_crypto]") } #endif - -} diff --git a/components/wpa_supplicant/src/crypto/fastpbkdf2.c b/components/wpa_supplicant/src/crypto/fastpbkdf2.c index 4f8fa2f804..9084eef09c 100644 --- a/components/wpa_supplicant/src/crypto/fastpbkdf2.c +++ b/components/wpa_supplicant/src/crypto/fastpbkdf2.c @@ -301,13 +301,13 @@ static inline void sha1_xor(mbedtls_sha1_context *restrict out, const mbedtls_sh static int mbedtls_sha1_init_start(mbedtls_sha1_context *ctx) { - mbedtls_sha1_init(ctx); - mbedtls_sha1_starts(ctx); + mbedtls_sha1_init(ctx); + mbedtls_sha1_starts_ret(ctx); #if defined(CONFIG_IDF_TARGET_ESP32) && defined(MBEDTLS_SHA1_ALT) - /* Use software mode for esp32 since hardware can't give output more than 20 */ - esp_mbedtls_set_sha1_mode(ctx, ESP_MBEDTLS_SHA1_SOFTWARE); + /* Use software mode for esp32 since hardware can't give output more than 20 */ + esp_mbedtls_set_sha1_mode(ctx, ESP_MBEDTLS_SHA1_SOFTWARE); #endif - return 0; + return 0; } #ifndef MBEDTLS_SHA1_ALT @@ -374,10 +374,10 @@ DECL_PBKDF2(sha1, // _name 20, // _hashsz mbedtls_sha1_context, // _ctx mbedtls_sha1_init_start, // _init - mbedtls_sha1_update, // _update + mbedtls_sha1_update_ret, // _update mbedtls_internal_sha1_process, // _xform #if defined(MBEDTLS_SHA1_ALT) - mbedtls_sha1_finish, // _final + mbedtls_sha1_finish_ret, // _final #else sha1_finish, // _final #endif diff --git a/docs/en/COPYRIGHT.rst b/docs/en/COPYRIGHT.rst index 256a6dbb71..871cc197ed 100644 --- a/docs/en/COPYRIGHT.rst +++ b/docs/en/COPYRIGHT.rst @@ -25,7 +25,7 @@ These third party libraries can be included into the application (firmware) prod * `wpa_supplicant`_ Copyright (c) 2003-2005 Jouni Malinen and licensed under the BSD license. -* :component_file:`Fast PBKDF2 ` Copyright (c) 2015 Joseph Birr-Pixton and licensed under CC0 Public Domain Dedication license. +* :component_file:`Fast PBKDF2 ` 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. From f157786e2dbdffccc9b86a5cd858c756bc629e54 Mon Sep 17 00:00:00 2001 From: Shreyas Sheth Date: Wed, 6 Dec 2023 00:09:11 +0530 Subject: [PATCH 8/8] fix(ci): Increment number of runner for test UT_T1_1 for esp32s2 --- .gitlab/ci/target-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 44aaba3060..06b4d26e9a 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -701,7 +701,7 @@ UT_046: UT_047: extends: .unit_test_esp32s2_template - parallel: 7 + parallel: 8 tags: - ESP32S2_IDF - UT_T1_1