Skip to content

Commit 655ec90

Browse files
cyliangtwccli8
authored andcommitted
Update M467 AES-GCM to pass AWS-IoT test
1 parent 9f01968 commit 655ec90

File tree

2 files changed

+72
-32
lines changed

2 files changed

+72
-32
lines changed

connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/gcm/gcm_alt.c

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
#define GHASH_MODE (AES_MODE_GHASH << CRPT_AES_CTL_OPMODE_Pos)
8181
#define CTR_MODE (AES_MODE_CTR << CRPT_AES_CTL_OPMODE_Pos)
8282

83+
#define Debug_GCM_Info(x) {}
84+
//#define Debug_GCM_Info(x) { printf x; }
8385

8486
/*
8587
* Initialize a context
@@ -351,7 +353,11 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
351353
uint32_t size;
352354
size_t *pSz;
353355
int32_t ret;
354-
356+
357+
if( ctx-> pcntLen == 0 ) ctx-> pcntLen = -1;
358+
ctx->len= 0x00;
359+
360+
Debug_GCM_Info(("## FUNC: %s, mode=%s, pcnt=%d, ctx->len=%d\n", __FUNCTION__, (mode) ? "Enc":"Dec", ctx-> pcntLen, ctx->len));
355361
/* Acquire ownership of AES H/W */
356362
crypto_aes_acquire();
357363

@@ -387,16 +393,18 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
387393
CRPT->AES_CNT = ctx->gcm_buf_bytes;
388394

389395
/* Set a big number for unknown P length */
390-
CRPT->AES_GCM_PCNT[0] = (uint32_t)-1;
396+
CRPT->AES_GCM_PCNT[0] = ctx-> pcntLen; //(uint32_t)-1;
391397
CRPT->AES_GCM_PCNT[1] = 0;
392398

393399
/* Start with cascade mode */
394-
if((ret = AES_Run(ctx, ctx->basicOpt | FBOUT)))
400+
// if((ret = AES_Run(ctx, ctx->basicOpt | FBOUT)))
401+
if((ret = AES_Run(ctx, ctx->basicOpt | GCM_MODE | FBOUT | DMAEN)))
395402
{
396403
return ret;
397404
}
398405

399-
ctx->firstFlag = 1;
406+
ctx->firstFlag = 1;
407+
ctx->endFlag = 0;
400408

401409
return( 0 );
402410
}
@@ -413,11 +421,11 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
413421
int32_t ret;
414422
int32_t len, len_aligned;
415423
uint32_t u32Size;
416-
424+
Debug_GCM_Info(("## FUNC: %s, input_length=%d\n", __FUNCTION__, input_length));
417425
GCM_VALIDATE_RET( ctx != NULL );
418426
GCM_VALIDATE_RET( input_length == 0 || input != NULL );
419427
GCM_VALIDATE_RET( input_length == 0 || output != NULL );
420-
428+
421429
len = (int32_t)input_length;
422430
/* Error if length too large */
423431
if( (size_t)len != input_length)
@@ -474,16 +482,18 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
474482
}
475483
else
476484
{
485+
477486
/* Over buffer size */
478487
return (MBEDTLS_ERR_GCM_BAD_INPUT);
479488
}
480489

