Skip to content

Commit ab5996a

Browse files
cyliangtwccli8
authored andcommitted
Support HW AES CBC block chain & AES CFB
1 parent 591a54c commit ab5996a

File tree

2 files changed

+132
-90
lines changed

2 files changed

+132
-90
lines changed

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

Lines changed: 130 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
1-
/*
2-
* AES hardware acceleration implementation
3-
*
4-
* Copyright (C) 2015-2020, Nuvoton, All Rights Reserved
5-
* SPDX-License-Identifier: Apache-2.0
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2015-2016 Nuvoton
63
*
7-
* Licensed under the Apache License, Version 2.0 (the "License"); you may
8-
* not use this file except in compliance with the License.
9-
* You may obtain a copy of the License at
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
107
*
11-
* http://www.apache.org/licenses/LICENSE-2.0
12-
*
13-
* Unless required by applicable law or agreed to in writing, software
14-
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16-
* See the License for the specific language governing permissions and
17-
* limitations under the License.
8+
* http://www.apache.org/licenses/LICENSE-2.0
189
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
1915
*/
16+
2017
/*
2118
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
2219
*
@@ -31,32 +28,18 @@
3128
#endif
3229

3330
#if defined(MBEDTLS_AES_C)
31+
#if defined(MBEDTLS_AES_ALT)
3432

3533
#include <string.h>
3634

3735
#include "mbedtls/aes.h"
38-
#if defined(MBEDTLS_PADLOCK_C)
39-
#include "mbedtls/padlock.h"
40-
#endif
41-
#if defined(MBEDTLS_AESNI_C)
42-
#include "mbedtls/aesni.h"
43-
#endif
44-
45-
#if defined(MBEDTLS_SELF_TEST)
46-
#if defined(MBEDTLS_PLATFORM_C)
47-
#include "mbedtls/platform.h"
48-
#else
49-
#include <stdio.h>
50-
#define mbedtls_printf printf
51-
#endif /* MBEDTLS_PLATFORM_C */
52-
#endif /* MBEDTLS_SELF_TEST */
5336

5437
#include "NUC472_442.h"
5538
#include "toolchain.h"
39+
#include "mbed_assert.h"
5640

5741
//static int aes_init_done = 0;
5842

59-
#if defined(MBEDTLS_AES_ALT)
6043

6144
#define mbedtls_trace //printf
6245

@@ -73,16 +56,34 @@ static uint32_t au32MyAESIV[4] = {
7356

7457
extern volatile int g_AES_done;
7558

76-
uint8_t au8OutputData[16] MBED_ALIGN(4);
77-
uint8_t au8InputData[16] MBED_ALIGN(4);
59+
// Must be a multiple of 16 bytes block size
60+
#define MAX_DMA_CHAIN_SIZE (16*6)
61+
static uint8_t au8OutputData[MAX_DMA_CHAIN_SIZE] MBED_ALIGN(4);
62+
static uint8_t au8InputData[MAX_DMA_CHAIN_SIZE] MBED_ALIGN(4);
7863

79-
static void dumpHex(uint8_t au8Data[], int len)
64+
static void dumpHex(const unsigned char au8Data[], int len)
8065
{
8166
int j;
8267
for (j = 0; j < len; j++) mbedtls_trace("%02x ", au8Data[j]);
8368
mbedtls_trace("\r\n");
8469
}
8570

71+
static void swapInitVector(unsigned char iv[16])
72+
{
73+
unsigned int* piv;
74+
int i;
75+
// iv SWAP
76+
piv = (unsigned int*)iv;
77+
for( i=0; i< 4; i++)
78+
{
79+
*piv = (((*piv) & 0x000000FF) << 24) |
80+
(((*piv) & 0x0000FF00) << 8) |
81+
(((*piv) & 0x00FF0000) >> 8) |
82+
(((*piv) & 0xFF000000) >> 24);
83+
piv++;
84+
}
85+
}
86+
8687
//volatile void CRYPTO_IRQHandler()
8788
//{
8889
// if (AES_GET_INT_FLAG()) {
@@ -104,7 +105,6 @@ static int channel_alloc()
104105
return i;
105106
}
106107
}
107-
printf("%s: No available AES channel \r\n", __FUNCTION__);
108108
return(-1);
109109
}
110110

