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