mirror of https://github.com/ARMmbed/mbed-os.git
[NUC472/M487] Refine AES alter. DMA buffer code
parent
f24ca8c857
commit
93f6ef996f
|
@ -27,10 +27,12 @@
|
||||||
#if defined(MBEDTLS_AES_ALT)
|
#if defined(MBEDTLS_AES_ALT)
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "M480.h"
|
#include "M480.h"
|
||||||
#include "mbed_toolchain.h"
|
#include "mbed_toolchain.h"
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_error.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +63,17 @@ static void swapInitVector(unsigned char iv[16])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if buffer can be used for AES DMA. It requires to be:
|
||||||
|
* 1) Word-aligned
|
||||||
|
* 2) Located in 0x2xxxxxxx region
|
||||||
|
*/
|
||||||
|
static bool aes_dma_buff_compat(const void *buff)
|
||||||
|
{
|
||||||
|
uint32_t buff_ = (uint32_t) buff;
|
||||||
|
|
||||||
|
return (((buff_ & 0x03) == 0) && ((buff_ & 0x20000000) == 0x20000000));
|
||||||
|
}
|
||||||
|
|
||||||
void mbedtls_aes_init( mbedtls_aes_context *ctx )
|
void mbedtls_aes_init( mbedtls_aes_context *ctx )
|
||||||
{
|
{
|
||||||
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
|
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
|
||||||
|
@ -144,12 +157,13 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
|
||||||
|
|
||||||
/* AES DMA buffer requires to be:
|
/* AES DMA buffer requires to be:
|
||||||
* 1) Word-aligned
|
* 1) Word-aligned
|
||||||
* 2) Located in 0x2xxxxxxx range
|
* 2) Located in 0x2xxxxxxx region
|
||||||
*/
|
*/
|
||||||
MBED_ALIGN(4) uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE];
|
MBED_ALIGN(4) uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE];
|
||||||
MBED_ALIGN(4) uint8_t au8InputData[MAX_DMA_CHAIN_SIZE];
|
MBED_ALIGN(4) uint8_t au8InputData[MAX_DMA_CHAIN_SIZE];
|
||||||
MBED_ASSERT(((((uint32_t) au8OutputData) & 0x03) == 0) && ((((uint32_t) au8OutputData) & 0x20000000) == 0x20000000));
|
if ((! aes_dma_buff_compat(au8OutputData)) || (! aes_dma_buff_compat(au8InputData))) {
|
||||||
MBED_ASSERT(((((uint32_t) au8InputData) & 0x03) == 0) && ((((uint32_t) au8InputData) & 0x20000000) == 0x20000000));
|
error("Buffer for AES alter. DMA requires to be word-aligned and located in 0x2xxxxxxx region.");
|
||||||
|
}
|
||||||
|
|
||||||
/* We support multiple contexts with context save & restore and so needs just one
|
/* We support multiple contexts with context save & restore and so needs just one
|
||||||
* H/W channel. Always use H/W channel #0. */
|
* H/W channel. Always use H/W channel #0. */
|
||||||
|
@ -158,14 +172,17 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
|
||||||
AES_SetInitVect(0, ctx->iv);
|
AES_SetInitVect(0, ctx->iv);
|
||||||
AES_SetKey(0, ctx->buf, ctx->keySize);
|
AES_SetKey(0, ctx->buf, ctx->keySize);
|
||||||
/* AES DMA buffer requirements same as above */
|
/* AES DMA buffer requirements same as above */
|
||||||
if ((((uint32_t) input) & 0x03) || ((((uint32_t) input) & 0x20000000) != 0x20000000)) {
|
if (! aes_dma_buff_compat(input)) {
|
||||||
|
if (dataSize > MAX_DMA_CHAIN_SIZE) {
|
||||||
|
error("Internal AES alter. error. DMA buffer is too small.");
|
||||||
|
}
|
||||||
memcpy(au8InputData, input, dataSize);
|
memcpy(au8InputData, input, dataSize);
|
||||||
pIn = au8InputData;
|
pIn = au8InputData;
|
||||||
} else {
|
} else {
|
||||||
pIn = input;
|
pIn = input;
|
||||||
}
|
}
|
||||||
/* AES DMA buffer requirements same as above */
|
/* AES DMA buffer requirements same as above */
|
||||||
if ((((uint32_t) output) & 0x03) || ((((uint32_t) output) & 0x20000000) != 0x20000000)) {
|
if (! aes_dma_buff_compat(output)) {
|
||||||
pOut = au8OutputData;
|
pOut = au8OutputData;
|
||||||
} else {
|
} else {
|
||||||
pOut = output;
|
pOut = output;
|
||||||
|
@ -177,8 +194,13 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
|
||||||
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
||||||
while (!g_AES_done);
|
while (!g_AES_done);
|
||||||
|
|
||||||
if( pOut != output ) memcpy(output, au8OutputData, dataSize);
|
if( pOut != output ) {
|
||||||
|
if (dataSize > MAX_DMA_CHAIN_SIZE) {
|
||||||
|
error("Internal AES alter. error. DMA buffer is too small.");
|
||||||
|
}
|
||||||
|
memcpy(output, au8OutputData, dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
/* Save IV for next block */
|
/* Save IV for next block */
|
||||||
ctx->iv[0] = CRPT->AES_FDBCK[0];
|
ctx->iv[0] = CRPT->AES_FDBCK[0];
|
||||||
ctx->iv[1] = CRPT->AES_FDBCK[1];
|
ctx->iv[1] = CRPT->AES_FDBCK[1];
|
||||||
|
@ -244,13 +266,10 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
||||||
if( length % 16 )
|
if( length % 16 )
|
||||||
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
|
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
|
||||||
|
|
||||||
if( (((uint32_t)input) & 0x03) || (((uint32_t)output) & 0x03) ) {
|
|
||||||
blockChainLen = (( length > MAX_DMA_CHAIN_SIZE ) ? MAX_DMA_CHAIN_SIZE : length );
|
|
||||||
} else {
|
|
||||||
blockChainLen = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
while( length > 0 ) {
|
while( length > 0 ) {
|
||||||
|
blockChainLen = (length > MAX_DMA_CHAIN_SIZE) ? MAX_DMA_CHAIN_SIZE : length;
|
||||||
|
|
||||||
ctx->opMode = AES_MODE_CBC;
|
ctx->opMode = AES_MODE_CBC;
|
||||||
swapInitVector(iv); // iv SWAP
|
swapInitVector(iv); // iv SWAP
|
||||||
memcpy(ctx->iv, iv, 16);
|
memcpy(ctx->iv, iv, 16);
|
||||||
|
@ -268,8 +287,6 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
||||||
length -= blockChainLen;
|
length -= blockChainLen;
|
||||||
input += blockChainLen;
|
input += blockChainLen;
|
||||||
output += blockChainLen;
|
output += blockChainLen;
|
||||||
if(length < MAX_DMA_CHAIN_SIZE ) blockChainLen = length; // For last remainder block chain
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
|
|
@ -27,10 +27,12 @@
|
||||||
#if defined(MBEDTLS_AES_ALT)
|
#if defined(MBEDTLS_AES_ALT)
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "NUC472_442.h"
|
#include "NUC472_442.h"
|
||||||
#include "mbed_toolchain.h"
|
#include "mbed_toolchain.h"
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
|
#include "mbed_error.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +63,17 @@ static void swapInitVector(unsigned char iv[16])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if buffer can be used for AES DMA. It requires to be:
|
||||||
|
* 1) Word-aligned
|
||||||
|
* 2) Located in 0x2xxxxxxx region
|
||||||
|
*/
|
||||||
|
static bool aes_dma_buff_compat(const void *buff)
|
||||||
|
{
|
||||||
|
uint32_t buff_ = (uint32_t) buff;
|
||||||
|
|
||||||
|
return (((buff_ & 0x03) == 0) && ((buff_ & 0x20000000) == 0x20000000));
|
||||||
|
}
|
||||||
|
|
||||||
void mbedtls_aes_init( mbedtls_aes_context *ctx )
|
void mbedtls_aes_init( mbedtls_aes_context *ctx )
|
||||||
{
|
{
|
||||||
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
|
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
|
||||||
|
@ -144,12 +157,13 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
|
||||||
|
|
||||||
/* AES DMA buffer requires to be:
|
/* AES DMA buffer requires to be:
|
||||||
* 1) Word-aligned
|
* 1) Word-aligned
|
||||||
* 2) Located in 0x2xxxxxxx range
|
* 2) Located in 0x2xxxxxxx region
|
||||||
*/
|
*/
|
||||||
MBED_ALIGN(4) uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE];
|
MBED_ALIGN(4) uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE];
|
||||||
MBED_ALIGN(4) uint8_t au8InputData[MAX_DMA_CHAIN_SIZE];
|
MBED_ALIGN(4) uint8_t au8InputData[MAX_DMA_CHAIN_SIZE];
|
||||||
MBED_ASSERT(((((uint32_t) au8OutputData) & 0x03) == 0) && ((((uint32_t) au8OutputData) & 0x20000000) == 0x20000000));
|
if ((! aes_dma_buff_compat(au8OutputData)) || (! aes_dma_buff_compat(au8InputData))) {
|
||||||
MBED_ASSERT(((((uint32_t) au8InputData) & 0x03) == 0) && ((((uint32_t) au8InputData) & 0x20000000) == 0x20000000));
|
error("Buffer for AES alter. DMA requires to be word-aligned and located in 0x2xxxxxxx region.");
|
||||||
|
}
|
||||||
|
|
||||||
/* We support multiple contexts with context save & restore and so needs just one
|
/* We support multiple contexts with context save & restore and so needs just one
|
||||||
* H/W channel. Always use H/W channel #0. */
|
* H/W channel. Always use H/W channel #0. */
|
||||||
|
@ -158,14 +172,17 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
|
||||||
AES_SetInitVect(0, ctx->iv);
|
AES_SetInitVect(0, ctx->iv);
|
||||||
AES_SetKey(0, ctx->buf, ctx->keySize);
|
AES_SetKey(0, ctx->buf, ctx->keySize);
|
||||||
/* AES DMA buffer requirements same as above */
|
/* AES DMA buffer requirements same as above */
|
||||||
if ((((uint32_t) input) & 0x03) || ((((uint32_t) input) & 0x20000000) != 0x20000000)) {
|
if (! aes_dma_buff_compat(input)) {
|
||||||
|
if (dataSize > MAX_DMA_CHAIN_SIZE) {
|
||||||
|
error("Internal AES alter. error. DMA buffer is too small.");
|
||||||
|
}
|
||||||
memcpy(au8InputData, input, dataSize);
|
memcpy(au8InputData, input, dataSize);
|
||||||
pIn = au8InputData;
|
pIn = au8InputData;
|
||||||
} else {
|
} else {
|
||||||
pIn = input;
|
pIn = input;
|
||||||
}
|
}
|
||||||
/* AES DMA buffer requirements same as above */
|
/* AES DMA buffer requirements same as above */
|
||||||
if ((((uint32_t) output) & 0x03) || ((((uint32_t) output) & 0x20000000) != 0x20000000)) {
|
if (! aes_dma_buff_compat(output)) {
|
||||||
pOut = au8OutputData;
|
pOut = au8OutputData;
|
||||||
} else {
|
} else {
|
||||||
pOut = output;
|
pOut = output;
|
||||||
|
@ -177,8 +194,13 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
|
||||||
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
|
||||||
while (!g_AES_done);
|
while (!g_AES_done);
|
||||||
|
|
||||||
if( pOut != output ) memcpy(output, au8OutputData, dataSize);
|
if( pOut != output ) {
|
||||||
|
if (dataSize > MAX_DMA_CHAIN_SIZE) {
|
||||||
|
error("Internal AES alter. error. DMA buffer is too small.");
|
||||||
|
}
|
||||||
|
memcpy(output, au8OutputData, dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
/* Save IV for next block */
|
/* Save IV for next block */
|
||||||
ctx->iv[0] = CRPT->AES_FDBCK0;
|
ctx->iv[0] = CRPT->AES_FDBCK0;
|
||||||
ctx->iv[1] = CRPT->AES_FDBCK1;
|
ctx->iv[1] = CRPT->AES_FDBCK1;
|
||||||
|
@ -244,13 +266,10 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
||||||
if( length % 16 )
|
if( length % 16 )
|
||||||
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
|
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
|
||||||
|
|
||||||
if( (((uint32_t)input) & 0x03) || (((uint32_t)output) & 0x03) ) {
|
|
||||||
blockChainLen = (( length > MAX_DMA_CHAIN_SIZE ) ? MAX_DMA_CHAIN_SIZE : length );
|
|
||||||
} else {
|
|
||||||
blockChainLen = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
while( length > 0 ) {
|
while( length > 0 ) {
|
||||||
|
blockChainLen = (length > MAX_DMA_CHAIN_SIZE) ? MAX_DMA_CHAIN_SIZE : length;
|
||||||
|
|
||||||
ctx->opMode = AES_MODE_CBC;
|
ctx->opMode = AES_MODE_CBC;
|
||||||
swapInitVector(iv); // iv SWAP
|
swapInitVector(iv); // iv SWAP
|
||||||
memcpy(ctx->iv, iv, 16);
|
memcpy(ctx->iv, iv, 16);
|
||||||
|
@ -268,8 +287,6 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
||||||
length -= blockChainLen;
|
length -= blockChainLen;
|
||||||
input += blockChainLen;
|
input += blockChainLen;
|
||||||
output += blockChainLen;
|
output += blockChainLen;
|
||||||
if(length < MAX_DMA_CHAIN_SIZE ) blockChainLen = length; // For last remainder block chain
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
|
Loading…
Reference in New Issue