@@ -126,8 +126,11 @@ void mbedtls_aes_init( mbedtls_aes_context *ctx )
126126
memset( ctx, 0, sizeof( mbedtls_aes_context ) );
127127

128128
ctx->swapType = AES_IN_OUT_SWAP;
129-
while( (i = channel_alloc()) < 0 ) osDelay(300);
130-
129+
while( (i = channel_alloc()) < 0 )
130+
{
131+
mbed_assert_internal("No available AES channel", __FILE__, __LINE__);
132+
//osDelay(300);
133+
}
131134
ctx->channel = i;
132135
ctx->iv = au32MyAESIV;
133136

@@ -215,7 +218,7 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
215218
int ret;
216219

217220
mbedtls_trace("=== %s keybits[%d]\r\n", __FUNCTION__, keybits);
218-
dumpHex(key,keybits/8);
221+
dumpHex((uint8_t *)key,keybits/8);
219222

220223
/* Also checks keybits */
221224
if( ( ret = mbedtls_aes_setkey_enc( ctx, key, keybits ) ) != 0 )
@@ -230,9 +233,8 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
230233

231234
static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
232235
const unsigned char input[16],
233-
unsigned char output[16])
236+
unsigned char output[16], int dataSize)
234237
{
235-
int i;
236238
unsigned char* pIn;
237239
unsigned char* pOut;
238240

@@ -243,28 +245,27 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
243245
AES_SetInitVect(ctx->channel, ctx->iv);
244246
if( ((uint32_t)input) & 0x03 )
245247
{
246-
memcpy(au8InputData, input, sizeof(au8InputData));
248+
memcpy(au8InputData, input, dataSize);
247249
pIn = au8InputData;
248250
}else{
249-
pIn = (uint32_t)input;
251+
pIn = input;
250252
}
251253
if( ((uint32_t)output) & 0x03 )
252254
{
253255
pOut = au8OutputData;
254256
} else {
255-
pOut = (uint32_t)output;
257+
pOut = output;
256258
}
257259

258-
AES_SetDMATransfer(ctx->channel, (uint32_t)pIn, (uint32_t)pOut, sizeof(au8InputData));
260+
AES_SetDMATransfer(ctx->channel, (uint32_t)pIn, (uint32_t)pOut, dataSize);
259261

260262
g_AES_done = 0;
261263
AES_Start(ctx->channel, CRYPTO_DMA_ONE_SHOT);
262264
while (!g_AES_done);
263265

264-
if( pOut != (uint32_t)output ) memcpy(output, au8OutputData, sizeof(au8InputData));
266+
if( pOut != output ) memcpy(output, au8OutputData, dataSize);
265267
dumpHex(output,16);
266268

267-
268269
}
269270

