[NUC472/M487] Refine AES/DES alter. code

pull/4925/head
ccli8 2017-09-27 14:29:40 +08:00
parent 289bbf0ec7
commit 0c2d59d327
10 changed files with 102 additions and 130 deletions

View File

@ -45,26 +45,15 @@ static void mbedtls_zeroize( void *v, size_t n )
extern volatile int g_AES_done; extern volatile int g_AES_done;
// Must be a multiple of 16 bytes block size /* DMA compatible backup buffer if user buffer doesn't meet requirements
*
* MAX_DMA_CHAIN_SIZE must be a multiple of 16-byte block size.
* Its value is estimated to trade memory footprint off against performance.
*/
#define MAX_DMA_CHAIN_SIZE (16*6) #define MAX_DMA_CHAIN_SIZE (16*6)
/* Backup buffer for DMA if user buffer doesn't meet requirements. */
MBED_ALIGN(4) static uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE]; MBED_ALIGN(4) static uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE];
MBED_ALIGN(4) static uint8_t au8InputData[MAX_DMA_CHAIN_SIZE]; MBED_ALIGN(4) static uint8_t au8InputData[MAX_DMA_CHAIN_SIZE];
/* Check if buffer can be used for AES DMA. It requires to be:
* 1) Word-aligned
* 2) Located in 0x20000000-0x2FFFFFFF region
*/
static bool aes_dma_buff_compat(const void *buff, unsigned buff_size)
{
uint32_t buff_ = (uint32_t) buff;
return (((buff_ & 0x03) == 0) && /* Word-aligned */
(((unsigned) buff_) >= 0x20000000) && /* 0x20000000-0x2FFFFFFF */
((((unsigned) buff) + buff_size) <= 0x30000000));
}
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 ) );
@ -102,7 +91,7 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
// key swap // key swap
for( i = 0; i < ( keybits >> 5 ); i++ ) { for( i = 0; i < ( keybits >> 5 ); i++ ) {
ctx->buf[i] = (*(key+i*4) << 24) | ctx->keys[i] = (*(key+i*4) << 24) |
(*(key+1+i*4) << 16) | (*(key+1+i*4) << 16) |
(*(key+2+i*4) << 8) | (*(key+2+i*4) << 8) |
(*(key+3+i*4) ); (*(key+3+i*4) );
@ -127,19 +116,29 @@ exit:
return( ret ); return( ret );
} }
/* Do AES encrypt/decrypt with H/W accelerator
*
* NOTE: As input/output buffer doesn't follow constraint of DMA buffer, static allocated
* DMA compatible buffer is used for DMA instead and this needs extra copy.
*
* NOTE: dataSize requires to be:
* 1) Multiple of block size 16
* 2) <= MAX_DMA_CHAIN_SIZE
*/
static void __nvt_aes_crypt( mbedtls_aes_context *ctx, static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
const unsigned char input[16], const unsigned char *input,
unsigned char output[16], int dataSize) unsigned char *output, size_t dataSize)
{ {
const unsigned char* pIn; const unsigned char* pIn;
unsigned char* pOut; unsigned char* pOut;
MBED_ASSERT((dataSize % 16 == 0) && (dataSize <= MAX_DMA_CHAIN_SIZE));
/* AES DMA buffer requires to be: /* AES DMA buffer requires to be:
* 1) Word-aligned * 1) Word-aligned
* 2) Located in 0x2xxxxxxx region * 2) Located in 0x2xxxxxxx region
*/ */
if ((! aes_dma_buff_compat(au8OutputData, MAX_DMA_CHAIN_SIZE)) || (! aes_dma_buff_compat(au8InputData, MAX_DMA_CHAIN_SIZE))) { if ((! crypto_dma_buff_compat(au8OutputData, MAX_DMA_CHAIN_SIZE)) || (! crypto_dma_buff_compat(au8InputData, MAX_DMA_CHAIN_SIZE))) {
error("Buffer for AES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region."); error("Buffer for AES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region.");
} }
@ -158,19 +157,16 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
/* AES_IN_OUT_SWAP: Let H/W know both input/output data are arranged in little-endian */ /* AES_IN_OUT_SWAP: Let H/W know both input/output data are arranged in little-endian */
AES_Open(0, ctx->encDec, ctx->opMode, ctx->keySize, AES_IN_OUT_SWAP); AES_Open(0, ctx->encDec, ctx->opMode, ctx->keySize, AES_IN_OUT_SWAP);
AES_SetInitVect(0, ctx->iv); AES_SetInitVect(0, ctx->iv);
AES_SetKey(0, ctx->buf, ctx->keySize); AES_SetKey(0, ctx->keys, ctx->keySize);
/* AES DMA buffer requirements same as above */ /* AES DMA buffer requirements same as above */
if (! aes_dma_buff_compat(input, dataSize)) { if (! crypto_dma_buff_compat(input, dataSize)) {
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 (! aes_dma_buff_compat(output, dataSize)) { if (! crypto_dma_buff_compat(output, dataSize)) {
pOut = au8OutputData; pOut = au8OutputData;
} else { } else {
pOut = output; pOut = output;
@ -183,9 +179,6 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
while (!g_AES_done); while (!g_AES_done);
if( pOut != output ) { if( pOut != output ) {
if (dataSize > MAX_DMA_CHAIN_SIZE) {
error("Internal AES alter. error. DMA buffer is too small.");
}
memcpy(output, au8OutputData, dataSize); memcpy(output, au8OutputData, dataSize);
} }
@ -311,12 +304,9 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
int c; int c;
size_t n = *iv_off; size_t n = *iv_off;
/* First incomplete block*/ /* First incomplete block */
if (n % 16) { if (n % 16) {
size_t rmn = 16 - n; while (n && length) {
rmn = (rmn > length) ? length : rmn;
while( rmn -- ) {
if (mode == MBEDTLS_AES_DECRYPT) { if (mode == MBEDTLS_AES_DECRYPT) {
c = *input++; c = *input++;
*output++ = (unsigned char)( c ^ iv[n] ); *output++ = (unsigned char)( c ^ iv[n] );
@ -332,7 +322,7 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
} }
/* Middle complete block(s) */ /* Middle complete block(s) */
size_t block_chain_len = length / 16 * 16; size_t block_chain_len = length - (length % 16);
if (block_chain_len) { if (block_chain_len) {
ctx->opMode = AES_MODE_CFB; ctx->opMode = AES_MODE_CFB;
@ -371,15 +361,10 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
} }
/* Last incomplete block */ /* Last incomplete block */
size_t last_block_len = length; if (length) {
if (last_block_len) {
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
size_t rmn = last_block_len; while (length --) {
rmn = (rmn > length) ? length : rmn;
while (rmn --) {
if (mode == MBEDTLS_AES_DECRYPT) { if (mode == MBEDTLS_AES_DECRYPT) {
c = *input++; c = *input++;
*output++ = (unsigned char)( c ^ iv[n] ); *output++ = (unsigned char)( c ^ iv[n] );
@ -390,7 +375,6 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
} }
n = ( n + 1 ) & 0x0F; n = ( n + 1 ) & 0x0F;
length --;
} }
} }

View File

@ -35,18 +35,13 @@ extern "C" {
/** /**
* \brief AES context structure * \brief AES context structure
*
* \note buf is able to hold 32 extra bytes, which can be used:
* - for alignment purposes if VIA padlock is used, and/or
* - to simplify key expansion in the 256-bit case by
* generating an extra round key
*/ */
typedef struct { typedef struct {
uint32_t keySize; /* Key size: AES_KEY_SIZE_128/192/256 */ uint32_t keySize; /* Key size: AES_KEY_SIZE_128/192/256 */
uint32_t encDec; /* 0: decrypt, 1: encrypt */ uint32_t encDec; /* 0: decrypt, 1: encrypt */
uint32_t opMode; /* AES_MODE_ECB/CBC/CFB */ uint32_t opMode; /* AES_MODE_ECB/CBC/CFB */
uint32_t iv[4]; /* IV for next block cipher */ uint32_t iv[4]; /* IV for next block cipher */
uint32_t buf[8]; /* Cipher key */ uint32_t keys[8]; /* Cipher key */
} }
mbedtls_aes_context; mbedtls_aes_context;

View File

@ -122,6 +122,15 @@ void crypto_sha_release(void)
crypto_submodule_release(&crypto_sha_avail); crypto_submodule_release(&crypto_sha_avail);
} }
bool crypto_dma_buff_compat(const void *buff, size_t buff_size)
{
uint32_t buff_ = (uint32_t) buff;
return (((buff_ & 0x03) == 0) && /* Word-aligned */
(buff_ >= 0x20000000) && /* 0x20000000-0x2FFFFFFF */
((buff_ + buff_size) <= 0x30000000));
}
static bool crypto_submodule_acquire(uint16_t *submodule_avail) static bool crypto_submodule_acquire(uint16_t *submodule_avail)
{ {
uint16_t expectedCurrentValue = 1; uint16_t expectedCurrentValue = 1;

View File

@ -44,6 +44,13 @@ void crypto_des_release(void);
bool crypto_sha_acquire(void); bool crypto_sha_acquire(void);
void crypto_sha_release(void); void crypto_sha_release(void);
/* Check if buffer can be used for crypto DMA. It requires to be:
*
* 1) Word-aligned
* 2) Located in 0x20000000-0x2FFFFFFF region
*/
bool crypto_dma_buff_compat(const void *buff, size_t buff_size);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -26,24 +26,15 @@
#include "mbed_toolchain.h" #include "mbed_toolchain.h"
#include "mbed_error.h" #include "mbed_error.h"
// Must be a multiple of 64-bit block size /* DMA buffer
*
* MAXSIZE_DMABUF must be a multiple of 64-bit block size.
* Its value is estimated to trade memory footprint off against performance.
*/
#define MAXSIZE_DMABUF (8 * 5) #define MAXSIZE_DMABUF (8 * 5)
MBED_ALIGN(4) static uint8_t dmabuf_in[MAXSIZE_DMABUF]; MBED_ALIGN(4) static uint8_t dmabuf_in[MAXSIZE_DMABUF];
MBED_ALIGN(4) static uint8_t dmabuf_out[MAXSIZE_DMABUF]; MBED_ALIGN(4) static uint8_t dmabuf_out[MAXSIZE_DMABUF];
/* Check if buffer can be used for DES DMA. It requires to be:
* 1) Word-aligned
* 2) Located in 0x20000000-0x2FFFFFFF region
*/
static bool des_dma_buff_compat(const void *buff, unsigned buff_size)
{
uint32_t buff_ = (uint32_t) buff;
return (((buff_ & 0x03) == 0) && /* Word-aligned */
(((unsigned) buff_) >= 0x20000000) && /* 0x20000000-0x2FFFFFFF */
((((unsigned) buff) + buff_size) <= 0x30000000));
}
static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_SIZE], int enc, uint32_t tdes_opmode, size_t length, static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_SIZE], int enc, uint32_t tdes_opmode, size_t length,
unsigned char iv[8], const unsigned char *input, unsigned char *output); unsigned char iv[8], const unsigned char *input, unsigned char *output);
@ -323,7 +314,7 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
* 1) Word-aligned * 1) Word-aligned
* 2) Located in 0x2xxxxxxx region * 2) Located in 0x2xxxxxxx region
*/ */
if ((! des_dma_buff_compat(dmabuf_in, MAXSIZE_DMABUF)) || (! des_dma_buff_compat(dmabuf_out, MAXSIZE_DMABUF))) { if ((! crypto_dma_buff_compat(dmabuf_in, MAXSIZE_DMABUF)) || (! crypto_dma_buff_compat(dmabuf_out, MAXSIZE_DMABUF))) {
error("Buffer for DES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region."); error("Buffer for DES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region.");
} }

View File

@ -45,26 +45,15 @@ static void mbedtls_zeroize( void *v, size_t n )
extern volatile int g_AES_done; extern volatile int g_AES_done;
// Must be a multiple of 16 bytes block size /* DMA compatible backup buffer if user buffer doesn't meet requirements
*
* MAX_DMA_CHAIN_SIZE must be a multiple of 16-byte block size.
* Its value is estimated to trade memory footprint off against performance.
*/
#define MAX_DMA_CHAIN_SIZE (16*6) #define MAX_DMA_CHAIN_SIZE (16*6)
/* Backup buffer for DMA if user buffer doesn't meet requirements. */
MBED_ALIGN(4) static uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE]; MBED_ALIGN(4) static uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE];
MBED_ALIGN(4) static uint8_t au8InputData[MAX_DMA_CHAIN_SIZE]; MBED_ALIGN(4) static uint8_t au8InputData[MAX_DMA_CHAIN_SIZE];
/* Check if buffer can be used for AES DMA. It requires to be:
* 1) Word-aligned
* 2) Located in 0x20000000-0x2FFFFFFF region
*/
static bool aes_dma_buff_compat(const void *buff, unsigned buff_size)
{
uint32_t buff_ = (uint32_t) buff;
return (((buff_ & 0x03) == 0) && /* Word-aligned */
(((unsigned) buff_) >= 0x20000000) && /* 0x20000000-0x2FFFFFFF */
((((unsigned) buff) + buff_size) <= 0x30000000));
}
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 ) );
@ -102,7 +91,7 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
// key swap // key swap
for( i = 0; i < ( keybits >> 5 ); i++ ) { for( i = 0; i < ( keybits >> 5 ); i++ ) {
ctx->buf[i] = (*(key+i*4) << 24) | ctx->keys[i] = (*(key+i*4) << 24) |
(*(key+1+i*4) << 16) | (*(key+1+i*4) << 16) |
(*(key+2+i*4) << 8) | (*(key+2+i*4) << 8) |
(*(key+3+i*4) ); (*(key+3+i*4) );
@ -127,19 +116,29 @@ exit:
return( ret ); return( ret );
} }
/* Do AES encrypt/decrypt with H/W accelerator
*
* NOTE: As input/output buffer doesn't follow constraint of DMA buffer, static allocated
* DMA compatible buffer is used for DMA instead and this needs extra copy.
*
* NOTE: dataSize requires to be:
* 1) Multiple of block size 16
* 2) <= MAX_DMA_CHAIN_SIZE
*/
static void __nvt_aes_crypt( mbedtls_aes_context *ctx, static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
const unsigned char input[16], const unsigned char *input,
unsigned char output[16], int dataSize) unsigned char *output, size_t dataSize)
{ {
const unsigned char* pIn; const unsigned char* pIn;
unsigned char* pOut; unsigned char* pOut;
MBED_ASSERT((dataSize % 16 == 0) && (dataSize <= MAX_DMA_CHAIN_SIZE));
/* AES DMA buffer requires to be: /* AES DMA buffer requires to be:
* 1) Word-aligned * 1) Word-aligned
* 2) Located in 0x2xxxxxxx region * 2) Located in 0x2xxxxxxx region
*/ */
if ((! aes_dma_buff_compat(au8OutputData, MAX_DMA_CHAIN_SIZE)) || (! aes_dma_buff_compat(au8InputData, MAX_DMA_CHAIN_SIZE))) { if ((! crypto_dma_buff_compat(au8OutputData, MAX_DMA_CHAIN_SIZE)) || (! crypto_dma_buff_compat(au8InputData, MAX_DMA_CHAIN_SIZE))) {
error("Buffer for AES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region."); error("Buffer for AES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region.");
} }
@ -158,19 +157,16 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
/* AES_IN_OUT_SWAP: Let H/W know both input/output data are arranged in little-endian */ /* AES_IN_OUT_SWAP: Let H/W know both input/output data are arranged in little-endian */
AES_Open(0, ctx->encDec, ctx->opMode, ctx->keySize, AES_IN_OUT_SWAP); AES_Open(0, ctx->encDec, ctx->opMode, ctx->keySize, AES_IN_OUT_SWAP);
AES_SetInitVect(0, ctx->iv); AES_SetInitVect(0, ctx->iv);
AES_SetKey(0, ctx->buf, ctx->keySize); AES_SetKey(0, ctx->keys, ctx->keySize);
/* AES DMA buffer requirements same as above */ /* AES DMA buffer requirements same as above */
if (! aes_dma_buff_compat(input, dataSize)) { if (! crypto_dma_buff_compat(input, dataSize)) {
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 (! aes_dma_buff_compat(output, dataSize)) { if (! crypto_dma_buff_compat(output, dataSize)) {
pOut = au8OutputData; pOut = au8OutputData;
} else { } else {
pOut = output; pOut = output;
@ -183,9 +179,6 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
while (!g_AES_done); while (!g_AES_done);
if( pOut != output ) { if( pOut != output ) {
if (dataSize > MAX_DMA_CHAIN_SIZE) {
error("Internal AES alter. error. DMA buffer is too small.");
}
memcpy(output, au8OutputData, dataSize); memcpy(output, au8OutputData, dataSize);
} }
@ -311,12 +304,9 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
int c; int c;
size_t n = *iv_off; size_t n = *iv_off;
/* First incomplete block*/ /* First incomplete block */
if (n % 16) { if (n % 16) {
size_t rmn = 16 - n; while (n && length) {
rmn = (rmn > length) ? length : rmn;
while( rmn -- ) {
if (mode == MBEDTLS_AES_DECRYPT) { if (mode == MBEDTLS_AES_DECRYPT) {
c = *input++; c = *input++;
*output++ = (unsigned char)( c ^ iv[n] ); *output++ = (unsigned char)( c ^ iv[n] );
@ -332,7 +322,7 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
} }
/* Middle complete block(s) */ /* Middle complete block(s) */
size_t block_chain_len = length / 16 * 16; size_t block_chain_len = length - (length % 16);
if (block_chain_len) { if (block_chain_len) {
ctx->opMode = AES_MODE_CFB; ctx->opMode = AES_MODE_CFB;
@ -371,15 +361,10 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
} }
/* Last incomplete block */ /* Last incomplete block */
size_t last_block_len = length; if (length) {
if (last_block_len) {
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
size_t rmn = last_block_len; while (length --) {
rmn = (rmn > length) ? length : rmn;
while (rmn --) {
if (mode == MBEDTLS_AES_DECRYPT) { if (mode == MBEDTLS_AES_DECRYPT) {
c = *input++; c = *input++;
*output++ = (unsigned char)( c ^ iv[n] ); *output++ = (unsigned char)( c ^ iv[n] );
@ -390,7 +375,6 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
} }
n = ( n + 1 ) & 0x0F; n = ( n + 1 ) & 0x0F;
length --;
} }
} }

View File

@ -35,18 +35,13 @@ extern "C" {
/** /**
* \brief AES context structure * \brief AES context structure
*
* \note buf is able to hold 32 extra bytes, which can be used:
* - for alignment purposes if VIA padlock is used, and/or
* - to simplify key expansion in the 256-bit case by
* generating an extra round key
*/ */
typedef struct { typedef struct {
uint32_t keySize; /* Key size: AES_KEY_SIZE_128/192/256 */ uint32_t keySize; /* Key size: AES_KEY_SIZE_128/192/256 */
uint32_t encDec; /* 0: decrypt, 1: encrypt */ uint32_t encDec; /* 0: decrypt, 1: encrypt */
uint32_t opMode; /* AES_MODE_ECB/CBC/CFB */ uint32_t opMode; /* AES_MODE_ECB/CBC/CFB */
uint32_t iv[4]; /* IV for next block cipher */ uint32_t iv[4]; /* IV for next block cipher */
uint32_t buf[8]; /* Cipher key */ uint32_t keys[8]; /* Cipher key */
} }
mbedtls_aes_context; mbedtls_aes_context;

View File

@ -122,6 +122,15 @@ void crypto_sha_release(void)
crypto_submodule_release(&crypto_sha_avail); crypto_submodule_release(&crypto_sha_avail);
} }
bool crypto_dma_buff_compat(const void *buff, size_t buff_size)
{
uint32_t buff_ = (uint32_t) buff;
return (((buff_ & 0x03) == 0) && /* Word-aligned */
(buff_ >= 0x20000000) && /* 0x20000000-0x2FFFFFFF */
((buff_ + buff_size) <= 0x30000000));
}
static bool crypto_submodule_acquire(uint16_t *submodule_avail) static bool crypto_submodule_acquire(uint16_t *submodule_avail)
{ {
uint16_t expectedCurrentValue = 1; uint16_t expectedCurrentValue = 1;

View File

@ -44,6 +44,13 @@ void crypto_des_release(void);
bool crypto_sha_acquire(void); bool crypto_sha_acquire(void);
void crypto_sha_release(void); void crypto_sha_release(void);
/* Check if buffer can be used for crypto DMA. It requires to be:
*
* 1) Word-aligned
* 2) Located in 0x20000000-0x2FFFFFFF region
*/
bool crypto_dma_buff_compat(const void *buff, size_t buff_size);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -26,24 +26,15 @@
#include "mbed_toolchain.h" #include "mbed_toolchain.h"
#include "mbed_error.h" #include "mbed_error.h"
// Must be a multiple of 64-bit block size /* DMA buffer
*
* MAXSIZE_DMABUF must be a multiple of 64-bit block size.
* Its value is estimated to trade memory footprint off against performance.
*/
#define MAXSIZE_DMABUF (8 * 5) #define MAXSIZE_DMABUF (8 * 5)
MBED_ALIGN(4) static uint8_t dmabuf_in[MAXSIZE_DMABUF]; MBED_ALIGN(4) static uint8_t dmabuf_in[MAXSIZE_DMABUF];
MBED_ALIGN(4) static uint8_t dmabuf_out[MAXSIZE_DMABUF]; MBED_ALIGN(4) static uint8_t dmabuf_out[MAXSIZE_DMABUF];
/* Check if buffer can be used for DES DMA. It requires to be:
* 1) Word-aligned
* 2) Located in 0x20000000-0x2FFFFFFF region
*/
static bool des_dma_buff_compat(const void *buff, unsigned buff_size)
{
uint32_t buff_ = (uint32_t) buff;
return (((buff_ & 0x03) == 0) && /* Word-aligned */
(((unsigned) buff_) >= 0x20000000) && /* 0x20000000-0x2FFFFFFF */
((((unsigned) buff) + buff_size) <= 0x30000000));
}
static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_SIZE], int enc, uint32_t tdes_opmode, size_t length, static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_SIZE], int enc, uint32_t tdes_opmode, size_t length,
unsigned char iv[8], const unsigned char *input, unsigned char *output); unsigned char iv[8], const unsigned char *input, unsigned char *output);
@ -323,7 +314,7 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
* 1) Word-aligned * 1) Word-aligned
* 2) Located in 0x2xxxxxxx region * 2) Located in 0x2xxxxxxx region
*/ */
if ((! des_dma_buff_compat(dmabuf_in, MAXSIZE_DMABUF)) || (! des_dma_buff_compat(dmabuf_out, MAXSIZE_DMABUF))) { if ((! crypto_dma_buff_compat(dmabuf_in, MAXSIZE_DMABUF)) || (! crypto_dma_buff_compat(dmabuf_out, MAXSIZE_DMABUF))) {
error("Buffer for DES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region."); error("Buffer for DES alter. DMA requires to be word-aligned and located in 0x20000000-0x2FFFFFFF region.");
} }