New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix use of AES_ALT on STM32F439 for example-tls-client #5018
Changes from 3 commits
458b0ec
c1fcae6
cd1a18f
e6fa5f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Hardware aes collector for the STM32F4 family | ||
* Hardware aes collector for the STM32F4 F7 and L4 family | ||
******************************************************************************* | ||
* Copyright (c) 2017, STMicroelectronics | ||
* SPDX-License-Identifier: Apache-2.0 | ||
|
@@ -129,15 +129,18 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, | |
|
||
/* allow multi-instance of CRYP use: restore context for CRYP hw module */ | ||
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr; | ||
ctx->hcryp_aes.Phase = HAL_CRYP_PHASE_READY; | ||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B; | ||
ctx->hcryp_aes.Init.pKey = ctx->aes_key; | ||
|
||
if(mode == MBEDTLS_AES_DECRYPT) { /* AES decryption */ | ||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B; | ||
ctx->hcryp_aes.Init.pKey = ctx->aes_key; | ||
mbedtls_aes_decrypt( ctx, input, output ); | ||
if (mbedtls_internal_aes_decrypt( ctx, input, output )){ | ||
return 1; | ||
} | ||
} else { /* AES encryption */ | ||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B; | ||
ctx->hcryp_aes.Init.pKey = ctx->aes_key; | ||
mbedtls_aes_encrypt( ctx, input, output ); | ||
if (mbedtls_internal_aes_encrypt( ctx, input, output )) { | ||
return 1; | ||
} | ||
} | ||
/* allow multi-instance of CRYP use: save context for CRYP HW module CR */ | ||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR; | ||
|
@@ -147,31 +150,93 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, | |
|
||
#if defined(MBEDTLS_CIPHER_MODE_CBC) | ||
#if defined (TARGET_STM32L486xG) | ||
static int st_cbc_restore_context(mbedtls_aes_context *ctx){ | ||
uint32_t tickstart; | ||
tickstart = HAL_GetTick(); | ||
while((ctx->hcryp_aes.Instance->SR & AES_SR_BUSY) != 0){ | ||
if ((HAL_GetTick() - tickstart) > ST_AES_TIMEOUT) { | ||
return 1; // timeout: CRYP processor is busy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is quite interesting. What should happen if the crypto accelerator is busy? Normally you would have a lock or something to protect concurrent use of the accelerator. However, if you do not lock accesses and find out that the accelerator is busy, should you return a generic error? IMHO we should be returning something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll return ST_ERR_AES_BUSY, as MBEDTLS_ERR_AES_BUSY is not defined There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it is a very good choice, that error code is not used in mbed TLS at the moment. Even if later the code gets assigned to some mbed TLS error, this shouldn't be a problem as long as the AES module has strictly synchronous interface in mbed TLS (this seems highly unlikely to change in the future). |
||
} | ||
} | ||
/* allow multi-instance of CRYP use: restore context for CRYP hw module */ | ||
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr; | ||
return 0; | ||
} | ||
static int st_cbc_save_context(mbedtls_aes_context *ctx){ | ||
uint32_t tickstart; | ||
|
||
tickstart = HAL_GetTick(); | ||
while((ctx->hcryp_aes.Instance->SR & AES_SR_BUSY) != 0){ | ||
if ((HAL_GetTick() - tickstart) > ST_AES_TIMEOUT) { | ||
return 1; // timeout: CRYP processor is busy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
} | ||
} | ||
/* allow multi-instance of CRYP use: save context for CRYP HW module CR */ | ||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR; | ||
|
||
return 0; | ||
} | ||
static int st_hal_cryp_cbc( mbedtls_aes_context *ctx, uint32_t opmode, size_t length, | ||
unsigned char iv[16], uint8_t *input, uint8_t *output) | ||
{ | ||
int status = 0; | ||
ctx->hcryp_aes.Init.pInitVect = &iv[0]; // used in process, not in the init | ||
if ((ctx->hcryp_aes.Init.OperatingMode != opmode) || \ | ||
(ctx->hcryp_aes.Init.ChainingMode != CRYP_CHAINMODE_AES_CBC) || \ | ||
(ctx->hcryp_aes.Init.KeyWriteFlag != CRYP_KEY_WRITE_ENABLE)) { | ||
|
||
/* Re-initialize AES IP with proper parameters */ | ||
if (HAL_CRYP_DeInit(&ctx->hcryp_aes) != HAL_OK) | ||
return HAL_ERROR; | ||
ctx->hcryp_aes.Init.OperatingMode = opmode; | ||
ctx->hcryp_aes.Init.ChainingMode = CRYP_CHAINMODE_AES_CBC; | ||
ctx->hcryp_aes.Init.KeyWriteFlag = CRYP_KEY_WRITE_ENABLE; | ||
if (HAL_CRYP_Init(&ctx->hcryp_aes) != HAL_OK) | ||
return HAL_ERROR; | ||
} | ||
/* At this moment only, we know we have CBC mode: Re-initialize AES | ||
IP with proper parameters and apply key and IV for multi context usecase */ | ||
if (HAL_CRYP_DeInit(&ctx->hcryp_aes) != HAL_OK) | ||
return HAL_ERROR; | ||
ctx->hcryp_aes.Init.OperatingMode = opmode; | ||
ctx->hcryp_aes.Init.ChainingMode = CRYP_CHAINMODE_AES_CBC; | ||
ctx->hcryp_aes.Init.KeyWriteFlag = CRYP_KEY_WRITE_ENABLE; | ||
if (HAL_CRYP_Init(&ctx->hcryp_aes) != HAL_OK) | ||
return HAL_ERROR; | ||
|
||
status = HAL_CRYPEx_AES(&ctx->hcryp_aes, input, length, output, 10); | ||
|
||
return status; | ||
} | ||
#else | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we document why we need two different implementations for save/restore depending on the target family? |
||
static int st_cbc_restore_context(mbedtls_aes_context *ctx){ | ||
uint32_t tickstart; | ||
tickstart = HAL_GetTick(); | ||
while((ctx->hcryp_aes.Instance->SR & (CRYP_SR_IFEM | CRYP_SR_OFNE | CRYP_SR_BUSY)) != CRYP_SR_IFEM){ | ||
if ((HAL_GetTick() - tickstart) > ST_AES_TIMEOUT) { | ||
return 1; // timeout: CRYP processor is busy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
} | ||
} | ||
ctx->hcryp_aes.Instance->CR &= ~CRYP_CR_CRYPEN; | ||
/* save initvector for multi-instance use of CRYP */ | ||
ctx->hcryp_aes.Instance->IV1RR = ctx->save_iv[3]; | ||
ctx->hcryp_aes.Instance->IV1LR = ctx->save_iv[2]; | ||
ctx->hcryp_aes.Instance->IV0RR = ctx->save_iv[1]; | ||
ctx->hcryp_aes.Instance->IV0LR = ctx->save_iv[0]; | ||
ctx->hcryp_aes.Phase = HAL_CRYP_PHASE_READY; | ||
/* allow multi-instance of CRYP use: restore context for CRYP hw module */ | ||
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr; | ||
return 0; | ||
} | ||
static int st_cbc_save_context(mbedtls_aes_context *ctx){ | ||
uint32_t tickstart; | ||
tickstart = HAL_GetTick(); | ||
while((ctx->hcryp_aes.Instance->SR & (CRYP_SR_IFEM | CRYP_SR_OFNE | CRYP_SR_BUSY)) != CRYP_SR_IFEM){ | ||
if ((HAL_GetTick() - tickstart) > ST_AES_TIMEOUT) { | ||
return 1; // timeout: CRYP processor is busy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
} | ||
} | ||
/* allow multi-instance of CRYP use: save context for CRYP HW module CR */ | ||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR; | ||
ctx->hcryp_aes.Instance->CR &= ~CRYP_CR_CRYPEN; | ||
/* save initvector for multi-instance use of CRYP */ | ||
ctx->save_iv[3] = ctx->hcryp_aes.Instance->IV1RR; | ||
ctx->save_iv[2] = ctx->hcryp_aes.Instance->IV1LR; | ||
ctx->save_iv[1] = ctx->hcryp_aes.Instance->IV0RR; | ||
ctx->save_iv[0] = ctx->hcryp_aes.Instance->IV0LR; | ||
if ((ctx->ctx_save_cr & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) { | ||
ctx->hcryp_aes.Instance->CR &= CRYP_CR_CRYPEN; | ||
} | ||
return 0; | ||
} | ||
#endif /* TARGET_STM32L486xG */ | ||
|
||
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that procedure to save/restore contexts is quite involved and has different requirements for different functions. Would it be possible to include a comment somewhere in the code that documents in plain English what is the thinking behind these operations to enable interleaved uses of the accelerator with multiple contexts? |
||
int mode, | ||
size_t length, | ||
|
@@ -182,21 +247,41 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, | |
int status = 0; | ||
if( length % 16 ) | ||
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); | ||
ctx->hcryp_aes.Init.pInitVect = &iv[0]; | ||
status |= st_cbc_restore_context(ctx); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should check the return value here and return on error, because otherwise it is theoretically possible for a compromised application to use another applications key/context if it gets the timing right. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One of my review comments is shown as outdated, reposting it for visibility: I think we should check the return value here and return on error, because otherwise it is theoretically possible for a compromised application to use another applications key/context if it gets the timing right. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I think that would be good practice and a more defensive coding! |
||
#if defined (TARGET_STM32L486xG) | ||
uint32_t *iv_ptr = (uint32_t *)&iv[0]; | ||
if( mode == MBEDTLS_AES_DECRYPT ) { | ||
status = st_hal_cryp_cbc(ctx, CRYP_ALGOMODE_KEYDERIVATION_DECRYPT, length, iv, (uint8_t *)input, (uint8_t *)output); | ||
status |= st_hal_cryp_cbc(ctx, CRYP_ALGOMODE_KEYDERIVATION_DECRYPT, length, iv, (uint8_t *)input, (uint8_t *)output); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see that the |
||
// update IV | ||
uint32_t tickstart; | ||
tickstart = HAL_GetTick(); | ||
while((ctx->hcryp_aes.Instance->SR & AES_SR_BUSY) != 0){ | ||
if ((HAL_GetTick() - tickstart) > ST_AES_TIMEOUT) { | ||
return 1; // timeout: CRYP processor is busy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
} | ||
} | ||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR; | ||
ctx->hcryp_aes.Instance->CR &= ~AES_CR_EN; | ||
*iv_ptr++ = ctx->hcryp_aes.Instance->IVR3; | ||
*iv_ptr++ = ctx->hcryp_aes.Instance->IVR2; | ||
*iv_ptr++ = ctx->hcryp_aes.Instance->IVR1; | ||
*iv_ptr++ = ctx->hcryp_aes.Instance->IVR0; | ||
|
||
} else { | ||
status = st_hal_cryp_cbc(ctx, CRYP_ALGOMODE_ENCRYPT, length, iv, (uint8_t *)input, (uint8_t *)output); | ||
status |= st_hal_cryp_cbc(ctx, CRYP_ALGOMODE_ENCRYPT, length, iv, (uint8_t *)input, (uint8_t *)output); | ||
memcpy( iv, output, 16 ); | ||
} | ||
#else | ||
ctx->hcryp_aes.Init.pInitVect = &iv[0]; | ||
|
||
if( mode == MBEDTLS_AES_DECRYPT ) { | ||
status = HAL_CRYP_AESCBC_Decrypt(&ctx->hcryp_aes, (uint8_t *)input, length, (uint8_t *)output, 10); | ||
status |= HAL_CRYP_AESCBC_Decrypt(&ctx->hcryp_aes, (uint8_t *)input, length, (uint8_t *)output, 10); | ||
} else { | ||
status = HAL_CRYP_AESCBC_Encrypt(&ctx->hcryp_aes, (uint8_t *)input, length, (uint8_t *)output, 10); | ||
status |= HAL_CRYP_AESCBC_Encrypt(&ctx->hcryp_aes, (uint8_t *)input, length, (uint8_t *)output, 10); | ||
} | ||
#endif | ||
status |= st_cbc_save_context(ctx); | ||
|
||
return( status ); | ||
} | ||
#endif /* MBEDTLS_CIPHER_MODE_CBC */ | ||
|
@@ -304,26 +389,41 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, | |
} | ||
#endif /* MBEDTLS_CIPHER_MODE_CTR */ | ||
|
||
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, | ||
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, | ||
const unsigned char input[16], | ||
unsigned char output[16] ) | ||
{ | ||
|
||
if (HAL_CRYP_AESECB_Encrypt(&ctx->hcryp_aes, (uint8_t *)input, 16, (uint8_t *)output, 10) !=0) { | ||
// error found to be returned | ||
// error found | ||
return 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
return 0; | ||
|
||
} | ||
|
||
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, | ||
const unsigned char input[16], | ||
unsigned char output[16] ) | ||
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, | ||
const unsigned char input[16], | ||
unsigned char output[16] ) | ||
{ | ||
|
||
if(HAL_CRYP_AESECB_Decrypt(&ctx->hcryp_aes, (uint8_t *)input, 16, (uint8_t *)output, 10)) { | ||
// error found to be returned | ||
// error found | ||
return 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
} | ||
return 0; | ||
} | ||
|
||
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, | ||
const unsigned char input[16], | ||
unsigned char output[16] ) | ||
{ | ||
mbedtls_internal_aes_encrypt( ctx, input, output ); | ||
} | ||
|
||
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, | ||
const unsigned char input[16], | ||
unsigned char output[16] ) | ||
{ | ||
mbedtls_internal_aes_decrypt( ctx, input, output ); | ||
} | ||
|
||
#endif /*MBEDTLS_AES_ALT*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
/* | ||
* aes_alt.h AES block cipher | ||
******************************************************************************* | ||
* Copyright (c) 2016, STMicroelectronics | ||
* Copyright (c) 2017, STMicroelectronics | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
|
@@ -30,6 +30,8 @@ | |
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#define ST_AES_TIMEOUT ((uint32_t) 3) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please add a comment explaining the rationale behind this #define? Also, it would be good to document what units are used and why is 3 a good choice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I must check that the crypto processor is not busy before reading / writing some registers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that instead of lowering the timeout to one it would be better to raise it to a very high value, preferably high enough to make the behaviour practically synchronous, because:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How many milliseconds would you consider as high enough ? The default value used in ST examples codes is 0xFF There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Considering that as you say 1 ms should be fine in most cases, 0xFF seems good enough to me. |
||
/** | ||
* \brief AES context structure | ||
* | ||
|
@@ -43,6 +45,7 @@ typedef struct | |
unsigned char aes_key[32]; /* Decryption key */ | ||
CRYP_HandleTypeDef hcryp_aes; | ||
uint32_t ctx_save_cr; /* save context for multi-instance */ | ||
uint32_t save_iv[4]; /* save context for multi-instance */ | ||
} | ||
mbedtls_aes_context; | ||
|
||
|
@@ -236,10 +239,12 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, | |
* \param ctx AES context | ||
* \param input Plaintext block | ||
* \param output Output (ciphertext) block | ||
* | ||
* \return 0 if successful | ||
*/ | ||
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, | ||
const unsigned char input[16], | ||
unsigned char output[16] ); | ||
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, | ||
const unsigned char input[16], | ||
unsigned char output[16] ); | ||
|
||
/** | ||
* \brief Internal AES block decryption function | ||
|
@@ -249,10 +254,49 @@ void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, | |
* \param ctx AES context | ||
* \param input Ciphertext block | ||
* \param output Output (plaintext) block | ||
* | ||
* \return 0 if successful | ||
*/ | ||
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, | ||
const unsigned char input[16], | ||
unsigned char output[16] ); | ||
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, | ||
const unsigned char input[16], | ||
unsigned char output[16] ); | ||
|
||
#if !defined(MBEDTLS_DEPRECATED_REMOVED) | ||
#if defined(MBEDTLS_DEPRECATED_WARNING) | ||
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) | ||
#else | ||
#define MBEDTLS_DEPRECATED | ||
#endif | ||
/** | ||
* \brief Deprecated internal AES block encryption function | ||
* without return value. | ||
* | ||
* \deprecated Superseded by mbedtls_aes_encrypt_ext() in 2.5.0 | ||
* | ||
* \param ctx AES context | ||
* \param input Plaintext block | ||
* \param output Output (ciphertext) block | ||
*/ | ||
MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since it's deprecated and you don't call this API, you don't need to declare it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if it is called by users ? |
||
const unsigned char input[16], | ||
unsigned char output[16] ); | ||
|
||
/** | ||
* \brief Deprecated internal AES block decryption function | ||
* without return value. | ||
* | ||
* \deprecated Superseded by mbedtls_aes_decrypt_ext() in 2.5.0 | ||
* | ||
* \param ctx AES context | ||
* \param input Ciphertext block | ||
* \param output Output (plaintext) block | ||
*/ | ||
MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since it's deprecated and you don't call this API, you don't need to declare it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if it is called by users ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that both @adustm and @RonEld have a point: @RonEld: @adustm: In the unlikely case that I am not sure what the right course of action is in these cases. @yanesca what do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't noticed you implemented these functions. But at least you should surround the implementation of these functions with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The options of giving deprecated warnings for deprecated functions and for removing them is an mbed TLS feature, and as far as I know mbed OS doesn't have it and even if it does, it is unlikely to be integrated. (@0xc0170 Do you know something about a feature like this in mbed OS?) Therefore I think that we should implement the deprecated functions and enable the applications to call them (even if they were never supposed to do so). Although I think that the current solution is acceptable, @RonEld is right that it would be prettier if the implementations would be surrounded by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you all for these answers. I'll add the #if !defined(MBEDTLS_DEPRECATED_REMOVED) |
||
const unsigned char input[16], | ||
unsigned char output[16] ); | ||
|
||
#undef MBEDTLS_DEPRECATED | ||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ | ||
|
||
#ifdef __cplusplus | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am terribly sorry, but I am not very familiar with this terminology, could you please give me some pointers on what an "AES collector" is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly don't remember where I copied this expression from. I'll rephrase to
Hardware AES implementation for STM32F4 / STM32L4 and STM32F7 families