Sync inav to Gitea
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s
This commit is contained in:
+882
@@ -0,0 +1,882 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020, STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements ST AES HW services based on API from mbed TLS
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_AES_ALT)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
/* Parameter validation macros based on platform_util.h */
|
||||
#define AES_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
|
||||
#define AES_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
static int aes_set_key( mbedtls_aes_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits )
|
||||
{
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( key != NULL );
|
||||
|
||||
/* Protect context access */
|
||||
/* (it may occur at a same time in a threaded environment) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
switch (keybits)
|
||||
{
|
||||
case 128:
|
||||
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_128B;
|
||||
break;
|
||||
|
||||
case 192:
|
||||
#if ( USE_AES_KEY192 == 1 )
|
||||
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_192B;
|
||||
break;
|
||||
#else
|
||||
ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||
goto exit;
|
||||
#endif /* USE_AES_KEY192 */
|
||||
|
||||
case 256:
|
||||
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_256B;
|
||||
break;
|
||||
|
||||
default :
|
||||
ret = MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Format and fill AES key */
|
||||
for( i=0; i < (keybits/32); i++)
|
||||
GET_UINT32_BE( ctx->aes_key[i], key,4*i );
|
||||
|
||||
/* include the appropriate instance name */
|
||||
#if defined (AES)
|
||||
ctx->hcryp_aes.Instance = AES;
|
||||
#elif defined (AES1)
|
||||
ctx->hcryp_aes.Instance = AES1;
|
||||
#else /* CRYP */
|
||||
ctx->hcryp_aes.Instance = CRYP;
|
||||
#endif /* AES */
|
||||
|
||||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
||||
ctx->hcryp_aes.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||
ctx->hcryp_aes.Init.pKey = ctx->aes_key;
|
||||
|
||||
if ( HAL_CRYP_Init(&ctx->hcryp_aes) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* allow multi-context of CRYP : save context */
|
||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &cryp_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
void mbedtls_aes_init( mbedtls_aes_context *ctx )
|
||||
{
|
||||
AES_VALIDATE( ctx != NULL );
|
||||
|
||||
__disable_irq();
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* mutex cannot be initialized twice */
|
||||
if ( !cryp_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_init( &cryp_mutex );
|
||||
cryp_mutex_started = 1;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
cryp_context_count++;
|
||||
__enable_irq();
|
||||
|
||||
cryp_zeroize( (void*)ctx, sizeof(mbedtls_aes_context) );
|
||||
}
|
||||
|
||||
|
||||
void mbedtls_aes_free( mbedtls_aes_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
__disable_irq();
|
||||
if (cryp_context_count > 0)
|
||||
cryp_context_count--;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ( cryp_context_count == 0 )
|
||||
{
|
||||
mbedtls_mutex_free( &cryp_mutex );
|
||||
cryp_mutex_started = 0;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
__enable_irq();
|
||||
|
||||
/* Shut down CRYP on last context */
|
||||
if (cryp_context_count == 0)
|
||||
HAL_CRYP_DeInit( &ctx->hcryp_aes );
|
||||
|
||||
cryp_zeroize( (void*)ctx, sizeof(mbedtls_aes_context) );
|
||||
}
|
||||
|
||||
/* XTS SW implementation inherited code from aes.c */
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
|
||||
{
|
||||
AES_VALIDATE( ctx != NULL );
|
||||
|
||||
mbedtls_aes_init( &ctx->crypt );
|
||||
mbedtls_aes_init( &ctx->tweak );
|
||||
}
|
||||
|
||||
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
mbedtls_aes_free( &ctx->crypt );
|
||||
mbedtls_aes_free( &ctx->tweak );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
/*
|
||||
* AES key schedule (encryption)
|
||||
*/
|
||||
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( key != NULL );
|
||||
|
||||
return( aes_set_key( ctx, key, keybits ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* AES key schedule (decryption)
|
||||
*/
|
||||
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( key != NULL );
|
||||
|
||||
return( aes_set_key( ctx, key, keybits ) );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
static int mbedtls_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 mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( key != NULL );
|
||||
|
||||
ret = mbedtls_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 = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set crypt key for encryption. */
|
||||
return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
|
||||
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
int ret;
|
||||
const unsigned char *key1, *key2;
|
||||
unsigned int key1bits, key2bits;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( key != NULL );
|
||||
|
||||
ret = mbedtls_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 = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Set crypt key for decryption. */
|
||||
return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
/*
|
||||
* AES-ECB block encryption/decryption
|
||||
*/
|
||||
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
|
||||
/* Protect context access */
|
||||
/* (it may occur at a same time in a threaded environment) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* allow multi-context of CRYP use: restore context */
|
||||
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
|
||||
|
||||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
||||
ctx->hcryp_aes.Init.pKey = ctx->aes_key;
|
||||
|
||||
/* Set the Algo if not configured till now */
|
||||
if ( CRYP_AES_ECB != ctx->hcryp_aes.Init.Algorithm )
|
||||
{
|
||||
ctx->hcryp_aes.Init.Algorithm = CRYP_AES_ECB;
|
||||
|
||||
/* Configure the CRYP */
|
||||
if ( HAL_CRYP_SetConfig( &ctx->hcryp_aes,
|
||||
&ctx->hcryp_aes.Init ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mode == MBEDTLS_AES_DECRYPT )
|
||||
{
|
||||
/* AES decryption */
|
||||
ret = mbedtls_internal_aes_decrypt( ctx, input, output );
|
||||
if ( ret != 0 )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* AES encryption */
|
||||
ret = mbedtls_internal_aes_encrypt( ctx, input, output );
|
||||
if( ret != 0 )
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* allow multi-context of CRYP : save context */
|
||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
||||
|
||||
exit:
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &cryp_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/*
|
||||
* AES-CBC buffer encryption/decryption
|
||||
*/
|
||||
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
unsigned int i;
|
||||
__ALIGN_BEGIN static uint32_t iv_32B[4]; __ALIGN_END
|
||||
int ret = 0;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
AES_VALIDATE_RET( iv != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
|
||||
if ( length % 16 )
|
||||
{
|
||||
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
|
||||
}
|
||||
|
||||
/* Protect context access */
|
||||
/* (it may occur at a same time in a threaded environment) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* allow multi-context of CRYP use: restore context */
|
||||
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
|
||||
|
||||
/* Set the Algo if not configured till now */
|
||||
if ( CRYP_AES_CBC != ctx->hcryp_aes.Init.Algorithm )
|
||||
{
|
||||
ctx->hcryp_aes.Init.Algorithm = CRYP_AES_CBC;
|
||||
}
|
||||
|
||||
/* Set IV with invert endianness */
|
||||
for( i=0; i < 4; i++)
|
||||
GET_UINT32_BE( iv_32B[i], iv, 4*i );
|
||||
|
||||
ctx->hcryp_aes.Init.pInitVect = iv_32B;
|
||||
|
||||
/* reconfigure the CRYP */
|
||||
if ( HAL_CRYP_SetConfig( &ctx->hcryp_aes,
|
||||
&ctx->hcryp_aes.Init ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ( mode == MBEDTLS_AES_DECRYPT )
|
||||
{
|
||||
/* current input is the IV vector for the next decrypt */
|
||||
memcpy( iv, input, 16 );
|
||||
|
||||
if ( HAL_CRYP_Decrypt( &ctx->hcryp_aes,
|
||||
(uint32_t *)input,
|
||||
length,
|
||||
(uint32_t *)output,
|
||||
ST_CRYP_TIMEOUT ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HAL_CRYP_Encrypt( &ctx->hcryp_aes,
|
||||
(uint32_t *)input,
|
||||
length,
|
||||
(uint32_t *)output,
|
||||
ST_CRYP_TIMEOUT ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* current output is the IV vector for the next encrypt */
|
||||
memcpy( iv, output, 16 );
|
||||
}
|
||||
|
||||
/* allow multi-context of CRYP : save context */
|
||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
||||
|
||||
exit:
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
|
||||
/* 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 mbedtls_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 mbedtls_aes_crypt_xts( mbedtls_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];
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
AES_VALIDATE_RET( data_unit != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
|
||||
/* Data units must be at least 16 bytes long. */
|
||||
if( length < 16 )
|
||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
|
||||
/* NIST SP 800-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 = mbedtls_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 ) );
|
||||
mbedtls_gf128mul_x_ble( tweak, tweak );
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
tmp[i] = input[i] ^ tweak[i];
|
||||
|
||||
ret = mbedtls_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. */
|
||||
mbedtls_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 = mbedtls_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 );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
/*
|
||||
* AES-CFB128 buffer encryption/decryption
|
||||
*/
|
||||
int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output)
|
||||
{
|
||||
int ret;
|
||||
int c;
|
||||
size_t n;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
AES_VALIDATE_RET( iv_off != NULL );
|
||||
AES_VALIDATE_RET( iv != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
|
||||
n = *iv_off;
|
||||
|
||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||
while (length--) {
|
||||
if (n == 0) {
|
||||
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
c = *input++;
|
||||
*output++ = (unsigned char)(c ^ iv[n]);
|
||||
iv[n] = (unsigned char) c;
|
||||
|
||||
n = (n + 1) & 0x0F;
|
||||
}
|
||||
} else {
|
||||
while (length--) {
|
||||
if (n == 0) {
|
||||
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
iv[n] = *output++ = (unsigned char)(iv[n] ^ *input++);
|
||||
|
||||
n = (n + 1) & 0x0F;
|
||||
}
|
||||
}
|
||||
|
||||
*iv_off = n;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-CFB8 buffer encryption/decryption
|
||||
*/
|
||||
int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output)
|
||||
{
|
||||
int ret;
|
||||
unsigned char c;
|
||||
unsigned char ov[17];
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
|
||||
mode == MBEDTLS_AES_DECRYPT );
|
||||
AES_VALIDATE_RET( iv != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
|
||||
while (length--) {
|
||||
memcpy(ov, iv, 16);
|
||||
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
|
||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||
ov[16] = *input;
|
||||
}
|
||||
|
||||
c = *output++ = (unsigned char)(iv[0] ^ *input++);
|
||||
|
||||
if (mode == MBEDTLS_AES_ENCRYPT) {
|
||||
ov[16] = c;
|
||||
}
|
||||
|
||||
memcpy(iv, ov + 1, 16);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
||||
/*
|
||||
* AES-OFB (Output Feedback Mode) buffer encryption/decryption
|
||||
*/
|
||||
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t n;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( iv_off != NULL );
|
||||
AES_VALIDATE_RET( iv != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
|
||||
n = *iv_off;
|
||||
|
||||
if( n > 15 )
|
||||
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
|
||||
|
||||
while( length-- )
|
||||
{
|
||||
if( n == 0 )
|
||||
{
|
||||
ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
}
|
||||
*output++ = *input++ ^ iv[n];
|
||||
|
||||
n = ( n + 1 ) & 0x0F;
|
||||
}
|
||||
|
||||
*iv_off = n;
|
||||
|
||||
exit:
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_OFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
/*
|
||||
* AES-CTR buffer encryption/decryption
|
||||
*/
|
||||
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int c, i;
|
||||
size_t n;
|
||||
|
||||
AES_VALIDATE_RET( ctx != NULL );
|
||||
AES_VALIDATE_RET( nc_off != NULL );
|
||||
AES_VALIDATE_RET( nonce_counter != NULL );
|
||||
AES_VALIDATE_RET( stream_block != NULL );
|
||||
AES_VALIDATE_RET( input != NULL );
|
||||
AES_VALIDATE_RET( output != NULL );
|
||||
|
||||
n = *nc_off;
|
||||
|
||||
if ( n > 0x0F )
|
||||
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
|
||||
|
||||
while( length-- )
|
||||
{
|
||||
if( n == 0 ) {
|
||||
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block) != 0) {
|
||||
return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
|
||||
}
|
||||
|
||||
for( i = 16; i > 0; i-- )
|
||||
if( ++nonce_counter[i - 1] != 0 )
|
||||
break;
|
||||
}
|
||||
c = *input++;
|
||||
*output++ = (unsigned char)( c ^ stream_block[n] );
|
||||
|
||||
n = ( n + 1 ) & 0x0F;
|
||||
}
|
||||
|
||||
*nc_off = n;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||
|
||||
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
|
||||
if (HAL_CRYP_Encrypt( &ctx->hcryp_aes,
|
||||
(uint32_t *)input,
|
||||
16,
|
||||
(uint32_t *)output,
|
||||
ST_CRYP_TIMEOUT) != HAL_OK )
|
||||
{
|
||||
return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
|
||||
}
|
||||
return( 0 );
|
||||
|
||||
}
|
||||
|
||||
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
if (HAL_CRYP_Decrypt( &ctx->hcryp_aes,
|
||||
(uint32_t *)input,
|
||||
16,
|
||||
(uint32_t *)output,
|
||||
ST_CRYP_TIMEOUT) != HAL_OK )
|
||||
{
|
||||
return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
#error "mbedtls_aes_encrypt() is a deprecated function (not implemented)"
|
||||
}
|
||||
|
||||
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
#error "mbedtls_aes_decrypt() is a deprecated function (not implemented)"
|
||||
}
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
#endif /*MBEDTLS_AES_ALT*/
|
||||
#endif /* MBEDTLS_AES_C */
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* \file aes_alt.h
|
||||
*
|
||||
* \brief This file contains AES definitions and functions.
|
||||
*
|
||||
* The Advanced Encryption Standard (AES) specifies a FIPS-approved
|
||||
* cryptographic algorithm that can be used to protect electronic
|
||||
* data.
|
||||
*
|
||||
* The AES algorithm is a symmetric block cipher that can
|
||||
* encrypt and decrypt information. For more information, see
|
||||
* <em>FIPS Publication 197: Advanced Encryption Standard</em> and
|
||||
* <em>ISO/IEC 18033-2:2006: Information technology -- Security
|
||||
* techniques -- Encryption algorithms -- Part 2: Asymmetric
|
||||
* ciphers</em>.
|
||||
*
|
||||
* The AES-XTS block mode is standardized by NIST SP 800-38E
|
||||
* <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
|
||||
* and described in detail by IEEE P1619
|
||||
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
|
||||
* Copyright (C) 2019-2020 STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements ST AES HW services based on API from mbed TLS
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef MBEDTLS_AES_ALT_H
|
||||
#define MBEDTLS_AES_ALT_H
|
||||
|
||||
#if defined(MBEDTLS_AES_ALT)
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "cryp_stm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/* Encryption/Decryption key */
|
||||
uint32_t aes_key[8];
|
||||
|
||||
CRYP_HandleTypeDef hcryp_aes; /* AES context */
|
||||
uint32_t ctx_save_cr; /* save context for multi-context */
|
||||
}
|
||||
mbedtls_aes_context;
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
/**
|
||||
* \brief The AES XTS context-type definition.
|
||||
*/
|
||||
typedef struct mbedtls_aes_xts_context
|
||||
{
|
||||
mbedtls_aes_context crypt; /*!< The AES context to use for AES block
|
||||
encryption or decryption. */
|
||||
mbedtls_aes_context tweak; /*!< The AES context used for tweak
|
||||
computation. */
|
||||
} mbedtls_aes_xts_context;
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_AES_ALT */
|
||||
|
||||
#endif /* MBEDTLS_AES_ALT_H */
|
||||
+496
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020 STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements ST CCM HW services based on API from mbed TLS
|
||||
*/
|
||||
|
||||
/*
|
||||
* Definition of CCM:
|
||||
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
|
||||
* RFC 3610 "Counter with CBC-MAC (CCM)"
|
||||
*
|
||||
* Related:
|
||||
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "mbedtls/ccm.h"
|
||||
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
#if defined(MBEDTLS_CCM_ALT)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
/* Parameter validation macros */
|
||||
#define CCM_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT )
|
||||
#define CCM_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define CCM_ENCRYPT 0
|
||||
#define CCM_DECRYPT 1
|
||||
|
||||
#define H_LENGTH 2 /* Formatting of the Associated Data */
|
||||
/* If 0 < a < 2e16-2e8, */
|
||||
/* then a is encoded as [a]16, i.e., two octets */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/*
|
||||
* Initialize context
|
||||
*/
|
||||
void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
|
||||
{
|
||||
CCM_VALIDATE( ctx != NULL );
|
||||
|
||||
__disable_irq();
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* mutex cannot be initialized twice */
|
||||
if ( !cryp_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_init( &cryp_mutex );
|
||||
cryp_mutex_started = 1;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
cryp_context_count++;
|
||||
__enable_irq();
|
||||
|
||||
cryp_zeroize( (void*)ctx, sizeof(mbedtls_ccm_context) );
|
||||
}
|
||||
|
||||
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
|
||||
mbedtls_cipher_id_t cipher,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits )
|
||||
{
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
||||
CCM_VALIDATE_RET( ctx != NULL );
|
||||
CCM_VALIDATE_RET( key != NULL );
|
||||
|
||||
/* Protect context access */
|
||||
/* (it may occur at a same time in a threaded environment) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
switch (keybits)
|
||||
{
|
||||
case 128:
|
||||
ctx->hcryp_ccm.Init.KeySize = CRYP_KEYSIZE_128B;;
|
||||
break;
|
||||
|
||||
case 192:
|
||||
#if ( USE_AES_KEY192 == 1 )
|
||||
ctx->hcryp_ccm.Init.KeySize = CRYP_KEYSIZE_192B;
|
||||
break;
|
||||
#else
|
||||
ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||
goto exit;
|
||||
#endif /* USE_AES_KEY192 */
|
||||
|
||||
case 256:
|
||||
ctx->hcryp_ccm.Init.KeySize = CRYP_KEYSIZE_256B;
|
||||
break;
|
||||
|
||||
default :
|
||||
ret = MBEDTLS_ERR_CCM_BAD_INPUT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Format and fill AES key */
|
||||
for( i=0; i < (keybits/32) ; i++ )
|
||||
GET_UINT32_BE( ctx->ccm_key[i], key, 4*i );
|
||||
|
||||
/* include the appropriate instance name */
|
||||
#if defined (AES)
|
||||
ctx->hcryp_ccm.Instance = AES;
|
||||
#elif defined (AES1)
|
||||
ctx->hcryp_ccm.Instance = AES1;
|
||||
#else /* CRYP */
|
||||
ctx->hcryp_ccm.Instance = CRYP;
|
||||
#endif /* AES */
|
||||
|
||||
ctx->hcryp_ccm.Init.DataType = CRYP_DATATYPE_8B;
|
||||
ctx->hcryp_ccm.Init.pKey = ctx->ccm_key;
|
||||
ctx->hcryp_ccm.Init.pInitVect = NULL;
|
||||
ctx->hcryp_ccm.Init.Algorithm = CRYP_AES_CCM;
|
||||
ctx->hcryp_ccm.Init.Header = NULL;
|
||||
ctx->hcryp_ccm.Init.HeaderSize = 0;
|
||||
ctx->hcryp_ccm.Init.B0 = NULL;
|
||||
ctx->hcryp_ccm.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||
|
||||
if (HAL_CRYP_Init(&ctx->hcryp_ccm) != HAL_OK)
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* allow multi-context of CRYP : save context */
|
||||
ctx->ctx_save_cr = ctx->hcryp_ccm.Instance->CR;
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &cryp_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Free context
|
||||
*/
|
||||
void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
__disable_irq();
|
||||
if (cryp_context_count > 0)
|
||||
cryp_context_count--;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ( cryp_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_free( &cryp_mutex );
|
||||
cryp_mutex_started = 0;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
__enable_irq();
|
||||
|
||||
/* Shut down CRYP on last context */
|
||||
if ( cryp_context_count == 0 )
|
||||
HAL_CRYP_DeInit( &ctx->hcryp_ccm );
|
||||
|
||||
cryp_zeroize( (void*)ctx, sizeof(mbedtls_ccm_context) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticated encryption or decryption
|
||||
*/
|
||||
static int ccm_auth_crypt( mbedtls_ccm_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,
|
||||
unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char i;
|
||||
unsigned char q;
|
||||
size_t len_left;
|
||||
unsigned int j;
|
||||
|
||||
__ALIGN_BEGIN unsigned char b0[16] __ALIGN_END; /* Formatting of B0 */
|
||||
__ALIGN_BEGIN uint32_t b0_32B[4] __ALIGN_END; /* B0 data swapping */
|
||||
unsigned char *b1_padded_addr = NULL; /* Formatting of B1 */
|
||||
unsigned char *b1_aligned_addr = NULL;
|
||||
size_t b1_length; /* B1 with padding */
|
||||
uint8_t b1_padding; /* B1 word alignement */
|
||||
|
||||
__ALIGN_BEGIN uint8_t mac[16] __ALIGN_END; /* temporary mac */
|
||||
|
||||
|
||||
CCM_VALIDATE_RET( mode != CCM_ENCRYPT || mode != CCM_DECRYPT );
|
||||
|
||||
/*
|
||||
* Check length requirements: SP800-38C A.1
|
||||
* Additional requirement: a < 2^16 - 2^8 to simplify the code.
|
||||
* 'length' checked later (when writing it to the first block)
|
||||
*
|
||||
* Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
|
||||
*/
|
||||
|
||||
/* tag_len, aka t, is an element of {4, 6, 8, 10, 12, 14, 16} */
|
||||
if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
/* Also implies q is within bounds */
|
||||
/* iv_len, aka n, is an element of {7, 8, 9, 10, 11, 12, 13} */
|
||||
if( iv_len < 7 || iv_len > 13 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
/* add_len, aka a, a < 2^16 - 2^8 */
|
||||
if( add_len > 0xFF00 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
/* The octet length of Q, denoted q */
|
||||
q = 15 - (unsigned char) iv_len;
|
||||
|
||||
/*
|
||||
* First block B_0:
|
||||
* 0 .. 0 flags
|
||||
* 1 .. iv_len nonce (aka iv)
|
||||
* iv_len+1 .. 15 length
|
||||
*
|
||||
* With flags as (bits):
|
||||
* 7 0
|
||||
* 6 add present?
|
||||
* 5 .. 3 (t - 2) / 2
|
||||
* 2 .. 0 q - 1
|
||||
*/
|
||||
memset( b0, 0, 16 );
|
||||
if( add_len > 0 ) b0[0] |= 0x40;
|
||||
b0[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
|
||||
b0[0] |= q - 1;
|
||||
|
||||
/* Nonce concatenation */
|
||||
memcpy( b0 + 1, iv, iv_len );
|
||||
|
||||
/* Data length concatenation */
|
||||
for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
|
||||
b0[15-i] = (unsigned char)( len_left & 0xFF );
|
||||
|
||||
if( len_left > 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
}
|
||||
|
||||
/* Protect context access */
|
||||
/* (it may occur at a same time in a threaded environment) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* allow multi-context of CRYP use: restore context */
|
||||
ctx->hcryp_ccm.Instance->CR = ctx->ctx_save_cr;
|
||||
/*
|
||||
* If there is additional data, update with
|
||||
* add_len, add, 0 (padding to a block boundary)
|
||||
*/
|
||||
if( add_len > 0 )
|
||||
{
|
||||
/* Extra bytes to deal with data padding such that */
|
||||
/* the resulting string can be partitioned into words */
|
||||
b1_padding = ((add_len + H_LENGTH) % 4);
|
||||
b1_length = add_len + H_LENGTH + b1_padding;
|
||||
|
||||
/* reserve extra bytes to deal with 4-bytes memory alignement */
|
||||
b1_padded_addr =
|
||||
mbedtls_calloc( 1, b1_length + 3);
|
||||
|
||||
if( b1_padded_addr == NULL )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* move up to a 4-bytes aligned address in the reserved memory chuck */
|
||||
b1_aligned_addr =
|
||||
(unsigned char*) ((uint32_t)(b1_padded_addr + 3) & 0xFFFFFFFC);
|
||||
|
||||
/* Header length */
|
||||
b1_aligned_addr[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
|
||||
b1_aligned_addr[1] = (unsigned char)( ( add_len ) & 0xFF );
|
||||
|
||||
/* data concatenation */
|
||||
memcpy( b1_aligned_addr + H_LENGTH, add, add_len );
|
||||
|
||||
/* blocks (B) associated to the Associated Data (A) */
|
||||
ctx->hcryp_ccm.Init.Header = (uint32_t *)b1_aligned_addr;
|
||||
|
||||
ctx->hcryp_ccm.Init.HeaderSize = b1_length/4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->hcryp_ccm.Init.Header = NULL;
|
||||
ctx->hcryp_ccm.Init.HeaderSize = 0;
|
||||
}
|
||||
|
||||
/* first authentication block */
|
||||
for( j=0; j < 4; j++ )
|
||||
GET_UINT32_BE( b0_32B[j], b0, 4*j );
|
||||
|
||||
ctx->hcryp_ccm.Init.B0 = b0_32B;
|
||||
|
||||
/* reconfigure the CRYP */
|
||||
if ( HAL_CRYP_SetConfig( &ctx->hcryp_ccm, &ctx->hcryp_ccm.Init ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto free_block;
|
||||
}
|
||||
|
||||
/* blocks (B) associated to the plaintext message (P) */
|
||||
if( mode == CCM_DECRYPT )
|
||||
{
|
||||
if ( HAL_CRYP_Decrypt( &ctx->hcryp_ccm,
|
||||
(uint32_t *)input,
|
||||
length,
|
||||
(uint32_t *)output,
|
||||
ST_CRYP_TIMEOUT ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto free_block;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HAL_CRYP_Encrypt( &ctx->hcryp_ccm,
|
||||
(uint32_t *)input,
|
||||
length,
|
||||
(uint32_t *)output,
|
||||
ST_CRYP_TIMEOUT ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto free_block;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tag has a variable length */
|
||||
memset(mac, 0, sizeof(mac));
|
||||
|
||||
/* Generate the authentication TAG */
|
||||
if ( HAL_CRYPEx_AESCCM_GenerateAuthTAG( &ctx->hcryp_ccm,
|
||||
(uint32_t *)mac,
|
||||
ST_CRYP_TIMEOUT )!= HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto free_block;
|
||||
}
|
||||
|
||||
memcpy( tag, mac, tag_len );
|
||||
|
||||
/* allow multi-context of CRYP : save context */
|
||||
ctx->ctx_save_cr = ctx->hcryp_ccm.Instance->CR;
|
||||
|
||||
free_block:
|
||||
if( add_len > 0 )
|
||||
mbedtls_free( b1_padded_addr );
|
||||
|
||||
exit:
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &cryp_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticated encryption
|
||||
*/
|
||||
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, 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,
|
||||
unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
CCM_VALIDATE_RET( ctx != NULL );
|
||||
CCM_VALIDATE_RET( iv != NULL );
|
||||
CCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
CCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||
CCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||
return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
|
||||
add, add_len, input, output, tag, tag_len ) );
|
||||
}
|
||||
|
||||
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, 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,
|
||||
unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
CCM_VALIDATE_RET( ctx != NULL );
|
||||
CCM_VALIDATE_RET( iv != NULL );
|
||||
CCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
CCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||
CCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||
if( tag_len == 0 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add,
|
||||
add_len, input, output, tag, tag_len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticated decryption
|
||||
*/
|
||||
int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, 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,
|
||||
const unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
int ret;
|
||||
unsigned char check_tag[16];
|
||||
unsigned char i;
|
||||
int diff;
|
||||
|
||||
CCM_VALIDATE_RET( ctx != NULL );
|
||||
CCM_VALIDATE_RET( iv != NULL );
|
||||
CCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
CCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||
CCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||
|
||||
if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
|
||||
iv, iv_len, add, add_len,
|
||||
input, output, check_tag, tag_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Check tag in "constant-time" */
|
||||
for( diff = 0, i = 0; i < tag_len; i++ )
|
||||
diff |= tag[i] ^ check_tag[i];
|
||||
|
||||
if( diff != 0 )
|
||||
{
|
||||
mbedtls_platform_zeroize( output, length );
|
||||
return( MBEDTLS_ERR_CCM_AUTH_FAILED );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, 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,
|
||||
const unsigned char *tag, size_t tag_len )
|
||||
{
|
||||
CCM_VALIDATE_RET( ctx != NULL );
|
||||
CCM_VALIDATE_RET( iv != NULL );
|
||||
CCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
CCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||
CCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
|
||||
|
||||
if( tag_len == 0 )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
|
||||
return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add,
|
||||
add_len, input, output, tag, tag_len ) );
|
||||
}
|
||||
|
||||
#endif /*MBEDTLS_CCM_ALT*/
|
||||
#endif /*MBEDTLS_CCM_C*/
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* \file ccm.h
|
||||
*
|
||||
* \brief This file provides an API for the CCM authenticated encryption
|
||||
* mode for block ciphers.
|
||||
*
|
||||
* CCM combines Counter mode encryption with CBC-MAC authentication
|
||||
* for 128-bit block ciphers.
|
||||
*
|
||||
* Input to CCM includes the following elements:
|
||||
* <ul><li>Payload - data that is both authenticated and encrypted.</li>
|
||||
* <li>Associated data (Adata) - data that is authenticated but not
|
||||
* encrypted, For example, a header.</li>
|
||||
* <li>Nonce - A unique value that is assigned to the payload and the
|
||||
* associated data.</li></ul>
|
||||
*
|
||||
* Definition of CCM:
|
||||
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
|
||||
* RFC 3610 "Counter with CBC-MAC (CCM)"
|
||||
*
|
||||
* Related:
|
||||
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
|
||||
*
|
||||
* Definition of CCM*:
|
||||
* IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks
|
||||
* Integer representation is fixed most-significant-octet-first order and
|
||||
* the representation of octets is most-significant-bit-first order. This is
|
||||
* consistent with RFC 3610.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
||||
* Copyright (C) 2019-2020 STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements ST CCM HW services based on API from mbed TLS
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef MBEDTLS_CCM_ALT_H
|
||||
#define MBEDTLS_CCM_ALT_H
|
||||
|
||||
#if defined(MBEDTLS_CCM_ALT)
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "cryp_stm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief The CCM context-type definition. The CCM context is passed
|
||||
* to the APIs called.
|
||||
*/
|
||||
typedef struct mbedtls_ccm_context
|
||||
{
|
||||
/* Encryption/Decryption key */
|
||||
uint32_t ccm_key[8];
|
||||
|
||||
CRYP_HandleTypeDef hcryp_ccm; /* CCM context */
|
||||
uint32_t ctx_save_cr; /* save context for multi-context */
|
||||
}
|
||||
mbedtls_ccm_context;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CCM_ALT */
|
||||
#endif /* MBEDTLS_CCM_ALT_H */
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020 STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements ST shared CRYP services based on API from mbed TLS
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AES_ALT) || defined(MBEDTLS_CCM_ALT) || defined(MBEDTLS_GCM_ALT)
|
||||
|
||||
#include "cryp_stm32.h"
|
||||
|
||||
|
||||
/* Variables -----------------------------------------------------------------*/
|
||||
/* Mutex protection because of one Crypt Hw instance is shared over several */
|
||||
/* mode of operations (AES, GCM, CCM implementations may be enabled together) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_threading_mutex_t cryp_mutex;
|
||||
unsigned char cryp_mutex_started = 0;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
unsigned int cryp_context_count = 0;
|
||||
|
||||
/* Functions -----------------------------------------------------------------*/
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
void cryp_zeroize(void *v, size_t n)
|
||||
{
|
||||
volatile unsigned char *p = (unsigned char *)v;
|
||||
while (n--) {
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* HAL function that should be implemented in the user file */
|
||||
/**
|
||||
* @brief CRYP MSP Initialization
|
||||
* This function configures the hardware resources used in this example:
|
||||
* - Peripherals clock enable
|
||||
* @param hcryp: CRYP handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
|
||||
{
|
||||
#if defined (AES)
|
||||
/* Enable CRYP clock */
|
||||
__HAL_RCC_AES_CLK_ENABLE();
|
||||
|
||||
/* Force the CRYP Peripheral Clock Reset */
|
||||
__HAL_RCC_AES_FORCE_RESET();
|
||||
|
||||
/* Release the CRYP Peripheral Clock Reset */
|
||||
__HAL_RCC_AES_RELEASE_RESET();
|
||||
#elif defined (AES1)
|
||||
/* Enable CRYP clock */
|
||||
__HAL_RCC_AES1_CLK_ENABLE();
|
||||
|
||||
/* Force the CRYP Peripheral Clock Reset */
|
||||
__HAL_RCC_AES1_FORCE_RESET();
|
||||
|
||||
/* Release the CRYP Peripheral Clock Reset */
|
||||
__HAL_RCC_AES1_RELEASE_RESET();
|
||||
#else /* CRYP */
|
||||
/* Enable CRYP clock */
|
||||
__HAL_RCC_CRYP_CLK_ENABLE();
|
||||
|
||||
/* Force the CRYP Peripheral Clock Reset */
|
||||
__HAL_RCC_CRYP_FORCE_RESET();
|
||||
|
||||
/* Release the CRYP Peripheral Clock Reset */
|
||||
__HAL_RCC_CRYP_RELEASE_RESET();
|
||||
#endif /* AES */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CRYP MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example:
|
||||
* - Disable the Peripherals clock
|
||||
* @param hcryp: CRYP handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
|
||||
{
|
||||
#if defined (AES)
|
||||
__HAL_RCC_AES_CLK_DISABLE();
|
||||
#elif defined (AES1)
|
||||
__HAL_RCC_AES1_CLK_DISABLE();
|
||||
#else /* CRYP */
|
||||
/* Disable CRYP clock */
|
||||
__HAL_RCC_CRYP_CLK_DISABLE();
|
||||
#endif /* AES */
|
||||
}
|
||||
#endif /* MBEDTLS_AES_ALT or MBEDTLS_CCM_ALT or MBEDTLS_GCM_ALT */
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Header file of mbed TLS HW crypto (CRYP) implementation.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020 STMicroelectronics, All Rights Reserved
|
||||
*
|
||||
* This software component is licensed by ST under Apache 2.0 license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* https://opensource.org/licenses/Apache-2.0
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __CRYP_H
|
||||
#define __CRYP_H
|
||||
|
||||
#if defined(MBEDTLS_AES_ALT) || defined(MBEDTLS_CCM_ALT) || defined(MBEDTLS_GCM_ALT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* include the appropriate header file */
|
||||
#include "stm32<xxxxx>_hal.h"
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
#include "mbedtls/threading.h"
|
||||
#endif
|
||||
|
||||
/* macros --------------------------------------------------------------------*/
|
||||
/*
|
||||
* 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
|
||||
|
||||
/* constants -----------------------------------------------------------------*/
|
||||
#define ST_CRYP_TIMEOUT 1000 /* timeout (in ms) for the crypto processor */
|
||||
|
||||
/* defines -------------------------------------------------------------------*/
|
||||
/* AES 192 bits key length may be optional in the HW */
|
||||
#if defined CRYP_KEYSIZE_192B
|
||||
#define USE_AES_KEY192 1
|
||||
#else
|
||||
#define USE_AES_KEY192 0
|
||||
#endif /* USE_AES_KEY192 */
|
||||
|
||||
/* variables -----------------------------------------------------------------*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
extern mbedtls_threading_mutex_t cryp_mutex;
|
||||
extern unsigned char cryp_mutex_started;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
extern unsigned int cryp_context_count;
|
||||
|
||||
/* functions prototypes ------------------------------------------------------*/
|
||||
extern void cryp_zeroize(void *v, size_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_AES_ALT or MBEDTLS_CCM_ALT or MBEDTLS_GCM_ALT */
|
||||
#endif /*__CRYP_H */
|
||||
+493
@@ -0,0 +1,493 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020 STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements ST GCM HW services based on API from mbed TLS
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "mbedtls/gcm.h"
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
#if defined(MBEDTLS_GCM_ALT)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
|
||||
/* Parameter validation macros */
|
||||
#define GCM_VALIDATE_RET( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
|
||||
#define GCM_VALIDATE( cond ) \
|
||||
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define IV_LENGTH 12U /* implementations restrict support to 96 bits */
|
||||
|
||||
#if !defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||
#define AAD_WORD_ALIGN 4U /* implementations may restrict AAD support on */
|
||||
/* a buffer multiple of 32 bits */
|
||||
#endif
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialize a context
|
||||
*/
|
||||
void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
|
||||
{
|
||||
GCM_VALIDATE( ctx != NULL );
|
||||
|
||||
__disable_irq();
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* mutex cannot be initialized twice */
|
||||
if ( !cryp_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_init( &cryp_mutex );
|
||||
cryp_mutex_started = 1;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
cryp_context_count++;
|
||||
__enable_irq();
|
||||
|
||||
cryp_zeroize( (void*)ctx, sizeof(mbedtls_gcm_context) );
|
||||
}
|
||||
|
||||
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
|
||||
mbedtls_cipher_id_t cipher,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits )
|
||||
{
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( key != NULL );
|
||||
|
||||
/* Protect context access */
|
||||
/* (it may occur at a same time in a threaded environment) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
switch (keybits)
|
||||
{
|
||||
case 128:
|
||||
ctx->hcryp_gcm.Init.KeySize = CRYP_KEYSIZE_128B;
|
||||
break;
|
||||
|
||||
case 192:
|
||||
#if ( USE_AES_KEY192 == 1 )
|
||||
ctx->hcryp_gcm.Init.KeySize = CRYP_KEYSIZE_192B;
|
||||
break;
|
||||
#else
|
||||
ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||
goto exit;
|
||||
#endif /* USE_AES_KEY192 */
|
||||
|
||||
case 256:
|
||||
ctx->hcryp_gcm.Init.KeySize = CRYP_KEYSIZE_256B;
|
||||
break;
|
||||
|
||||
default :
|
||||
ret = MBEDTLS_ERR_GCM_BAD_INPUT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Format and fill AES key */
|
||||
for( i=0; i < (keybits/32); i++ )
|
||||
GET_UINT32_BE( ctx->gcm_key[i], key, 4*i );
|
||||
|
||||
/* include the appropriate instance name */
|
||||
#if defined (AES)
|
||||
ctx->hcryp_gcm.Instance = AES;
|
||||
ctx->hcryp_gcm.Init.Algorithm = CRYP_AES_GCM_GMAC;
|
||||
#elif defined (AES1)
|
||||
ctx->hcryp_gcm.Instance = AES1;
|
||||
ctx->hcryp_gcm.Init.Algorithm = CRYP_AES_GCM_GMAC;
|
||||
#else /* CRYP */
|
||||
ctx->hcryp_gcm.Instance = CRYP;
|
||||
ctx->hcryp_gcm.Init.Algorithm = CRYP_AES_GCM;
|
||||
#endif /* AES */
|
||||
|
||||
ctx->hcryp_gcm.Init.DataType = CRYP_DATATYPE_8B;
|
||||
ctx->hcryp_gcm.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||
ctx->hcryp_gcm.Init.pKey = ctx->gcm_key;
|
||||
|
||||
if ( HAL_CRYP_Init( &ctx->hcryp_gcm ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* allow multi-context of CRYP : save context */
|
||||
ctx->ctx_save_cr = ctx->hcryp_gcm.Instance->CR;
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &cryp_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
|
||||
int mode,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len )
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
__ALIGN_BEGIN static uint32_t iv_32B[4] __ALIGN_END;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( mode != MBEDTLS_GCM_ENCRYPT || mode != MBEDTLS_GCM_DECRYPT );
|
||||
GCM_VALIDATE_RET( iv != NULL );
|
||||
GCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
|
||||
/* IV and AD are limited to 2^64 bits, so 2^61 bytes */
|
||||
/* IV is not allowed to be zero length */
|
||||
if( iv_len == 0 ||
|
||||
( (uint64_t) iv_len ) >> 61 != 0 ||
|
||||
( (uint64_t) add_len ) >> 61 != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_GCM_BAD_INPUT );
|
||||
}
|
||||
|
||||
/* implementation restrict support to the length of 96 bits */
|
||||
if( IV_LENGTH != iv_len )
|
||||
{
|
||||
return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
|
||||
}
|
||||
|
||||
#if !defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||
/* implementation restrict support to a buffer multiple of 32 bits */
|
||||
if ((add_len % AAD_WORD_ALIGN) != 0U)
|
||||
{
|
||||
return( MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Protect context access */
|
||||
/* (it may occur at a same time in a threaded environment) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
if ( HAL_CRYP_Init( &ctx->hcryp_gcm ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* allow multi-context of CRYP use: restore context */
|
||||
ctx->hcryp_gcm.Instance->CR = ctx->ctx_save_cr;
|
||||
|
||||
ctx->mode = mode;
|
||||
ctx->len = 0;
|
||||
|
||||
/* Set IV with invert endianness */
|
||||
for( i=0; i < 3; i++ )
|
||||
GET_UINT32_BE( iv_32B[i], iv, 4*i );
|
||||
|
||||
/* According to NIST specification, the counter value is 0x2 when
|
||||
processing the first block of payload */
|
||||
iv_32B[3] = 0x00000002;
|
||||
|
||||
ctx->hcryp_gcm.Init.pInitVect = iv_32B;
|
||||
|
||||
if ( add_len > 0 )
|
||||
{
|
||||
ctx->hcryp_gcm.Init.Header = (uint32_t *)add;
|
||||
#if defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||
/* header buffer in byte length */
|
||||
ctx->hcryp_gcm.Init.HeaderSize = (uint32_t)add_len;
|
||||
#else
|
||||
/* header buffer in word length */
|
||||
ctx->hcryp_gcm.Init.HeaderSize = (uint32_t)(add_len/AAD_WORD_ALIGN);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->hcryp_gcm.Init.Header = NULL;
|
||||
ctx->hcryp_gcm.Init.HeaderSize = 0;
|
||||
}
|
||||
|
||||
#if defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||
/* Additional Authentication Data in bytes unit */
|
||||
ctx->hcryp_gcm.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
|
||||
#endif
|
||||
|
||||
/* Do not Allow IV reconfiguration at every gcm update */
|
||||
ctx->hcryp_gcm.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
|
||||
|
||||
/* reconfigure the CRYP */
|
||||
if ( HAL_CRYP_SetConfig( &ctx->hcryp_gcm, &ctx->hcryp_gcm.Init ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* allow multi-context of CRYP : save context */
|
||||
ctx->ctx_save_cr = ctx->hcryp_gcm.Instance->CR;
|
||||
|
||||
exit:
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &cryp_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
|
||||
size_t length,
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
|
||||
if( output > input && (size_t) ( output - input ) < length )
|
||||
return( MBEDTLS_ERR_GCM_BAD_INPUT );
|
||||
|
||||
/* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
|
||||
* Also check for possible overflow */
|
||||
if( ( (ctx->len + length) < ctx->len ) ||
|
||||
( (uint64_t)(ctx->len + length) > 0xFFFFFFFE0ull ) )
|
||||
{
|
||||
return( MBEDTLS_ERR_GCM_BAD_INPUT );
|
||||
}
|
||||
|
||||
/* Protect context access */
|
||||
/* (it may occur at a same time in a threaded environment) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* allow multi-context of CRYP use: restore context */
|
||||
ctx->hcryp_gcm.Instance->CR = ctx->ctx_save_cr;
|
||||
|
||||
ctx->len += length;
|
||||
|
||||
if( ctx->mode == MBEDTLS_GCM_DECRYPT )
|
||||
{
|
||||
if ( HAL_CRYP_Decrypt( &ctx->hcryp_gcm,
|
||||
(uint32_t *)input,
|
||||
length,
|
||||
(uint32_t *)output,
|
||||
ST_CRYP_TIMEOUT ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HAL_CRYP_Encrypt( &ctx->hcryp_gcm,
|
||||
(uint32_t *)input,
|
||||
length,
|
||||
(uint32_t *)output,
|
||||
ST_CRYP_TIMEOUT ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* allow multi-context of CRYP : save context */
|
||||
ctx->ctx_save_cr = ctx->hcryp_gcm.Instance->CR;
|
||||
|
||||
exit:
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &cryp_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
|
||||
unsigned char *tag,
|
||||
size_t tag_len )
|
||||
{
|
||||
int ret = 0;
|
||||
__ALIGN_BEGIN uint8_t mac[16] __ALIGN_END; /* temporary mac */
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( tag != NULL );
|
||||
|
||||
if( tag_len > 16 || tag_len < 4 )
|
||||
return( MBEDTLS_ERR_GCM_BAD_INPUT );
|
||||
|
||||
/* Protect context access */
|
||||
/* (it may occur at a same time in a threaded environment) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &cryp_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* allow multi-context of CRYP use: restore context */
|
||||
ctx->hcryp_gcm.Instance->CR = ctx->ctx_save_cr;
|
||||
|
||||
/* Tag has a variable length */
|
||||
memset(mac, 0, sizeof(mac));
|
||||
|
||||
/* Generate the authentication TAG */
|
||||
if ( HAL_CRYPEx_AESGCM_GenerateAuthTAG( &ctx->hcryp_gcm,
|
||||
(uint32_t *)mac,
|
||||
ST_CRYP_TIMEOUT )!= HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy( tag, mac, tag_len );
|
||||
|
||||
/* allow multi-context of CRYP : save context */
|
||||
ctx->ctx_save_cr = ctx->hcryp_gcm.Instance->CR;
|
||||
|
||||
exit:
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &cryp_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_gcm_crypt_and_tag( mbedtls_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 ret;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( iv != NULL );
|
||||
GCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
GCM_VALIDATE_RET( tag != NULL );
|
||||
|
||||
if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_gcm_auth_decrypt( mbedtls_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 ret;
|
||||
unsigned char check_tag[16];
|
||||
size_t i;
|
||||
int diff;
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( iv != NULL );
|
||||
GCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
GCM_VALIDATE_RET( tag != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || input != NULL );
|
||||
GCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
|
||||
if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
|
||||
iv, iv_len, add, add_len,
|
||||
input, output, tag_len, check_tag ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Check tag in "constant-time" */
|
||||
for( diff = 0, i = 0; i < tag_len; i++ )
|
||||
diff |= tag[i] ^ check_tag[i];
|
||||
|
||||
if( diff != 0 )
|
||||
{
|
||||
mbedtls_platform_zeroize( output, length );
|
||||
return( MBEDTLS_ERR_GCM_AUTH_FAILED );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
__disable_irq();
|
||||
if ( cryp_context_count > 0 )
|
||||
cryp_context_count--;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ( cryp_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_free( &cryp_mutex );
|
||||
cryp_mutex_started = 0;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
__enable_irq();
|
||||
|
||||
/* Shut down CRYP on last context */
|
||||
if ( cryp_context_count == 0 )
|
||||
HAL_CRYP_DeInit( &ctx->hcryp_gcm );
|
||||
|
||||
cryp_zeroize( (void*)ctx, sizeof(mbedtls_gcm_context) );
|
||||
}
|
||||
|
||||
#endif /*MBEDTLS_GCM_ALT*/
|
||||
#endif /*MBEDTLS_GCM_C*/
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* \file gcm_alt.h.h
|
||||
*
|
||||
* \brief This file contains GCM definitions and functions.
|
||||
*
|
||||
* The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
|
||||
* in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
|
||||
* (GCM), Natl. Inst. Stand. Technol.</em>
|
||||
*
|
||||
* For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
|
||||
* Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
||||
* Copyright (C) 2019-2020 STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements ST GCM HW services based on API from mbed TLS
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef MBEDTLS_GCM_ALT_H
|
||||
#define MBEDTLS_GCM_ALT_H
|
||||
|
||||
#if defined(MBEDTLS_GCM_ALT)
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "cryp_stm32.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*
|
||||
*/
|
||||
typedef struct mbedtls_gcm_context
|
||||
{
|
||||
/* Encryption/Decryption key */
|
||||
uint32_t gcm_key[8];
|
||||
|
||||
CRYP_HandleTypeDef hcryp_gcm; /* HW driver handle */
|
||||
uint32_t ctx_save_cr; /* save context for multi-context */
|
||||
uint64_t len; /* total length of the encrypted data. */
|
||||
int mode; /* The operation to perform:
|
||||
#MBEDTLS_GCM_ENCRYPT or
|
||||
#MBEDTLS_GCM_DECRYPT. */
|
||||
}
|
||||
mbedtls_gcm_context;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Uncomment if ADD (Additional Authentication Data) may have not a length */
|
||||
/* over a multiple of 32 bits (Hw implementation dependance) */
|
||||
#define STM32_AAD_ANY_LENGTH_SUPPORT
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_GCM_ALT */
|
||||
#endif /* MBEDTLS_GCM_ALT_H */
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020, STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements ST shared HASH services based on API from mbed TLS
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_MD5_ALT)
|
||||
|
||||
#include "hash_stm32.h"
|
||||
|
||||
/* Variables -----------------------------------------------------------------*/
|
||||
/* Mutex protection because of one Hash Hw instance is shared over several */
|
||||
/* algorithms (SHA-1, SHA-256, MD5 implementations may be enabled together) */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_threading_mutex_t hash_mutex;
|
||||
unsigned char hash_mutex_started = 0;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
unsigned int hash_context_count = 0;
|
||||
|
||||
/* Functions -----------------------------------------------------------------*/
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
void hash_zeroize( void *v, size_t n )
|
||||
{
|
||||
volatile unsigned char *p = (unsigned char *)v;
|
||||
while (n--)
|
||||
{
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* HAL function that should be implemented in the user file */
|
||||
/**
|
||||
* @brief HASH MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hhash: HASH handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_HASH_MspInit(HASH_HandleTypeDef* hhash)
|
||||
{
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_HASH_CLK_ENABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HASH MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hhash: HASH handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_HASH_MspDeInit(HASH_HandleTypeDef* hhash)
|
||||
{
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_HASH_CLK_DISABLE();
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT or MBEDTLS_SHA256_ALT or MBEDTLS_MD5_ALT */
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Header file of mbed TLS HW crypto (HASH) implementation.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019 STMicroelectronics, All Rights Reserved
|
||||
*
|
||||
* This software component is licensed by ST under Apache 2.0 license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* https://opensource.org/licenses/Apache-2.0
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __HASH_H
|
||||
#define __HASH_H
|
||||
|
||||
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_MD5_ALT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* include the appropriate header file */
|
||||
#include "stm32<xxxxx>_hal.h"
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
#include "mbedtls/threading.h"
|
||||
#endif
|
||||
|
||||
/* macros --------------------------------------------------------------------*/
|
||||
/* constants -----------------------------------------------------------------*/
|
||||
#define ST_HASH_TIMEOUT ((uint32_t) 1000) /* TO in ms for the hash processor */
|
||||
|
||||
/* defines -------------------------------------------------------------------*/
|
||||
/* variables -----------------------------------------------------------------*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
extern mbedtls_threading_mutex_t hash_mutex;
|
||||
extern unsigned char hash_mutex_started;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
extern unsigned int hash_context_count;
|
||||
|
||||
/* functions prototypes ------------------------------------------------------*/
|
||||
extern void hash_zeroize(void *v, size_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT or MBEDTLS_SHA256_ALT or MBEDTLS_MD5_ALT */
|
||||
#endif /*__HASH_H */
|
||||
+291
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020, STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements STMicroelectronics MD5 with HW services based on API
|
||||
* from mbed TLS
|
||||
*/
|
||||
/*
|
||||
* The MD5 algorithm was designed by Ron Rivest in 1991.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc1321.txt
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "mbedtls/md5.h"
|
||||
|
||||
#if defined(MBEDTLS_MD5_C)
|
||||
#if defined(MBEDTLS_MD5_ALT)
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
#define MD5_VALIDATE_RET(cond) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MD5_BAD_INPUT_DATA )
|
||||
#define MD5_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
void mbedtls_md5_init( mbedtls_md5_context *ctx )
|
||||
{
|
||||
MD5_VALIDATE( ctx != NULL );
|
||||
|
||||
__disable_irq();
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* mutex cannot be initialized twice */
|
||||
if ( !hash_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_init( &hash_mutex );
|
||||
hash_mutex_started = 1;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
hash_context_count++;
|
||||
__enable_irq();
|
||||
|
||||
hash_zeroize( ctx, sizeof(mbedtls_md5_context) );
|
||||
}
|
||||
|
||||
void mbedtls_md5_free( mbedtls_md5_context *ctx )
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
__disable_irq();
|
||||
if ( hash_context_count > 0 )
|
||||
hash_context_count--;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ( hash_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_free( &hash_mutex );
|
||||
hash_mutex_started = 0;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
__enable_irq();
|
||||
|
||||
/* Shut down HASH on last context */
|
||||
if ( hash_context_count == 0 )
|
||||
HAL_HASH_DeInit( &ctx->hhash );
|
||||
|
||||
hash_zeroize( ctx, sizeof(mbedtls_md5_context) );
|
||||
}
|
||||
|
||||
void mbedtls_md5_clone( mbedtls_md5_context *dst,
|
||||
const mbedtls_md5_context *src )
|
||||
{
|
||||
MD5_VALIDATE( dst != NULL );
|
||||
MD5_VALIDATE( src != NULL );
|
||||
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
MD5_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* HASH Configuration */
|
||||
if ( HAL_HASH_DeInit( &ctx->hhash ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
ctx->hhash.Init.DataType = HASH_DATATYPE_8B;
|
||||
if ( HAL_HASH_Init( &ctx->hhash ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* save hw context */
|
||||
HAL_HASH_ContextSaving( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
|
||||
const unsigned char data[ST_MD5_BLOCK_SIZE] )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
MD5_VALIDATE_RET( ctx != NULL );
|
||||
MD5_VALIDATE_RET( (const unsigned char *)data != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* restore hw context */
|
||||
HAL_HASH_ContextRestoring( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
if ( HAL_HASH_MD5_Accmlt( &ctx->hhash,
|
||||
(uint8_t *) data,
|
||||
ST_MD5_BLOCK_SIZE ) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* save hw context */
|
||||
HAL_HASH_ContextSaving( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t currentlen = ilen;
|
||||
|
||||
MD5_VALIDATE_RET( ctx != NULL );
|
||||
MD5_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* restore hw context */
|
||||
HAL_HASH_ContextRestoring( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
if ( currentlen < (ST_MD5_BLOCK_SIZE - ctx->sbuf_len) )
|
||||
{
|
||||
/* only store input data in context buffer */
|
||||
memcpy( ctx->sbuf + ctx->sbuf_len, input, currentlen );
|
||||
ctx->sbuf_len += currentlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fill context buffer until ST_MD5_BLOCK_SIZE bytes, and process it */
|
||||
memcpy( ctx->sbuf + ctx->sbuf_len,
|
||||
input,
|
||||
(ST_MD5_BLOCK_SIZE - ctx->sbuf_len) );
|
||||
currentlen -= ( ST_MD5_BLOCK_SIZE - ctx->sbuf_len );
|
||||
|
||||
if ( HAL_HASH_MD5_Accmlt( &ctx->hhash,
|
||||
(uint8_t *)(ctx->sbuf),
|
||||
ST_MD5_BLOCK_SIZE ) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Process following input data
|
||||
with size multiple of ST_MD5_BLOCK_SIZE bytes */
|
||||
size_t iter = currentlen / ST_MD5_BLOCK_SIZE;
|
||||
if ( iter != 0 )
|
||||
{
|
||||
if ( HAL_HASH_MD5_Accmlt( &ctx->hhash,
|
||||
(uint8_t *)(input + ST_MD5_BLOCK_SIZE - ctx->sbuf_len),
|
||||
(iter * ST_MD5_BLOCK_SIZE)) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store only the remaining input data
|
||||
up to (ST_MD5_BLOCK_SIZE - 1) bytes */
|
||||
ctx->sbuf_len = currentlen % ST_MD5_BLOCK_SIZE;
|
||||
if ( ctx->sbuf_len != 0 )
|
||||
{
|
||||
memcpy( ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len );
|
||||
}
|
||||
}
|
||||
|
||||
/* save hw context */
|
||||
HAL_HASH_ContextSaving( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, unsigned char output[32] )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
MD5_VALIDATE_RET( ctx != NULL );
|
||||
MD5_VALIDATE_RET( (unsigned char *)output != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* restore hw context */
|
||||
HAL_HASH_ContextRestoring( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
/* Last accumulation for pending bytes in sbuf_len,
|
||||
then trig processing and get digest */
|
||||
if ( HAL_HASH_MD5_Accmlt_End( &ctx->hhash,
|
||||
ctx->sbuf,
|
||||
ctx->sbuf_len,
|
||||
output,
|
||||
ST_HASH_TIMEOUT ) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ctx->sbuf_len = 0;
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_MD5_ALT*/
|
||||
#endif /* MBEDTLS_MD5_C */
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* \file md5.h
|
||||
*
|
||||
* \brief MD5 message digest algorithm (hash function)
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use constitutes a
|
||||
* security risk. We recommend considering stronger message
|
||||
* digests instead.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020, STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements STMicroelectronics MD5 API with HW services based
|
||||
* on mbed TLS API
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MD5_ALT_H
|
||||
#define MBEDTLS_MD5_ALT_H
|
||||
|
||||
#if defined (MBEDTLS_MD5_ALT)
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "hash_stm32.h"
|
||||
|
||||
#ifndef MBEDTLS_ERR_MD5_BAD_INPUT_DATA
|
||||
#define MBEDTLS_ERR_MD5_BAD_INPUT_DATA -0x00AF
|
||||
#endif
|
||||
|
||||
#define ST_MD5_BLOCK_SIZE ((size_t) 64) /*!< HW handles 512 bits, ie 64 bytes */
|
||||
#define ST_MD5_NB_HASH_REG ((uint32_t)57) /*!< Number of HASH HW context Registers:
|
||||
CR + STR + IMR + CSR[54] */
|
||||
|
||||
/**
|
||||
* \brief MD5 context structure
|
||||
*
|
||||
* STMicroelectronics edition
|
||||
*/
|
||||
typedef struct mbedtls_md5_context
|
||||
{
|
||||
HASH_HandleTypeDef hhash; /*!< Handle of HASH HAL */
|
||||
uint8_t sbuf[ST_MD5_BLOCK_SIZE]; /*!< Buffer to store input data until ST_MD5_BLOCK_SIZE
|
||||
is reached, or until last input data is reached */
|
||||
uint8_t sbuf_len; /*!< Number of bytes stored in sbuf */
|
||||
uint32_t ctx_save_regs[ST_MD5_NB_HASH_REG];
|
||||
}
|
||||
mbedtls_md5_context;
|
||||
|
||||
|
||||
#endif /* MBEDTLS_MD5_ALT */
|
||||
|
||||
#endif /* MBEDTLS_MD5_ALT_H */
|
||||
+620
@@ -0,0 +1,620 @@
|
||||
/**
|
||||
* Portions COPYRIGHT 2018 STMicroelectronics, All Rights Reserved
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
*
|
||||
******************************************************************************
|
||||
* @file net_sockets_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief TCP/IP or UDP/IP networking template based on LwIP API, this file
|
||||
* need to be copied into the project tree and renamed to "net_sockets.c"
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2018 STMicroelectronics
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Apache 2.0 license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* https://opensource.org/licenses/Apache-2.0
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a template implmentation of the net_socket.c based on the LwIP
|
||||
* TCP/IP Stack.
|
||||
*
|
||||
*/
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#if defined(MBEDTLS_NET_C)
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "mbedtls/net_sockets.h"
|
||||
|
||||
/*
|
||||
* LwIP header files
|
||||
* make sure that the LwIP project config file, "lwipopts.h", is enabling the following flags
|
||||
* LWIP_TCP==1 : Enable TCP
|
||||
* LWIP_UDP==1 : Enable UDP
|
||||
* LWIP_DNS==1 : Enable DNS module (could be optional depending on the application)
|
||||
* LWIP_SOCKET==1 : Enable Socket API
|
||||
* LWIP_COMPAT_SOCKETS==1 : Enable BSD-style sockets functions
|
||||
* SO_REUSE==1 : Enable SO_REUSEADDR option
|
||||
*/
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#include "netif/ethernet.h"
|
||||
|
||||
/*
|
||||
* the ethernetif.h is the lowlevel driver configuration file
|
||||
* it should be available under the application Inc directory
|
||||
*/
|
||||
#include "ethernetif.h"
|
||||
|
||||
|
||||
#if (LWIP_DHCP == 0)
|
||||
#ifndef IP_ADDR
|
||||
#define IP_ADDR "192.168.1.1"
|
||||
#endif
|
||||
|
||||
#ifndef GW_ADDR
|
||||
#define GW_ADDR "192.168.1.0"
|
||||
#endif
|
||||
|
||||
#ifndef MASK_ADDR
|
||||
#define MASK_ADDR "255.255.255.0"
|
||||
#endif
|
||||
#else
|
||||
#define DHCP_TIMEOUT 10000
|
||||
#endif /* LWIP_DHCP == 0 */
|
||||
|
||||
static struct netif netif;
|
||||
static int initialized = 0;
|
||||
struct sockaddr_storage client_addr;
|
||||
|
||||
static int net_would_block( const mbedtls_net_context *ctx );
|
||||
/*
|
||||
* Initialize LwIP stack
|
||||
*/
|
||||
void mbedtls_net_init( mbedtls_net_context *ctx )
|
||||
{
|
||||
|
||||
ip4_addr_t addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
uint32_t start;
|
||||
uint8_t dhcp_status = 0;
|
||||
|
||||
ctx->fd = -1;
|
||||
|
||||
if (initialized != 0)
|
||||
return;
|
||||
|
||||
tcpip_init(NULL, NULL);
|
||||
|
||||
/* IP default settings, to be overridden by DHCP */
|
||||
#if (LWIP_DHCP == 1)
|
||||
ip_addr_set_zero_ip4(&addr);
|
||||
ip_addr_set_zero_ip4(&netmask);
|
||||
ip_addr_set_zero_ip4(&gw);
|
||||
#else
|
||||
ip4addr_aton(IP_ADDR, &addr);
|
||||
ip4addr_aton(GW_ADDR, &gw);
|
||||
ip4addr_aton(MASK_ADDR, &netmask);
|
||||
#endif
|
||||
/* regsiter the network interface
|
||||
* ethernetif_init() is implemented in the ethernetif.c file in the app
|
||||
* project. Please refer to the file "LwIP/src/netif/ethernetif_template.c"
|
||||
* */
|
||||
netif_add(&netif, &addr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);
|
||||
|
||||
/* register the default network interface. */
|
||||
netif_set_default(&netif);
|
||||
|
||||
if (netif_is_link_up(&netif))
|
||||
{
|
||||
netif_set_up(&netif);
|
||||
}
|
||||
else
|
||||
{
|
||||
netif_set_down(&netif);
|
||||
}
|
||||
#if (LWIP_DHCP == 1)
|
||||
dhcp_start(&netif);
|
||||
start = sys_now();
|
||||
|
||||
while(( dhcp_status == 0) && (sys_now() - start < DHCP_TIMEOUT))
|
||||
{
|
||||
/* check whether an IP address was assigned to the interface */
|
||||
dhcp_status = dhcp_supplied_address(&netif);
|
||||
}
|
||||
|
||||
if (dhcp_status == 0)
|
||||
{
|
||||
mbedtls_printf(" Failed to get ip address! Please check your network configuration.\n");
|
||||
/* infinite loop if the network intefaces fails to init */
|
||||
while (1) {};
|
||||
}
|
||||
else
|
||||
{
|
||||
dhcp_stop(&netif);
|
||||
#endif
|
||||
mbedtls_printf("\nIpAdress = %s\n", ip4addr_ntoa(&netif.ip_addr));
|
||||
initialized = 1;
|
||||
#if (LWIP_DHCP == 1)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Initiate a TCP connection with host:port and the given protocol
|
||||
*/
|
||||
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
|
||||
{
|
||||
int ret;
|
||||
struct addrinfo hints, *addr_list, *cur;
|
||||
|
||||
/* Do name resolution with both IPv6 and IPv4 */
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
|
||||
if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
|
||||
return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
|
||||
|
||||
/* Try the sockaddrs until a connection succeeds */
|
||||
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||
for( cur = addr_list; cur != NULL; cur = cur->ai_next )
|
||||
{
|
||||
ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
|
||||
cur->ai_protocol );
|
||||
if( ctx->fd < 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( connect( ctx->fd, cur->ai_addr, cur->ai_addrlen ) == 0 )
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
close( ctx->fd );
|
||||
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
|
||||
}
|
||||
|
||||
freeaddrinfo( addr_list );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a listening socket on bind_ip:port
|
||||
*/
|
||||
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
|
||||
{
|
||||
int n, ret;
|
||||
struct addrinfo hints, *addr_list, *cur;
|
||||
|
||||
/* Bind to IPv6 and/or IPv4, but only in the desired protocol */
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
if( bind_ip == NULL )
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
|
||||
return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
|
||||
|
||||
/* Try the sockaddrs until a binding succeeds */
|
||||
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||
for( cur = addr_list; cur != NULL; cur = cur->ai_next )
|
||||
{
|
||||
ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
|
||||
cur->ai_protocol );
|
||||
if( ctx->fd < 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
n = 1;
|
||||
if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *) &n, sizeof( n ) ) != 0 )
|
||||
{
|
||||
close( ctx->fd );
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( bind( ctx->fd, cur->ai_addr, cur->ai_addrlen ) != 0 )
|
||||
{
|
||||
close( ctx->fd );
|
||||
ret = MBEDTLS_ERR_NET_BIND_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Listen only makes sense for TCP */
|
||||
if( proto == MBEDTLS_NET_PROTO_TCP )
|
||||
{
|
||||
if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
|
||||
{
|
||||
close( ctx->fd );
|
||||
ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bind was successful */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo( addr_list );
|
||||
|
||||
return( ret );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the requested operation would be blocking on a non-blocking socket
|
||||
* and thus 'failed' with a negative return value.
|
||||
*
|
||||
* Note: on a blocking socket this function always returns 0!
|
||||
*/
|
||||
static int net_would_block( const mbedtls_net_context *ctx )
|
||||
{
|
||||
int err = errno;
|
||||
|
||||
/*
|
||||
* Never return 'WOULD BLOCK' on a non-blocking socket
|
||||
*/
|
||||
if( fcntl( ctx->fd, F_GETFL, O_NONBLOCK ) != O_NONBLOCK )
|
||||
{
|
||||
errno = err;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
switch( errno = err )
|
||||
{
|
||||
#if defined EAGAIN
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
return( 1 );
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept a connection from a remote client
|
||||
*/
|
||||
int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
|
||||
mbedtls_net_context *client_ctx,
|
||||
void *client_ip, size_t buf_size, size_t *ip_len )
|
||||
{
|
||||
int ret;
|
||||
int type;
|
||||
|
||||
struct sockaddr_storage client_addr;
|
||||
|
||||
socklen_t n = (socklen_t) sizeof( client_addr );
|
||||
socklen_t type_len = (socklen_t) sizeof( type );
|
||||
|
||||
|
||||
/* Is this a TCP or UDP socket? */
|
||||
if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
|
||||
(void *) &type, &type_len ) != 0 ||
|
||||
( type != SOCK_STREAM && type != SOCK_DGRAM ) )
|
||||
{
|
||||
return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
|
||||
}
|
||||
|
||||
if( type == SOCK_STREAM )
|
||||
{
|
||||
/* TCP: actual accept() */
|
||||
ret = client_ctx->fd = (int) accept( bind_ctx->fd,
|
||||
(struct sockaddr *) &client_addr, &n );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* UDP: wait for a message, but keep it in the queue */
|
||||
char buf[1] = { 0 };
|
||||
|
||||
ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
|
||||
(struct sockaddr *) &client_addr, &n );
|
||||
|
||||
}
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
if( net_would_block( bind_ctx ) != 0 )
|
||||
return( MBEDTLS_ERR_SSL_WANT_READ );
|
||||
|
||||
return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
|
||||
}
|
||||
|
||||
/* UDP: hijack the listening socket to communicate with the client,
|
||||
* then bind a new socket to accept new connections */
|
||||
if( type != SOCK_STREAM )
|
||||
{
|
||||
struct sockaddr_storage local_addr;
|
||||
int one = 1;
|
||||
|
||||
if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
|
||||
return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
|
||||
|
||||
client_ctx->fd = bind_ctx->fd;
|
||||
bind_ctx->fd = -1; /* In case we exit early */
|
||||
|
||||
n = sizeof( struct sockaddr_storage );
|
||||
if( getsockname( client_ctx->fd,
|
||||
(struct sockaddr *) &local_addr, &n ) != 0 ||
|
||||
( bind_ctx->fd = (int) socket( local_addr.ss_family,
|
||||
SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
|
||||
setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *) &one, sizeof( one ) ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_NET_SOCKET_FAILED );
|
||||
}
|
||||
|
||||
if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_NET_BIND_FAILED );
|
||||
}
|
||||
}
|
||||
|
||||
if( client_ip != NULL )
|
||||
{
|
||||
if( client_addr.ss_family == AF_INET )
|
||||
{
|
||||
#if LWIP_IPV4
|
||||
struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
|
||||
*ip_len = sizeof( addr4->sin_addr.s_addr );
|
||||
|
||||
if( buf_size < *ip_len )
|
||||
return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
|
||||
|
||||
memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LWIP_IPV6
|
||||
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
|
||||
*ip_len = sizeof( addr6->sin6_addr.s6_addr );
|
||||
|
||||
if( buf_size < *ip_len )
|
||||
return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
|
||||
|
||||
memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the socket blocking or non-blocking
|
||||
*/
|
||||
int mbedtls_net_set_block( mbedtls_net_context *ctx )
|
||||
{
|
||||
/* LwIP doesn't currently support it */
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
|
||||
{
|
||||
|
||||
return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) | O_NONBLOCK ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if data is available on the socket
|
||||
*/
|
||||
|
||||
int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
|
||||
{
|
||||
int ret;
|
||||
struct timeval tv;
|
||||
|
||||
fd_set read_fds;
|
||||
fd_set write_fds;
|
||||
|
||||
int fd = ctx->fd;
|
||||
|
||||
if( fd < 0 )
|
||||
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
|
||||
|
||||
|
||||
FD_ZERO( &read_fds );
|
||||
if( rw & MBEDTLS_NET_POLL_READ )
|
||||
{
|
||||
rw &= ~MBEDTLS_NET_POLL_READ;
|
||||
FD_SET( fd, &read_fds );
|
||||
}
|
||||
|
||||
FD_ZERO( &write_fds );
|
||||
if( rw & MBEDTLS_NET_POLL_WRITE )
|
||||
{
|
||||
rw &= ~MBEDTLS_NET_POLL_WRITE;
|
||||
FD_SET( fd, &write_fds );
|
||||
}
|
||||
|
||||
if( rw != 0 )
|
||||
return( MBEDTLS_ERR_NET_BAD_INPUT_DATA );
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = ( timeout % 1000 ) * 1000;
|
||||
|
||||
do
|
||||
{
|
||||
ret = select( fd + 1, &read_fds, &write_fds, NULL,
|
||||
timeout == (uint32_t) -1 ? NULL : &tv );
|
||||
}
|
||||
while( ret == EINTR );
|
||||
|
||||
if( ret < 0 )
|
||||
return( MBEDTLS_ERR_NET_POLL_FAILED );
|
||||
|
||||
ret = 0;
|
||||
if( FD_ISSET( fd, &read_fds ) )
|
||||
ret |= MBEDTLS_NET_POLL_READ;
|
||||
if( FD_ISSET( fd, &write_fds ) )
|
||||
ret |= MBEDTLS_NET_POLL_WRITE;
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Portable usleep helper
|
||||
*/
|
||||
void mbedtls_net_usleep( unsigned long usec )
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = usec / 1000000;
|
||||
tv.tv_usec = usec % 1000000;
|
||||
|
||||
select( 0, NULL, NULL, NULL, &tv );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Read at most 'len' characters
|
||||
*/
|
||||
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||
|
||||
if( fd < 0 )
|
||||
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
|
||||
|
||||
ret = (int) read( fd, buf, len );
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
if( net_would_block( ctx ) != 0 )
|
||||
return( MBEDTLS_ERR_SSL_WANT_READ );
|
||||
|
||||
if( errno == EPIPE || errno == ECONNRESET )
|
||||
return( MBEDTLS_ERR_NET_CONN_RESET );
|
||||
|
||||
if( errno == EINTR )
|
||||
return( MBEDTLS_ERR_SSL_WANT_READ );
|
||||
|
||||
return( MBEDTLS_ERR_NET_RECV_FAILED );
|
||||
}
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Read at most 'len' characters, blocking for at most 'timeout' ms
|
||||
*/
|
||||
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
|
||||
size_t len, uint32_t timeout )
|
||||
{
|
||||
int ret;
|
||||
struct timeval tv;
|
||||
fd_set read_fds;
|
||||
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||
|
||||
if( fd < 0 )
|
||||
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
|
||||
|
||||
FD_ZERO( &read_fds );
|
||||
FD_SET( fd, &read_fds );
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = ( timeout % 1000 ) * 1000;
|
||||
|
||||
ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
|
||||
|
||||
/* Zero fds ready means we timed out */
|
||||
if( ret == 0 )
|
||||
return( MBEDTLS_ERR_SSL_TIMEOUT );
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
|
||||
if( errno == EINTR )
|
||||
return( MBEDTLS_ERR_SSL_WANT_READ );
|
||||
|
||||
return( MBEDTLS_ERR_NET_RECV_FAILED );
|
||||
}
|
||||
|
||||
/* This call will not block */
|
||||
return( mbedtls_net_recv( ctx, buf, len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Write at most 'len' characters
|
||||
*/
|
||||
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||
|
||||
if( fd < 0 )
|
||||
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
|
||||
|
||||
ret = (int) write( fd, buf, len );
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
if( net_would_block( ctx ) != 0 )
|
||||
return( MBEDTLS_ERR_SSL_WANT_WRITE );
|
||||
|
||||
if( errno == EPIPE || errno == ECONNRESET )
|
||||
return( MBEDTLS_ERR_NET_CONN_RESET );
|
||||
|
||||
if( errno == EINTR )
|
||||
return( MBEDTLS_ERR_SSL_WANT_WRITE );
|
||||
|
||||
return( MBEDTLS_ERR_NET_SEND_FAILED );
|
||||
}
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Gracefully close the connection
|
||||
*/
|
||||
void mbedtls_net_free( mbedtls_net_context *ctx )
|
||||
{
|
||||
if( ctx->fd == -1 )
|
||||
return;
|
||||
|
||||
shutdown( ctx->fd, 2 );
|
||||
close( ctx->fd );
|
||||
|
||||
ctx->fd = -1;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_NET_C */
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
|
||||
@verbatim
|
||||
******************************************************************************
|
||||
*
|
||||
* COPYRIGHT (C) 2018 STMicroelectronics
|
||||
*
|
||||
* @file readme.txt
|
||||
* @author MCD Application Team
|
||||
* @brief This file describes the content of the "templates" directory
|
||||
******************************************************************************
|
||||
*
|
||||
* original licensing conditions
|
||||
* as issued by SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
******************************************************************************
|
||||
@endverbatim
|
||||
|
||||
This file contains template files that provide some alternate implementation for
|
||||
mbedTLS algorithms.
|
||||
|
||||
aes_alt_template.[c/h], gcm_alt_template.[c/h], ccm_alt_template.[c/h], cryp_stm32.[c/h]
|
||||
----------------------------------------------------------------------------------
|
||||
Implements the mbedTLS AES crypto symmetric algorithms using the HAL/CRYP API.
|
||||
|
||||
- As the templates are generic for all STM32 families, you have to fill the appropriate
|
||||
HAL header file within cryp_stm32.h,
|
||||
for instance, stm32<xxxxx>_hal.h becomes stm32h7xx_hal.h for H7
|
||||
|
||||
- Make sure your mbed TLS config file enables the implementation with flags :
|
||||
MBEDTLS_AES_ALT (or/and) MBEDTLS_GCM_ALT (or/and) MBEDTLS_CCM_ALT.
|
||||
|
||||
- Make sure your mbed TLS config file enables the features with the flags :
|
||||
MBEDTLS_AES_C (or/and) MBEDTLS_GCM_C (or/and) MBEDTLS_CCM_C
|
||||
|
||||
- Files need to be copied at user level.
|
||||
aes_alt_template.[c/h] renamed to "aes_alt.[c/h]"
|
||||
gcm_alt_template.[c/h] renamed to "gcm_alt.[c/h]"
|
||||
ccm_alt_template.[c/h] renamed to "ccm_alt.[c/h]"
|
||||
cryp_stm32.[c/h], ST specific file mandatory to have whatever the implemented algorithm(s).
|
||||
|
||||
Note there may have a few family dependancies :
|
||||
- for key length, Hw implementations may not support 192-bits key length
|
||||
- for IVs, Hw implementations restric support to the length of 96 bits, to promote
|
||||
interoperability, efficiency, and simplicity of design.
|
||||
- for AAD, Hw implementations may restric support to an alignement over a length multiple
|
||||
of 32 bits (default SW configuration).
|
||||
AAD with any alignment limitation may be available by enabling STM32_AAD_ANY_LENGTH_SUPPORT.
|
||||
- this implementation is thread-safe ready and can be run from different threads.
|
||||
|
||||
sha1_alt_template.[c/h], sha256_alt_template.[c/h], md5_alt_template.[c/h], hash_stm32.[c/h]
|
||||
----------------------------------------------------------------------------------
|
||||
Implements the mbedTLS secure hash and Message-Digest 5 algorithms using the HAL/CRYP API.
|
||||
|
||||
- As the templates are generic for all STM32 families, you have to fill the appropriate
|
||||
HAL header file within hash_stm32.h,
|
||||
for instance, stm32<xxxxx>_hal.h becomes stm32h7xx_hal.h for H7
|
||||
|
||||
- Make sure your mbed TLS config file enables the implementation with flags :
|
||||
MBEDTLS_SHA1_ALT (or/and) MBEDTLS_SHA256_ALT (or/and) MBEDTLS_MD5_ALT.
|
||||
|
||||
- Make sure your mbed TLS config file enables the features with the flags :
|
||||
MBEDTLS_SHA1_C (or/and) MBEDTLS_SHA256_C (or/and) MBEDTLS_MD5_C
|
||||
|
||||
- Files need to be copied at user level.
|
||||
sha1_alt_template.[c/h] renamed to "sha1_alt.[c/h]"
|
||||
sha256_alt_template.[c/h] renamed to "sha256_alt.[c/h]"
|
||||
md5_alt_template.[c/h] renamed to "md5_alt.[c/h]"
|
||||
hash_stm32.[c/h], ST specific file mandatory to have whatever the implemented algorithm(s).
|
||||
|
||||
Note this implementation is thread-safe ready and can be run from different threads.
|
||||
|
||||
net_sockets_template.c
|
||||
-------------------------
|
||||
implements of the mbedTLS networking API using the LwIP TCP/IP Stack.
|
||||
This file implements the strict minimum required to ensure TCP/IP connection.
|
||||
This file need to be copied at user level and renamed to "net_sockets.c"
|
||||
|
||||
rng_alt_tempate.c
|
||||
---------------------
|
||||
Implements the function mbedtls_hardware_poll(), required by mbedTLS to generate
|
||||
random numbers. The function is using the HAL/RNG API to generate random number
|
||||
using the rng hw IP.
|
||||
|
||||
threading_alt_template.[c/h]
|
||||
-----------------------------
|
||||
Implements the mutex management API required by mbedTLS, using the CMSIS-RTOS
|
||||
V1 & V2 API
|
||||
|
||||
* <h3><center>© COPYRIGHT STMicroelectronics</center></h3>
|
||||
*/
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
* Portions COPYRIGHT 2018 STMicroelectronics, All Rights Reserved
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
*
|
||||
******************************************************************************
|
||||
* @file rng_alt_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief mbedtls alternate entropy data function.
|
||||
* the mbedtls_hardware_poll() is customized to use the STM32 RNG
|
||||
* to generate random data, required for TLS encryption algorithms.
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2018 STMicroelectronics
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Apache 2.0 license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* https://opensource.org/licenses/Apache-2.0
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/entropy_poll.h"
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#ifdef MBEDTLS_ENTROPY_HARDWARE_ALT
|
||||
/*
|
||||
* include the correct headerfile depending on the STM32 family */
|
||||
|
||||
#include "stm32XXXXX_hal.h"
|
||||
#include <string.h>
|
||||
|
||||
static __IO uint32_t isInitialized = 0;
|
||||
|
||||
static RNG_HandleTypeDef RNG_Handle;
|
||||
|
||||
|
||||
static void RNG_Init(void);
|
||||
/* RNG init function */
|
||||
static void RNG_Init(void)
|
||||
{
|
||||
if (isInitialized == 0)
|
||||
{
|
||||
RNG_Handle.Instance = RNG;
|
||||
/* DeInitialize the RNG peripheral */
|
||||
if (HAL_RNG_DeInit(&RNG_Handle) != HAL_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize the RNG peripheral */
|
||||
if (HAL_RNG_Init(&RNG_Handle) != HAL_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
isInitialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int mbedtls_hardware_poll( void *Data, unsigned char *Output, size_t Len, size_t *oLen )
|
||||
{
|
||||
__IO uint8_t random_value[4];
|
||||
int ret = 0;
|
||||
|
||||
RNG_Init();
|
||||
|
||||
if (isInitialized == 0)
|
||||
{
|
||||
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*oLen = 0;
|
||||
while ((*oLen < Len) && (ret == 0))
|
||||
{
|
||||
if (HAL_RNG_GenerateRandomNumber(&RNG_Handle, (uint32_t *)random_value)) == HAL_OK)
|
||||
{
|
||||
for (uint8_t i = 0; (i < sizeof(uint32_t)) && (*oLen < Len) ; i++)
|
||||
{
|
||||
Output[*oLen] = random_value[i];
|
||||
*oLen += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Just be extra sure that we didn't do it wrong */
|
||||
if ((__HAL_RNG_GET_FLAG(&RNG_Handle, (RNG_FLAG_CECS | RNG_FLAG_SECS))) != 0)
|
||||
{
|
||||
*oLen = 0;
|
||||
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* HAL_RNG_MspInit() and HAL_RNG_MspDeInit() are put here as reference
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief RNG MSP Initialization
|
||||
* This function configures the hardware resources used in this application:
|
||||
* - Peripheral's clock enable
|
||||
* @param hrng: RNG handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
|
||||
{
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
|
||||
|
||||
/*Select PLL output as RNG clock source */
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RNG;
|
||||
PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_PLL;
|
||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
|
||||
|
||||
/* RNG Peripheral clock enable */
|
||||
__RNG_CLK_ENABLE();
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief RNG MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this application:
|
||||
* - Disable the Peripheral's clock
|
||||
* @param hrng: RNG handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
|
||||
{
|
||||
/* Enable RNG reset state */
|
||||
__HAL_RCC_RNG_FORCE_RESET();
|
||||
|
||||
/* Release RNG from reset state */
|
||||
__HAL_RCC_RNG_RELEASE_RESET();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*MBEDTLS_ENTROPY_HARDWARE_ALT*/
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020, STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements STMicroelectronics SHA1 with HW services based on API
|
||||
* from mbed TLS
|
||||
*/
|
||||
/*
|
||||
* The SHA-1 standard was published by NIST in 1993.
|
||||
*
|
||||
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "mbedtls/sha1.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA1_C)
|
||||
#if defined(MBEDTLS_SHA1_ALT)
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
#define SHA1_VALIDATE_RET(cond) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA )
|
||||
#define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
SHA1_VALIDATE( ctx != NULL );
|
||||
|
||||
__disable_irq();
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* mutex cannot be initialized twice */
|
||||
if ( !hash_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_init( &hash_mutex );
|
||||
hash_mutex_started = 1;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
hash_context_count++;
|
||||
__enable_irq();
|
||||
|
||||
hash_zeroize( ctx, sizeof(mbedtls_sha1_context) );
|
||||
}
|
||||
|
||||
void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
__disable_irq();
|
||||
if (hash_context_count > 0)
|
||||
hash_context_count--;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ( hash_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_free( &hash_mutex );
|
||||
hash_mutex_started = 0;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
__enable_irq();
|
||||
|
||||
/* Shut down HASH on last context */
|
||||
if ( hash_context_count == 0 )
|
||||
HAL_HASH_DeInit( &ctx->hhash );
|
||||
|
||||
hash_zeroize( ctx, sizeof(mbedtls_sha1_context) );
|
||||
}
|
||||
|
||||
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
|
||||
const mbedtls_sha1_context *src )
|
||||
{
|
||||
SHA1_VALIDATE( dst != NULL );
|
||||
SHA1_VALIDATE( src != NULL );
|
||||
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
SHA1_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* HASH Configuration */
|
||||
if ( HAL_HASH_DeInit( &ctx->hhash ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
ctx->hhash.Init.DataType = HASH_DATATYPE_8B;
|
||||
if ( HAL_HASH_Init( &ctx->hhash ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* save hw context */
|
||||
HAL_HASH_ContextSaving( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
|
||||
const unsigned char data[ST_SHA1_BLOCK_SIZE] )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
SHA1_VALIDATE_RET( ctx != NULL );
|
||||
SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* restore hw context */
|
||||
HAL_HASH_ContextRestoring( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
if ( HAL_HASH_SHA1_Accmlt( &ctx->hhash,
|
||||
(uint8_t *) data,
|
||||
ST_SHA1_BLOCK_SIZE ) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* save hw context */
|
||||
HAL_HASH_ContextSaving( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
int ret = 0;
|
||||
size_t currentlen = ilen;
|
||||
|
||||
SHA1_VALIDATE_RET( ctx != NULL );
|
||||
SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* restore hw context */
|
||||
HAL_HASH_ContextRestoring( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
if ( currentlen < (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len) )
|
||||
{
|
||||
/* only store input data in context buffer */
|
||||
memcpy( ctx->sbuf + ctx->sbuf_len, input, currentlen );
|
||||
ctx->sbuf_len += currentlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fill context buffer until ST_SHA1_BLOCK_SIZE bytes, and process it */
|
||||
memcpy( ctx->sbuf + ctx->sbuf_len,
|
||||
input,
|
||||
(ST_SHA1_BLOCK_SIZE - ctx->sbuf_len) );
|
||||
currentlen -= (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len);
|
||||
|
||||
if ( HAL_HASH_SHA1_Accmlt( &ctx->hhash,
|
||||
(uint8_t *)(ctx->sbuf),
|
||||
ST_SHA1_BLOCK_SIZE) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Process following input data
|
||||
with size multiple of ST_SHA1_BLOCK_SIZE bytes */
|
||||
size_t iter = currentlen / ST_SHA1_BLOCK_SIZE;
|
||||
if (iter != 0)
|
||||
{
|
||||
if ( HAL_HASH_SHA1_Accmlt( &ctx->hhash,
|
||||
(uint8_t *)(input + ST_SHA1_BLOCK_SIZE - ctx->sbuf_len),
|
||||
(iter * ST_SHA1_BLOCK_SIZE)) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store only the remaining input data
|
||||
up to (ST_SHA1_BLOCK_SIZE - 1) bytes */
|
||||
ctx->sbuf_len = currentlen % ST_SHA1_BLOCK_SIZE;
|
||||
if ( ctx->sbuf_len != 0 )
|
||||
{
|
||||
memcpy( ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len );
|
||||
}
|
||||
}
|
||||
|
||||
/* save hw context */
|
||||
HAL_HASH_ContextSaving( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
|
||||
unsigned char output[32] )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
SHA1_VALIDATE_RET( ctx != NULL );
|
||||
SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* restore hw context */
|
||||
HAL_HASH_ContextRestoring( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
/* Last accumulation for pending bytes in sbuf_len,
|
||||
then trig processing and get digest */
|
||||
if ( HAL_HASH_SHA1_Accmlt_End( &ctx->hhash,
|
||||
ctx->sbuf,
|
||||
ctx->sbuf_len,
|
||||
output,
|
||||
ST_HASH_TIMEOUT) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ctx->sbuf_len = 0;
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT*/
|
||||
#endif /* MBEDTLS_SHA1_C */
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* \file sha1.h
|
||||
*
|
||||
* \brief This file contains SHA-1 definitions and functions.
|
||||
*
|
||||
* The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in
|
||||
* <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use constitutes
|
||||
* a security risk. We recommend considering stronger message
|
||||
* digests instead.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
||||
* Copyright (C) 2019-2020, STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements STMicroelectronics SHA1 API with HW services based
|
||||
* on mbed TLS API
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_SHA1_ALT_H
|
||||
#define MBEDTLS_SHA1_ALT_H
|
||||
|
||||
#if defined (MBEDTLS_SHA1_ALT)
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "hash_stm32.h"
|
||||
|
||||
#define ST_SHA1_BLOCK_SIZE ((size_t) 64) /*!< HW handles 512 bits, ie 64 bytes */
|
||||
#define ST_SHA1_NB_HASH_REG ((uint32_t)57) /*!< Number of HASH HW context Registers:
|
||||
CR + STR + IMR + CSR[54] */
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct mbedtls_sha1_context
|
||||
{
|
||||
HASH_HandleTypeDef hhash; /*!< Handle of HASH HAL */
|
||||
uint8_t sbuf[ST_SHA1_BLOCK_SIZE]; /*!< Buffer to store input data until ST_SHA1_BLOCK_SIZE
|
||||
is reached, or until last input data is reached */
|
||||
uint8_t sbuf_len; /*!< Number of bytes stored in sbuf */
|
||||
uint32_t ctx_save_regs[ST_SHA1_NB_HASH_REG];
|
||||
}
|
||||
mbedtls_sha1_context;
|
||||
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT */
|
||||
|
||||
#endif /* MBEDTLS_SHA1_ALT_H */
|
||||
+345
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright (C) 2019-2020, STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements STMicroelectronics SHA256 with HW services based on API
|
||||
* from mbed TLS
|
||||
*/
|
||||
/*
|
||||
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
#if defined(MBEDTLS_SHA256_ALT)
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
#define SHA256_VALIDATE_RET(cond) \
|
||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
|
||||
#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
|
||||
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
|
||||
{
|
||||
SHA256_VALIDATE( ctx != NULL );
|
||||
|
||||
__disable_irq();
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* mutex cannot be initialized twice */
|
||||
if ( !hash_mutex_started )
|
||||
{
|
||||
mbedtls_mutex_init( &hash_mutex );
|
||||
hash_mutex_started = 1;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
hash_context_count++;
|
||||
__enable_irq();
|
||||
|
||||
hash_zeroize( ctx, sizeof(mbedtls_sha256_context) );
|
||||
}
|
||||
|
||||
void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
__disable_irq();
|
||||
if (hash_context_count > 0)
|
||||
hash_context_count--;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ( hash_context_count == 0 )
|
||||
{
|
||||
mbedtls_mutex_free( &hash_mutex );
|
||||
hash_mutex_started = 0;
|
||||
}
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
__enable_irq();
|
||||
|
||||
/* Shut down HASH on last context */
|
||||
if (hash_context_count == 0)
|
||||
HAL_HASH_DeInit( &ctx->hhash );
|
||||
|
||||
hash_zeroize( ctx, sizeof(mbedtls_sha256_context) );
|
||||
}
|
||||
|
||||
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src )
|
||||
{
|
||||
SHA256_VALIDATE( dst != NULL );
|
||||
SHA256_VALIDATE( src != NULL );
|
||||
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
SHA256_VALIDATE_RET( ctx != NULL );
|
||||
SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* HASH Configuration */
|
||||
if (HAL_HASH_DeInit( &ctx->hhash ) != HAL_OK)
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
ctx->hhash.Init.DataType = HASH_DATATYPE_8B;
|
||||
if ( HAL_HASH_Init( &ctx->hhash ) != HAL_OK )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ctx->is224 = is224;
|
||||
|
||||
/* save hw context */
|
||||
HAL_HASH_ContextSaving( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
|
||||
const unsigned char data[ST_SHA256_BLOCK_SIZE] )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
SHA256_VALIDATE_RET( ctx != NULL );
|
||||
SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* restore hw context */
|
||||
HAL_HASH_ContextRestoring( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
if (ctx->is224 == 0) {
|
||||
if ( HAL_HASHEx_SHA256_Accmlt( &ctx->hhash,
|
||||
(uint8_t *) data,
|
||||
ST_SHA256_BLOCK_SIZE) != 0 ) {
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
if ( HAL_HASHEx_SHA224_Accmlt( &ctx->hhash,
|
||||
(uint8_t *) data,
|
||||
ST_SHA256_BLOCK_SIZE) != 0 ) {
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* save hw context */
|
||||
HAL_HASH_ContextSaving( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t currentlen = ilen;
|
||||
|
||||
SHA256_VALIDATE_RET( ctx != NULL );
|
||||
SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* restore hw context */
|
||||
HAL_HASH_ContextRestoring( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
if (currentlen < (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len))
|
||||
{
|
||||
/* only store input data in context buffer */
|
||||
memcpy( ctx->sbuf + ctx->sbuf_len, input, currentlen );
|
||||
ctx->sbuf_len += currentlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fill context buffer until ST_SHA256_BLOCK_SIZE bytes, and process it */
|
||||
memcpy( ctx->sbuf + ctx->sbuf_len,
|
||||
input,
|
||||
(ST_SHA256_BLOCK_SIZE - ctx->sbuf_len) );
|
||||
currentlen -= (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len);
|
||||
|
||||
if (ctx->is224 == 0)
|
||||
{
|
||||
if ( HAL_HASHEx_SHA256_Accmlt( &ctx->hhash,
|
||||
(uint8_t *)(ctx->sbuf),
|
||||
ST_SHA256_BLOCK_SIZE ) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HAL_HASHEx_SHA224_Accmlt( &ctx->hhash,
|
||||
(uint8_t *)(ctx->sbuf),
|
||||
ST_SHA256_BLOCK_SIZE ) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process following input data
|
||||
with size multiple of ST_SHA256_BLOCK_SIZE bytes */
|
||||
size_t iter = currentlen / ST_SHA256_BLOCK_SIZE;
|
||||
if (iter != 0)
|
||||
{
|
||||
if (ctx->is224 == 0)
|
||||
{
|
||||
if ( HAL_HASHEx_SHA256_Accmlt( &ctx->hhash,
|
||||
(uint8_t *)(input + ST_SHA256_BLOCK_SIZE - ctx->sbuf_len),
|
||||
(iter * ST_SHA256_BLOCK_SIZE)) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HAL_HASHEx_SHA224_Accmlt( &ctx->hhash,
|
||||
(uint8_t *)(input + ST_SHA256_BLOCK_SIZE - ctx->sbuf_len),
|
||||
(iter * ST_SHA256_BLOCK_SIZE)) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Store only the remaining input data
|
||||
up to (ST_SHA256_BLOCK_SIZE - 1) bytes */
|
||||
ctx->sbuf_len = currentlen % ST_SHA256_BLOCK_SIZE;
|
||||
if ( ctx->sbuf_len != 0 )
|
||||
{
|
||||
memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* save hw context */
|
||||
HAL_HASH_ContextSaving( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
|
||||
unsigned char output[32] )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
SHA256_VALIDATE_RET( ctx != NULL );
|
||||
SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( ( ret = mbedtls_mutex_lock( &hash_mutex ) ) != 0 )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
/* restore hw context */
|
||||
HAL_HASH_ContextRestoring( &ctx->hhash, (uint8_t *)ctx->ctx_save_regs );
|
||||
|
||||
/* Last accumulation for pending bytes in sbuf_len,
|
||||
then trig processing and get digest */
|
||||
if ( ctx->is224 == 0 )
|
||||
{
|
||||
if ( HAL_HASHEx_SHA256_Accmlt_End( &ctx->hhash,
|
||||
ctx->sbuf,
|
||||
ctx->sbuf_len,
|
||||
output,
|
||||
ST_HASH_TIMEOUT) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HAL_HASHEx_SHA224_Accmlt_End( &ctx->hhash,
|
||||
ctx->sbuf,
|
||||
ctx->sbuf_len,
|
||||
output,
|
||||
ST_HASH_TIMEOUT ) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->sbuf_len = 0;
|
||||
|
||||
exit :
|
||||
/* Free context access */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &hash_mutex ) != 0 )
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA256_ALT*/
|
||||
#endif /* MBEDTLS_SHA256_C */
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* \file sha256.h
|
||||
*
|
||||
* \brief This file contains SHA-224 and SHA-256 definitions and functions.
|
||||
*
|
||||
* The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic
|
||||
* hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
||||
* Copyright (C) 2019-2020, STMicroelectronics, 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.
|
||||
*
|
||||
* This file implements STMicroelectronics SHA256 API with HW services based
|
||||
* on mbed TLS API
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_SHA256_ALT_H
|
||||
#define MBEDTLS_SHA256_ALT_H
|
||||
|
||||
#if defined (MBEDTLS_SHA256_ALT)
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "hash_stm32.h"
|
||||
|
||||
#define ST_SHA256_BLOCK_SIZE ((size_t) 64) /*!< HW handles 512 bits, ie 64 bytes */
|
||||
#define ST_SHA256_NB_HASH_REG ((uint32_t)57) /*!< Number of HASH HW context Registers:
|
||||
CR + STR + IMR + CSR[54] */
|
||||
|
||||
/**
|
||||
* \brief SHA-256 context structure
|
||||
*
|
||||
* The structure is used both for SHA-256 and for SHA-224
|
||||
* checksum calculations. The choice between these two is
|
||||
* made in the call to mbedtls_sha256_starts_ret().
|
||||
*/
|
||||
typedef struct mbedtls_sha256_context
|
||||
{
|
||||
int is224; /*!< 0 = use SHA256, 1 = use SHA224 */
|
||||
HASH_HandleTypeDef hhash; /*!< Handle of HASH HAL */
|
||||
uint8_t sbuf[ST_SHA256_BLOCK_SIZE]; /*!< Buffer to store input data until ST_SHA256_BLOCK_SIZE
|
||||
is reached, or until last input data is reached */
|
||||
uint8_t sbuf_len; /*!< Number of bytes stored in sbuf */
|
||||
uint32_t ctx_save_regs[ST_SHA256_NB_HASH_REG];
|
||||
}
|
||||
mbedtls_sha256_context;
|
||||
|
||||
|
||||
#endif /* MBEDTLS_SHA256_ALT */
|
||||
#endif /* MBEDTLS_SHA256_ALT_H */
|
||||
Vendored
+106
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Portions COPYRIGHT 2018 STMicroelectronics, All Rights Reserved
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
*
|
||||
********************************************************************************
|
||||
* @file threading_alt_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief mutex management functions implementation based on cmsis-os V1/V2
|
||||
API. This file to be copied under the application project source tree.
|
||||
********************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2018 STMicroelectronics
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Apache 2.0 license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* https://opensource.org/licenses/Apache-2.0
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* This files implments the mbedTLS mutex management API using the CMSIS-RTOS
|
||||
* V1 & V2 API. To correctly use this file make sure that:
|
||||
*
|
||||
* - this file as well as the "threading_alt_template.h" files are renamed
|
||||
* and copied under the project source tree.
|
||||
*
|
||||
* - The project seetings are pointing to the correct CMSIS-RTOS files
|
||||
*
|
||||
* - the mbedTLS config file is enabling the flags "MBEDTLS_THREADING_C" and
|
||||
* "MBEDTLS_THREADING_ALT"
|
||||
*
|
||||
* - the mbedtls_set_threading_alt(...) is called before any other mbedtls
|
||||
* API, in order to register the cmisis_os_mutex_xxx() API.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "threading_alt.h"
|
||||
|
||||
#if defined(MBEDTLS_THREADING_ALT)
|
||||
|
||||
void cmsis_os_mutex_init( mbedtls_threading_mutex_t *mutex )
|
||||
{
|
||||
#if (osCMSIS < 0x20000U)
|
||||
osMutexDef(thread_mutex);
|
||||
mutex->mutex_id = osMutexCreate(osMutex(thread_mutex));
|
||||
#else
|
||||
mutex->mutex_id = osMutexNew(NULL);
|
||||
#endif
|
||||
if (mutex->mutex_id != NULL)
|
||||
{
|
||||
mutex->status = osOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
mutex->status = osErrorOS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cmsis_os_mutex_free( mbedtls_threading_mutex_t *mutex )
|
||||
{
|
||||
if (mutex->mutex_id != NULL)
|
||||
{
|
||||
osMutexDelete(mutex->mutex_id);
|
||||
}
|
||||
}
|
||||
|
||||
int cmsis_os_mutex_lock( mbedtls_threading_mutex_t *mutex )
|
||||
{
|
||||
if ((mutex == NULL) || (mutex->mutex_id == NULL) || (mutex->status != osOK))
|
||||
{
|
||||
return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
|
||||
}
|
||||
#if (osCMSIS < 0x20000U)
|
||||
mutex->status = osMutexWait(mutex->mutex_id, osWaitForever);
|
||||
#else
|
||||
mutex->status = osMutexAcquire(mutex->mutex_id, osWaitForever);
|
||||
#endif
|
||||
if (mutex->status != osOK)
|
||||
{
|
||||
return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmsis_os_mutex_unlock( mbedtls_threading_mutex_t *mutex )
|
||||
{
|
||||
if((mutex == NULL) || (mutex->mutex_id == NULL) || (mutex->status != osOK))
|
||||
{
|
||||
return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mutex->status = osMutexRelease(mutex->mutex_id);
|
||||
if (mutex->status != osOK)
|
||||
{
|
||||
return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Portions COPYRIGHT 2018 STMicroelectronics, All Rights Reserved
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
*
|
||||
********************************************************************************
|
||||
* @file threading_alt_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief template header file to be included the threading_alt.c
|
||||
|
||||
********************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2018 STMicroelectronics
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Apache 2.0 license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* https://opensource.org/licenses/Apache-2.0
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* this files defines the mbedtls_threading_mutex_t data type used by the
|
||||
* mbedtls_mutex_xxx() API.
|
||||
* this file is included in the "threadind_alt_template.c", thus it should be
|
||||
* copied under the project Inc directory and renamed "thredading_alt.h"
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_THREADING_ALT_H
|
||||
#define MBEDTLS_THREADING_ALT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */
|
||||
#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */
|
||||
#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */
|
||||
|
||||
|
||||
#include "cmsis_os.h"
|
||||
typedef struct {
|
||||
#if (osCMSIS < 0x20000U)
|
||||
osMutexId mutex_id;
|
||||
osStatus status;
|
||||
#else
|
||||
osMutexId_t mutex_id;
|
||||
osStatus_t status;
|
||||
#endif
|
||||
|
||||
} mbedtls_threading_mutex_t;
|
||||
|
||||
void cmsis_os_mutex_init( mbedtls_threading_mutex_t *mutex );
|
||||
void cmsis_os_mutex_free( mbedtls_threading_mutex_t *mutex );
|
||||
int cmsis_os_mutex_lock( mbedtls_threading_mutex_t *mutex );
|
||||
int cmsis_os_mutex_unlock( mbedtls_threading_mutex_t *mutex );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_THREADING_ALT_H */
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
*
|
||||
* Portions COPYRIGHT 2018 STMicroelectronics, All Rights Reserved
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
*
|
||||
******************************************************************************
|
||||
* @file timing_alt_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief mbedtls alternate timing functions implementation.
|
||||
* mbedtls timing API is implemented using the CMSIS-RTOS v1/v2 API
|
||||
* this file has to be renamed to timing_alt.c and copied under
|
||||
* the project tree.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2018 STMicroelectronics
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Apache 2.0 license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* https://opensource.org/licenses/Apache-2.0
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "timing_alt.h"
|
||||
|
||||
#if defined(MBEDTLS_TIMING_ALT)
|
||||
|
||||
/* include the appropriate header file */
|
||||
#include "stm32<xxxxx>_hal.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
struct _hr_time
|
||||
{
|
||||
uint32_t elapsed_time;
|
||||
};
|
||||
volatile int mbedtls_timing_alarmed = 0;
|
||||
|
||||
static uint8_t timer_created = 0;
|
||||
#if (osCMSIS < 0x20000)
|
||||
static osTimerId timer;
|
||||
#else
|
||||
static osTimerId_t timer;
|
||||
#endif
|
||||
static void osTimerCallback(void const *argument)
|
||||
{
|
||||
UNUSED(argument);
|
||||
mbedtls_timing_alarmed = 1;
|
||||
osTimerStop(timer);
|
||||
}
|
||||
|
||||
unsigned long mbedtls_timing_hardclock( void )
|
||||
{
|
||||
/* retrieve the CPU cycles using the Cortex-M DWT->CYCCNT register
|
||||
* avaialable only starting from CM3
|
||||
*/
|
||||
|
||||
#if (__CORTEX_M >= 0x03U)
|
||||
static int dwt_started = 0;
|
||||
if( dwt_started == 0 )
|
||||
{
|
||||
dwt_started = 1;
|
||||
/* Enable Tracing */
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
#if (__CORTEX_M == 0x07U)
|
||||
/* in Cortex M7, the trace needs to be unlocked
|
||||
* via the DWT->LAR register with 0xC5ACCE55 value
|
||||
*/
|
||||
DWT->LAR = 0xC5ACCE55;
|
||||
#endif
|
||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
||||
|
||||
/* Reset counter */
|
||||
DWT->CYCCNT = 0;
|
||||
}
|
||||
|
||||
return (unsigned long)DWT->CYCCNT;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
|
||||
{
|
||||
unsigned long delta;
|
||||
uint32_t offset;
|
||||
struct _hr_time *t = (struct _hr_time *) val;
|
||||
|
||||
offset = osKernelSysTick();
|
||||
|
||||
if( reset )
|
||||
{
|
||||
t->elapsed_time = offset;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
delta = offset - t->elapsed_time;
|
||||
return( delta );
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_set_alarm( int seconds )
|
||||
{
|
||||
if (timer_created == 0)
|
||||
{
|
||||
#if (osCMSIS < 0x20000)
|
||||
osTimerDef(Timer, osTimerCallback);
|
||||
timer = osTimerCreate(osTimer(Timer), osTimerOnce, NULL);
|
||||
#else
|
||||
timer = osTimerNew((osTimerFunc_t)osTimerCallback, osTimerOnce, NULL, NULL);
|
||||
#endif
|
||||
timer_created = 1;
|
||||
}
|
||||
|
||||
mbedtls_timing_alarmed = 0;
|
||||
osTimerStart(timer, seconds * 1000);
|
||||
}
|
||||
|
||||
void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms )
|
||||
{
|
||||
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
|
||||
|
||||
ctx->int_ms = int_ms;
|
||||
ctx->fin_ms = fin_ms;
|
||||
|
||||
if( fin_ms != 0 )
|
||||
mbedtls_timing_get_timer( &ctx->timer, 1 );
|
||||
}
|
||||
|
||||
int mbedtls_timing_get_delay( void *data )
|
||||
{
|
||||
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
|
||||
unsigned long elapsed_ms;
|
||||
|
||||
if( ctx->fin_ms == 0 )
|
||||
return( -1 );
|
||||
|
||||
elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 );
|
||||
|
||||
if( elapsed_ms >= ctx->fin_ms )
|
||||
return( 2 );
|
||||
|
||||
if( elapsed_ms >= ctx->int_ms )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_TIMING_ALT */
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/******************************************************************************
|
||||
* @file timing_alt_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief mbedtls alternate timing data structure and API prototypes
|
||||
* this file is included by the timing_alt.c, thus need to be renamed
|
||||
* to timing_alt.h then copied under the project tree.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* 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
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_TIMING_ALT_H
|
||||
#define MBEDTLS_TIMING_ALT_H
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief timer structure
|
||||
*/
|
||||
struct mbedtls_timing_hr_time
|
||||
{
|
||||
unsigned char opaque[32];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Context for mbedtls_timing_set/get_delay()
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct mbedtls_timing_hr_time timer;
|
||||
uint32_t int_ms;
|
||||
uint32_t fin_ms;
|
||||
} mbedtls_timing_delay_context;
|
||||
|
||||
extern volatile int mbedtls_timing_alarmed;
|
||||
|
||||
/**
|
||||
* \brief Return the CPU cycle counter value
|
||||
*
|
||||
* \warning This is only a best effort! Do not rely on this!
|
||||
* In particular, it is known to be unreliable on virtual
|
||||
* machines.
|
||||
*/
|
||||
unsigned long mbedtls_timing_hardclock( void );
|
||||
|
||||
/**
|
||||
* \brief Return the elapsed time in milliseconds
|
||||
*
|
||||
* \param val points to a timer structure
|
||||
* \param reset if set to 1, the timer is restarted
|
||||
*/
|
||||
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset );
|
||||
|
||||
/**
|
||||
* \brief Setup an alarm clock
|
||||
*
|
||||
* \param seconds delay before the "mbedtls_timing_alarmed" flag is set
|
||||
*
|
||||
* \warning Only one alarm at a time is supported. In a threaded
|
||||
* context, this means one for the whole process, not one per
|
||||
* thread.
|
||||
*/
|
||||
void mbedtls_set_alarm( int seconds );
|
||||
|
||||
/**
|
||||
* \brief Set a pair of delays to watch
|
||||
* (See \c mbedtls_timing_get_delay().)
|
||||
*
|
||||
* \param data Pointer to timing data
|
||||
* Must point to a valid \c mbedtls_timing_delay_context struct.
|
||||
* \param int_ms First (intermediate) delay in milliseconds.
|
||||
* \param fin_ms Second (final) delay in milliseconds.
|
||||
* Pass 0 to cancel the current delay.
|
||||
*/
|
||||
void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
|
||||
|
||||
/**
|
||||
* \brief Get the status of delays
|
||||
* (Memory helper: number of delays passed.)
|
||||
*
|
||||
* \param data Pointer to timing data
|
||||
* Must point to a valid \c mbedtls_timing_delay_context struct.
|
||||
*
|
||||
* \return -1 if cancelled (fin_ms = 0)
|
||||
* 0 if none of the delays are passed,
|
||||
* 1 if only the intermediate delay is passed,
|
||||
* 2 if the final delay is passed.
|
||||
*/
|
||||
int mbedtls_timing_get_delay( void *data );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* MBEDTLS_TIMING_ALT_H */
|
||||
Reference in New Issue
Block a user