@@ -250,7 +250,7 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
250
250
}else {
251
251
pIn = input ;
252
252
}
253
- if ( ((uint32_t )output ) & 0x03 )
253
+ if ( ((( uint32_t )output ) & 0x03 ) || ( dataSize % 4 )) // HW CFB output byte count must be multiple of word
254
254
{
255
255
pOut = au8OutputData ;
256
256
} else {
@@ -385,51 +385,77 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
385
385
*/
386
386
int mbedtls_aes_crypt_cfb128 ( mbedtls_aes_context * ctx ,
387
387
int mode ,
388
- size_t length ,
388
+ size_t len ,
389
389
size_t * iv_off ,
390
390
unsigned char iv [16 ],
391
391
const unsigned char * input ,
392
392
unsigned char * output )
393
393
{
394
-
395
- size_t n = * iv_off ;
394
+ size_t n = * iv_off ;
396
395
unsigned char temp [16 ];
396
+ int length = len ;
397
+ int blockChainLen ;
398
+ int remLen = 0 ;
397
399
int ivLen ;
398
400
399
401
mbedtls_trace ("=== %s \r\n" , __FUNCTION__ );
400
402
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
404
426
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 );
407
430
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
+ }
426
451
427
- * iv_off = n ;
452
+ * iv_off = remLen ;
428
453
429
- return ( 0 );
454
+ return ( 0 );
430
455
}
431
456
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 ,
433
459
int mode ,
434
460
size_t length ,
435
461
size_t * iv_off ,
@@ -439,15 +465,21 @@ static int __aes_crypt_over_dma_size_cfb128( mbedtls_aes_context *ctx,
439
465
{
440
466
int c ;
441
467
size_t n = * iv_off ;
442
-
468
+ unsigned char iv_tmp [ 16 ];
443
469
mbedtls_trace ("=== %s \r\n" , __FUNCTION__ );
444
470
if ( mode == MBEDTLS_AES_DECRYPT )
445
471
{
446
472
while ( length -- )
447
473
{
448
- if ( n == 0 )
474
+ if ( n == 0 )
449
475
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
+
451
483
c = * input ++ ;
452
484
* output ++ = (unsigned char )( c ^ iv [n ] );
453
485
iv [n ] = (unsigned char ) c ;
@@ -461,7 +493,13 @@ static int __aes_crypt_over_dma_size_cfb128( mbedtls_aes_context *ctx,
461
493
{
462
494
if ( n == 0 )
463
495
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
+
465
503
iv [n ] = * output ++ = (unsigned char )( iv [n ] ^ * input ++ );
466
504
467
505
n = ( n + 1 ) & 0x0F ;
0 commit comments