mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
Merge branch 'feature/pbkdf2_fast_implementation_v4.4' into 'release/v4.4'
Feature/pbkdf2 fast implementation v4.4 See merge request espressif/esp-idf!25515
This commit is contained in:
@ -701,7 +701,7 @@ UT_046:
|
||||
|
||||
UT_047:
|
||||
extends: .unit_test_esp32s2_template
|
||||
parallel: 7
|
||||
parallel: 8
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- UT_T1_1
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
|
@ -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];
|
||||
|
@ -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];
|
||||
|
@ -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];
|
||||
|
@ -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];
|
||||
|
@ -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];
|
||||
|
@ -142,3 +142,92 @@ TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]")
|
||||
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);
|
||||
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);
|
||||
|
||||
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_ret(&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);
|
||||
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);
|
||||
|
||||
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_ret(&sha512_ctx, output);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
|
||||
mbedtls_sha512_free(&sha512_ctx);
|
||||
|
||||
#endif
|
||||
free(buffer);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
394
components/wpa_supplicant/src/crypto/fastpbkdf2.c
Normal file
394
components/wpa_supplicant/src/crypto/fastpbkdf2.c
Normal file
@ -0,0 +1,394 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015 Joseph Birr-Pixton <jpixton@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* fast-pbkdf2 - Optimal PBKDF2-HMAC calculation
|
||||
* Written in 2015 by Joseph Birr-Pixton <jpixton@gmail.com>
|
||||
*
|
||||
* To the extent possible under law, the author(s) have dedicated all
|
||||
* copyright and related and neighboring rights to this software to the
|
||||
* public domain worldwide. This software is distributed without any
|
||||
* warranty.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication
|
||||
* along with this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#include "utils/common.h"
|
||||
#include "fastpbkdf2.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#if defined(__GNUC__)
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#include <mbedtls/sha1.h>
|
||||
#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
|
||||
#define _Pragma __pragma
|
||||
#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])
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
/* 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: (_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)
|
||||
* 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(&ctx->inner, k); \
|
||||
\
|
||||
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(&ctx->inner, out); \
|
||||
_update(&ctx->outer, out, _hashsz); \
|
||||
_final(&ctx->outer, out); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
/* --- 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; \
|
||||
\
|
||||
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(mbedtls_sha1_context *restrict ctx, uint8_t *restrict out)
|
||||
{
|
||||
#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(mbedtls_sha1_context *restrict out, const mbedtls_sha1_context *restrict in)
|
||||
{
|
||||
#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(mbedtls_sha1_context *restrict out, const mbedtls_sha1_context *restrict in)
|
||||
{
|
||||
#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 int mbedtls_sha1_init_start(mbedtls_sha1_context *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);
|
||||
#endif
|
||||
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
|
||||
mbedtls_sha1_context, // _ctx
|
||||
mbedtls_sha1_init_start, // _init
|
||||
mbedtls_sha1_update_ret, // _update
|
||||
mbedtls_internal_sha1_process, // _xform
|
||||
#if defined(MBEDTLS_SHA1_ALT)
|
||||
mbedtls_sha1_finish_ret, // _final
|
||||
#else
|
||||
sha1_finish, // _final
|
||||
#endif
|
||||
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,
|
||||
uint32_t iterations,
|
||||
uint8_t *out, size_t nout)
|
||||
{
|
||||
PBKDF2(sha1)(pw, npw, salt, nsalt, iterations, out, nout);
|
||||
}
|
48
components/wpa_supplicant/src/crypto/fastpbkdf2.h
Normal file
48
components/wpa_supplicant/src/crypto/fastpbkdf2.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015 Joseph Birr-Pixton <jpixton@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* fastpbkdf2 - Faster PBKDF2-HMAC calculation
|
||||
* Written in 2015 by Joseph Birr-Pixton <jpixton@gmail.com>
|
||||
*
|
||||
* To the extent possible under law, the author(s) have dedicated all
|
||||
* copyright and related and neighboring rights to this software to the
|
||||
* public domain worldwide. This software is distributed without any
|
||||
* warranty.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication
|
||||
* along with this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef FASTPBKDF2_H
|
||||
#define FASTPBKDF2_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Calculates PBKDF2-HMAC-SHA1.
|
||||
*
|
||||
* @p npw bytes at @p pw are the password input.
|
||||
* @p nsalt bytes at @p salt are the salt input.
|
||||
* @p iterations is the PBKDF2 iteration count and must be non-zero.
|
||||
* @p nout bytes of output are written to @p out. @p nout must be non-zero.
|
||||
*
|
||||
* This function cannot fail; it does not report errors.
|
||||
*/
|
||||
void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw,
|
||||
const uint8_t *salt, size_t nsalt,
|
||||
uint32_t iterations,
|
||||
uint8_t *out, size_t nout);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
74
components/wpa_supplicant/test/test_fast_pbkdf2.c
Normal file
74
components/wpa_supplicant/test/test_fast_pbkdf2.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "string.h"
|
||||
#include <inttypes.h>
|
||||
#include "unity.h"
|
||||
#include "utils/common.h"
|
||||
#include "mbedtls/pkcs5.h"
|
||||
#include "crypto/sha1.h"
|
||||
|
||||
#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);
|
||||
}
|
@ -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 <wpa_supplicant/src/crypto/crypto_mbedtls.c>` Copyright (c) 2015 Joseph Birr-Pixton and licensed under CC0 Public Domain Dedication license.
|
||||
|
||||
* `FreeBSD net80211`_ Copyright (c) 2004-2008 Sam Leffler, Errno Consulting and licensed under the BSD license.
|
||||
|
||||
* `JSMN`_ JSON Parser (components/jsmn) Copyright (c) 2010 Serge A. Zaitsev and licensed under the MIT license.
|
||||
|
Reference in New Issue
Block a user