mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
crypto: SHA and AES accelerator bring up for S2
Brings up, fixes and enables AES and SHA hardware acceleration. Closes IDF-714 Closes IDF-716
This commit is contained in:
parent
59381b60c0
commit
37369a8a57
@ -74,14 +74,15 @@ target_sources(mbedtls PRIVATE "${COMPONENT_DIR}/port/mbedtls_debug.c"
|
||||
|
||||
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c"
|
||||
"${COMPONENT_DIR}/port/esp_mem.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha1.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha256.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha512.c"
|
||||
"${COMPONENT_DIR}/port/esp_timing.c"
|
||||
"${COMPONENT_DIR}/port/esp_sha.c"
|
||||
"${COMPONENT_DIR}/port/esp_aes_xts.c"
|
||||
"${COMPONENT_DIR}/port/${idf_target}/esp_bignum.c"
|
||||
"${COMPONENT_DIR}/port/${idf_target}/aes.c"
|
||||
"${COMPONENT_DIR}/port/${idf_target}/sha.c")
|
||||
"${COMPONENT_DIR}/port/${idf_target}/sha.c"
|
||||
"${COMPONENT_DIR}/port/${idf_target}/esp_sha1.c"
|
||||
"${COMPONENT_DIR}/port/${idf_target}/esp_sha256.c"
|
||||
"${COMPONENT_DIR}/port/${idf_target}/esp_sha512.c")
|
||||
|
||||
foreach(target ${mbedtls_targets})
|
||||
target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h")
|
||||
|
@ -189,13 +189,33 @@ menu "mbedTLS"
|
||||
config MBEDTLS_HARDWARE_AES
|
||||
bool "Enable hardware AES acceleration"
|
||||
default y
|
||||
depends on !IDF_TARGET_ESP32S2
|
||||
help
|
||||
Enable hardware accelerated AES encryption & decryption.
|
||||
|
||||
Note that if the ESP32 CPU is running at 240MHz, hardware AES does not
|
||||
offer any speed boost over software AES.
|
||||
|
||||
config MBEDTLS_AES_USE_INTERRUPT
|
||||
bool "Use interrupt for long AES operations"
|
||||
depends on MBEDTLS_HARDWARE_AES
|
||||
default y
|
||||
help
|
||||
Use an interrupt to coordinate long AES operations.
|
||||
|
||||
This allows other code to run on the CPU while an AES operation is pending.
|
||||
Otherwise the CPU busy-waits.
|
||||
|
||||
config MBEDTLS_HARDWARE_GCM
|
||||
bool "Enable partially hardware accelerated GCM"
|
||||
#depends on IDF_TARGET_ESP32S2 && MBEDTLS_HARDWARE_AES
|
||||
depends on 0
|
||||
default n
|
||||
help
|
||||
Enable partially hardware accelerated GCM.
|
||||
|
||||
Due to hardware limitations, hardware acceleration currently does not
|
||||
offer any speed boost over software GCM with hardware accelerated AES operations.
|
||||
|
||||
config MBEDTLS_HARDWARE_MPI
|
||||
bool "Enable hardware MPI (bignum) acceleration"
|
||||
default y
|
||||
@ -211,11 +231,10 @@ menu "mbedTLS"
|
||||
config MBEDTLS_HARDWARE_SHA
|
||||
bool "Enable hardware SHA acceleration"
|
||||
default y
|
||||
depends on !IDF_TARGET_ESP32S2
|
||||
help
|
||||
Enable hardware accelerated SHA1, SHA256, SHA384 & SHA512 in mbedTLS.
|
||||
|
||||
Due to a hardware limitation, hardware acceleration is only
|
||||
Due to a hardware limitation, on the ESP32 hardware acceleration is only
|
||||
guaranteed if SHA digests are calculated one at a time. If more
|
||||
than one SHA digest is calculated at the same time, one will
|
||||
be calculated fully in hardware and the rest will be calculated
|
||||
|
@ -508,247 +508,4 @@ int esp_aes_crypt_ofb( esp_aes_context *ctx,
|
||||
esp_aes_release_hardware();
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Below XTS implementation is copied aes.c of mbedtls library.
|
||||
* When MBEDTLS_AES_ALT is defined mbedtls expects alternate
|
||||
* definition of XTS functions to be available. Even if this
|
||||
* could have been avoided, it is done for consistency reason.
|
||||
*/
|
||||
|
||||
void esp_aes_xts_init( esp_aes_xts_context *ctx )
|
||||
{
|
||||
esp_aes_init( &ctx->crypt );
|
||||
esp_aes_init( &ctx->tweak );
|
||||
}
|
||||
|
||||
void esp_aes_xts_free( esp_aes_xts_context *ctx )
|
||||
{
|
||||
esp_aes_free( &ctx->crypt );
|
||||
esp_aes_free( &ctx->tweak );
|
||||
}
|
||||
|
||||
static int esp_aes_xts_decode_keys( const unsigned char *key,
|
||||
unsigned int keybits,
|
||||
const unsigned char **key1,
|
||||
unsigned int *key1bits,
|
||||
const unsigned char **key2,
|
||||
unsigned int *key2bits )
|
||||
{
|
||||
const unsigned int half_keybits = keybits / 2;
|
||||
const unsigned int half_keybytes = half_keybits / 8;
|
||||
|
||||
switch( keybits )
|
||||
{
|
||||
case 256: break;
|
||||
case 512: break;
|
||||
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
|
||||
}
|
||||
|
||||
*key1bits = half_keybits;
|
||||
*key2bits = half_keybits;
|
||||
*key1 = &key[0];
|
||||
*key2 = &key[half_keybytes];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
ret = esp_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set the tweak key. Always set tweak key for the encryption mode. */
|
||||
ret = esp_aes_setkey( &ctx->tweak, key2, key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set crypt key for encryption. */
|
||||
return esp_aes_setkey( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
|
||||
int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
ret = esp_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set the tweak key. Always set tweak key for encryption. */
|
||||
ret = esp_aes_setkey( &ctx->tweak, key2, key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set crypt key for decryption. */
|
||||
return esp_aes_setkey( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
|
||||
/* Endianess with 64 bits values */
|
||||
#ifndef GET_UINT64_LE
|
||||
#define GET_UINT64_LE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
|
||||
| ( (uint64_t) (b)[(i) + 6] << 48 ) \
|
||||
| ( (uint64_t) (b)[(i) + 5] << 40 ) \
|
||||
| ( (uint64_t) (b)[(i) + 4] << 32 ) \
|
||||
| ( (uint64_t) (b)[(i) + 3] << 24 ) \
|
||||
| ( (uint64_t) (b)[(i) + 2] << 16 ) \
|
||||
| ( (uint64_t) (b)[(i) + 1] << 8 ) \
|
||||
| ( (uint64_t) (b)[(i) ] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT64_LE
|
||||
#define PUT_UINT64_LE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) ] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef unsigned char esp_be128[16];
|
||||
|
||||
/*
|
||||
* GF(2^128) multiplication function
|
||||
*
|
||||
* This function multiplies a field element by x in the polynomial field
|
||||
* representation. It uses 64-bit word operations to gain speed but compensates
|
||||
* for machine endianess and hence works correctly on both big and little
|
||||
* endian machines.
|
||||
*/
|
||||
static void esp_gf128mul_x_ble( unsigned char r[16],
|
||||
const unsigned char x[16] )
|
||||
{
|
||||
uint64_t a, b, ra, rb;
|
||||
|
||||
GET_UINT64_LE( a, x, 0 );
|
||||
GET_UINT64_LE( b, x, 8 );
|
||||
|
||||
ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
|
||||
rb = ( a >> 63 ) | ( b << 1 );
|
||||
|
||||
PUT_UINT64_LE( ra, r, 0 );
|
||||
PUT_UINT64_LE( rb, r, 8 );
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-XTS buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_xts( esp_aes_xts_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char data_unit[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret;
|
||||
size_t blocks = length / 16;
|
||||
size_t leftover = length % 16;
|
||||
unsigned char tweak[16];
|
||||
unsigned char prev_tweak[16];
|
||||
unsigned char tmp[16];
|
||||
|
||||
/* Sectors must be at least 16 bytes. */
|
||||
if( length < 16 )
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
|
||||
/* NIST SP 80-38E disallows data units larger than 2**20 blocks. */
|
||||
if( length > ( 1 << 20 ) * 16 )
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
|
||||
/* Compute the tweak. */
|
||||
ret = esp_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
|
||||
data_unit, tweak );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
while( blocks-- )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
|
||||
{
|
||||
/* We are on the last block in a decrypt operation that has
|
||||
* leftover bytes, so we need to use the next tweak for this block,
|
||||
* and this tweak for the lefover bytes. Save the current tweak for
|
||||
* the leftovers and then update the current tweak for use on this,
|
||||
* the last full block. */
|
||||
memcpy( prev_tweak, tweak, sizeof( tweak ) );
|
||||
esp_gf128mul_x_ble( tweak, tweak );
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
tmp[i] = input[i] ^ tweak[i];
|
||||
|
||||
ret = esp_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
output[i] = tmp[i] ^ tweak[i];
|
||||
|
||||
/* Update the tweak for the next block. */
|
||||
esp_gf128mul_x_ble( tweak, tweak );
|
||||
|
||||
output += 16;
|
||||
input += 16;
|
||||
}
|
||||
|
||||
if( leftover )
|
||||
{
|
||||
/* If we are on the leftover bytes in a decrypt operation, we need to
|
||||
* use the previous tweak for these bytes (as saved in prev_tweak). */
|
||||
unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
|
||||
|
||||
/* We are now on the final part of the data unit, which doesn't divide
|
||||
* evenly by 16. It's time for ciphertext stealing. */
|
||||
size_t i;
|
||||
unsigned char *prev_output = output - 16;
|
||||
|
||||
/* Copy ciphertext bytes from the previous block to our output for each
|
||||
* byte of cyphertext we won't steal. At the same time, copy the
|
||||
* remainder of the input for this final round (since the loop bounds
|
||||
* are the same). */
|
||||
for( i = 0; i < leftover; i++ )
|
||||
{
|
||||
output[i] = prev_output[i];
|
||||
tmp[i] = input[i] ^ t[i];
|
||||
}
|
||||
|
||||
/* Copy ciphertext bytes from the previous block for input in this
|
||||
* round. */
|
||||
for( ; i < 16; i++ )
|
||||
tmp[i] = prev_output[i] ^ t[i];
|
||||
|
||||
ret = esp_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
|
||||
if( ret != 0 )
|
||||
return ret;
|
||||
|
||||
/* Write the result back to the previous block, overriding the previous
|
||||
* output we copied. */
|
||||
for( i = 0; i < 16; i++ )
|
||||
prev_output[i] = tmp[i] ^ t[i];
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -223,8 +223,8 @@ static inline void start_op(uint32_t op_reg)
|
||||
*/
|
||||
static inline void wait_op_complete(uint32_t op_reg)
|
||||
{
|
||||
while(DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG) != 1)
|
||||
{ }
|
||||
while (DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG) != 1)
|
||||
{ }
|
||||
|
||||
/* clear the interrupt */
|
||||
DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1);
|
||||
@ -258,7 +258,7 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
|
||||
|
||||
esp_mpi_acquire_hardware();
|
||||
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words-1));
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words - 1));
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, (uint32_t)Mprime);
|
||||
|
||||
/* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */
|
||||
@ -404,17 +404,17 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
|
||||
size_t num_words = MAX(x_words, y_words);
|
||||
size_t z_words = x_words + y_words;
|
||||
|
||||
/* Short-circuit eval if either argument is 0 or 1.
|
||||
/* Short-circuit eval if either argument is 0 or 1.
|
||||
|
||||
This is needed as the mpi modular division
|
||||
argument will sometimes call in here when one
|
||||
argument is too large for the hardware unit, but the other
|
||||
argument is zero or one.
|
||||
This is needed as the mpi modular division
|
||||
argument will sometimes call in here when one
|
||||
argument is too large for the hardware unit, but the other
|
||||
argument is zero or one.
|
||||
|
||||
This leaks some timing information, although overall there is a
|
||||
lot less timing variation than a software MPI approach.
|
||||
This leaks some timing information, although overall there is a
|
||||
lot less timing variation than a software MPI approach.
|
||||
*/
|
||||
if (x_bits == 0 || y_bits== 0) {
|
||||
if (x_bits == 0 || y_bits == 0) {
|
||||
mbedtls_mpi_lset(Z, 0);
|
||||
return 0;
|
||||
}
|
||||
@ -449,7 +449,7 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
|
||||
} else {
|
||||
/* Still too long for the hardware unit... */
|
||||
mbedtls_mpi_grow(Z, z_words);
|
||||
if(y_words > x_words) {
|
||||
if (y_words > x_words) {
|
||||
return mpi_mult_mpi_overlong(Z, X, Y, y_words, z_words);
|
||||
} else {
|
||||
return mpi_mult_mpi_overlong(Z, Y, X, x_words, z_words);
|
||||
@ -468,7 +468,7 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi
|
||||
*/
|
||||
|
||||
DPORT_REG_WRITE(RSA_M_DASH_REG, 0);
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words*2 - 1));
|
||||
DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words * 2 - 1));
|
||||
start_op(RSA_MULT_START_REG);
|
||||
|
||||
wait_op_complete(RSA_MULT_START_REG);
|
||||
|
255
components/mbedtls/port/esp32s2/esp_sha1.c
Normal file
255
components/mbedtls/port/esp32s2/esp_sha1.c
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* SHA-1 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* The SHA-1 standard was published by NIST in 1993.
|
||||
*
|
||||
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
#include "mbedtls/sha1.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#include "esp32s2/sha.h"
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n )
|
||||
{
|
||||
volatile unsigned char *p = (unsigned char *)v; while ( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
if ( ctx == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
|
||||
const mbedtls_sha1_context *src )
|
||||
{
|
||||
memcpy(dst, src, sizeof(mbedtls_sha1_context));
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 context setup
|
||||
*/
|
||||
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
|
||||
ctx->mode = SHA1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
mbedtls_sha1_starts_ret( ctx );
|
||||
}
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
return esp_sha_dma(SHA1, data, len, buf, buf_len, ctx->first_block);
|
||||
}
|
||||
|
||||
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
int ret;
|
||||
esp_sha_acquire_hardware();
|
||||
ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block);
|
||||
esp_sha_release_hardware();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
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;
|
||||
|
||||
if ( !ilen || (input == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if ( ctx->total[0] < (uint32_t) ilen ) {
|
||||
ctx->total[1]++;
|
||||
}
|
||||
|
||||
if ( left && ilen >= fill ) {
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
local_len = 64;
|
||||
}
|
||||
|
||||
len = (ilen / 64) * 64;
|
||||
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);
|
||||
}
|
||||
|
||||
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 ) {
|
||||
memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
mbedtls_sha1_update_ret( ctx, input, ilen );
|
||||
}
|
||||
#endif
|
||||
|
||||
static const unsigned char sha1_padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-1 final digest
|
||||
*/
|
||||
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] )
|
||||
{
|
||||
int ret;
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_BE( high, msglen, 0 );
|
||||
PUT_UINT32_BE( low, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
|
||||
if ( ( ret = mbedtls_sha1_update_ret( ctx, sha1_padding, padn ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
if ( ( ret = mbedtls_sha1_update_ret( ctx, msglen, 8 ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(output, ctx->state, 20);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
|
||||
unsigned char output[20] )
|
||||
{
|
||||
mbedtls_sha1_finish_ret( ctx, output );
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */
|
267
components/mbedtls/port/esp32s2/esp_sha256.c
Normal file
267
components/mbedtls/port/esp32s2/esp_sha256.c
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* SHA-256 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#include "esp32s2/sha.h"
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n )
|
||||
{
|
||||
volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
do { \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
} while( 0 )
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
do { \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
} while( 0 )
|
||||
#endif
|
||||
|
||||
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
|
||||
{
|
||||
if ( ctx == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 context setup
|
||||
*/
|
||||
int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
|
||||
|
||||
if ( is224 ) {
|
||||
ctx->mode = SHA2_224;
|
||||
} else {
|
||||
ctx->mode = SHA2_256;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
|
||||
int is224 )
|
||||
{
|
||||
mbedtls_sha256_starts_ret( ctx, is224 );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
int ret;
|
||||
esp_sha_acquire_hardware();
|
||||
ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block);
|
||||
esp_sha_release_hardware();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
|
||||
const unsigned char data[64] )
|
||||
{
|
||||
mbedtls_internal_sha256_process( ctx, data );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SHA-256 process buffer
|
||||
*/
|
||||
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;
|
||||
|
||||
if ( ilen == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if ( ctx->total[0] < (uint32_t) ilen ) {
|
||||
ctx->total[1]++;
|
||||
}
|
||||
|
||||
/* Check if any data pending from previous call to this API */
|
||||
if ( left && ilen >= fill ) {
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
local_len = 64;
|
||||
}
|
||||
|
||||
len = (ilen / 64) * 64;
|
||||
|
||||
if ( len || local_len) {
|
||||
esp_sha_acquire_hardware();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 ) {
|
||||
memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
mbedtls_sha256_update_ret( ctx, input, ilen );
|
||||
}
|
||||
#endif
|
||||
|
||||
static const unsigned char sha256_padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-256 final digest
|
||||
*/
|
||||
int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] )
|
||||
{
|
||||
int ret;
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_BE( high, msglen, 0 );
|
||||
PUT_UINT32_BE( low, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
if ( ( ret = mbedtls_sha256_update_ret( ctx, sha256_padding, padn ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( ( ret = mbedtls_sha256_update_ret( ctx, msglen, 8 ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(output, ctx->state, 32);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
|
||||
unsigned char output[32] )
|
||||
{
|
||||
mbedtls_sha256_finish_ret( ctx, output );
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */
|
317
components/mbedtls/port/esp32s2/esp_sha512.c
Normal file
317
components/mbedtls/port/esp32s2/esp_sha512.c
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* SHA-512 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
#include "mbedtls/sha512.h"
|
||||
|
||||
#if defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
#define UL64(x) x##ui64
|
||||
#else
|
||||
#define UL64(x) x##ULL
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#include "esp32s2/sha.h"
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n )
|
||||
{
|
||||
volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 64-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef PUT_UINT64_BE
|
||||
#define PUT_UINT64_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif /* PUT_UINT64_BE */
|
||||
|
||||
void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SHA2_384:
|
||||
case SHA2_512224:
|
||||
case SHA2_512256:
|
||||
case SHA2_512T:
|
||||
ctx->mode = type;
|
||||
break;
|
||||
default:
|
||||
ctx->mode = SHA2_512;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* For SHA512/t mode the intial hash value will depend on t */
|
||||
void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val)
|
||||
{
|
||||
ctx->t_val = t_val;
|
||||
}
|
||||
|
||||
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
|
||||
{
|
||||
if ( ctx == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
|
||||
const mbedtls_sha512_context *src )
|
||||
{
|
||||
memcpy(dst, src, sizeof(mbedtls_sha512_context));
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 context setup
|
||||
*/
|
||||
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
|
||||
{
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
|
||||
|
||||
if ( is384 ) {
|
||||
ctx->mode = SHA2_384;
|
||||
} else {
|
||||
ctx->mode = SHA2_512;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
|
||||
int is384 )
|
||||
{
|
||||
mbedtls_sha512_starts_ret( ctx, is384 );
|
||||
}
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
|
||||
return esp_sha_dma(ctx->mode, data, len, buf, buf_len, ctx->first_block);
|
||||
|
||||
|
||||
}
|
||||
|
||||
int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
|
||||
{
|
||||
int ret;
|
||||
esp_sha_acquire_hardware();
|
||||
ret = esp_internal_sha512_dma_process(ctx, data, 128, 0, 0);
|
||||
esp_sha_release_hardware();
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
|
||||
const unsigned char data[128] )
|
||||
{
|
||||
mbedtls_internal_sha512_process( ctx, data );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SHA-512 process buffer
|
||||
*/
|
||||
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;
|
||||
|
||||
if ( ilen == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
left = (unsigned int) (ctx->total[0] & 0x7F);
|
||||
fill = 128 - left;
|
||||
|
||||
ctx->total[0] += (uint64_t) ilen;
|
||||
|
||||
if ( ctx->total[0] < (uint64_t) ilen ) {
|
||||
ctx->total[1]++;
|
||||
}
|
||||
|
||||
if ( left && ilen >= fill ) {
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
local_len = 128;
|
||||
}
|
||||
|
||||
len = (ilen / 128) * 128;
|
||||
|
||||
if ( len || local_len) {
|
||||
|
||||
esp_sha_acquire_hardware();
|
||||
|
||||
if (ctx->sha_state == ESP_SHA512_STATE_INIT) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ret = esp_internal_sha512_dma_process(ctx, input, len, ctx->buffer, local_len);
|
||||
|
||||
esp_sha_read_digest_state(ctx->mode, ctx->state);
|
||||
|
||||
esp_sha_release_hardware();
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( ilen > 0 ) {
|
||||
memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
mbedtls_sha512_update_ret( ctx, input, ilen );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static const unsigned char sha512_padding[128] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-512 final digest
|
||||
*/
|
||||
int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] )
|
||||
{
|
||||
int ret;
|
||||
size_t last, padn;
|
||||
uint64_t high, low;
|
||||
unsigned char msglen[16];
|
||||
|
||||
high = ( ctx->total[0] >> 61 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT64_BE( high, msglen, 0 );
|
||||
PUT_UINT64_BE( low, msglen, 8 );
|
||||
|
||||
last = (size_t)( ctx->total[0] & 0x7F );
|
||||
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
|
||||
|
||||
if ( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ctx->mode == SHA2_384) {
|
||||
memcpy(output, ctx->state, 48);
|
||||
} else {
|
||||
memcpy(output, ctx->state, 64);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
|
||||
unsigned char output[64] )
|
||||
{
|
||||
mbedtls_sha512_finish_ret( ctx, output );
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */
|
@ -3,7 +3,7 @@
|
||||
* based on mbedTLS FIPS-197 compliant version.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
|
||||
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE Ltd
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -28,34 +28,38 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/lock.h>
|
||||
#include <assert.h>
|
||||
#include "soc/soc.h"
|
||||
#include "esp32s2/crypto_dma.h"
|
||||
#include "esp32s2/sha.h"
|
||||
#include "soc/crypto_dma_reg.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "esp32s2/rom/lldesc.h"
|
||||
|
||||
#include "esp32s2/rom/cache.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/periph_defs.h"
|
||||
|
||||
#include "soc/cache_memory.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
/* Single lock for SHA engine
|
||||
#include "esp32s2/sha.h"
|
||||
#include "esp32s2/crypto_dma.h"
|
||||
#include "esp32s2/rom/lldesc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/crypto_dma_reg.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "sys/param.h"
|
||||
|
||||
|
||||
/* Max amount of bytes in a single DMA operation is 4095,
|
||||
for SHA this means that the biggest safe amount of bytes is
|
||||
31 blocks of 128 bytes = 3968
|
||||
*/
|
||||
#define SHA_DMA_MAX_BYTES 3968
|
||||
|
||||
/* Lock for SHA engine */
|
||||
static _lock_t s_sha_lock;
|
||||
|
||||
/* Enable if want to use SHA interrupt */
|
||||
//#define CONFIG_MBEDTLS_SHA_USE_INTERRUPT
|
||||
|
||||
#if defined(CONFIG_MBEDTLS_SHA_USE_INTERRUPT)
|
||||
static SemaphoreHandle_t op_complete_sem;
|
||||
#endif
|
||||
const static char *TAG = "esp-sha";
|
||||
|
||||
/* Return block size (in bytes) for a given SHA type */
|
||||
inline static size_t block_length(esp_sha_type type)
|
||||
@ -96,190 +100,265 @@ inline static size_t state_length(esp_sha_type type)
|
||||
}
|
||||
}
|
||||
|
||||
/* This API was designed for ESP32, which has seperate
|
||||
engines for SHA1,256,512. ESP32C has a single engine.
|
||||
*/
|
||||
static void esp_sha_lock_engine_inner(void);
|
||||
|
||||
bool esp_sha_try_lock_engine(esp_sha_type sha_type)
|
||||
{
|
||||
if (_lock_try_acquire(&s_sha_lock) != 0) {
|
||||
/* SHA engine is already in use */
|
||||
return false;
|
||||
} else {
|
||||
esp_sha_lock_engine_inner();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void esp_sha_lock_engine(esp_sha_type sha_type)
|
||||
{
|
||||
_lock_acquire(&s_sha_lock);
|
||||
esp_sha_lock_engine_inner();
|
||||
}
|
||||
|
||||
/* Enable SHA block and then lock it */
|
||||
static void esp_sha_lock_engine_inner(void)
|
||||
/* Enable SHA peripheral and then lock it */
|
||||
void esp_sha_acquire_hardware()
|
||||
{
|
||||
/* Need to lock DMA since it is shared with AES block */
|
||||
portENTER_CRITICAL(&crypto_dma_spinlock);
|
||||
_lock_acquire(&crypto_dma_lock);
|
||||
_lock_acquire(&s_sha_lock);
|
||||
|
||||
REG_SET_BIT(DPORT_PERIP_CLK_EN1_REG, DPORT_CRYPTO_SHA_CLK_EN | DPORT_CRYPTO_DMA_CLK_EN);
|
||||
REG_CLR_BIT(DPORT_PERIP_RST_EN1_REG, DPORT_CRYPTO_SHA_RST | DPORT_CRYPTO_HMAC_RST |
|
||||
DPORT_CRYPTO_DMA_RST | DPORT_CRYPTO_DS_RST);
|
||||
/* Enable SHA and DMA hardware */
|
||||
periph_module_enable(PERIPH_SHA_DMA_MODULE);
|
||||
|
||||
/* DMA for SHA */
|
||||
REG_WRITE(CRYPTO_DMA_AES_SHA_SELECT_REG, 1);
|
||||
}
|
||||
|
||||
/* Disable SHA block and then unlock it */
|
||||
void esp_sha_unlock_engine(esp_sha_type sha_type)
|
||||
/* Disable SHA peripheral block and then release it */
|
||||
void esp_sha_release_hardware()
|
||||
{
|
||||
REG_WRITE(CRYPTO_DMA_AES_SHA_SELECT_REG, 0);
|
||||
|
||||
REG_SET_BIT(DPORT_PERIP_RST_EN1_REG, DPORT_CRYPTO_SHA_RST | DPORT_CRYPTO_DMA_RST |
|
||||
DPORT_CRYPTO_DS_RST);
|
||||
REG_CLR_BIT(DPORT_PERIP_CLK_EN1_REG, DPORT_CRYPTO_SHA_CLK_EN | DPORT_CRYPTO_DMA_CLK_EN);
|
||||
|
||||
portEXIT_CRITICAL(&crypto_dma_spinlock);
|
||||
/* Disable SHA and DMA hardware */
|
||||
periph_module_disable(PERIPH_SHA_DMA_MODULE);
|
||||
|
||||
/* Need to lock DMA since it is shared with AES block */
|
||||
_lock_release(&s_sha_lock);
|
||||
_lock_release(&crypto_dma_lock);
|
||||
|
||||
}
|
||||
|
||||
#if defined (CONFIG_MBEDTLS_SHA_USE_INTERRUPT)
|
||||
static IRAM_ATTR void esp_sha_dma_isr(void *arg)
|
||||
|
||||
/* Busy wait until SHA is idle */
|
||||
static void esp_sha_wait_idle(void)
|
||||
{
|
||||
BaseType_t higher_woken;
|
||||
REG_WRITE(SHA_CLEAR_IRQ_REG, 1);
|
||||
xSemaphoreGiveFromISR(op_complete_sem, &higher_woken);
|
||||
if (higher_woken) {
|
||||
portYIELD_FROM_ISR();
|
||||
while (DPORT_REG_READ(SHA_BUSY_REG) != 0) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if SHA operation completed */
|
||||
static int esp_sha_dma_complete(void)
|
||||
|
||||
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
|
||||
{
|
||||
#if defined (CONFIG_MBEDTLS_SHA_USE_INTERRUPT)
|
||||
if (!xSemaphoreTake(op_complete_sem, 2000 / portTICK_PERIOD_MS)) {
|
||||
ESP_LOGE("SHA", "Timed out waiting for completion of SHA Interrupt");
|
||||
return -1;
|
||||
uint32_t *digest_state_words = (uint32_t *)digest_state;
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
|
||||
|
||||
for (int i = 0; i < state_length(sha_type) / 4; i++) {
|
||||
REG_WRITE(®_addr_buf[i], digest_state_words[i]);
|
||||
}
|
||||
#else
|
||||
esp_sha_wait_idle();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait until SHA is busy */
|
||||
void esp_sha_wait_idle(void)
|
||||
{
|
||||
while (DPORT_REG_READ(SHA_BUSY_REG) != 0) { }
|
||||
}
|
||||
|
||||
/* Read the SHA digest from hardware */
|
||||
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
|
||||
{
|
||||
uint32_t *digest_state_words = (uint32_t *)digest_state;
|
||||
int word_len = state_length(sha_type) / 4;
|
||||
|
||||
esp_dport_access_read_buffer(digest_state_words, SHA_H_BASE, word_len);
|
||||
|
||||
/* Fault injection check: verify SHA engine actually ran,
|
||||
state is not all zeroes.
|
||||
*/
|
||||
for (int i = 0; i < word_len; i++) {
|
||||
if (digest_state_words[i] != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
abort(); // SHA peripheral returned all zero state, probably due to fault injection
|
||||
}
|
||||
|
||||
/* The initial hash value for SHA512/t is generated according to the
|
||||
algorithm described in the TRM, chapter SHA-Accelerator
|
||||
*/
|
||||
int esp_sha_512_t_init_hash(uint16_t t)
|
||||
{
|
||||
uint32_t t_string = 0;
|
||||
uint8_t t0, t1, t2, t_len;
|
||||
|
||||
if (t == 384) {
|
||||
ESP_LOGE(TAG, "Invalid t for SHA512/t, t = %u,cannot be 384", t);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (t <= 9) {
|
||||
t_string = (uint32_t)((1 << 23) | ((0x30 + t) << 24));
|
||||
t_len = 0x48;
|
||||
} else if (t <= 99) {
|
||||
t0 = t % 10;
|
||||
t1 = (t / 10) % 10;
|
||||
t_string = (uint32_t)((1 << 15) | ((0x30 + t0) << 16) |
|
||||
(((0x30 + t1) << 24)));
|
||||
t_len = 0x50;
|
||||
} else if (t <= 512) {
|
||||
t0 = t % 10;
|
||||
t1 = (t / 10) % 10;
|
||||
t2 = t / 100;
|
||||
t_string = (uint32_t)((1 << 7) | ((0x30 + t0) << 8) |
|
||||
(((0x30 + t1) << 16) + ((0x30 + t2) << 24)));
|
||||
t_len = 0x58;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Invalid t for SHA512/t, t = %u, must equal or less than 512", t);
|
||||
return -1;
|
||||
}
|
||||
|
||||
REG_WRITE(SHA_T_LENGTH_REG, t_len);
|
||||
REG_WRITE(SHA_T_STRING_REG, t_string);
|
||||
REG_WRITE(SHA_MODE_REG, SHA2_512T);
|
||||
REG_WRITE(SHA_START_REG, 1);
|
||||
|
||||
esp_sha_wait_idle();
|
||||
memcpy(digest_state, (void *)SHA_H_BASE, state_length(sha_type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Internally calls DMA API for single block */
|
||||
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block)
|
||||
{
|
||||
esp_sha_dma(sha_type, data_block, block_length(sha_type), is_first_block);
|
||||
}
|
||||
|
||||
/* Performs SHA on multiple blocks at a time */
|
||||
int esp_sha_dma(esp_sha_type sha_type, const void *data_block, uint32_t ilen, bool is_first_block)
|
||||
static int esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
|
||||
const void *buf, uint32_t buf_len, bool is_first_block);
|
||||
|
||||
/* Performs SHA on multiple blocks at a time using DMA
|
||||
splits up into smaller operations for inputs that exceed a single DMA list
|
||||
*/
|
||||
int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
|
||||
const void *buf, uint32_t buf_len, bool is_first_block)
|
||||
{
|
||||
size_t blk_len = 0;
|
||||
const uint8_t *local_buf = data_block;
|
||||
int ret = 0;
|
||||
volatile lldesc_t dma_descr;
|
||||
const void *dma_input;
|
||||
unsigned char *non_icache_input = NULL;
|
||||
unsigned char *non_icache_buf = NULL;
|
||||
int dma_op_num = ( ilen / (SHA_DMA_MAX_BYTES + 1) ) + 1;
|
||||
|
||||
if (ilen == 0) {
|
||||
return ret;
|
||||
if (buf_len > 128) {
|
||||
ESP_LOGE(TAG, "SHA DMA buf_len cannot exceed max size for a single block");
|
||||
return -1;
|
||||
}
|
||||
|
||||
blk_len = block_length(sha_type);
|
||||
|
||||
REG_WRITE(SHA_MODE_REG, sha_type);
|
||||
if ((sha_type == SHA2_512T) && (is_first_block == true)) {
|
||||
REG_WRITE(SHA_START_REG, 1);
|
||||
}
|
||||
|
||||
REG_WRITE(SHA_BLOCK_NUM_REG, (ilen / blk_len));
|
||||
|
||||
if ((sha_type == SHA2_512T) && (is_first_block == true)) {
|
||||
esp_sha_wait_idle();
|
||||
is_first_block = false;
|
||||
}
|
||||
|
||||
bzero( (void *)&dma_descr, sizeof( dma_descr ) );
|
||||
|
||||
/* DMA descriptor for Memory to DMA-AES transfer */
|
||||
dma_descr.length = ilen;
|
||||
dma_descr.size = ilen;
|
||||
dma_descr.owner = 1;
|
||||
dma_descr.eof = 1;
|
||||
dma_descr.buf = local_buf;
|
||||
dma_descr.sosf = 0;
|
||||
dma_descr.empty = 0;
|
||||
|
||||
#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
|
||||
if ((unsigned int)data_block >= SOC_EXTRAM_DATA_LOW && (unsigned int)data_block <= SOC_EXTRAM_DATA_HIGH) {
|
||||
if (esp_ptr_external_ram(input) || esp_ptr_external_ram(buf)) {
|
||||
Cache_WriteBack_All();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DMA cannot access memory in the iCache range, copy data to temporary buffers before transfer */
|
||||
if (!esp_ptr_dma_ext_capable(input) && !esp_ptr_dma_capable(input)) {
|
||||
non_icache_input = malloc(sizeof(unsigned char) * MIN(ilen, SHA_DMA_MAX_BYTES));
|
||||
if (non_icache_input == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory");
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!esp_ptr_dma_ext_capable(buf) && !esp_ptr_dma_capable(buf)) {
|
||||
non_icache_buf = malloc(sizeof(unsigned char) * buf_len);
|
||||
if (non_icache_buf == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory");
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(non_icache_buf, buf, buf_len);
|
||||
buf = non_icache_buf;
|
||||
}
|
||||
|
||||
/* The max amount of blocks in a single hardware operation is 2^6 - 1 = 63
|
||||
Thus we only do a single DMA input list + dma buf list,
|
||||
which is max 3968/64 + 64/64 = 63 blocks */
|
||||
for (int i = 0; i < dma_op_num; i++) {
|
||||
int dma_chunk_len = MIN(ilen, SHA_DMA_MAX_BYTES);
|
||||
|
||||
|
||||
/* Input depends on if it's a temp alloc buffer or supplied by user */
|
||||
if (non_icache_input != NULL) {
|
||||
memcpy(non_icache_input, input, dma_chunk_len);
|
||||
dma_input = non_icache_input;
|
||||
} else {
|
||||
dma_input = input;
|
||||
}
|
||||
|
||||
ret = esp_sha_dma_process(sha_type, dma_input, dma_chunk_len, buf, buf_len, is_first_block);
|
||||
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
is_first_block = false;
|
||||
|
||||
|
||||
ilen -= dma_chunk_len;
|
||||
input += dma_chunk_len;
|
||||
|
||||
// Only append buf to the first operation
|
||||
buf_len = 0;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
free(non_icache_input);
|
||||
free(non_icache_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void esp_sha_dma_init(lldesc_t *input)
|
||||
{
|
||||
/* Reset DMA */
|
||||
SET_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
|
||||
CLEAR_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
|
||||
|
||||
/* Set descriptors */
|
||||
CLEAR_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_ADDR);
|
||||
SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, ((uint32_t)(&dma_descr))&OUT_LINK_REG_OUTLINK_ADDR);
|
||||
SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, ((uint32_t)(input))&OUT_LINK_REG_OUTLINK_ADDR);
|
||||
/* Start transfer */
|
||||
SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_START);
|
||||
}
|
||||
|
||||
#if defined (CONFIG_MBEDTLS_SHA_USE_INTERRUPT)
|
||||
REG_WRITE(SHA_CLEAR_IRQ_REG, 1);
|
||||
if (op_complete_sem == NULL) {
|
||||
op_complete_sem = xSemaphoreCreateBinary();
|
||||
esp_intr_alloc(ETS_SHA_INTR_SOURCE, 0, esp_sha_dma_isr, 0, 0);
|
||||
/* Performs SHA on multiple blocks at a time */
|
||||
static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
|
||||
const void *buf, uint32_t buf_len, bool is_first_block)
|
||||
{
|
||||
size_t blk_len = 0;
|
||||
int ret = 0;
|
||||
lldesc_t dma_descr_input = {};
|
||||
lldesc_t dma_descr_buf = {};
|
||||
lldesc_t *dma_descr_head;
|
||||
|
||||
blk_len = block_length(sha_type);
|
||||
|
||||
REG_WRITE(SHA_MODE_REG, sha_type);
|
||||
REG_WRITE(SHA_BLOCK_NUM_REG, ((ilen + buf_len) / blk_len));
|
||||
|
||||
|
||||
/* DMA descriptor for Memory to DMA-SHA transfer */
|
||||
if (ilen) {
|
||||
dma_descr_input.length = ilen;
|
||||
dma_descr_input.size = ilen;
|
||||
dma_descr_input.owner = 1;
|
||||
dma_descr_input.eof = 1;
|
||||
dma_descr_input.buf = input;
|
||||
dma_descr_head = &dma_descr_input;
|
||||
}
|
||||
/* Check after input to overide head if there is any buf*/
|
||||
if (buf_len) {
|
||||
dma_descr_buf.length = buf_len;
|
||||
dma_descr_buf.size = buf_len;
|
||||
dma_descr_buf.owner = 1;
|
||||
dma_descr_buf.eof = 1;
|
||||
dma_descr_buf.buf = buf;
|
||||
dma_descr_head = &dma_descr_buf;
|
||||
}
|
||||
REG_WRITE(SHA_INT_ENA_REG, 1);
|
||||
#endif
|
||||
|
||||
/* Link DMA lists */
|
||||
if (buf_len && ilen) {
|
||||
dma_descr_buf.eof = 0;
|
||||
dma_descr_buf.empty = (uint32_t)(&dma_descr_input);
|
||||
}
|
||||
|
||||
esp_sha_dma_init(dma_descr_head);
|
||||
|
||||
/* Start hashing */
|
||||
if (is_first_block) {
|
||||
REG_WRITE(SHA_DMA_START_REG, 1);
|
||||
} else {
|
||||
REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
|
||||
}
|
||||
|
||||
ret = esp_sha_dma_complete();
|
||||
|
||||
#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
|
||||
if ((unsigned int)data_block >= SOC_EXTRAM_DATA_LOW && (unsigned int)data_block <= SOC_EXTRAM_DATA_HIGH) {
|
||||
Cache_Invalidate_DCache_All();
|
||||
}
|
||||
#endif
|
||||
esp_sha_wait_idle();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
|
||||
{
|
||||
SHA_CTX ctx;
|
||||
|
||||
esp_sha_lock_engine(sha_type);
|
||||
|
||||
ets_sha_init(&ctx, sha_type);
|
||||
ets_sha_starts(&ctx, 0);
|
||||
ets_sha_update(&ctx, input, ilen, false);
|
||||
ets_sha_finish(&ctx, output);
|
||||
|
||||
esp_sha_unlock_engine(sha_type);
|
||||
}
|
||||
|
288
components/mbedtls/port/esp_aes_xts.c
Normal file
288
components/mbedtls/port/esp_aes_xts.c
Normal file
@ -0,0 +1,288 @@
|
||||
/**
|
||||
* \brief AES block cipher, ESP32-S2 hardware accelerated version
|
||||
* Based on mbedTLS FIPS-197 compliant version.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE Ltd
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
|
||||
*
|
||||
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
|
||||
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
||||
*/
|
||||
|
||||
|
||||
/* Below XTS implementation is copied aes.c of mbedtls library.
|
||||
* When MBEDTLS_AES_ALT is defined mbedtls expects alternate
|
||||
* definition of XTS functions to be available. Even if this
|
||||
* could have been avoided, it is done for consistency reason.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/lock.h>
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/aes.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/aes.h"
|
||||
#endif
|
||||
|
||||
void esp_aes_xts_init( esp_aes_xts_context *ctx )
|
||||
{
|
||||
esp_aes_init( &ctx->crypt );
|
||||
esp_aes_init( &ctx->tweak );
|
||||
}
|
||||
|
||||
void esp_aes_xts_free( esp_aes_xts_context *ctx )
|
||||
{
|
||||
esp_aes_free( &ctx->crypt );
|
||||
esp_aes_free( &ctx->tweak );
|
||||
}
|
||||
|
||||
static int esp_aes_xts_decode_keys( const unsigned char *key,
|
||||
unsigned int keybits,
|
||||
const unsigned char **key1,
|
||||
unsigned int *key1bits,
|
||||
const unsigned char **key2,
|
||||
unsigned int *key2bits )
|
||||
{
|
||||
const unsigned int half_keybits = keybits / 2;
|
||||
const unsigned int half_keybytes = half_keybits / 8;
|
||||
|
||||
switch ( keybits ) {
|
||||
case 256: break;
|
||||
case 512: break;
|
||||
default : return ( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
|
||||
}
|
||||
|
||||
*key1bits = half_keybits;
|
||||
*key2bits = half_keybits;
|
||||
*key1 = &key[0];
|
||||
*key2 = &key[half_keybytes];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
ret = esp_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if ( ret != 0 ) {
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/* Set the tweak key. Always set tweak key for the encryption mode. */
|
||||
ret = esp_aes_setkey( &ctx->tweak, key2, key2bits );
|
||||
if ( ret != 0 ) {
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/* Set crypt key for encryption. */
|
||||
return esp_aes_setkey( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
|
||||
int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
ret = esp_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
|
||||
&key2, &key2bits );
|
||||
if ( ret != 0 ) {
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/* Set the tweak key. Always set tweak key for encryption. */
|
||||
ret = esp_aes_setkey( &ctx->tweak, key2, key2bits );
|
||||
if ( ret != 0 ) {
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/* Set crypt key for decryption. */
|
||||
return esp_aes_setkey( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
|
||||
/* Endianess with 64 bits values */
|
||||
#ifndef GET_UINT64_LE
|
||||
#define GET_UINT64_LE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
|
||||
| ( (uint64_t) (b)[(i) + 6] << 48 ) \
|
||||
| ( (uint64_t) (b)[(i) + 5] << 40 ) \
|
||||
| ( (uint64_t) (b)[(i) + 4] << 32 ) \
|
||||
| ( (uint64_t) (b)[(i) + 3] << 24 ) \
|
||||
| ( (uint64_t) (b)[(i) + 2] << 16 ) \
|
||||
| ( (uint64_t) (b)[(i) + 1] << 8 ) \
|
||||
| ( (uint64_t) (b)[(i) ] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT64_LE
|
||||
#define PUT_UINT64_LE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) ] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GF(2^128) multiplication function
|
||||
*
|
||||
* This function multiplies a field element by x in the polynomial field
|
||||
* representation. It uses 64-bit word operations to gain speed but compensates
|
||||
* for machine endianess and hence works correctly on both big and little
|
||||
* endian machines.
|
||||
*/
|
||||
static void esp_gf128mul_x_ble( unsigned char r[16],
|
||||
const unsigned char x[16] )
|
||||
{
|
||||
uint64_t a, b, ra, rb;
|
||||
|
||||
GET_UINT64_LE( a, x, 0 );
|
||||
GET_UINT64_LE( b, x, 8 );
|
||||
|
||||
ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
|
||||
rb = ( a >> 63 ) | ( b << 1 );
|
||||
|
||||
PUT_UINT64_LE( ra, r, 0 );
|
||||
PUT_UINT64_LE( rb, r, 8 );
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-XTS buffer encryption/decryption
|
||||
*/
|
||||
int esp_aes_crypt_xts( esp_aes_xts_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char data_unit[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret;
|
||||
size_t blocks = length / 16;
|
||||
size_t leftover = length % 16;
|
||||
unsigned char tweak[16];
|
||||
unsigned char prev_tweak[16];
|
||||
unsigned char tmp[16];
|
||||
|
||||
/* Sectors must be at least 16 bytes. */
|
||||
if ( length < 16 ) {
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
}
|
||||
|
||||
/* NIST SP 80-38E disallows data units larger than 2**20 blocks. */
|
||||
if ( length > ( 1 << 20 ) * 16 ) {
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
}
|
||||
|
||||
/* Compute the tweak. */
|
||||
ret = esp_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
|
||||
data_unit, tweak );
|
||||
if ( ret != 0 ) {
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
while ( blocks-- ) {
|
||||
size_t i;
|
||||
|
||||
if ( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) {
|
||||
/* We are on the last block in a decrypt operation that has
|
||||
* leftover bytes, so we need to use the next tweak for this block,
|
||||
* and this tweak for the lefover bytes. Save the current tweak for
|
||||
* the leftovers and then update the current tweak for use on this,
|
||||
* the last full block. */
|
||||
memcpy( prev_tweak, tweak, sizeof( tweak ) );
|
||||
esp_gf128mul_x_ble( tweak, tweak );
|
||||
}
|
||||
|
||||
for ( i = 0; i < 16; i++ ) {
|
||||
tmp[i] = input[i] ^ tweak[i];
|
||||
}
|
||||
|
||||
ret = esp_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
|
||||
if ( ret != 0 ) {
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
for ( i = 0; i < 16; i++ ) {
|
||||
output[i] = tmp[i] ^ tweak[i];
|
||||
}
|
||||
|
||||
/* Update the tweak for the next block. */
|
||||
esp_gf128mul_x_ble( tweak, tweak );
|
||||
|
||||
output += 16;
|
||||
input += 16;
|
||||
}
|
||||
|
||||
if ( leftover ) {
|
||||
/* If we are on the leftover bytes in a decrypt operation, we need to
|
||||
* use the previous tweak for these bytes (as saved in prev_tweak). */
|
||||
unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
|
||||
|
||||
/* We are now on the final part of the data unit, which doesn't divide
|
||||
* evenly by 16. It's time for ciphertext stealing. */
|
||||
size_t i;
|
||||
unsigned char *prev_output = output - 16;
|
||||
|
||||
/* Copy ciphertext bytes from the previous block to our output for each
|
||||
* byte of cyphertext we won't steal. At the same time, copy the
|
||||
* remainder of the input for this final round (since the loop bounds
|
||||
* are the same). */
|
||||
for ( i = 0; i < leftover; i++ ) {
|
||||
output[i] = prev_output[i];
|
||||
tmp[i] = input[i] ^ t[i];
|
||||
}
|
||||
|
||||
/* Copy ciphertext bytes from the previous block for input in this
|
||||
* round. */
|
||||
for ( ; i < 16; i++ ) {
|
||||
tmp[i] = prev_output[i] ^ t[i];
|
||||
}
|
||||
|
||||
ret = esp_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
|
||||
if ( ret != 0 ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Write the result back to the previous block, overriding the previous
|
||||
* output we copied. */
|
||||
for ( i = 0; i < 16; i++ ) {
|
||||
prev_output[i] = tmp[i] ^ t[i];
|
||||
}
|
||||
}
|
||||
|
||||
return ( 0 );
|
||||
}
|
@ -26,7 +26,6 @@
|
||||
#include <mbedtls/sha512.h>
|
||||
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
|
||||
{
|
||||
int ret;
|
||||
@ -83,4 +82,3 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Based on mbedTLS FIPS-197 compliant version.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
|
||||
* Additions Copyright (C) 2016-20, Espressif Systems (Shanghai) PTE Ltd
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -38,6 +38,7 @@ extern "C" {
|
||||
#define ERR_ESP_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||
#define ERR_ESP_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||
|
||||
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*
|
||||
@ -52,11 +53,11 @@ typedef struct {
|
||||
uint8_t key[32];
|
||||
} esp_aes_context;
|
||||
|
||||
|
||||
/**
|
||||
* \brief The AES XTS context-type definition.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
esp_aes_context crypt; /*!< The AES context to use for AES block
|
||||
encryption or decryption. */
|
||||
esp_aes_context tweak; /*!< The AES context used for tweak
|
||||
@ -312,8 +313,8 @@ int esp_aes_crypt_ofb( esp_aes_context *ctx,
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
|
||||
/**
|
||||
* \brief Internal AES block encryption function
|
||||
@ -325,8 +326,8 @@ int esp_aes_xts_setkey_enc( esp_aes_xts_context *ctx,
|
||||
* \param output Output (ciphertext) block
|
||||
*/
|
||||
int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -31,8 +31,8 @@ extern "C" {
|
||||
/* Since crypto DMA is shared between DMA-AES and SHA blocks
|
||||
* Needs to be taken by respective blocks before using Crypto DMA
|
||||
*/
|
||||
extern portMUX_TYPE crypto_dma_spinlock;
|
||||
|
||||
extern _lock_t crypto_dma_lock;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Based on mbedTLS FIPS-197 compliant version.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
|
||||
* Additions Copyright (C) 2019-2020, Espressif Systems (Shanghai) PTE Ltd
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -30,27 +30,39 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
|
||||
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function.*/
|
||||
|
||||
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
|
||||
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function.*/
|
||||
|
||||
typedef enum {
|
||||
ESP_AES_GCM_STATE_INIT,
|
||||
ESP_AES_GCM_STATE_UPDATE,
|
||||
ESP_AES_GCM_STATE_FINISH
|
||||
} esp_aes_gcm_state;
|
||||
/**
|
||||
* \brief The GCM context structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t H[16]; /*!< H */
|
||||
uint8_t S[16];
|
||||
uint8_t J0[16];
|
||||
uint8_t ori_j0[16];
|
||||
const uint8_t *iv;
|
||||
size_t iv_len; /*!< The length of IV. */
|
||||
uint64_t aad_len; /*!< The total length of the additional data. */
|
||||
uint64_t aad_len; /*!< The total length of the additional data. */
|
||||
size_t data_len;
|
||||
int mode;
|
||||
const unsigned char *aad; /*!< The additional data. */
|
||||
esp_aes_context aes_ctx;
|
||||
}
|
||||
esp_aes_gcm_context;
|
||||
esp_aes_context aes_ctx;
|
||||
esp_aes_gcm_state gcm_state;
|
||||
} esp_gcm_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified GCM context
|
||||
*
|
||||
* \param ctx The GCM context to initialize.
|
||||
*/
|
||||
void esp_aes_gcm_init( esp_aes_gcm_context *ctx);
|
||||
void esp_aes_gcm_init( esp_gcm_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function associates a GCM context with a
|
||||
@ -67,7 +79,7 @@ void esp_aes_gcm_init( esp_aes_gcm_context *ctx);
|
||||
* \return \c 0 on success.
|
||||
* \return A cipher-specific error code on failure.
|
||||
*/
|
||||
int esp_aes_gcm_setkey( esp_aes_gcm_context *ctx,
|
||||
int esp_aes_gcm_setkey( esp_gcm_context *ctx,
|
||||
mbedtls_cipher_id_t cipher,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
@ -88,12 +100,12 @@ int esp_aes_gcm_setkey( esp_aes_gcm_context *ctx,
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int esp_aes_gcm_starts( esp_aes_gcm_context *ctx,
|
||||
int mode,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *aad,
|
||||
size_t aad_len );
|
||||
int esp_aes_gcm_starts( esp_gcm_context *ctx,
|
||||
int mode,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *aad,
|
||||
size_t aad_len );
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing GCM
|
||||
@ -116,7 +128,7 @@ int esp_aes_gcm_starts( esp_aes_gcm_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
|
||||
*/
|
||||
int esp_aes_gcm_update( esp_aes_gcm_context *ctx,
|
||||
int esp_aes_gcm_update( esp_gcm_context *ctx,
|
||||
size_t length,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
@ -135,16 +147,16 @@ int esp_aes_gcm_update( esp_aes_gcm_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
|
||||
*/
|
||||
int esp_aes_gcm_finish( esp_aes_gcm_context *ctx,
|
||||
unsigned char *tag,
|
||||
size_t tag_len );
|
||||
int esp_aes_gcm_finish( esp_gcm_context *ctx,
|
||||
unsigned char *tag,
|
||||
size_t tag_len );
|
||||
|
||||
/**
|
||||
* \brief This function clears a GCM context
|
||||
*
|
||||
* \param ctx The GCM context to clear.
|
||||
*/
|
||||
void esp_aes_gcm_free( esp_aes_gcm_context *ctx);
|
||||
void esp_aes_gcm_free( esp_gcm_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function performs GCM encryption or decryption of a buffer.
|
||||
@ -170,17 +182,17 @@ void esp_aes_gcm_free( esp_aes_gcm_context *ctx);
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int esp_aes_gcm_crypt_and_tag( esp_aes_gcm_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t tag_len,
|
||||
unsigned char *tag );
|
||||
int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t tag_len,
|
||||
unsigned char *tag );
|
||||
|
||||
|
||||
/**
|
||||
@ -206,16 +218,16 @@ int esp_aes_gcm_crypt_and_tag( esp_aes_gcm_context *ctx,
|
||||
* \return 0 if successful and authenticated.
|
||||
* \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
|
||||
*/
|
||||
int esp_aes_gcm_auth_decrypt( esp_aes_gcm_context *ctx,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *tag,
|
||||
size_t tag_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int esp_aes_gcm_auth_decrypt( esp_gcm_context *ctx,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *tag,
|
||||
size_t tag_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -16,9 +16,8 @@
|
||||
#define _ESP_SHA_H_
|
||||
|
||||
#include "esp32s2/rom/sha.h"
|
||||
#include "esp_types.h"
|
||||
|
||||
/** @brief Low-level support functions for the hardware SHA engine
|
||||
/** @brief Low-level support functions for the hardware SHA engine using DMA
|
||||
*
|
||||
* @note If you're looking for a SHA API to use, try mbedtls component
|
||||
* mbedtls/shaXX.h. That API supports hardware acceleration.
|
||||
@ -28,15 +27,8 @@
|
||||
*
|
||||
* Some technical details about the hardware SHA engine:
|
||||
*
|
||||
* - SHA accelerator engine calculates one digest at a time, per SHA
|
||||
* algorithm type. It initialises and maintains the digest state
|
||||
* internally. It is possible to read out an in-progress SHA digest
|
||||
* state, but it is not possible to restore a SHA digest state
|
||||
* into the engine.
|
||||
*
|
||||
* - The memory block SHA_TEXT_BASE is shared between all SHA digest
|
||||
* engines, so all engines must be idle before this memory block is
|
||||
* modified.
|
||||
* - The crypto DMA is shared between the SHA and AES engine, it is not
|
||||
* possible for them to run calcalutions in parallel.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -50,17 +42,11 @@ typedef SHA_TYPE esp_sha_type;
|
||||
/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
|
||||
*
|
||||
* @note For more versatile SHA calculations, where data doesn't need
|
||||
* to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs. The
|
||||
* hardware-accelerated mbedTLS implementation is also faster when
|
||||
* hashing large amounts of data.
|
||||
* to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs.
|
||||
*
|
||||
* @note It is not necessary to lock any SHA hardware before calling
|
||||
* this function, thread safety is managed internally.
|
||||
*
|
||||
* @note If a TLS connection is open then this function may block
|
||||
* indefinitely waiting for a SHA engine to become available. Use the
|
||||
* mbedTLS SHA API to avoid this problem.
|
||||
*
|
||||
* @param sha_type SHA algorithm to use.
|
||||
*
|
||||
* @param input Input data buffer.
|
||||
@ -73,157 +59,106 @@ typedef SHA_TYPE esp_sha_type;
|
||||
*/
|
||||
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
|
||||
|
||||
/* @brief Begin to execute a single SHA block operation
|
||||
/** @brief Execute SHA block operation using DMA
|
||||
*
|
||||
* @note This is a piece of a SHA algorithm, rather than an entire SHA
|
||||
* algorithm.
|
||||
*
|
||||
* @note Call esp_sha_try_lock_engine() before calling this
|
||||
* function. Do not call esp_sha_lock_memory_block() beforehand, this
|
||||
* is done inside the function.
|
||||
* @note Call esp_sha_aquire_hardware() before calling this
|
||||
* function.
|
||||
*
|
||||
* @param sha_type SHA algorithm to use.
|
||||
*
|
||||
* @param data_block Pointer to block of data. Block size is
|
||||
* determined by algorithm (SHA1/SHA2_256 = 64 bytes,
|
||||
* SHA2_384/SHA2_512 = 128 bytes)
|
||||
*
|
||||
* @param is_first_block If this parameter is true, the SHA state will
|
||||
* be initialised (with the initial state of the given SHA algorithm)
|
||||
* before the block is calculated. If false, the existing state of the
|
||||
* SHA engine will be used.
|
||||
*
|
||||
* @return As a performance optimisation, this function returns before
|
||||
* the SHA block operation is complete. Both this function and
|
||||
* esp_sha_read_state() will automatically wait for any previous
|
||||
* operation to complete before they begin. If using the SHA registers
|
||||
* directly in another way, call esp_sha_wait_idle() after calling this
|
||||
* function but before accessing the SHA registers.
|
||||
*/
|
||||
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
|
||||
|
||||
/* @brief Begin to execute SHA block operation using DMA
|
||||
*
|
||||
* @note This is a piece of a SHA algorithm, rather than an entire SHA
|
||||
* algorithm.
|
||||
*
|
||||
* @note Call esp_sha_try_lock_engine() before calling this
|
||||
* function. Do not call esp_sha_lock_memory_block() beforehand, this
|
||||
* is done inside the function.
|
||||
*
|
||||
* @param sha_type SHA algorithm to use.
|
||||
*
|
||||
* @param data_block Pointer to block of data. Block size is
|
||||
* @param input Pointer to the input data. Block size is
|
||||
* determined by algorithm (SHA1/SHA2_256 = 64 bytes,
|
||||
* SHA2_384/SHA2_512 = 128 bytes)
|
||||
*
|
||||
* @param ilen length of input data should be multiple of block length.
|
||||
*
|
||||
* @param buf Pointer to blocks of data that will be prepended
|
||||
* to data_block before hashing. Useful when there is two sources of
|
||||
* data that need to be efficiently calculated in a single SHA DMA
|
||||
* operation.
|
||||
*
|
||||
* @param buf_len length of buf data should be multiple of block length.
|
||||
* Should not be longer than the maximum amount of bytes in a single block
|
||||
* (128 bytes)
|
||||
*
|
||||
* @param is_first_block If this parameter is true, the SHA state will
|
||||
* be initialised (with the initial state of the given SHA algorithm)
|
||||
* before the block is calculated. If false, the existing state of the
|
||||
* SHA engine will be used.
|
||||
*
|
||||
* @param t The number of bits for the SHA512/t hash function, with
|
||||
* output truncated to t bits. Used for calculating the inital hash.
|
||||
* t is any positive integer between 1 and 512, except 384.
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int esp_sha_dma(esp_sha_type sha_type, const void *data_block, uint32_t ilen, bool is_first_block);
|
||||
int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
|
||||
const void *buf, uint32_t buf_len, bool is_first_block);
|
||||
|
||||
/** @brief Read out the current state of the SHA digest loaded in the engine.
|
||||
/**
|
||||
* @brief Read out the current state of the SHA digest
|
||||
*
|
||||
* @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
|
||||
*
|
||||
* @note Call esp_sha_try_lock_engine() before calling this
|
||||
* function. Do not call esp_sha_lock_memory_block() beforehand, this
|
||||
* is done inside the function.
|
||||
* @note Call esp_sha_aquire_hardware() before calling this
|
||||
* function.
|
||||
*
|
||||
* If the SHA suffix padding block has been executed already, the
|
||||
* value that is read is the SHA digest (in big endian
|
||||
* format). Otherwise, the value that is read is an interim SHA state.
|
||||
*
|
||||
* @note If sha_type is SHA2_384, only 48 bytes of state will be read.
|
||||
* This is enough for the final SHA2_384 digest, but if you want the
|
||||
* interim SHA-384 state (to continue digesting) then pass SHA2_512 instead.
|
||||
* value that is read is the SHA digest.
|
||||
* Otherwise, the value that is read is an interim SHA state.
|
||||
*
|
||||
* @param sha_type SHA algorithm in use.
|
||||
*
|
||||
* @param state Pointer to a memory buffer to hold the SHA state. Size
|
||||
* is 20 bytes (SHA1), 32 bytes (SHA2_256), 48 bytes (SHA2_384) or 64 bytes (SHA2_512).
|
||||
*
|
||||
* @param digest_state Pointer to a memory buffer to hold the SHA state. Size
|
||||
* is 20 bytes (SHA1), 32 bytes (SHA2_256), or 64 bytes (SHA2_384, SHA2_512).
|
||||
*/
|
||||
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
|
||||
|
||||
/**
|
||||
* @brief Obtain exclusive access to a particular SHA engine
|
||||
* @brief Set the current state of the SHA digest
|
||||
*
|
||||
* @param sha_type Type of SHA engine to use.
|
||||
* @note Call esp_sha_aquire_hardware() before calling this
|
||||
* function.
|
||||
*
|
||||
* Blocks until engine is available. Note: Can block indefinitely
|
||||
* while a TLS connection is open, suggest using
|
||||
* esp_sha_try_lock_engine() and failing over to software SHA.
|
||||
* When resuming a
|
||||
*
|
||||
* @param sha_type SHA algorithm in use.
|
||||
* @param digest_state
|
||||
*/
|
||||
void esp_sha_lock_engine(esp_sha_type sha_type);
|
||||
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Try and obtain exclusive access to a particular SHA engine
|
||||
*
|
||||
* @param sha_type Type of SHA engine to use.
|
||||
*
|
||||
* @return Returns true if the SHA engine is locked for exclusive
|
||||
* use. Call esp_sha_unlock_sha_engine() when done. Returns false if
|
||||
* the SHA engine is already in use, caller should use software SHA
|
||||
* algorithm for this digest.
|
||||
* @brief Enables the SHA and crypto DMA peripheral and takes the
|
||||
* locks for both of them.
|
||||
*/
|
||||
bool esp_sha_try_lock_engine(esp_sha_type sha_type);
|
||||
void esp_sha_acquire_hardware(void);
|
||||
|
||||
/**
|
||||
* @brief Unlock an engine previously locked with esp_sha_lock_engine() or esp_sha_try_lock_engine()
|
||||
*
|
||||
* @param sha_type Type of engine to release.
|
||||
* @brief Disables the SHA and crypto DMA peripheral and releases the
|
||||
* locks.
|
||||
*/
|
||||
void esp_sha_unlock_engine(esp_sha_type sha_type);
|
||||
void esp_sha_release_hardware(void);
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Acquire exclusive access to the SHA shared memory block at SHA_TEXT_BASE
|
||||
* @brief Sets the initial hash value for SHA512/t.
|
||||
*
|
||||
* This memory block is shared across all the SHA algorithm types.
|
||||
* @note Is generated according to the algorithm described in the TRM,
|
||||
* chapter SHA-Accelerator
|
||||
*
|
||||
* Caller should have already locked a SHA engine before calling this function.
|
||||
* @note The engine must be locked until the value is used for an operation
|
||||
* or read out. Else you risk another operation overwriting it.
|
||||
*
|
||||
* Note that it is possible to obtain exclusive access to the memory block even
|
||||
* while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
|
||||
* to ensure the SHA engine is not reading from the memory block in hardware.
|
||||
* @param t
|
||||
*
|
||||
* @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
|
||||
*
|
||||
* Call esp_sha_unlock_memory_block() when done.
|
||||
* @return 0 if successful
|
||||
*/
|
||||
void esp_sha_lock_memory_block(void);
|
||||
|
||||
/**
|
||||
* @brief Release exclusive access to the SHA register memory block at SHA_TEXT_BASE
|
||||
*
|
||||
* Caller should have already locked a SHA engine before calling this function.
|
||||
*
|
||||
* Call following esp_sha_lock_memory_block().
|
||||
*/
|
||||
void esp_sha_unlock_memory_block(void);
|
||||
|
||||
/** @brief Wait for the SHA engine to finish any current operation
|
||||
*
|
||||
* @note This function does not ensure exclusive access to any SHA
|
||||
* engine. Caller should use esp_sha_try_lock_engine() and
|
||||
* esp_sha_lock_memory_block() as required.
|
||||
*
|
||||
* @note Functions declared in this header file wait for SHA engine
|
||||
* completion automatically, so you don't need to use this API for
|
||||
* these. However if accessing SHA registers directly, you will need
|
||||
* to call this before accessing SHA registers if using the
|
||||
* esp_sha_block() function.
|
||||
*
|
||||
* @note This function busy-waits, so wastes CPU resources.
|
||||
* Best to delay calling until you are about to need it.
|
||||
*
|
||||
*/
|
||||
void esp_sha_wait_idle(void);
|
||||
int esp_sha_512_t_init_hash(uint16_t t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
55
components/mbedtls/port/include/gcm_alt.h
Normal file
55
components/mbedtls/port/include/gcm_alt.h
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* \file gcm_alt.h
|
||||
*
|
||||
* \brief AES block cipher
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#ifndef GCM_ALT_H
|
||||
#define GCM_ALT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_ALT)
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/gcm.h"
|
||||
|
||||
|
||||
typedef esp_gcm_context mbedtls_gcm_context;
|
||||
|
||||
#define mbedtls_gcm_init esp_aes_gcm_init
|
||||
#define mbedtls_gcm_free esp_aes_gcm_free
|
||||
#define mbedtls_gcm_setkey esp_aes_gcm_setkey
|
||||
#define mbedtls_gcm_starts esp_aes_gcm_starts
|
||||
#define mbedtls_gcm_update esp_aes_gcm_update
|
||||
#define mbedtls_gcm_finish esp_aes_gcm_finish
|
||||
#define mbedtls_gcm_auth_decrypt esp_aes_gcm_auth_decrypt
|
||||
#define mbedtls_gcm_crypt_and_tag esp_aes_gcm_crypt_and_tag
|
||||
|
||||
#endif // CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
#endif /* MBEDTLS_GCM_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -118,6 +118,12 @@
|
||||
#undef MBEDTLS_AES_ALT
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_GCM
|
||||
#define MBEDTLS_GCM_ALT
|
||||
#else
|
||||
#undef MBEDTLS_GCM_ALT
|
||||
#endif
|
||||
|
||||
/* MBEDTLS_SHAxx_ALT to enable hardware SHA support
|
||||
with software fallback.
|
||||
*/
|
||||
|
@ -29,6 +29,30 @@ extern "C" {
|
||||
|
||||
#if defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
#include "esp32s2/sha.h"
|
||||
typedef enum {
|
||||
ESP_SHA1_STATE_INIT,
|
||||
ESP_SHA1_STATE_IN_PROCESS
|
||||
} esp_sha1_state;
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[5]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
int first_block; /*!< if first then true else false */
|
||||
esp_sha_type mode;
|
||||
esp_sha1_state sha_state;
|
||||
} mbedtls_sha1_context;
|
||||
|
||||
#endif //CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SHA1_UNUSED, /* first block hasn't been processed yet */
|
||||
ESP_MBEDTLS_SHA1_HARDWARE, /* using hardware SHA engine */
|
||||
@ -38,8 +62,7 @@ typedef enum {
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[5]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
@ -47,6 +70,8 @@ typedef struct
|
||||
}
|
||||
mbedtls_sha1_context;
|
||||
|
||||
#endif //CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -29,6 +29,33 @@ extern "C" {
|
||||
|
||||
#if defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
#include "esp32s2/sha.h"
|
||||
|
||||
typedef enum {
|
||||
ESP_SHA256_STATE_INIT,
|
||||
ESP_SHA256_STATE_IN_PROCESS
|
||||
} esp_sha256_state;
|
||||
|
||||
/**
|
||||
* \brief SHA-256 context structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
int first_block; /*!< if first then true, else false */
|
||||
esp_sha_type mode;
|
||||
esp_sha256_state sha_state;
|
||||
}
|
||||
mbedtls_sha256_context;
|
||||
|
||||
#endif //CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SHA256_UNUSED, /* first block hasn't been processed yet */
|
||||
ESP_MBEDTLS_SHA256_HARDWARE, /* using hardware SHA engine */
|
||||
@ -38,8 +65,7 @@ typedef enum {
|
||||
/**
|
||||
* \brief SHA-256 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
@ -48,6 +74,8 @@ typedef struct
|
||||
}
|
||||
mbedtls_sha256_context;
|
||||
|
||||
#endif //CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -23,12 +23,51 @@
|
||||
#ifndef _SHA512_ALT_H_
|
||||
#define _SHA512_ALT_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/sha.h"
|
||||
|
||||
typedef enum {
|
||||
ESP_SHA512_STATE_INIT,
|
||||
ESP_SHA512_STATE_IN_PROCESS
|
||||
} esp_sha512_state;
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t total[2]; /*!< number of bytes processed */
|
||||
uint64_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[128]; /*!< data block being processed */
|
||||
int first_block;
|
||||
esp_sha_type mode;
|
||||
uint32_t t_val; /*!< t_val for 512/t mode */
|
||||
esp_sha512_state sha_state;
|
||||
} mbedtls_sha512_context;
|
||||
|
||||
/**
|
||||
* @brief Sets the specfic algorithm for SHA512
|
||||
*
|
||||
* @param ctx The mbedtls sha512 context
|
||||
*
|
||||
* @param type The mode, used for setting SHA2_512224 and SHA2_512256:
|
||||
*
|
||||
*/
|
||||
void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type);
|
||||
|
||||
/* For SHA512/t mode the intial hash value will depend on t */
|
||||
void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val);
|
||||
|
||||
#endif //CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SHA512_UNUSED, /* first block hasn't been processed yet */
|
||||
ESP_MBEDTLS_SHA512_HARDWARE, /* using hardware SHA engine */
|
||||
@ -38,8 +77,7 @@ typedef enum {
|
||||
/**
|
||||
* \brief SHA-512 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint64_t total[2]; /*!< number of bytes processed */
|
||||
uint64_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[128]; /*!< data block being processed */
|
||||
@ -48,6 +86,8 @@ typedef struct
|
||||
}
|
||||
mbedtls_sha512_context;
|
||||
|
||||
#endif //CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
1025
components/mbedtls/test/test_aes.c
Normal file
1025
components/mbedtls/test/test_aes.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_timer.h"
|
||||
@ -14,7 +15,7 @@
|
||||
TEST_CASE("mbedtls AES performance", "[aes]")
|
||||
{
|
||||
const unsigned CALLS = 256;
|
||||
const unsigned CALL_SZ = 32*1024;
|
||||
const unsigned CALL_SZ = 32 * 1024;
|
||||
mbedtls_aes_context ctx;
|
||||
int64_t start, end;
|
||||
uint8_t iv[16];
|
||||
@ -24,7 +25,7 @@ TEST_CASE("mbedtls AES performance", "[aes]")
|
||||
memset(key, 0x44, 16);
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buf);
|
||||
mbedtls_aes_init(&ctx);
|
||||
mbedtls_aes_setkey_enc(&ctx, key, 128);
|
||||
@ -63,9 +64,65 @@ TEST_CASE("mbedtls AES performance", "[aes]")
|
||||
float mb_sec = (CALL_SZ * CALLS) / usecs;
|
||||
printf("Encryption rate %.3fMB/sec\n", mb_sec);
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_AES
|
||||
// Don't put a hard limit on software AES performance (software is approx 2.3MB/sec on Release config)
|
||||
// Don't put a hard limit on software AES performance
|
||||
TEST_PERFORMANCE_GREATER_THAN(AES_CBC_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("mbedtls AES GCM performance", "[aes]")
|
||||
{
|
||||
const unsigned CALLS = 1;
|
||||
const unsigned CALL_SZ = 32 * 1024;
|
||||
mbedtls_gcm_context ctx;
|
||||
int64_t start, end;
|
||||
unsigned char tag_buf[16];
|
||||
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
|
||||
memset(iv, 0xEE, 16);
|
||||
memset(key, 0x44, 16);
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buf);
|
||||
mbedtls_gcm_init(&ctx);
|
||||
mbedtls_gcm_setkey( &ctx, cipher, key, 128);
|
||||
|
||||
start = esp_timer_get_time();
|
||||
for (int c = 0; c < CALLS; c++) {
|
||||
memset(buf, 0xAA, CALL_SZ);
|
||||
mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_AES_ENCRYPT, CALL_SZ, iv, sizeof(iv), NULL, 0, buf, buf, 16, tag_buf);
|
||||
}
|
||||
end = esp_timer_get_time();
|
||||
|
||||
/* Sanity check: make sure the last ciphertext block matches
|
||||
what we expect to see.
|
||||
|
||||
Last block produced via this Python:
|
||||
import os, binascii
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
key = b'\x44' * 16
|
||||
iv = b'\xee' * 16
|
||||
cipher = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend())
|
||||
encryptor = cipher.encryptor()
|
||||
ct = encryptor.update(b'\xaa' * 1 * 32 * 1024) + encryptor.finalize()
|
||||
print(binascii.hexlify(ct[-16:]))
|
||||
*/
|
||||
const uint8_t expected_last_block[] = {
|
||||
0x7d, 0x3d, 0x16, 0x84, 0xd0, 0xb4, 0x38, 0x30,
|
||||
0xd1, 0x24, 0x6f, 0x7e, 0x9a, 0x9c, 0x81, 0x58,
|
||||
};
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16);
|
||||
|
||||
free(buf);
|
||||
|
||||
float usecs = end - start;
|
||||
// bytes/usec = MB/sec
|
||||
float mb_sec = (CALL_SZ * CALLS) / usecs;
|
||||
printf("GCM encryption rate %.3fMB/sec\n", mb_sec);
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "test_apb_dport_access.h"
|
||||
#include "sodium/utils.h"
|
||||
|
||||
TEST_CASE("mbedtls SHA self-tests", "[mbedtls]")
|
||||
{
|
||||
@ -21,19 +22,19 @@ TEST_CASE("mbedtls SHA self-tests", "[mbedtls]")
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha256_self_test(1), "SHA256 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass.");
|
||||
verify_apb_access_loop();
|
||||
}
|
||||
|
||||
static const unsigned char *one_hundred_as = (unsigned char *)
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
|
||||
static const unsigned char *one_hundred_bs = (unsigned char *)
|
||||
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
||||
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
||||
|
||||
static const uint8_t sha256_thousand_as[32] = {
|
||||
0x41, 0xed, 0xec, 0xe4, 0x2d, 0x63, 0xe8, 0xd9, 0xbf, 0x51, 0x5a, 0x9b, 0xa6, 0x93, 0x2e, 0x1c,
|
||||
0x20, 0xcb, 0xc9, 0xf5, 0xa5, 0xd1, 0x34, 0x64, 0x5a, 0xdb, 0x5d, 0xb1, 0xb9, 0x73, 0x7e, 0xa3 };
|
||||
0x20, 0xcb, 0xc9, 0xf5, 0xa5, 0xd1, 0x34, 0x64, 0x5a, 0xdb, 0x5d, 0xb1, 0xb9, 0x73, 0x7e, 0xa3
|
||||
};
|
||||
|
||||
static const uint8_t sha256_thousand_bs[32] = {
|
||||
0xf6, 0xf1, 0x18, 0xe1, 0x20, 0xe5, 0x2b, 0xe0, 0xbd, 0x0c, 0xfd, 0xf2, 0x79, 0x4c, 0xd1, 0x2c, 0x07, 0x68, 0x6c, 0xc8, 0x71, 0x23, 0x5a, 0xc2, 0xf1, 0x14, 0x59, 0x37, 0x8e, 0x6d, 0x23, 0x5b
|
||||
@ -49,7 +50,9 @@ static const uint8_t sha384_thousand_bs[48] = {
|
||||
|
||||
static const uint8_t sha1_thousand_as[20] = {
|
||||
0x29, 0x1e, 0x9a, 0x6c, 0x66, 0x99, 0x49, 0x49, 0xb5, 0x7b, 0xa5,
|
||||
0xe6, 0x50, 0x36, 0x1e, 0x98, 0xfc, 0x36, 0xb1, 0xba };
|
||||
0xe6, 0x50, 0x36, 0x1e, 0x98, 0xfc, 0x36, 0xb1, 0xba
|
||||
};
|
||||
|
||||
|
||||
TEST_CASE("mbedtls SHA interleaving", "[mbedtls]")
|
||||
{
|
||||
@ -129,8 +132,8 @@ TEST_CASE("mbedtls SHA multithreading", "[mbedtls]")
|
||||
xTaskCreate(tskRunSHA256Test, "SHA256Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA256Test, "SHA256Task2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(!xSemaphoreTake(done_sem, 10000/portTICK_PERIOD_MS)) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)) {
|
||||
TEST_FAIL_MESSAGE("done_sem not released by test task");
|
||||
}
|
||||
}
|
||||
@ -140,31 +143,30 @@ TEST_CASE("mbedtls SHA multithreading", "[mbedtls]")
|
||||
void tskRunSHASelftests(void *param)
|
||||
{
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if(mbedtls_sha1_self_test(1)) {
|
||||
if (mbedtls_sha1_self_test(1)) {
|
||||
printf("SHA1 self-tests failed.\n");
|
||||
while(1) {}
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
if(mbedtls_sha256_self_test(1)) {
|
||||
if (mbedtls_sha256_self_test(1)) {
|
||||
printf("SHA256 self-tests failed.\n");
|
||||
while(1) {}
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
if(mbedtls_sha512_self_test(1)) {
|
||||
if (mbedtls_sha512_self_test(1)) {
|
||||
printf("SHA512 self-tests failed.\n");
|
||||
while(1) {}
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
if(mbedtls_sha512_self_test(1)) {
|
||||
if (mbedtls_sha512_self_test(1)) {
|
||||
printf("SHA512 self-tests failed.\n");
|
||||
while(1) {}
|
||||
while (1) {}
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
|
||||
TEST_CASE("mbedtls SHA self-tests multithreaded", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateCounting(2, 0);
|
||||
@ -173,14 +175,13 @@ TEST_CASE("mbedtls SHA self-tests multithreaded", "[mbedtls]")
|
||||
|
||||
const int TIMEOUT_MS = 40000;
|
||||
|
||||
for(int i = 0; i < 2; i++) {
|
||||
if(!xSemaphoreTake(done_sem, TIMEOUT_MS/portTICK_PERIOD_MS)) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (!xSemaphoreTake(done_sem, TIMEOUT_MS / portTICK_PERIOD_MS)) {
|
||||
TEST_FAIL_MESSAGE("done_sem not released by test task");
|
||||
}
|
||||
}
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
|
||||
|
||||
TEST_CASE("mbedtls SHA512 clone", "[mbedtls]")
|
||||
{
|
||||
@ -207,10 +208,11 @@ TEST_CASE("mbedtls SHA512 clone", "[mbedtls]")
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 cloned calculation");
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA384 clone", "[mbedtls]")
|
||||
TEST_CASE("mbedtls SHA384 clone", "[mbedtls][")
|
||||
{
|
||||
mbedtls_sha512_context ctx;
|
||||
mbedtls_sha512_context clone;
|
||||
|
||||
unsigned char sha384[48];
|
||||
|
||||
mbedtls_sha512_init(&ctx);
|
||||
@ -220,12 +222,12 @@ TEST_CASE("mbedtls SHA384 clone", "[mbedtls]")
|
||||
}
|
||||
|
||||
mbedtls_sha512_clone(&clone, &ctx);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&ctx, one_hundred_bs, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&clone, one_hundred_bs, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&ctx, sha384));
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 original calculation");
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&clone, sha384));
|
||||
@ -258,7 +260,6 @@ TEST_CASE("mbedtls SHA256 clone", "[mbedtls]")
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 cloned calculation");
|
||||
}
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
|
||||
typedef struct {
|
||||
mbedtls_sha256_context ctx;
|
||||
uint8_t result[32];
|
||||
@ -279,8 +280,8 @@ static void tskFinaliseSha(void *v_param)
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
// No concurrent SHA sessions in esp32s2, only has one engine
|
||||
TEST_CASE("mbedtls SHA session passed between tasks" , "[mbedtls]")
|
||||
|
||||
TEST_CASE("mbedtls SHA session passed between tasks", "[mbedtls]")
|
||||
{
|
||||
finalise_sha_param_t param = { 0 };
|
||||
|
||||
@ -303,4 +304,130 @@ TEST_CASE("mbedtls SHA session passed between tasks" , "[mbedtls]")
|
||||
TEST_ASSERT_EQUAL(0, param.ret);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, param.result, 32, "SHA256 result from other task");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ESP32 do not have SHA512/t functions */
|
||||
#if !DISABLED_FOR_TARGETS(ESP32)
|
||||
|
||||
/* Function are not implemented in SW */
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
|
||||
/*
|
||||
* FIPS-180-2 test vectors
|
||||
*/
|
||||
static unsigned char sha512T_test_buf[2][113] = {
|
||||
{ "abc" },
|
||||
{
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
|
||||
}
|
||||
};
|
||||
|
||||
static const size_t sha512T_test_buflen[2] = {
|
||||
3, 112
|
||||
};
|
||||
|
||||
static const esp_sha_type sha512T_algo[4] = {
|
||||
SHA2_512224, SHA2_512256, SHA2_512T, SHA2_512T
|
||||
};
|
||||
|
||||
static const size_t sha512T_t_len[4] = { 224, 256, 224, 256 };
|
||||
|
||||
static const unsigned char sha512_test_sum[4][32] = {
|
||||
/* SHA512-224 */
|
||||
{
|
||||
0x46, 0x34, 0x27, 0x0f, 0x70, 0x7b, 0x6a, 0x54,
|
||||
0xda, 0xae, 0x75, 0x30, 0x46, 0x08, 0x42, 0xe2,
|
||||
0x0e, 0x37, 0xed, 0x26, 0x5c, 0xee, 0xe9, 0xa4,
|
||||
0x3e, 0x89, 0x24, 0xaa
|
||||
},
|
||||
{
|
||||
0x23, 0xfe, 0xc5, 0xbb, 0x94, 0xd6, 0x0b, 0x23,
|
||||
0x30, 0x81, 0x92, 0x64, 0x0b, 0x0c, 0x45, 0x33,
|
||||
0x35, 0xd6, 0x64, 0x73, 0x4f, 0xe4, 0x0e, 0x72,
|
||||
0x68, 0x67, 0x4a, 0xf9
|
||||
},
|
||||
|
||||
/* SHA512-256 */
|
||||
{
|
||||
0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9,
|
||||
0x9b, 0x2e, 0x29, 0xb7, 0x6b, 0x4c, 0x7d, 0xab,
|
||||
0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, 0x6d, 0x46,
|
||||
0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23
|
||||
},
|
||||
{
|
||||
0x39, 0x28, 0xe1, 0x84, 0xfb, 0x86, 0x90, 0xf8,
|
||||
0x40, 0xda, 0x39, 0x88, 0x12, 0x1d, 0x31, 0xbe,
|
||||
0x65, 0xcb, 0x9d, 0x3e, 0xf8, 0x3e, 0xe6, 0x14,
|
||||
0x6f, 0xea, 0xc8, 0x61, 0xe1, 0x9b, 0x56, 0x3a
|
||||
}
|
||||
|
||||
/* For SHA512_T testing we use t=224 & t=256
|
||||
* so the hash digest should be same as above
|
||||
*/
|
||||
};
|
||||
|
||||
/* This will run total of 8 test cases, 2 for each of the below MODE
|
||||
* SHA512/224, SHA512/256, SHA512/t with t=224 & SHA512/t with t=256
|
||||
*
|
||||
* Test is disabled for ESP32 as there is no hardware for SHA512/t
|
||||
*/
|
||||
TEST_CASE("mbedtls SHA512/t", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context sha512_ctx;
|
||||
unsigned char sha512[64], k;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
k = i * 2 + j;
|
||||
mbedtls_sha512_init(&sha512_ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts_ret(&sha512_ctx, false));
|
||||
esp_sha512_set_mode(&sha512_ctx, sha512T_algo[i]);
|
||||
if (i > 1) {
|
||||
k = (i - 2) * 2 + j;
|
||||
esp_sha512_set_t(&sha512_ctx, sha512T_t_len[i]);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update_ret(&sha512_ctx, sha512T_test_buf[j], sha512T_test_buflen[j]));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish_ret(&sha512_ctx, sha512));
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_test_sum[k], sha512, sha512T_t_len[i] / 8, "SHA512t calculation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPIRAM
|
||||
TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]")
|
||||
{
|
||||
|
||||
const unsigned CALLS = 256;
|
||||
const unsigned CALL_SZ = 16 * 1024;
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
unsigned char sha256[32];
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_SPIRAM);
|
||||
TEST_ASSERT(esp_ptr_external_ram(buf));
|
||||
memset(buf, 0x54, CALL_SZ);
|
||||
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts_ret(&sha256_ctx, false));
|
||||
for (int c = 0; c < CALLS; c++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update_ret(&sha256_ctx, buf, CALL_SZ));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish_ret(&sha256_ctx, sha256));
|
||||
|
||||
free(buf);
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
|
||||
/* Check the result. Reference value can be calculated using:
|
||||
* dd if=/dev/zero bs=$((16*1024)) count=256 | tr '\000' '\124' | sha256sum
|
||||
*/
|
||||
const char *expected_hash = "8d031167bd706ac337e07aa9129c34ae4ae792d0a79a2c70e7f012102e8adc3d";
|
||||
char hash_str[sizeof(sha256) * 2 + 1];
|
||||
sodium_bin2hex(hash_str, sizeof(hash_str), sha256, sizeof(sha256));
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str);
|
||||
|
||||
}
|
||||
#endif //CONFIG_SPIRAM
|
||||
|
||||
#endif //CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
#endif //!DISABLED_FOR_TARGETS(ESP32S2)
|
@ -14,13 +14,13 @@
|
||||
TEST_CASE("mbedtls SHA performance", "[aes]")
|
||||
{
|
||||
const unsigned CALLS = 256;
|
||||
const unsigned CALL_SZ = 16*1024;
|
||||
const unsigned CALL_SZ = 16 * 1024;
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
int64_t start, end;
|
||||
unsigned char sha256[32];
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buf);
|
||||
memset(buf, 0x55, CALL_SZ);
|
||||
|
||||
@ -39,7 +39,7 @@ TEST_CASE("mbedtls SHA performance", "[aes]")
|
||||
/* Check the result. Reference value can be calculated using:
|
||||
* dd if=/dev/zero bs=$((16*1024)) count=256 | tr '\000' '\125' | sha256sum
|
||||
*/
|
||||
const char* expected_hash = "c88df2638fb9699abaad05780fa5e0fdb6058f477069040eac8bed3231286275";
|
||||
const char *expected_hash = "c88df2638fb9699abaad05780fa5e0fdb6058f477069040eac8bed3231286275";
|
||||
char hash_str[sizeof(sha256) * 2 + 1];
|
||||
sodium_bin2hex(hash_str, sizeof(hash_str), sha256, sizeof(sha256));
|
||||
|
||||
@ -49,7 +49,7 @@ TEST_CASE("mbedtls SHA performance", "[aes]")
|
||||
// bytes/usec = MB/sec
|
||||
float mb_sec = (CALL_SZ * CALLS) / usecs;
|
||||
printf("SHA256 rate %.3fMB/sec\n", mb_sec);
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
// Don't put a hard limit on software SHA performance
|
||||
TEST_PERFORMANCE_GREATER_THAN(SHA256_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec);
|
||||
#endif
|
||||
|
@ -145,6 +145,15 @@ inline static bool IRAM_ATTR esp_ptr_dma_capable(const void *p)
|
||||
return (intptr_t)p >= SOC_DMA_LOW && (intptr_t)p < SOC_DMA_HIGH;
|
||||
}
|
||||
|
||||
inline static bool IRAM_ATTR esp_ptr_dma_ext_capable(const void *p)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
return (intptr_t)p >= SOC_DMA_EXT_LOW && (intptr_t)p < SOC_DMA_EXT_HIGH;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline static bool IRAM_ATTR esp_ptr_word_aligned(const void *p)
|
||||
{
|
||||
return ((intptr_t)p) % 4 == 0;
|
||||
|
@ -69,24 +69,6 @@
|
||||
#define SHA_H_BASE ((DR_REG_SHA_BASE) + 0x40)
|
||||
#define SHA_TEXT_BASE ((DR_REG_SHA_BASE) + 0x80)
|
||||
|
||||
/* AES Block operation modes */
|
||||
#define AES_BLOCK_MODE_ECB 0
|
||||
#define AES_BLOCK_MODE_CBC 1
|
||||
#define AES_BLOCK_MODE_OFB 2
|
||||
#define AES_BLOCK_MODE_CTR 3
|
||||
#define AES_BLOCK_MODE_CFB8 4
|
||||
#define AES_BLOCK_MODE_CFB128 5
|
||||
#define AES_BLOCK_MODE_GCM 6
|
||||
|
||||
/* AES Block operation modes (used with DMA) */
|
||||
#define AES_BLOCK_MODE_ECB 0
|
||||
#define AES_BLOCK_MODE_CBC 1
|
||||
#define AES_BLOCK_MODE_OFB 2
|
||||
#define AES_BLOCK_MODE_CTR 3
|
||||
#define AES_BLOCK_MODE_CFB8 4
|
||||
#define AES_BLOCK_MODE_CFB128 5
|
||||
#define AES_BLOCK_MODE_GCM 6
|
||||
|
||||
/* AES acceleration registers */
|
||||
#define AES_MODE_REG ((DR_REG_AES_BASE) + 0x40)
|
||||
#define AES_ENDIAN_REG ((DR_REG_AES_BASE) + 0x44)
|
||||
|
@ -48,6 +48,12 @@ typedef enum {
|
||||
PERIPH_WIFI_MODULE,
|
||||
PERIPH_WIFI_BT_COMMON_MODULE,
|
||||
PERIPH_SYSTIMER_MODULE,
|
||||
PERIPH_AES_MODULE,
|
||||
PERIPH_SHA_MODULE,
|
||||
PERIPH_RSA_MODULE,
|
||||
PERIPH_CRYPTO_DMA_MODULE, //this DMA is shared between AES and SHA
|
||||
PERIPH_AES_DMA_MODULE,
|
||||
PERIPH_SHA_DMA_MODULE,
|
||||
} periph_module_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -270,10 +270,14 @@
|
||||
#define SOC_DIRAM_DRAM_LOW 0x3FFB0000
|
||||
#define SOC_DIRAM_DRAM_HIGH 0x40000000
|
||||
|
||||
// Region of memory accessible via DMA. See esp_ptr_dma_capable().
|
||||
// Region of memory accessible via DMA in internal memory. See esp_ptr_dma_capable().
|
||||
#define SOC_DMA_LOW 0x3FFB0000
|
||||
#define SOC_DMA_HIGH 0x40000000
|
||||
|
||||
// Region of memory accessible via DMA in external memory. See esp_ptr_dma_ext_capable().
|
||||
#define SOC_DMA_EXT_LOW 0x3F500000
|
||||
#define SOC_DMA_EXT_HIGH 0x3FF80000
|
||||
|
||||
// Region of memory that is byte-accessible. See esp_ptr_byte_accessible().
|
||||
#define SOC_BYTE_ACCESSIBLE_LOW 0x3FF9E000
|
||||
#define SOC_BYTE_ACCESSIBLE_HIGH 0x40000000
|
||||
|
@ -84,6 +84,18 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
|
||||
return DPORT_WIFI_CLK_WIFI_BT_COMMON_M;
|
||||
case PERIPH_SYSTIMER_MODULE:
|
||||
return DPORT_SYSTIMER_CLK_EN;
|
||||
case PERIPH_AES_MODULE:
|
||||
return DPORT_CRYPTO_AES_CLK_EN;
|
||||
case PERIPH_SHA_MODULE:
|
||||
return DPORT_CRYPTO_SHA_CLK_EN;
|
||||
case PERIPH_RSA_MODULE:
|
||||
return DPORT_CRYPTO_RSA_CLK_EN;
|
||||
case PERIPH_CRYPTO_DMA_MODULE:
|
||||
return DPORT_CRYPTO_DMA_CLK_EN;
|
||||
case PERIPH_SHA_DMA_MODULE:
|
||||
return DPORT_CRYPTO_DMA_CLK_EN | DPORT_CRYPTO_SHA_CLK_EN;
|
||||
case PERIPH_AES_DMA_MODULE:
|
||||
return DPORT_CRYPTO_DMA_CLK_EN | DPORT_CRYPTO_AES_CLK_EN;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -144,6 +156,49 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
|
||||
return DPORT_CAN_RST;
|
||||
case PERIPH_SYSTIMER_MODULE:
|
||||
return DPORT_SYSTIMER_RST;
|
||||
case PERIPH_AES_MODULE:
|
||||
if (enable == true) {
|
||||
// Clear reset on digital signature, otherwise AES unit is held in reset also.
|
||||
return (DPORT_CRYPTO_AES_RST | DPORT_CRYPTO_DS_RST);
|
||||
} else {
|
||||
//Don't return other units to reset, as this pulls reset on RSA & SHA units, respectively.
|
||||
return DPORT_CRYPTO_AES_RST;
|
||||
}
|
||||
case PERIPH_SHA_MODULE:
|
||||
if (enable == true) {
|
||||
// Clear reset on digital signature and HMAC, otherwise SHA is held in reset
|
||||
return (DPORT_CRYPTO_SHA_RST | DPORT_CRYPTO_DS_RST | DPORT_CRYPTO_HMAC_RST);
|
||||
} else {
|
||||
// Don't assert reset on secure boot, otherwise AES is held in reset
|
||||
return DPORT_CRYPTO_SHA_RST;
|
||||
}
|
||||
case PERIPH_RSA_MODULE:
|
||||
if (enable == true) {
|
||||
// Also clear reset on digital signature, otherwise RSA is held in reset
|
||||
return (DPORT_CRYPTO_RSA_RST | DPORT_CRYPTO_DS_RST);
|
||||
} else {
|
||||
// Don't reset digital signature unit, as this resets AES also
|
||||
return DPORT_CRYPTO_RSA_RST;
|
||||
}
|
||||
case PERIPH_CRYPTO_DMA_MODULE:
|
||||
return DPORT_CRYPTO_DMA_RST;
|
||||
|
||||
case PERIPH_AES_DMA_MODULE:
|
||||
if (enable == true) {
|
||||
// Clear reset on digital signature, otherwise AES unit is held in reset also.
|
||||
return (DPORT_CRYPTO_AES_RST | DPORT_CRYPTO_DS_RST | DPORT_CRYPTO_DMA_RST);
|
||||
} else {
|
||||
//Don't return other units to reset, as this pulls reset on RSA & SHA units, respectively.
|
||||
return (DPORT_CRYPTO_AES_RST | DPORT_CRYPTO_DMA_RST);
|
||||
}
|
||||
case PERIPH_SHA_DMA_MODULE:
|
||||
if (enable == true) {
|
||||
// Clear reset on digital signature and HMAC, otherwise SHA is held in reset
|
||||
return (DPORT_CRYPTO_SHA_RST | DPORT_CRYPTO_DS_RST | DPORT_CRYPTO_HMAC_RST | DPORT_CRYPTO_DMA_RST);
|
||||
} else {
|
||||
// Don't assert reset on secure boot, otherwise AES is held in reset
|
||||
return (DPORT_CRYPTO_SHA_RST | DPORT_CRYPTO_DMA_RST);
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -156,6 +211,13 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
|
||||
case PERIPH_WIFI_MODULE:
|
||||
case PERIPH_WIFI_BT_COMMON_MODULE:
|
||||
return DPORT_WIFI_CLK_EN_REG;
|
||||
case PERIPH_AES_MODULE:
|
||||
case PERIPH_SHA_MODULE:
|
||||
case PERIPH_RSA_MODULE:
|
||||
case PERIPH_CRYPTO_DMA_MODULE:
|
||||
case PERIPH_AES_DMA_MODULE:
|
||||
case PERIPH_SHA_DMA_MODULE:
|
||||
return DPORT_PERIP_CLK_EN1_REG;
|
||||
default:
|
||||
return DPORT_PERIP_CLK_EN_REG;
|
||||
}
|
||||
@ -168,6 +230,13 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
|
||||
case PERIPH_WIFI_MODULE:
|
||||
case PERIPH_WIFI_BT_COMMON_MODULE:
|
||||
return DPORT_CORE_RST_EN_REG;
|
||||
case PERIPH_AES_MODULE:
|
||||
case PERIPH_SHA_MODULE:
|
||||
case PERIPH_RSA_MODULE:
|
||||
case PERIPH_CRYPTO_DMA_MODULE:
|
||||
case PERIPH_AES_DMA_MODULE:
|
||||
case PERIPH_SHA_DMA_MODULE:
|
||||
return DPORT_PERIP_RST_EN1_REG;
|
||||
default:
|
||||
return DPORT_PERIP_RST_EN_REG;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user