270271
/*
@@ -275,12 +276,11 @@ void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
275276
const unsigned char input[16],
276277
unsigned char output[16] )
277278
{
278-
int i;
279279

280280
mbedtls_trace("=== %s \r\n", __FUNCTION__);
281281

282282
ctx->encDec = 1;
283-
__nvt_aes_crypt(ctx, input, output);
283+
__nvt_aes_crypt(ctx, input, output, 16);
284284

285285
}
286286
#endif /* MBEDTLS_AES_ENCRYPT_ALT */
@@ -293,12 +293,11 @@ void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
293293
const unsigned char input[16],
294294
unsigned char output[16] )
295295
{
296-
int i;
297296

298297
mbedtls_trace("=== %s \r\n", __FUNCTION__);
299298

300299
ctx->encDec = 0;
301-
__nvt_aes_crypt(ctx, input, output);
300+
__nvt_aes_crypt(ctx, input, output, 16);
302301

303302

304303
}
@@ -312,8 +311,6 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
312311
const unsigned char input[16],
313312
unsigned char output[16] )
314313
{
315-
unsigned char sw_output[16];
316-
317314

318315
mbedtls_trace("=== %s \r\n", __FUNCTION__);
319316

@@ -333,52 +330,50 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
333330
*/
334331
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
335332
int mode,
336-
size_t length,
333+
size_t len,
337334
unsigned char iv[16],
338335
const unsigned char *input,
339336
unsigned char *output )
340337
{
341-
int i;
342338
unsigned char temp[16];
343-
unsigned int* piv;
344-
339+
int length = len;
340+
int blockChainLen;
345341
mbedtls_trace("=== %s \r\n", __FUNCTION__);
346342
if( length % 16 )
347343
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
348344

349-
350-
while( length > 0 )
351-
{
352-
ctx->opMode = AES_MODE_CBC;
353-
ctx->iv = iv;
354-
if( mode == MBEDTLS_AES_ENCRYPT )
355-
{
356-
mbedtls_aes_encrypt( ctx, input, output );
357-
memcpy( iv, output, 16 );
358-
}else{
359-
memcpy( temp, input, 16 );
360-
dumpHex(input,16);
361-
mbedtls_aes_decrypt( ctx, input, output );
362-
dumpHex(iv,16);
363-
dumpHex(output,16);
364-
memcpy( iv, temp, 16 );
365-
}
366-
367-
// iv SWAP
368-
piv = (unsigned int*)iv;
369-
for( i=0; i< 4; i++)
370-
{
371-
*piv = (((*piv) & 0x000000FF) << 24) |
372-
(((*piv) & 0x0000FF00) << 8) |
373-
(((*piv) & 0x00FF0000) >> 8) |
374-
(((*piv) & 0xFF000000) >> 24);
375-
piv++;
376-
}
377-
input += 16;
378-
output += 16;
379-
length -= 16;
380-
}
381-
345+
if( (((uint32_t)input) & 0x03) || (((uint32_t)output) & 0x03) )
346+
{
347+
blockChainLen = (( length > MAX_DMA_CHAIN_SIZE ) ? MAX_DMA_CHAIN_SIZE : length );
348+
} else {
349+
blockChainLen = length;
350+
}
351+
352+
while( length > 0 )
353+
{
354+
ctx->opMode = AES_MODE_CBC;
355+
swapInitVector(iv); // iv SWAP
356+
ctx->iv = (uint32_t *)iv;
357+
358+
if( mode == MBEDTLS_AES_ENCRYPT )
359+
{
360+
ctx->encDec = 1;
361+
__nvt_aes_crypt(ctx, input, output, blockChainLen);
362+
// if( blockChainLen == length ) break; // finish last block chain but still need to prepare next iv for mbedtls_aes_self_test()
363+
memcpy( iv, output+blockChainLen-16, 16 );
364+
}else{
365+
memcpy( temp, input+blockChainLen-16, 16 );
366+
ctx->encDec = 0;
367+
__nvt_aes_crypt(ctx, input, output, blockChainLen);
368+
// if( blockChainLen == length ) break; // finish last block chain but still need to prepare next iv for mbedtls_aes_self_test()
369+
memcpy( iv, temp, 16 );
370+
}
371+
length -= blockChainLen;
372+
input += blockChainLen;
373+
output += blockChainLen;
374+
if(length < MAX_DMA_CHAIN_SIZE ) blockChainLen = length; // For last remainder block chain
375+
376+
}
382377

383378
return( 0 );
384379
}
@@ -396,6 +391,52 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
396391
const unsigned char *input,
397392
unsigned char *output )
398393
{
394+
395+
size_t n = *iv_off;
396+
unsigned char temp[16];
397+
int ivLen;
398+
399+
mbedtls_trace("=== %s \r\n", __FUNCTION__);
400+
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);
404+
405+
ctx->opMode = AES_MODE_CFB;
406+
swapInitVector(iv); // iv SWAP
407+
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+
}
426+
427+
*iv_off = n;
428+
429+
return( 0 );
430+
}
431+
432+
static int __aes_crypt_over_dma_size_cfb128( mbedtls_aes_context *ctx,
433+
int mode,
434+
size_t length,
435+
size_t *iv_off,
436+
unsigned char iv[16],
437+
const unsigned char *input,
438+
unsigned char *output )
439+
{
399440
int c;
400441
size_t n = *iv_off;
401442

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ typedef struct
4444
uint32_t channel;
4545
uint32_t swapType;
4646
uint32_t *iv;
47+
#if 1
4748
uint32_t buf[8];
4849
/* For comparsion with software AES for correctness */
49-
#if 0
50+
#else
5051
uint32_t buf[68]; /*!< unaligned data */
5152
int nr; /*!< number of rounds */
5253
uint32_t *rk; /*!< AES round keys */

0 commit comments

Comments
 (0)