481490
/* Do GCM with cascade */
482491
if(len & 0xf)
483492
{
484-
485493
/* No 16 bytes alignment, it should be last */
494+
486495
CRPT->AES_GCM_PCNT[0] = ctx->len;
496+
CRPT->AES_GCM_PCNT[1] = 0;
487497
CRPT->AES_CNT = u32Size;
488498

489499
if((ret = AES_Run(ctx, ctx->basicOpt | FBIN | FBOUT | DMACC | DMALAST)))
@@ -526,9 +536,8 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
526536
size_t tag_len )
527537
{
528538

529-
530539
int32_t ret = 0;
531-
540+
Debug_GCM_Info(("## FUNC: %s, tag_len=%d, pcnt=%d\n", __FUNCTION__, tag_len, ctx->len));
532541
GCM_VALIDATE_RET( ctx != NULL );
533542
GCM_VALIDATE_RET( tag != NULL );
534543

@@ -581,6 +590,11 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
581590
size_t tag_len,
582591
unsigned char *tag )
583592
{
593+
int32_t plen_cur;
594+
int32_t len, len_aligned;
595+
const uint8_t *pin;
596+
uint8_t *pout;
597+
584598
int ret = MBEDTLS_ERR_GCM_AUTH_FAILED;
585599

586600
GCM_VALIDATE_RET( ctx != NULL );
@@ -589,13 +603,37 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
589603
GCM_VALIDATE_RET( length == 0 || input != NULL );
590604
GCM_VALIDATE_RET( length == 0 || output != NULL );
591605
GCM_VALIDATE_RET( tag != NULL );
592-
606+
ctx-> pcntLen = length;
593607
if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
594608
return( ret );
595609

596-
if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
597-
return( ret );
610+
if( length == 0 ) /* if P length > 0, mbedtls_gcm_update not need gcm_buf_bytes for AES_CNT */
611+
{
612+
ctx->gcm_buf_bytes = 16;
613+
}else{
614+
ctx->gcm_buf_bytes = 0;
615+
}
616+
plen_cur = length;
617+
pin = input;
618+
pout = output;
619+
do
620+
{
621+
len = plen_cur;
622+
if(len > GCM_PBLOCK_SIZE)
623+
{
624+
len = GCM_PBLOCK_SIZE;
625+
}
626+
plen_cur -= len;
627+
628+
/* Prepare the blocked buffer for GCM */
629+
memcpy(ctx->gcm_buf, pin, len);
598630

631+
if( ( ret = mbedtls_gcm_update( ctx, len, pin, pout ) ) != 0 )
632+
return( ret );
633+
pin += len;
634+
pout += len;
635+
}while(plen_cur);
636+
599637
if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
600638
return( ret );
601639

@@ -665,7 +703,8 @@ static int32_t _GCMTag(mbedtls_gcm_context *ctx, const uint8_t *iv, uint32_t ivl
665703
uint32_t u32OptBasic;
666704
uint32_t u32OptKeySize;
667705
uint32_t tag[4];
668-
706+
707+
Debug_GCM_Info(("## FUNC: %s\n", __FUNCTION__));
669708
/* Prepare key size option */
670709
i = ctx->keySize >> 3;
671710
u32OptKeySize = (((i >> 2) << 1) | (i & 1)) << CRPT_AES_CTL_KEYSZ_Pos;
@@ -712,10 +751,7 @@ static int32_t _GCMTag(mbedtls_gcm_context *ctx, const uint8_t *iv, uint32_t ivl
712751
CRPT->AES_DADDR = (uint32_t)&ghashbuf[0];
713752
CRPT->AES_CNT = len;
714753

715-
716754
AES_Run(ctx, u32OptBasic | GHASH_MODE | DMAEN /*| DMALAST*/);
717-
718-
719755
}
720756
else
721757
{
@@ -855,7 +891,8 @@ static int32_t _GCMTag(mbedtls_gcm_context *ctx, const uint8_t *iv, uint32_t ivl
855891
ret = AES_Run(ctx, u32OptBasic | CTR_MODE | DMAEN /*| DMALAST*/);
856892

857893
memcpy(tagbuf, tag, 16);
858-
894+
Debug_GCM_Info(("## FUNC: %s finish tag 0x%x, 0x%x, 0x%x, 0x%x\n", __FUNCTION__, tag[0], tag[1], tag[2], tag[3]));
895+
859896
return ret;
860897
}
861898

@@ -891,7 +928,8 @@ static int32_t _GCM(mbedtls_gcm_context *ctx, const uint8_t *iv, uint32_t ivlen,
891928
CRPT->AES_GCM_PCNT[1] = 0;
892929

893930
plen_aligned = (plen & 0xful) ? ((plen + 16) / 16) * 16 : plen;
894-
if(plen <= GCM_PBLOCK_SIZE)
931+
932+
if(plen == 0) /* For AWS-IoT connection case, force go cascade instead of if(plen <= GCM_PBLOCK_SIZE) */
895933
{
896934
/* Just one shot */
897935

@@ -903,10 +941,10 @@ static int32_t _GCM(mbedtls_gcm_context *ctx, const uint8_t *iv, uint32_t ivlen,
903941
CRPT->AES_CNT = size;
904942

905943
ret = AES_Run(ctx, u32OptBasic | GCM_MODE | DMAEN);
906-
944+
907945
memcpy(buf, ctx->out_buf, plen);
908946
memcpy(tag, ctx->out_buf + plen_aligned, tag_len);
909-
947+
910948
}
911949
else
912950
{
@@ -980,13 +1018,15 @@ static int32_t _GCM(mbedtls_gcm_context *ctx, const uint8_t *iv, uint32_t ivlen,
9801018
}
9811019

9821020
memcpy(tag, ctx->out_buf+len_aligned, tag_len);
1021+
Debug_GCM_Info(("## Tag in FUNC: %s, plen=%d, tag=0x%x, 0x%x, 0x%x, 0x%x\n", __FUNCTION__, plen,
1022+
*((uint32_t*)tag), *((uint32_t*)(tag+4)), *((uint32_t*)(tag+8)), *((uint32_t*)(tag+16)) ));
9831023
}
9841024

9851025
if(ctx->mode)
9861026
{
9871027
/* H/W limitation under plen%16 as 1 or 15, need re-calculate tag by _GCMTag */
9881028
/* Need to calculate Tag when plen % 16 == 1 or 15 */
989-
if(((plen & 0xf) == 1) || ((plen & 0xf) == 15))
1029+
if(( (plen & 0xf) == 1) || ((plen & 0xf) == 15))
9901030
{
9911031
if((ret = _GCMTag(ctx, iv, ivlen, A, alen, ctx->out_buf, plen, tag)))
9921032
{
@@ -1011,7 +1051,7 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
10111051
unsigned char *tag )
10121052
{
10131053
int ret;
1014-
1054+
Debug_GCM_Info(("## FUNC: %s, mode=%s, length=%d, tag_len=%d, in/out=0x%x/0x%x\n", __FUNCTION__, (mode) ? "Enc":"Dec", length, tag_len, input, output));
10151055
GCM_VALIDATE_RET( ctx != NULL );
10161056
GCM_VALIDATE_RET( iv != NULL );
10171057
GCM_VALIDATE_RET( add_len == 0 || add != NULL );
@@ -1042,7 +1082,7 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
10421082

10431083
/* Release ownership of AES H/W */
10441084
crypto_aes_release();
1045-
1085+
10461086
return (ret);
10471087
}
10481088

@@ -1061,7 +1101,7 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
10611101
unsigned char check_tag[16];
10621102
size_t i;
10631103
int diff;
1064-
1104+
Debug_GCM_Info(("## FUNC: %s\n", __FUNCTION__));
10651105
GCM_VALIDATE_RET( ctx != NULL );
10661106
GCM_VALIDATE_RET( iv != NULL );
10671107
GCM_VALIDATE_RET( add_len == 0 || add != NULL );

connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/gcm/gcm_alt.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,17 @@
3232
#define MBEDTLS_GCM_ALT_H
3333

3434
#if defined(MBEDTLS_GCM_ALT)
35-
35+
#include "mbed_toolchain.h"
3636
#define MAX_GCM_BUF 256
37-
#define GCM_PBLOCK_SIZE MAX_GCM_BUF /* NOTE: This value must be 16 bytes alignment. This value must > size of A */
37+
#define GCM_PBLOCK_SIZE (MAX_GCM_BUF) /* NOTE: This value must be 16 bytes alignment. This value must > size of A */
3838

3939

4040
/**
4141
* \brief The GCM context structure.
4242
*/
4343
typedef struct mbedtls_gcm_context
4444
{
45-
uint64_t len; /*!< The total length of the encrypted data. */
45+
uint32_t len; /*!< The total length of the encrypted data. */
4646
int mode; /*!< The operation to perform:
4747
#MBEDTLS_GCM_ENCRYPT or
4848
#MBEDTLS_GCM_DECRYPT. */
@@ -53,15 +53,15 @@ typedef struct mbedtls_gcm_context
5353
uint32_t iv[4]; /* IV for next block cipher */
5454
uint32_t keys[8]; /* Cipher key */
5555
uint32_t basicOpt; /* Basic option of AES controller */
56-
uint8_t gcm_buf[MAX_GCM_BUF]; /* buffer for GCM DMA input */
57-
uint8_t out_buf[MAX_GCM_BUF+16]; /* buffer for GCM DMA output */
58-
uint8_t fb_buf[72]; /* feedback buffer for GCM DMA */
59-
uint8_t fb_buf2[72]; /* feedback buffer 2 for GCM DMA */
56+
MBED_ALIGN(4) uint8_t gcm_buf[MAX_GCM_BUF]; /* buffer for GCM DMA input */
57+
MBED_ALIGN(4) uint8_t out_buf[MAX_GCM_BUF+16]; /* buffer for GCM DMA output */
58+
MBED_ALIGN(4) uint8_t fb_buf[72]; /* feedback buffer for GCM DMA */
59+
MBED_ALIGN(4) uint8_t fb_buf2[72]; /* feedback buffer 2 for GCM DMA */
6060
uint8_t tag[16]; /* Tag */
6161
uint32_t gcm_buf_bytes; /* Bytes in gcm_buf */
6262
uint32_t firstFlag; /* A flag for the first data block */
6363
uint32_t endFlag; /* final block is done */
64-
64+
uint32_t pcntLen; /* PCNT length*/
6565
// uint8_t *add;
6666
// size_t addlen;
6767
}

0 commit comments

Comments
 (0)