Skip to content

Commit be9e74b

Browse files
cyliangtwccli8
authored andcommitted
Support block chain & partial block in HW AES CFB mode
1 parent ab5996a commit be9e74b

File tree

2 files changed

+73
-34
lines changed

2 files changed

+73
-34
lines changed

hal/targets/hal/TARGET_NUVOTON/TARGET_NUC472/crypto/aes/aes_alt.c

Lines changed: 72 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
250250
}else{
251251
pIn = input;
252252
}
253-
if( ((uint32_t)output) & 0x03 )
253+
if( (((uint32_t)output) & 0x03) || (dataSize%4)) // HW CFB output byte count must be multiple of word
254254
{
255255
pOut = au8OutputData;
256256
} else {
@@ -385,51 +385,77 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
385385
*/
386386
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
387387
int mode,
388-
size_t length,
388+
size_t len,
389389
size_t *iv_off,
390390
unsigned char iv[16],
391391
const unsigned char *input,
392392
unsigned char *output )
393393
{
394-
395-
size_t n = *iv_off;
394+
size_t n = *iv_off;
396395
unsigned char temp[16];
396+
int length=len;
397+
int blockChainLen;
398+
int remLen=0;
397399
int ivLen;
398400

399401
mbedtls_trace("=== %s \r\n", __FUNCTION__);
400402

401-
// Over reserved Max DMA buffer size
402-
if( length > MAX_DMA_CHAIN_SIZE )
403-
return __aes_crypt_over_dma_size_cfb128(ctx, mode, length, iv_off, iv, input, output);
403+
// proceed: start with partial block by ECB mode first
404+
if( n !=0 ) {
405+
__nvt_aes_crypt_partial_block_cfb128(ctx, mode, 16 - n , iv_off, iv, input, output);
406+
input += (16 - n);
407+
output += (16 - n);
408+
length -= (16 - n);
409+
}
410+
411+
// For address or byte count non-word alignment, go through reserved DMA buffer.
412+
if( (((uint32_t)input) & 0x03) || (((uint32_t)output) & 0x03) || (length%4) )
413+
{
414+
blockChainLen = (( length > MAX_DMA_CHAIN_SIZE ) ? MAX_DMA_CHAIN_SIZE : length );
415+
} else {
416+
blockChainLen = length;
417+
}
418+
419+
// proceed: start with block alignment
420+
while( length > 0 )
421+
{
422+
423+
ctx->opMode = AES_MODE_CFB;
424+
425+
swapInitVector(iv); // iv SWAP
404426

405-
ctx->opMode = AES_MODE_CFB;
406-
swapInitVector(iv); // iv SWAP
427+
ctx->iv = (uint32_t *)iv;
428+
remLen = blockChainLen%16;
429+
ivLen = (( remLen > 0) ? remLen: 16 );
407430

408-
ctx->iv = (uint32_t *)iv;
409-
if( mode == MBEDTLS_AES_DECRYPT )
410-
{
411-
n= length%16;
412-
ivLen = (( n > 0) ? n : 16);
413-
memcpy(temp, input+length-ivLen, ivLen);
414-
ctx->encDec = 0;
415-
__nvt_aes_crypt(ctx, input, output, length);
416-
memcpy(iv,temp,ivLen);
417-
}
418-
else
419-
{
420-
n= length%16;
421-
ivLen = (( n > 0) ? n : 16);
422-
ctx->encDec = 1;
423-
__nvt_aes_crypt(ctx, input, output, length);
424-
memcpy(iv, output+length-ivLen, ivLen);
425-
}
431+
if( mode == MBEDTLS_AES_DECRYPT )
432+
{
433+
memcpy(temp, input+blockChainLen - ivLen, ivLen);
434+
if(blockChainLen >= 16) memcpy(ctx->prv_iv, input+blockChainLen-remLen-16 , 16);
435+
ctx->encDec = 0;
436+
__nvt_aes_crypt(ctx, input, output, blockChainLen);
437+
memcpy(iv,temp, ivLen);
438+
}
439+
else
440+
{
441+
ctx->encDec = 1;
442+
__nvt_aes_crypt(ctx, input, output, blockChainLen);
443+
if(blockChainLen >= 16) memcpy(ctx->prv_iv, output+blockChainLen-remLen-16 , 16);
444+
memcpy(iv,output+blockChainLen-ivLen,ivLen);
445+
}
446+
length -= blockChainLen;
447+
input += blockChainLen;
448+
output += blockChainLen;
449+
if(length < MAX_DMA_CHAIN_SIZE ) blockChainLen = length; // For last remainder block chain
450+
}
426451

427-
*iv_off = n;
452+
*iv_off = remLen;
428453

429-
return( 0 );
454+
return( 0 );
430455
}
431456

432-
static int __aes_crypt_over_dma_size_cfb128( mbedtls_aes_context *ctx,
457+
/* Support partial block encryption/decryption */
458+
static int __nvt_aes_crypt_partial_block_cfb128( mbedtls_aes_context *ctx,
433459
int mode,
434460
size_t length,
435461
size_t *iv_off,
@@ -439,15 +465,21 @@ static int __aes_crypt_over_dma_size_cfb128( mbedtls_aes_context *ctx,
439465
{
440466
int c;
441467
size_t n = *iv_off;
442-
468+
unsigned char iv_tmp[16];
443469
mbedtls_trace("=== %s \r\n", __FUNCTION__);
444470
if( mode == MBEDTLS_AES_DECRYPT )
445471
{
446472
while( length-- )
447473
{
448-
if( n == 0 )
474+
if( n == 0)
449475
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
450-
476+
else if( ctx->opMode == AES_MODE_CFB) // For previous cryption is CFB mode
477+
{
478+
memcpy(iv_tmp, iv, n);
479+
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, ctx->prv_iv, iv );
480+
memcpy(iv, iv_tmp, n);
481+
}
482+
451483
c = *input++;
452484
*output++ = (unsigned char)( c ^ iv[n] );
453485
iv[n] = (unsigned char) c;
@@ -461,7 +493,13 @@ static int __aes_crypt_over_dma_size_cfb128( mbedtls_aes_context *ctx,
461493
{
462494
if( n == 0 )
463495
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
464-
496+
else if( ctx->opMode == AES_MODE_CFB) // For previous cryption is CFB mode
497+
{
498+
memcpy(iv_tmp, iv, n);
499+
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, ctx->prv_iv, iv );
500+
memcpy(iv, iv_tmp, n);
501+
}
502+
465503
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
466504

467505
n = ( n + 1 ) & 0x0F;

hal/targets/hal/TARGET_NUVOTON/TARGET_NUC472/crypto/aes/aes_alt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ typedef struct
4444
uint32_t channel;
4545
uint32_t swapType;
4646
uint32_t *iv;
47+
unsigned char prv_iv[16];
4748
#if 1
4849
uint32_t buf[8];
4950
/* For comparsion with software AES for correctness */

0 commit comments

Comments
 (0)