1 /*
2 * FIPS-197 compliant AES implementation
3 *
4 * Copyright The Mbed TLS Contributors
5 * Copyright (C) 2021, STMicroelectronics, All Rights Reserved
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 * This file implements ST AES HW services based on API from mbed TLS
21 *
22 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
23 *
24 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
25 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
26 */
27
28
29 /* Includes ------------------------------------------------------------------*/
30 #include "mbedtls/aes.h"
31
32 #if defined(MBEDTLS_AES_C)
33 #if defined(MBEDTLS_AES_ALT)
34 #include <string.h>
35 #include "mbedtls/platform.h"
36 #include "mbedtls/platform_util.h"
37 #include "mbedtls/error.h"
38
39 /* Parameter validation macros - mbedtls/platform_util.h has deprecated them */
40 #define AES_VALIDATE_RET( cond ) do { } while(0)
41 #define AES_VALIDATE( cond ) do { } while(0)
42
43 /* Private typedef -----------------------------------------------------------*/
44 /* Private define ------------------------------------------------------------*/
45 #define ST_AES_TIMEOUT 0xFFU /* 255 ms timeout for the crypto processor */
46 #define ST_AES_NO_ALGO 0xFFFFU /* any algo is programmed */
47
48 /* Private macro -------------------------------------------------------------*/
49 #define SWAP_B8_TO_B32(b32,b8,i) \
50 { \
51 (b32) = ( (uint32_t) (b8)[(i) + 3] ) \
52 | ( (uint32_t) (b8)[(i) + 2] << 8 ) \
53 | ( (uint32_t) (b8)[(i) + 1] << 16 ) \
54 | ( (uint32_t) (b8)[(i) ] << 24 ); \
55 }
56
57 #define SWAP_B32_TO_B8(b32,b8,i) \
58 { \
59 (b8)[(i) + 3] = (unsigned char) ( ( (b32) ) & 0xFF ); \
60 (b8)[(i) + 2] = (unsigned char) ( ( (b32) >> 8 ) & 0xFF ); \
61 (b8)[(i) + 1] = (unsigned char) ( ( (b32) >> 16 ) & 0xFF ); \
62 (b8)[(i) ] = (unsigned char) ( ( (b32) >> 24 ) & 0xFF ); \
63 }
64
65 /* Private variables ---------------------------------------------------------*/
66 /* Private function prototypes -----------------------------------------------*/
67 /* Private functions ---------------------------------------------------------*/
68
aes_set_key(mbedtls_aes_context * ctx,const unsigned char * key,unsigned int keybits)69 static int aes_set_key(mbedtls_aes_context *ctx,
70 const unsigned char *key,
71 unsigned int keybits)
72 {
73 AES_VALIDATE_RET( ctx != NULL );
74
75 switch (keybits) {
76 #if defined(GENERATOR_HW_CRYPTO_DPA_SUPPORTED) && defined(HW_CRYPTO_DPA_AES)
77 case 0:
78 /* implicit request for using HUK */
79 break;
80 #endif
81 case 128:
82 ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_128B;;
83
84 SWAP_B8_TO_B32(ctx->aes_key[0],key,0);
85 SWAP_B8_TO_B32(ctx->aes_key[1],key,4);
86 SWAP_B8_TO_B32(ctx->aes_key[2],key,8);
87 SWAP_B8_TO_B32(ctx->aes_key[3],key,12);
88 break;
89
90 case 192:
91 return (MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED);
92
93 case 256:
94 ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_256B;
95
96 SWAP_B8_TO_B32(ctx->aes_key[0],key,0);
97 SWAP_B8_TO_B32(ctx->aes_key[1],key,4);
98 SWAP_B8_TO_B32(ctx->aes_key[2],key,8);
99 SWAP_B8_TO_B32(ctx->aes_key[3],key,12);
100 SWAP_B8_TO_B32(ctx->aes_key[4],key,16);
101 SWAP_B8_TO_B32(ctx->aes_key[5],key,20);
102 SWAP_B8_TO_B32(ctx->aes_key[6],key,24);
103 SWAP_B8_TO_B32(ctx->aes_key[7],key,28);
104 break;
105
106 default :
107 return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
108 }
109 #if defined(GENERATOR_HW_CRYPTO_DPA_SUPPORTED) && defined(HW_CRYPTO_DPA_AES)
110 ctx->hcryp_aes.Instance = SAES;
111 #else
112 ctx->hcryp_aes.Instance = AES;
113 #endif
114 #if defined(STM32L5)
115 ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
116 #else
117 ctx->hcryp_aes.Init.DataType = CRYP_BYTE_SWAP;
118 #endif
119 ctx->hcryp_aes.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
120 ctx->hcryp_aes.Init.pKey = ctx->aes_key;
121
122 #if defined(GENERATOR_HW_CRYPTO_DPA_SUPPORTED) && defined(HW_CRYPTO_DPA_AES)
123 if ( 0 == keybits )
124 {
125 ctx->hcryp_aes.Init.KeyMode = CRYP_KEYMODE_NORMAL;
126 ctx->hcryp_aes.Init.KeyProtection = CRYP_KEYSEL_HW;
127 }
128 else
129 {
130 ctx->hcryp_aes.Init.KeyMode = CRYP_KEYMODE_NORMAL;
131 ctx->hcryp_aes.Init.KeyProtection = CRYP_KEYSEL_NORMAL;
132 }
133 #endif
134
135 /* Initializes the CRYP peripheral */
136 if (HAL_CRYP_DeInit(&ctx->hcryp_aes) != HAL_OK) {
137 return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
138 }
139
140 #if defined(GENERATOR_HW_CRYPTO_DPA_SUPPORTED) && defined(HW_CRYPTO_DPA_AES)
141 /* Enable SAES clock */
142 __HAL_RCC_SAES_CLK_ENABLE();
143 #else
144 /* Enable AES clock */
145 __HAL_RCC_AES_CLK_ENABLE();
146 #endif
147
148 if (HAL_CRYP_Init(&ctx->hcryp_aes) != HAL_OK) {
149 return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
150 }
151
152 /* allow multi-instance of CRYP use: save context for CRYP HW module CR */
153 ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
154
155 return (0);
156 }
157
158 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)159 static void mbedtls_zeroize(void *v, size_t n)
160 {
161 volatile unsigned char *p = (unsigned char *)v;
162 while (n--) {
163 *p++ = 0;
164 }
165 }
166
mbedtls_aes_init(mbedtls_aes_context * ctx)167 void mbedtls_aes_init(mbedtls_aes_context *ctx)
168 {
169 AES_VALIDATE( ctx != NULL );
170
171 memset(ctx, 0, sizeof(mbedtls_aes_context));
172
173 #if defined(STM32L5)
174 #else
175 ctx->hcryp_aes.Init.Algorithm = ST_AES_NO_ALGO;
176 #endif
177 }
178
179
mbedtls_aes_free(mbedtls_aes_context * ctx)180 void mbedtls_aes_free(mbedtls_aes_context *ctx)
181 {
182 if (ctx == NULL) {
183 return;
184 }
185
186 mbedtls_zeroize(ctx, sizeof(mbedtls_aes_context));
187 }
188
189 #if defined(MBEDTLS_CIPHER_MODE_XTS)
mbedtls_aes_xts_init(mbedtls_aes_xts_context * ctx)190 void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
191 {
192 AES_VALIDATE( ctx != NULL );
193
194 mbedtls_aes_init( &ctx->crypt );
195 mbedtls_aes_init( &ctx->tweak );
196 }
197
mbedtls_aes_xts_free(mbedtls_aes_xts_context * ctx)198 void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
199 {
200 if( ctx == NULL )
201 return;
202
203 mbedtls_aes_free( &ctx->crypt );
204 mbedtls_aes_free( &ctx->tweak );
205 }
206 #endif /* MBEDTLS_CIPHER_MODE_XTS */
207
208 /*
209 * AES key schedule (encryption)
210 */
mbedtls_aes_setkey_enc(mbedtls_aes_context * ctx,const unsigned char * key,unsigned int keybits)211 int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
212 unsigned int keybits)
213 {
214 return (aes_set_key(ctx, key, keybits));
215 }
216
217 /*
218 * AES key schedule (decryption)
219 */
mbedtls_aes_setkey_dec(mbedtls_aes_context * ctx,const unsigned char * key,unsigned int keybits)220 int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
221 unsigned int keybits)
222 {
223 return (aes_set_key(ctx, key, keybits));
224 }
225
226 #if defined(MBEDTLS_CIPHER_MODE_XTS)
mbedtls_aes_xts_decode_keys(const unsigned char * key,unsigned int keybits,const unsigned char ** key1,unsigned int * key1bits,const unsigned char ** key2,unsigned int * key2bits)227 static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
228 unsigned int keybits,
229 const unsigned char **key1,
230 unsigned int *key1bits,
231 const unsigned char **key2,
232 unsigned int *key2bits )
233 {
234 const unsigned int half_keybits = keybits / 2;
235 const unsigned int half_keybytes = half_keybits / 8;
236
237 switch( keybits )
238 {
239 case 256: break;
240 case 512: break;
241 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
242 }
243
244 *key1bits = half_keybits;
245 *key2bits = half_keybits;
246 *key1 = &key[0];
247 *key2 = &key[half_keybytes];
248
249 return ( 0 );
250 }
251
mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context * ctx,const unsigned char * key,unsigned int keybits)252 int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
253 const unsigned char *key,
254 unsigned int keybits)
255 {
256 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
257 const unsigned char *key1, *key2;
258 unsigned int key1bits, key2bits;
259
260 AES_VALIDATE_RET( ctx != NULL );
261 AES_VALIDATE_RET( key != NULL );
262
263 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
264 &key2, &key2bits );
265 if( ret != 0 )
266 return( ret );
267
268 /* Set the tweak key. Always set tweak key for the encryption mode. */
269 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
270 if( ret != 0 )
271 return( ret );
272
273 /* Set crypt key for encryption. */
274 return (mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits ));
275 }
276
mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context * ctx,const unsigned char * key,unsigned int keybits)277 int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
278 const unsigned char *key,
279 unsigned int keybits)
280 {
281 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
282 const unsigned char *key1, *key2;
283 unsigned int key1bits, key2bits;
284
285 AES_VALIDATE_RET( ctx != NULL );
286 AES_VALIDATE_RET( key != NULL );
287
288 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
289 &key2, &key2bits );
290 if( ret != 0 )
291 return( ret );
292
293 /* Set the tweak key. Always set tweak key for encryption. */
294 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
295 if( ret != 0 )
296 return( ret );
297
298 /* Set crypt key for decryption. */
299 return (mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits ));
300 }
301 #endif /* MBEDTLS_CIPHER_MODE_XTS */
302
303 /*
304 * AES-ECB block encryption/decryption
305 */
mbedtls_aes_crypt_ecb(mbedtls_aes_context * ctx,int mode,const unsigned char input[16],unsigned char output[16])306 int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
307 int mode,
308 const unsigned char input[16],
309 unsigned char output[16])
310 {
311 int ret;
312
313 AES_VALIDATE_RET( ctx != NULL );
314 AES_VALIDATE_RET( input != NULL );
315 AES_VALIDATE_RET( output != NULL );
316 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
317 mode == MBEDTLS_AES_DECRYPT );
318
319 /* allow multi-instance of CRYP use: restore context for CRYP hw module */
320 ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
321
322 /* Set the Algo if not configured till now */
323 if (CRYP_AES_ECB != ctx->hcryp_aes.Init.Algorithm)
324 {
325 ctx->hcryp_aes.Init.Algorithm = CRYP_AES_ECB;
326
327 /* Configure the CRYP */
328 if (HAL_CRYP_SetConfig(&ctx->hcryp_aes, &ctx->hcryp_aes.Init) != HAL_OK)
329 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
330 }
331
332 if (mode == MBEDTLS_AES_DECRYPT) { /* AES decryption */
333 ret = mbedtls_internal_aes_decrypt(ctx, input, output);
334 if( ret != 0 )
335 return (ret);
336 } else { /* AES encryption */
337 ret = mbedtls_internal_aes_encrypt(ctx, input, output);
338 if( ret != 0 )
339 return (ret);
340 }
341 /* allow multi-instance of CRYP use: save context for CRYP HW module CR */
342 ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
343
344 return (0);
345 }
346
347 #if defined(MBEDTLS_CIPHER_MODE_CBC)
348 /*
349 * AES-CBC buffer encryption/decryption
350 */
st_cbc_restore_context(mbedtls_aes_context * ctx)351 static int st_cbc_restore_context(mbedtls_aes_context *ctx)
352 {
353 /* allow multi-instance of CRYP use: restore context for CRYP hw module */
354 ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
355
356 /* Re-initialize AES processor with proper parameters
357 and (re-)apply key and IV for multi context usecases */
358 if (HAL_CRYP_DeInit(&ctx->hcryp_aes) != HAL_OK) {
359 return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
360 }
361
362 if (HAL_CRYP_Init(&ctx->hcryp_aes) != HAL_OK) {
363 return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
364 }
365 return (0);
366 }
367
mbedtls_aes_crypt_cbc(mbedtls_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)368 int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
369 int mode,
370 size_t length,
371 unsigned char iv[16],
372 const unsigned char *input,
373 unsigned char *output)
374 {
375 __ALIGN_BEGIN static uint32_t iv_32B[4] __ALIGN_END;
376 int ret = 0;
377
378 AES_VALIDATE_RET( ctx != NULL );
379 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
380 mode == MBEDTLS_AES_DECRYPT );
381 AES_VALIDATE_RET( iv != NULL );
382 AES_VALIDATE_RET( input != NULL );
383 AES_VALIDATE_RET( output != NULL );
384
385 if (length % 16) {
386 return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
387 }
388
389 ret = st_cbc_restore_context(ctx);
390 if (ret != 0)
391 return (ret);
392
393 /* Set the Algo if not configured till now */
394 if (CRYP_AES_CBC != ctx->hcryp_aes.Init.Algorithm)
395 {
396 ctx->hcryp_aes.Init.Algorithm = CRYP_AES_CBC;
397 }
398
399 /* Set IV with invert endianness */
400 SWAP_B8_TO_B32(iv_32B[0],iv,0);
401 SWAP_B8_TO_B32(iv_32B[1],iv,4);
402 SWAP_B8_TO_B32(iv_32B[2],iv,8);
403 SWAP_B8_TO_B32(iv_32B[3],iv,12);
404
405 ctx->hcryp_aes.Init.pInitVect = iv_32B;
406
407 /* reconfigure the CRYP */
408 if (HAL_CRYP_SetConfig(&ctx->hcryp_aes, &ctx->hcryp_aes.Init) != HAL_OK) {
409 return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
410 }
411
412 if (mode == MBEDTLS_AES_DECRYPT) {
413 if (HAL_CRYP_Decrypt(&ctx->hcryp_aes, (uint32_t *)input, length, (uint32_t *)output, ST_AES_TIMEOUT) != HAL_OK) {
414 return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
415 }
416
417 /* Get IV vector for the next call */
418 SWAP_B32_TO_B8(ctx->hcryp_aes.Instance->IVR3,iv,0);
419 SWAP_B32_TO_B8(ctx->hcryp_aes.Instance->IVR2,iv,4);
420 SWAP_B32_TO_B8(ctx->hcryp_aes.Instance->IVR1,iv,8);
421 SWAP_B32_TO_B8(ctx->hcryp_aes.Instance->IVR0,iv,12);
422
423 } else {
424 if (HAL_CRYP_Encrypt(&ctx->hcryp_aes, (uint32_t *)input, length, (uint32_t *)output, ST_AES_TIMEOUT) != HAL_OK) {
425 return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
426 }
427
428 /* current output is the IV vector for the next call */
429 memcpy(iv, &output[length - 16], 16);
430 }
431
432 /* Save the internal IV vector for multi context purpose */
433 ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR; // save here before overwritten
434 ctx->hcryp_aes.Instance->CR &= ~AES_CR_EN;
435
436 return (0);
437 }
438 #endif /* MBEDTLS_CIPHER_MODE_CBC */
439
440 #if defined(MBEDTLS_CIPHER_MODE_XTS)
441
442 /* Endianness with 64 bits values */
443 #ifndef GET_UINT64_LE
444 #define GET_UINT64_LE(n,b,i) \
445 { \
446 (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
447 | ( (uint64_t) (b)[(i) + 6] << 48 ) \
448 | ( (uint64_t) (b)[(i) + 5] << 40 ) \
449 | ( (uint64_t) (b)[(i) + 4] << 32 ) \
450 | ( (uint64_t) (b)[(i) + 3] << 24 ) \
451 | ( (uint64_t) (b)[(i) + 2] << 16 ) \
452 | ( (uint64_t) (b)[(i) + 1] << 8 ) \
453 | ( (uint64_t) (b)[(i) ] ); \
454 }
455 #endif
456
457 #ifndef PUT_UINT64_LE
458 #define PUT_UINT64_LE(n,b,i) \
459 { \
460 (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
461 (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
462 (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
463 (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
464 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
465 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
466 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
467 (b)[(i) ] = (unsigned char) ( (n) ); \
468 }
469 #endif
470
471 /*
472 * GF(2^128) multiplication function
473 *
474 * This function multiplies a field element by x in the polynomial field
475 * representation. It uses 64-bit word operations to gain speed but compensates
476 * for machine endianness and hence works correctly on both big and little
477 * endian machines.
478 */
mbedtls_gf128mul_x_ble(unsigned char r[16],const unsigned char x[16])479 static void mbedtls_gf128mul_x_ble( unsigned char r[16],
480 const unsigned char x[16] )
481 {
482 uint64_t a, b, ra, rb;
483
484 GET_UINT64_LE( a, x, 0 );
485 GET_UINT64_LE( b, x, 8 );
486
487 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
488 rb = ( a >> 63 ) | ( b << 1 );
489
490 PUT_UINT64_LE( ra, r, 0 );
491 PUT_UINT64_LE( rb, r, 8 );
492 }
493
494 /*
495 * AES-XTS buffer encryption/decryption
496 */
mbedtls_aes_crypt_xts(mbedtls_aes_xts_context * ctx,int mode,size_t length,const unsigned char data_unit[16],const unsigned char * input,unsigned char * output)497 int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
498 int mode,
499 size_t length,
500 const unsigned char data_unit[16],
501 const unsigned char *input,
502 unsigned char *output )
503 {
504 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
505 size_t blocks = length / 16;
506 size_t leftover = length % 16;
507 unsigned char tweak[16];
508 unsigned char prev_tweak[16];
509 unsigned char tmp[16];
510
511 AES_VALIDATE_RET( ctx != NULL );
512 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
513 mode == MBEDTLS_AES_DECRYPT );
514 AES_VALIDATE_RET( data_unit != NULL );
515 AES_VALIDATE_RET( input != NULL );
516 AES_VALIDATE_RET( output != NULL );
517
518 /* Data units must be at least 16 bytes long. */
519 if( length < 16 )
520 return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
521
522 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
523 if( length > ( 1 << 20 ) * 16 )
524 return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
525
526 /* Compute the tweak. */
527 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
528 data_unit, tweak );
529 if( ret != 0 )
530 return( ret );
531
532 while( blocks-- )
533 {
534 size_t i;
535
536 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
537 {
538 /* We are on the last block in a decrypt operation that has
539 * leftover bytes, so we need to use the next tweak for this block,
540 * and this tweak for the lefover bytes. Save the current tweak for
541 * the leftovers and then update the current tweak for use on this,
542 * the last full block. */
543 memcpy( prev_tweak, tweak, sizeof( tweak ) );
544 mbedtls_gf128mul_x_ble( tweak, tweak );
545 }
546
547 for( i = 0; i < 16; i++ )
548 tmp[i] = input[i] ^ tweak[i];
549
550 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
551 if( ret != 0 )
552 return( ret );
553
554 for( i = 0; i < 16; i++ )
555 output[i] = tmp[i] ^ tweak[i];
556
557 /* Update the tweak for the next block. */
558 mbedtls_gf128mul_x_ble( tweak, tweak );
559
560 output += 16;
561 input += 16;
562 }
563
564 if( leftover )
565 {
566 /* If we are on the leftover bytes in a decrypt operation, we need to
567 * use the previous tweak for these bytes (as saved in prev_tweak). */
568 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
569
570 /* We are now on the final part of the data unit, which doesn't divide
571 * evenly by 16. It's time for ciphertext stealing. */
572 size_t i;
573 unsigned char *prev_output = output - 16;
574
575 /* Copy ciphertext bytes from the previous block to our output for each
576 * byte of cyphertext we won't steal. At the same time, copy the
577 * remainder of the input for this final round (since the loop bounds
578 * are the same). */
579 for( i = 0; i < leftover; i++ )
580 {
581 output[i] = prev_output[i];
582 tmp[i] = input[i] ^ t[i];
583 }
584
585 /* Copy ciphertext bytes from the previous block for input in this
586 * round. */
587 for( ; i < 16; i++ )
588 tmp[i] = prev_output[i] ^ t[i];
589
590 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
591 if( ret != 0 )
592 return (ret);
593
594 /* Write the result back to the previous block, overriding the previous
595 * output we copied. */
596 for( i = 0; i < 16; i++ )
597 prev_output[i] = tmp[i] ^ t[i];
598 }
599
600 return( 0 );
601 }
602 #endif /* MBEDTLS_CIPHER_MODE_XTS */
603
604 #if defined(MBEDTLS_CIPHER_MODE_CFB)
605 /*
606 * AES-CFB128 buffer encryption/decryption
607 */
mbedtls_aes_crypt_cfb128(mbedtls_aes_context * ctx,int mode,size_t length,size_t * iv_off,unsigned char iv[16],const unsigned char * input,unsigned char * output)608 int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
609 int mode,
610 size_t length,
611 size_t *iv_off,
612 unsigned char iv[16],
613 const unsigned char *input,
614 unsigned char *output)
615 {
616 int ret;
617 int c;
618 size_t n;
619
620 AES_VALIDATE_RET( ctx != NULL );
621 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
622 mode == MBEDTLS_AES_DECRYPT );
623 AES_VALIDATE_RET( iv_off != NULL );
624 AES_VALIDATE_RET( iv != NULL );
625 AES_VALIDATE_RET( input != NULL );
626 AES_VALIDATE_RET( output != NULL );
627
628 n = *iv_off;
629
630 if (mode == MBEDTLS_AES_DECRYPT) {
631 while (length--) {
632 if (n == 0) {
633 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
634 if (ret != 0)
635 return (ret);
636 }
637
638 c = *input++;
639 *output++ = (unsigned char)(c ^ iv[n]);
640 iv[n] = (unsigned char) c;
641
642 n = (n + 1) & 0x0F;
643 }
644 } else {
645 while (length--) {
646 if (n == 0) {
647 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
648 if (ret != 0)
649 return (ret);
650 }
651
652 iv[n] = *output++ = (unsigned char)(iv[n] ^ *input++);
653
654 n = (n + 1) & 0x0F;
655 }
656 }
657
658 *iv_off = n;
659
660 return (0);
661 }
662
663 /*
664 * AES-CFB8 buffer encryption/decryption
665 */
mbedtls_aes_crypt_cfb8(mbedtls_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)666 int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
667 int mode,
668 size_t length,
669 unsigned char iv[16],
670 const unsigned char *input,
671 unsigned char *output)
672 {
673 int ret;
674 unsigned char c;
675 unsigned char ov[17];
676
677 AES_VALIDATE_RET( ctx != NULL );
678 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
679 mode == MBEDTLS_AES_DECRYPT );
680 AES_VALIDATE_RET( iv != NULL );
681 AES_VALIDATE_RET( input != NULL );
682 AES_VALIDATE_RET( output != NULL );
683
684 while (length--) {
685 memcpy(ov, iv, 16);
686 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
687 if (ret != 0)
688 return (ret);
689
690 if (mode == MBEDTLS_AES_DECRYPT) {
691 ov[16] = *input;
692 }
693
694 c = *output++ = (unsigned char)(iv[0] ^ *input++);
695
696 if (mode == MBEDTLS_AES_ENCRYPT) {
697 ov[16] = c;
698 }
699
700 memcpy(iv, ov + 1, 16);
701 }
702
703 return (0);
704 }
705
706 #endif /*MBEDTLS_CIPHER_MODE_CFB */
707
708 #if defined(MBEDTLS_CIPHER_MODE_OFB)
709 /*
710 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
711 */
mbedtls_aes_crypt_ofb(mbedtls_aes_context * ctx,size_t length,size_t * iv_off,unsigned char iv[16],const unsigned char * input,unsigned char * output)712 int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
713 size_t length,
714 size_t *iv_off,
715 unsigned char iv[16],
716 const unsigned char *input,
717 unsigned char *output )
718 {
719 int ret = 0;
720 size_t n;
721
722 AES_VALIDATE_RET( ctx != NULL );
723 AES_VALIDATE_RET( iv_off != NULL );
724 AES_VALIDATE_RET( iv != NULL );
725 AES_VALIDATE_RET( input != NULL );
726 AES_VALIDATE_RET( output != NULL );
727
728 n = *iv_off;
729
730 if( n > 15 )
731 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
732
733 while( length-- )
734 {
735 if( n == 0 )
736 {
737 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
738 if( ret != 0 )
739 goto exit;
740 }
741 *output++ = *input++ ^ iv[n];
742
743 n = ( n + 1 ) & 0x0F;
744 }
745
746 *iv_off = n;
747
748 exit:
749 return( ret );
750 }
751 #endif /* MBEDTLS_CIPHER_MODE_OFB */
752
753 #if defined(MBEDTLS_CIPHER_MODE_CTR)
754 /*
755 * AES-CTR buffer encryption/decryption
756 */
mbedtls_aes_crypt_ctr(mbedtls_aes_context * ctx,size_t length,size_t * nc_off,unsigned char nonce_counter[16],unsigned char stream_block[16],const unsigned char * input,unsigned char * output)757 int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
758 size_t length,
759 size_t *nc_off,
760 unsigned char nonce_counter[16],
761 unsigned char stream_block[16],
762 const unsigned char *input,
763 unsigned char *output)
764 {
765 int c, i;
766 size_t n;
767
768 AES_VALIDATE_RET( ctx != NULL );
769 AES_VALIDATE_RET( nc_off != NULL );
770 AES_VALIDATE_RET( nonce_counter != NULL );
771 AES_VALIDATE_RET( stream_block != NULL );
772 AES_VALIDATE_RET( input != NULL );
773 AES_VALIDATE_RET( output != NULL );
774
775 n = *nc_off;
776
777 while (length--) {
778 if (n == 0) {
779 if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block) != 0) {
780 return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
781 }
782
783 for (i = 16; i > 0; i--)
784 if (++nonce_counter[i - 1] != 0) {
785 break;
786 }
787 }
788 c = *input++;
789 *output++ = (unsigned char)(c ^ stream_block[n]);
790
791 n = (n + 1) & 0x0F;
792 }
793
794 *nc_off = n;
795
796 return (0);
797 }
798 #endif /* MBEDTLS_CIPHER_MODE_CTR */
799
mbedtls_internal_aes_encrypt(mbedtls_aes_context * ctx,const unsigned char input[16],unsigned char output[16])800 int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
801 const unsigned char input[16],
802 unsigned char output[16])
803 {
804
805 if (HAL_CRYP_Encrypt(&ctx->hcryp_aes, (uint32_t *)input, 16, (uint32_t *)output, ST_AES_TIMEOUT) != HAL_OK) {
806 return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
807 }
808 return (0);
809
810 }
811
mbedtls_internal_aes_decrypt(mbedtls_aes_context * ctx,const unsigned char input[16],unsigned char output[16])812 int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
813 const unsigned char input[16],
814 unsigned char output[16])
815 {
816 if (HAL_CRYP_Decrypt(&ctx->hcryp_aes, (uint32_t *)input, 16, (uint32_t *)output, ST_AES_TIMEOUT) != HAL_OK) {
817 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
818 }
819 return (0);
820 }
821 #endif /* MBEDTLS_AES_ALT */
822 #endif /* MBEDTLS_AES_C */
823