Coverage Report

Created: 2025-11-16 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-openssl-api/wolfcrypt/src/aes.c
Line
Count
Source
1
/* aes.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
/*
23
24
DESCRIPTION
25
This library provides the interfaces to the Advanced Encryption Standard (AES)
26
for encrypting and decrypting data. AES is the standard known for a symmetric
27
block cipher mechanism that uses n-bit binary string parameter key with 128-bits,
28
192-bits, and 256-bits of key sizes.
29
30
*/
31
32
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
33
34
#if !defined(NO_AES)
35
36
/* Tip: Locate the software cipher modes by searching for "Software AES" */
37
38
#if FIPS_VERSION3_GE(2,0,0)
39
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
40
    #define FIPS_NO_WRAPPERS
41
42
    #ifdef USE_WINDOWS_API
43
        #pragma code_seg(".fipsA$b")
44
        #pragma const_seg(".fipsB$b")
45
    #endif
46
#endif
47
48
#include <wolfssl/wolfcrypt/aes.h>
49
50
#ifdef WOLFSSL_AESNI
51
#include <wmmintrin.h>
52
#include <emmintrin.h>
53
#include <smmintrin.h>
54
#endif /* WOLFSSL_AESNI */
55
56
#include <wolfssl/wolfcrypt/cpuid.h>
57
58
#ifdef WOLF_CRYPTO_CB
59
    #include <wolfssl/wolfcrypt/cryptocb.h>
60
#endif
61
62
#ifdef WOLFSSL_SECO_CAAM
63
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
64
#endif
65
66
#ifdef WOLFSSL_IMXRT_DCP
67
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
68
#endif
69
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
70
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
71
#endif
72
73
#if defined(WOLFSSL_AES_SIV)
74
    #include <wolfssl/wolfcrypt/cmac.h>
75
#endif /* WOLFSSL_AES_SIV */
76
77
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
78
    #include <wolfssl/wolfcrypt/port/psa/psa.h>
79
#endif
80
81
#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
82
    #include <wolfssl/wolfcrypt/port/maxim/max3266x.h>
83
#ifdef MAX3266X_CB
84
    /* Revert back to SW so HW CB works */
85
    /* HW only works for AES: ECB, CBC, and partial via ECB for other modes */
86
    #include <wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h>
87
    /* Turn off MAX3266X_AES in the context of this file when using CB */
88
    #undef MAX3266X_AES
89
#endif
90
#endif
91
92
#if defined(WOLFSSL_TI_CRYPT)
93
    #include <wolfcrypt/src/port/ti/ti-aes.c>
94
#else
95
96
#ifdef NO_INLINE
97
    #include <wolfssl/wolfcrypt/misc.h>
98
#else
99
    #define WOLFSSL_MISC_INCLUDED
100
    #include <wolfcrypt/src/misc.c>
101
#endif
102
103
#if !defined(WOLFSSL_RISCV_ASM)
104
105
#ifdef WOLFSSL_IMX6_CAAM_BLOB
106
    /* case of possibly not using hardware acceleration for AES but using key
107
       blobs */
108
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
109
#endif
110
111
#ifdef DEBUG_AESNI
112
    #include <stdio.h>
113
#endif
114
115
#ifdef _MSC_VER
116
    /* 4127 warning constant while(1)  */
117
    #pragma warning(disable: 4127)
118
#endif
119
120
#if (!defined(WOLFSSL_ARMASM) && FIPS_VERSION3_GE(6,0,0)) || \
121
    FIPS_VERSION3_GE(7,0,0)
122
    const unsigned int wolfCrypt_FIPS_aes_ro_sanity[2] =
123
                                                     { 0x1a2b3c4d, 0x00000002 };
124
    int wolfCrypt_FIPS_AES_sanity(void)
125
    {
126
        return 0;
127
    }
128
#endif
129
130
/* Define AES implementation includes and functions */
131
#if defined(STM32_CRYPTO)
132
     /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
133
134
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
135
136
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
137
        Aes* aes, const byte* inBlock, byte* outBlock)
138
    {
139
        int ret = 0;
140
    #ifdef WOLFSSL_STM32_CUBEMX
141
        CRYP_HandleTypeDef hcryp;
142
    #else
143
        CRYP_InitTypeDef cryptInit;
144
        CRYP_KeyInitTypeDef keyInit;
145
    #endif
146
147
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
148
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
149
        if (ret < 0)
150
            return ret;
151
#endif
152
153
    #ifdef WOLFSSL_STM32U5_DHUK
154
        ret = wolfSSL_CryptHwMutexLock();
155
        if (ret != 0)
156
            return ret;
157
158
        /* Handle making use of wrapped key */
159
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
160
            CRYP_ConfigTypeDef Config = {0};
161
162
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key,
163
                aes->keylen, aes->dhukIV, aes->dhukIVLen);
164
            if (ret != HAL_OK) {
165
                WOLFSSL_MSG("Error with DHUK key unwrap");
166
                ret = BAD_FUNC_ARG;
167
            }
168
            /* reconfigure for using unwrapped key now */
169
            HAL_CRYP_GetConfig(&hcryp, &Config);
170
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
171
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
172
            Config.Algorithm = CRYP_AES_ECB;
173
            Config.DataType  = CRYP_DATATYPE_8B;
174
            Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
175
            HAL_CRYP_SetConfig(&hcryp, &Config);
176
        }
177
        else {
178
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
179
            if (ret == 0) {
180
                hcryp.Init.Algorithm  = CRYP_AES_ECB;
181
                ret = HAL_CRYP_Init(&hcryp);
182
                if (ret != HAL_OK) {
183
                    ret = BAD_FUNC_ARG;
184
                }
185
            }
186
        }
187
188
        if (ret == HAL_OK) {
189
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
190
                    (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
191
            if (ret != HAL_OK) {
192
                ret = WC_TIMEOUT_E;
193
            }
194
        }
195
        HAL_CRYP_DeInit(&hcryp);
196
    #elif defined(WOLFSSL_STM32_CUBEMX)
197
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
198
        if (ret != 0)
199
            return ret;
200
201
        ret = wolfSSL_CryptHwMutexLock();
202
        if (ret != 0)
203
            return ret;
204
205
    #if defined(STM32_HAL_V2)
206
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
207
    #elif defined(STM32_CRYPTO_AES_ONLY)
208
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
209
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
210
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
211
    #endif
212
        if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
213
            ret = BAD_FUNC_ARG;
214
        }
215
216
        if (ret == 0) {
217
        #if defined(STM32_HAL_V2)
218
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
219
                (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
220
        #elif defined(STM32_CRYPTO_AES_ONLY)
221
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
222
                outBlock, STM32_HAL_TIMEOUT);
223
        #else
224
            ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
225
                outBlock, STM32_HAL_TIMEOUT);
226
        #endif
227
            if (ret != HAL_OK) {
228
                ret = WC_TIMEOUT_E;
229
            }
230
            HAL_CRYP_DeInit(&hcryp);
231
        }
232
233
    #else /* Standard Peripheral Library */
234
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
235
        if (ret != 0)
236
            return ret;
237
238
        ret = wolfSSL_CryptHwMutexLock();
239
        if (ret != 0)
240
            return ret;
241
242
        /* reset registers to their default values */
243
        CRYP_DeInit();
244
245
        /* setup key */
246
        CRYP_KeyInit(&keyInit);
247
248
        /* set direction and mode */
249
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
250
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
251
        CRYP_Init(&cryptInit);
252
253
        /* enable crypto processor */
254
        CRYP_Cmd(ENABLE);
255
256
        /* flush IN/OUT FIFOs */
257
        CRYP_FIFOFlush();
258
259
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
260
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
261
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
262
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
263
264
        /* wait until the complete message has been processed */
265
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
266
267
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
268
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
269
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
270
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
271
272
        /* disable crypto processor */
273
        CRYP_Cmd(DISABLE);
274
    #endif /* WOLFSSL_STM32_CUBEMX */
275
        wolfSSL_CryptHwMutexUnLock();
276
        wc_Stm32_Aes_Cleanup();
277
278
        return ret;
279
    }
280
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
281
282
#ifdef HAVE_AES_DECRYPT
283
    #if defined(WOLFSSL_AES_DIRECT)
284
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
285
        Aes* aes, const byte* inBlock, byte* outBlock)
286
    {
287
        int ret = 0;
288
    #ifdef WOLFSSL_STM32_CUBEMX
289
        CRYP_HandleTypeDef hcryp;
290
    #else
291
        CRYP_InitTypeDef cryptInit;
292
        CRYP_KeyInitTypeDef keyInit;
293
    #endif
294
295
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
296
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
297
        if (ret < 0)
298
            return ret;
299
#endif
300
301
    #ifdef WOLFSSL_STM32U5_DHUK
302
        ret = wolfSSL_CryptHwMutexLock();
303
        if (ret != 0)
304
            return ret;
305
306
        /* Handle making use of wrapped key */
307
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
308
            CRYP_ConfigTypeDef Config;
309
310
            XMEMSET(&Config, 0, sizeof(Config));
311
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key,
312
                aes->keylen, aes->dhukIV, aes->dhukIVLen);
313
            if (ret != HAL_OK) {
314
                WOLFSSL_MSG("Error with DHUK unwrap");
315
                ret = BAD_FUNC_ARG;
316
            }
317
            /* reconfigure for using unwrapped key now */
318
            HAL_CRYP_GetConfig(&hcryp, &Config);
319
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
320
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
321
            Config.Algorithm = CRYP_AES_ECB;
322
            Config.DataType  = CRYP_DATATYPE_8B;
323
            Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
324
            HAL_CRYP_SetConfig(&hcryp, &Config);
325
        }
326
        else {
327
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
328
            if (ret == 0) {
329
                hcryp.Init.Algorithm  = CRYP_AES_ECB;
330
                ret = HAL_CRYP_Init(&hcryp);
331
                if (ret != HAL_OK) {
332
                    ret = BAD_FUNC_ARG;
333
                }
334
            }
335
        }
336
337
        if (ret == HAL_OK) {
338
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
339
                    (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
340
            if (ret != HAL_OK) {
341
                ret = WC_TIMEOUT_E;
342
            }
343
        }
344
        HAL_CRYP_DeInit(&hcryp);
345
    #elif defined(WOLFSSL_STM32_CUBEMX)
346
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
347
        if (ret != 0)
348
            return ret;
349
350
        ret = wolfSSL_CryptHwMutexLock();
351
        if (ret != 0)
352
            return ret;
353
354
    #if defined(STM32_HAL_V2)
355
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
356
    #elif defined(STM32_CRYPTO_AES_ONLY)
357
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
358
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
359
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
360
    #endif
361
        HAL_CRYP_Init(&hcryp);
362
363
    #if defined(STM32_HAL_V2)
364
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
365
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
366
    #elif defined(STM32_CRYPTO_AES_ONLY)
367
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
368
            outBlock, STM32_HAL_TIMEOUT);
369
    #else
370
        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
371
            outBlock, STM32_HAL_TIMEOUT);
372
    #endif
373
        if (ret != HAL_OK) {
374
            ret = WC_TIMEOUT_E;
375
        }
376
        HAL_CRYP_DeInit(&hcryp);
377
378
    #else /* Standard Peripheral Library */
379
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
380
        if (ret != 0)
381
            return ret;
382
383
        ret = wolfSSL_CryptHwMutexLock();
384
        if (ret != 0)
385
            return ret;
386
387
        /* reset registers to their default values */
388
        CRYP_DeInit();
389
390
        /* set direction and key */
391
        CRYP_KeyInit(&keyInit);
392
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
393
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
394
        CRYP_Init(&cryptInit);
395
396
        /* enable crypto processor */
397
        CRYP_Cmd(ENABLE);
398
399
        /* wait until decrypt key has been initialized */
400
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
401
402
        /* set direction and mode */
403
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
404
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
405
        CRYP_Init(&cryptInit);
406
407
        /* enable crypto processor */
408
        CRYP_Cmd(ENABLE);
409
410
        /* flush IN/OUT FIFOs */
411
        CRYP_FIFOFlush();
412
413
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
414
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
415
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
416
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
417
418
        /* wait until the complete message has been processed */
419
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
420
421
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
422
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
423
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
424
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
425
426
        /* disable crypto processor */
427
        CRYP_Cmd(DISABLE);
428
    #endif /* WOLFSSL_STM32_CUBEMX */
429
        wolfSSL_CryptHwMutexUnLock();
430
        wc_Stm32_Aes_Cleanup();
431
432
        return ret;
433
    }
434
    #endif /* WOLFSSL_AES_DIRECT */
435
#endif /* HAVE_AES_DECRYPT */
436
437
#elif defined(HAVE_COLDFIRE_SEC)
438
    /* Freescale Coldfire SEC support for CBC mode.
439
     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
440
    #include "sec.h"
441
    #include "mcf5475_sec.h"
442
    #include "mcf5475_siu.h"
443
#elif defined(FREESCALE_LTC)
444
    #include "fsl_ltc.h"
445
    #if defined(FREESCALE_LTC_AES_GCM)
446
        #undef NEED_AES_TABLES
447
        #undef GCM_TABLE
448
    #endif
449
450
        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
451
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
452
            Aes* aes, const byte* inBlock, byte* outBlock)
453
        {
454
            word32 keySize = 0;
455
            byte* key = (byte*)aes->key;
456
            int ret = wc_AesGetKeySize(aes, &keySize);
457
            if (ret != 0)
458
                return ret;
459
460
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
461
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
462
            if (ret < 0)
463
                return ret;
464
#endif
465
466
            if (wolfSSL_CryptHwMutexLock() == 0) {
467
                LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
468
                    key, keySize);
469
                wolfSSL_CryptHwMutexUnLock();
470
            }
471
            return 0;
472
        }
473
        #ifdef HAVE_AES_DECRYPT
474
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
475
            Aes* aes, const byte* inBlock, byte* outBlock)
476
        {
477
            word32 keySize = 0;
478
            byte* key = (byte*)aes->key;
479
            int ret = wc_AesGetKeySize(aes, &keySize);
480
            if (ret != 0)
481
                return ret;
482
483
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
484
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
485
            if (ret < 0)
486
                return ret;
487
#endif
488
489
            if (wolfSSL_CryptHwMutexLock() == 0) {
490
                LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
491
                    key, keySize, kLTC_EncryptKey);
492
                wolfSSL_CryptHwMutexUnLock();
493
            }
494
            return 0;
495
        }
496
        #endif
497
498
#elif defined(FREESCALE_MMCAU)
499
    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
500
     * through the CAU/mmCAU library. Documentation located in
501
     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
502
     * Guide (See note in README). */
503
    #ifdef FREESCALE_MMCAU_CLASSIC
504
        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
505
        #include "cau_api.h"
506
    #else
507
        #include "fsl_mmcau.h"
508
    #endif
509
510
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
511
        Aes* aes, const byte* inBlock, byte* outBlock)
512
    {
513
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
514
        {
515
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
516
            if (ret < 0)
517
                return ret;
518
        }
519
#endif
520
521
        if (wolfSSL_CryptHwMutexLock() == 0) {
522
        #ifdef FREESCALE_MMCAU_CLASSIC
523
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
524
                WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
525
                return BAD_ALIGN_E;
526
            }
527
            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
528
        #else
529
            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
530
                                 outBlock);
531
        #endif
532
            wolfSSL_CryptHwMutexUnLock();
533
        }
534
        return 0;
535
    }
536
    #ifdef HAVE_AES_DECRYPT
537
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
538
        Aes* aes, const byte* inBlock, byte* outBlock)
539
    {
540
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
541
        {
542
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
543
            if (ret < 0)
544
                return ret;
545
        }
546
#endif
547
        if (wolfSSL_CryptHwMutexLock() == 0) {
548
        #ifdef FREESCALE_MMCAU_CLASSIC
549
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
550
                WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
551
                return BAD_ALIGN_E;
552
            }
553
            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
554
        #else
555
            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
556
                                 outBlock);
557
        #endif
558
            wolfSSL_CryptHwMutexUnLock();
559
        }
560
        return 0;
561
    }
562
    #endif /* HAVE_AES_DECRYPT */
563
564
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
565
566
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
567
568
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
569
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
570
        Aes* aes, const byte* inBlock, byte* outBlock)
571
    {
572
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
573
        {
574
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
575
            if (ret < 0)
576
                return ret;
577
        }
578
#endif
579
        /* Thread mutex protection handled in Pic32Crypto */
580
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
581
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
582
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
583
    }
584
    #endif
585
586
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
587
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
588
        Aes* aes, const byte* inBlock, byte* outBlock)
589
    {
590
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
591
        {
592
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
593
            if (ret < 0)
594
                return ret;
595
        }
596
#endif
597
        /* Thread mutex protection handled in Pic32Crypto */
598
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
599
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
600
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
601
    }
602
    #endif
603
604
#elif defined(WOLFSSL_NRF51_AES)
605
    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
606
    #include "wolfssl/wolfcrypt/port/nrf51.h"
607
608
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
609
        Aes* aes, const byte* inBlock, byte* outBlock)
610
    {
611
        int ret;
612
613
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
614
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
615
        if (ret < 0)
616
            return ret;
617
#endif
618
619
        ret = wolfSSL_CryptHwMutexLock();
620
        if (ret == 0) {
621
            ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds,
622
                                    outBlock);
623
            wolfSSL_CryptHwMutexUnLock();
624
        }
625
        return ret;
626
    }
627
628
    #ifdef HAVE_AES_DECRYPT
629
        #error nRF51 AES Hardware does not support decrypt
630
    #endif /* HAVE_AES_DECRYPT */
631
632
#elif defined(WOLFSSL_ESP32_CRYPT) && \
633
     !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
634
    #include <esp_log.h>
635
    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
636
    #define TAG "aes"
637
638
    /* We'll use SW for fallback:
639
     *   unsupported key lengths. (e.g. ESP32-S3)
640
     *   chipsets not implemented.
641
     *   hardware busy. */
642
    #define NEED_AES_TABLES
643
    #define NEED_AES_HW_FALLBACK
644
    #define NEED_SOFTWARE_AES_SETKEY
645
    #undef  WOLFSSL_AES_DIRECT
646
    #define WOLFSSL_AES_DIRECT
647
648
    /* Encrypt: If we choose to never have a fallback to SW: */
649
    #if !defined(NEED_AES_HW_FALLBACK) && \
650
        (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
651
    /* calling this one when NO_AES_192 is defined */
652
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
653
        Aes* aes, const byte* inBlock, byte* outBlock)
654
    {
655
        int ret;
656
657
    #ifdef WC_DEBUG_CIPHER_LIFECYCLE
658
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
659
        if (ret < 0)
660
            return ret;
661
    #endif
662
663
        /* Thread mutex protection handled in esp_aes_hw_InUse */
664
    #ifdef NEED_AES_HW_FALLBACK
665
        if (wc_esp32AesSupportedKeyLen(aes)) {
666
            ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
667
        }
668
    #else
669
        ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
670
    #endif
671
        return ret;
672
    }
673
    #endif
674
675
    /* Decrypt: If we choose to never have a fallback to SW: */
676
    #if !defined(NEED_AES_HW_FALLBACK) && \
677
        (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
678
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
679
        Aes* aes, const byte* inBlock, byte* outBlock)
680
    {
681
        int ret = 0;
682
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
683
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
684
        if (ret < 0)
685
            return ret;
686
#endif
687
        /* Thread mutex protection handled in esp_aes_hw_InUse */
688
    #ifdef NEED_AES_HW_FALLBACK
689
        if (wc_esp32AesSupportedKeyLen(aes)) {
690
            ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
691
        }
692
        else {
693
            ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
694
        }
695
    #else
696
        /* if we don't need fallback, always use HW */
697
        ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
698
    #endif
699
        return ret;
700
    }
701
    #endif
702
703
#elif defined(WOLFSSL_AESNI)
704
705
    #define NEED_AES_TABLES
706
707
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
708
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
709
     */
710
711
    #ifndef AESNI_ALIGN
712
        #define AESNI_ALIGN 16
713
    #endif
714
715
    /* note that all write access to these static variables must be idempotent,
716
     * as arranged by Check_CPU_support_AES(), else they will be susceptible to
717
     * data races.
718
     */
719
    static int checkedAESNI = 0;
720
    static int haveAESNI  = 0;
721
    static cpuid_flags_t intel_flags = WC_CPUID_INITIALIZER;
722
723
    static WARN_UNUSED_RESULT int Check_CPU_support_AES(void)
724
    {
725
        cpuid_get_flags_ex(&intel_flags);
726
727
        return IS_INTEL_AESNI(intel_flags) != 0;
728
    }
729
730
731
    /* tell C compiler these are asm functions in case any mix up of ABI underscore
732
       prefix between clang/gcc/llvm etc */
733
    #ifdef HAVE_AES_CBC
734
        void AES_CBC_encrypt_AESNI(const unsigned char* in, unsigned char* out,
735
                             unsigned char* ivec, unsigned long length,
736
                             const unsigned char* KS, int nr)
737
                             XASM_LINK("AES_CBC_encrypt_AESNI");
738
739
        #ifdef HAVE_AES_DECRYPT
740
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
741
                void AES_CBC_decrypt_AESNI_by4(const unsigned char* in, unsigned char* out,
742
                                         unsigned char* ivec, unsigned long length,
743
                                         const unsigned char* KS, int nr)
744
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by4");
745
            #elif defined(WOLFSSL_AESNI_BY6)
746
                void AES_CBC_decrypt_AESNI_by6(const unsigned char* in, unsigned char* out,
747
                                         unsigned char* ivec, unsigned long length,
748
                                         const unsigned char* KS, int nr)
749
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by6");
750
            #else /* WOLFSSL_AESNI_BYx */
751
                void AES_CBC_decrypt_AESNI_by8(const unsigned char* in, unsigned char* out,
752
                                         unsigned char* ivec, unsigned long length,
753
                                         const unsigned char* KS, int nr)
754
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by8");
755
            #endif /* WOLFSSL_AESNI_BYx */
756
        #endif /* HAVE_AES_DECRYPT */
757
    #endif /* HAVE_AES_CBC */
758
759
    void AES_ECB_encrypt_AESNI(const unsigned char* in, unsigned char* out,
760
                         unsigned long length, const unsigned char* KS, int nr)
761
                         XASM_LINK("AES_ECB_encrypt_AESNI");
762
763
    #ifdef HAVE_AES_DECRYPT
764
        void AES_ECB_decrypt_AESNI(const unsigned char* in, unsigned char* out,
765
                             unsigned long length, const unsigned char* KS, int nr)
766
                             XASM_LINK("AES_ECB_decrypt_AESNI");
767
    #endif
768
769
    void AES_128_Key_Expansion_AESNI(const unsigned char* userkey,
770
                               unsigned char* key_schedule)
771
                               XASM_LINK("AES_128_Key_Expansion_AESNI");
772
773
    void AES_192_Key_Expansion_AESNI(const unsigned char* userkey,
774
                               unsigned char* key_schedule)
775
                               XASM_LINK("AES_192_Key_Expansion_AESNI");
776
777
    void AES_256_Key_Expansion_AESNI(const unsigned char* userkey,
778
                               unsigned char* key_schedule)
779
                               XASM_LINK("AES_256_Key_Expansion_AESNI");
780
781
782
    static WARN_UNUSED_RESULT int AES_set_encrypt_key_AESNI(
783
        const unsigned char *userKey, const int bits, Aes* aes)
784
    {
785
        int ret;
786
787
        ASSERT_SAVED_VECTOR_REGISTERS();
788
789
        if (!userKey || !aes)
790
            return BAD_FUNC_ARG;
791
792
        switch (bits) {
793
            case 128:
794
               AES_128_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 10;
795
               return 0;
796
            case 192:
797
               AES_192_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 12;
798
               return 0;
799
            case 256:
800
               AES_256_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 14;
801
               return 0;
802
            default:
803
                ret = BAD_FUNC_ARG;
804
        }
805
806
        return ret;
807
    }
808
809
    #ifdef HAVE_AES_DECRYPT
810
        static WARN_UNUSED_RESULT int AES_set_decrypt_key_AESNI(
811
            const unsigned char* userKey, const int bits, Aes* aes)
812
        {
813
            word32 nr;
814
            WC_DECLARE_VAR(temp_key, Aes, 1, 0);
815
            __m128i *Key_Schedule;
816
            __m128i *Temp_Key_Schedule;
817
818
            ASSERT_SAVED_VECTOR_REGISTERS();
819
820
            if (!userKey || !aes)
821
                return BAD_FUNC_ARG;
822
823
#ifdef WOLFSSL_SMALL_STACK
824
            if ((temp_key = (Aes *)XMALLOC(sizeof *aes, aes->heap,
825
                                           DYNAMIC_TYPE_AES)) == NULL)
826
                return MEMORY_E;
827
#endif
828
829
            if (AES_set_encrypt_key_AESNI(userKey,bits,temp_key)
830
                == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
831
                WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
832
                return BAD_FUNC_ARG;
833
            }
834
835
            Key_Schedule = (__m128i*)aes->key;
836
            Temp_Key_Schedule = (__m128i*)temp_key->key;
837
838
            nr = temp_key->rounds;
839
            aes->rounds = nr;
840
841
            Key_Schedule[nr] = Temp_Key_Schedule[0];
842
            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
843
            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
844
            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
845
            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
846
            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
847
            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
848
            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
849
            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
850
            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
851
852
            if (nr>10) {
853
                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
854
                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
855
            }
856
857
            if (nr>12) {
858
                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
859
                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
860
            }
861
862
            Key_Schedule[0] = Temp_Key_Schedule[nr];
863
864
            WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
865
866
            return 0;
867
        }
868
    #endif /* HAVE_AES_DECRYPT */
869
870
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
871
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
872
873
    #define NEED_AES_TABLES
874
875
    static cpuid_flags_t cpuid_flags = WC_CPUID_INITIALIZER;
876
877
    static void Check_CPU_support_HwCrypto(Aes* aes)
878
    {
879
        cpuid_get_flags_ex(&cpuid_flags);
880
        aes->use_aes_hw_crypto = IS_AARCH64_AES(cpuid_flags);
881
    #ifdef HAVE_AESGCM
882
        aes->use_pmull_hw_crypto = IS_AARCH64_PMULL(cpuid_flags);
883
        aes->use_sha3_hw_crypto = IS_AARCH64_SHA3(cpuid_flags);
884
    #endif
885
    }
886
887
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
888
889
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM)
890
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
891
    byte* outBlock)
892
{
893
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
894
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
895
#else
896
    AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
897
        (int)aes->rounds);
898
#endif
899
    return 0;
900
}
901
#endif
902
903
#ifdef HAVE_AES_DECRYPT
904
#ifdef WOLFSSL_AES_DIRECT
905
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
906
    byte* outBlock)
907
{
908
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
909
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
910
#else
911
    AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
912
        (int)aes->rounds);
913
#endif
914
    return 0;
915
}
916
#endif
917
#endif
918
919
#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
920
        && !defined(WOLFSSL_QNX_CAAM)) || \
921
      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
922
        defined(HAVE_AESCCM))
923
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
924
            Aes* aes, const byte* inBlock, byte* outBlock)
925
        {
926
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
927
            {
928
                int ret =
929
                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
930
                if (ret < 0)
931
                    return ret;
932
            }
933
#endif
934
            return wc_AesEncryptDirect(aes, outBlock, inBlock);
935
        }
936
937
#elif defined(WOLFSSL_AFALG)
938
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
939
940
#elif defined(WOLFSSL_DEVCRYPTO_AES)
941
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
942
943
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
944
    #include "hal_data.h"
945
946
    #ifndef WOLFSSL_SCE_AES256_HANDLE
947
        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
948
    #endif
949
950
    #ifndef WOLFSSL_SCE_AES192_HANDLE
951
        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
952
    #endif
953
954
    #ifndef WOLFSSL_SCE_AES128_HANDLE
955
        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
956
    #endif
957
958
    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
959
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
960
    {
961
        word32 ret;
962
963
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
964
                CRYPTO_WORD_ENDIAN_BIG) {
965
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
966
        }
967
968
        switch (aes->keylen) {
969
        #ifdef WOLFSSL_AES_128
970
            case AES_128_KEY_SIZE:
971
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
972
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
973
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
974
                        (word32*)outBlock);
975
                break;
976
        #endif
977
        #ifdef WOLFSSL_AES_192
978
            case AES_192_KEY_SIZE:
979
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
980
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
981
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
982
                        (word32*)outBlock);
983
                break;
984
        #endif
985
        #ifdef WOLFSSL_AES_256
986
            case AES_256_KEY_SIZE:
987
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
988
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
989
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
990
                        (word32*)outBlock);
991
                break;
992
        #endif
993
            default:
994
                WOLFSSL_MSG("Unknown key size");
995
                return BAD_FUNC_ARG;
996
        }
997
998
        if (ret != SSP_SUCCESS) {
999
            /* revert input */
1000
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1001
            return WC_HW_E;
1002
        }
1003
1004
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1005
                CRYPTO_WORD_ENDIAN_BIG) {
1006
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1007
            if (inBlock != outBlock) {
1008
                /* revert input */
1009
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1010
            }
1011
        }
1012
        return 0;
1013
    }
1014
1015
    #if defined(HAVE_AES_DECRYPT)
1016
    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
1017
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1018
    {
1019
        word32 ret;
1020
1021
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1022
                CRYPTO_WORD_ENDIAN_BIG) {
1023
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1024
        }
1025
1026
        switch (aes->keylen) {
1027
        #ifdef WOLFSSL_AES_128
1028
            case AES_128_KEY_SIZE:
1029
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
1030
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
1031
                        (sz / sizeof(word32)), (word32*)inBlock,
1032
                        (word32*)outBlock);
1033
                break;
1034
        #endif
1035
        #ifdef WOLFSSL_AES_192
1036
            case AES_192_KEY_SIZE:
1037
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
1038
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
1039
                        (sz / sizeof(word32)), (word32*)inBlock,
1040
                        (word32*)outBlock);
1041
                break;
1042
        #endif
1043
        #ifdef WOLFSSL_AES_256
1044
            case AES_256_KEY_SIZE:
1045
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
1046
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
1047
                        (sz / sizeof(word32)), (word32*)inBlock,
1048
                        (word32*)outBlock);
1049
                break;
1050
        #endif
1051
            default:
1052
                WOLFSSL_MSG("Unknown key size");
1053
                return BAD_FUNC_ARG;
1054
        }
1055
        if (ret != SSP_SUCCESS) {
1056
            return WC_HW_E;
1057
        }
1058
1059
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1060
                CRYPTO_WORD_ENDIAN_BIG) {
1061
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1062
            if (inBlock != outBlock) {
1063
                /* revert input */
1064
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1065
            }
1066
        }
1067
1068
        return 0;
1069
    }
1070
    #endif /* HAVE_AES_DECRYPT */
1071
1072
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
1073
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1074
        Aes* aes, const byte* inBlock, byte* outBlock)
1075
    {
1076
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1077
        {
1078
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1079
            if (ret < 0)
1080
                return ret;
1081
        }
1082
#endif
1083
        return AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1084
    }
1085
    #endif
1086
1087
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1088
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1089
        Aes* aes, const byte* inBlock, byte* outBlock)
1090
    {
1091
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1092
        {
1093
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1094
            if (ret < 0)
1095
                return ret;
1096
        }
1097
#endif
1098
        return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1099
    }
1100
    #endif
1101
1102
#elif defined(WOLFSSL_KCAPI_AES)
1103
    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
1104
    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
1105
        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1106
        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
1107
        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
1108
        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
1109
1110
        #define NEED_AES_TABLES
1111
    #endif
1112
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
1113
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
1114
1115
#elif defined(WOLFSSL_RISCV_ASM)
1116
/* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
1117
1118
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1119
/* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
1120
1121
#else
1122
1123
    /* using wolfCrypt software implementation */
1124
    #define NEED_AES_TABLES
1125
#endif
1126
1127
1128
1129
#if defined(WC_AES_BITSLICED) && !defined(HAVE_AES_ECB)
1130
    #error "When WC_AES_BITSLICED is defined, HAVE_AES_ECB is needed."
1131
#endif
1132
1133
#ifdef NEED_AES_TABLES
1134
1135
#ifndef WC_AES_BITSLICED
1136
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1137
#if !defined(WOLFSSL_ESP32_CRYPT) || \
1138
    (defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
1139
     defined(NEED_AES_HW_FALLBACK))
1140
static const FLASH_QUALIFIER word32 rcon[] = {
1141
    0x01000000, 0x02000000, 0x04000000, 0x08000000,
1142
    0x10000000, 0x20000000, 0x40000000, 0x80000000,
1143
    0x1B000000, 0x36000000,
1144
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1145
};
1146
#endif /* ESP32 */
1147
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1148
1149
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM) || \
1150
      defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || defined(WOLFSSL_AES_DIRECT) || \
1151
      defined(HAVE_AESCCM)
1152
#ifndef WOLFSSL_AES_SMALL_TABLES
1153
static const FLASH_QUALIFIER word32 Te[4][256] = {
1154
{
1155
    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1156
    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1157
    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1158
    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1159
    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1160
    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1161
    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1162
    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1163
    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1164
    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1165
    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1166
    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1167
    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1168
    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1169
    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1170
    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1171
    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1172
    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1173
    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1174
    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1175
    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1176
    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1177
    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1178
    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1179
    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1180
    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1181
    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1182
    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1183
    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1184
    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1185
    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1186
    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1187
    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1188
    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1189
    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1190
    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1191
    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1192
    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1193
    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1194
    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1195
    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1196
    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1197
    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1198
    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1199
    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1200
    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1201
    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1202
    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1203
    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1204
    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1205
    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1206
    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1207
    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1208
    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1209
    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1210
    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1211
    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1212
    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1213
    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1214
    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1215
    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1216
    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1217
    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1218
    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1219
},
1220
{
1221
    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1222
    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1223
    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1224
    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1225
    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1226
    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1227
    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1228
    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1229
    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1230
    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1231
    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1232
    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1233
    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1234
    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1235
    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1236
    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1237
    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1238
    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1239
    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1240
    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1241
    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1242
    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1243
    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1244
    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1245
    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1246
    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1247
    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1248
    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1249
    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1250
    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1251
    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1252
    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1253
    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1254
    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1255
    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1256
    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1257
    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1258
    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1259
    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1260
    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1261
    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1262
    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1263
    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1264
    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1265
    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1266
    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1267
    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1268
    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1269
    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1270
    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1271
    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1272
    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1273
    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1274
    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1275
    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1276
    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1277
    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1278
    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1279
    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1280
    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1281
    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1282
    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1283
    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1284
    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1285
},
1286
{
1287
    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1288
    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1289
    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1290
    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1291
    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1292
    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1293
    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1294
    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1295
    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1296
    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1297
    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1298
    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1299
    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1300
    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1301
    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1302
    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1303
    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1304
    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1305
    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1306
    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1307
    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1308
    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1309
    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1310
    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1311
    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1312
    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1313
    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1314
    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1315
    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1316
    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1317
    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1318
    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1319
    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1320
    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1321
    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1322
    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1323
    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1324
    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1325
    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1326
    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1327
    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1328
    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1329
    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1330
    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1331
    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1332
    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1333
    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1334
    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1335
    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1336
    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1337
    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1338
    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1339
    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1340
    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1341
    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1342
    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1343
    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1344
    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1345
    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1346
    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1347
    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1348
    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1349
    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1350
    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1351
},
1352
{
1353
    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1354
    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1355
    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1356
    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1357
    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1358
    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1359
    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1360
    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1361
    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1362
    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1363
    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1364
    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1365
    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1366
    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1367
    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1368
    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1369
    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1370
    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1371
    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1372
    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1373
    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1374
    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1375
    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1376
    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1377
    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1378
    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1379
    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1380
    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1381
    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1382
    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1383
    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1384
    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1385
    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1386
    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1387
    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1388
    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1389
    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1390
    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1391
    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1392
    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1393
    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1394
    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1395
    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1396
    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1397
    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1398
    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1399
    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1400
    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1401
    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1402
    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1403
    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1404
    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1405
    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1406
    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1407
    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1408
    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1409
    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1410
    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1411
    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1412
    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1413
    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1414
    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1415
    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1416
    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1417
}
1418
};
1419
1420
#ifdef HAVE_AES_DECRYPT
1421
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1422
static const FLASH_QUALIFIER word32 Td[4][256] = {
1423
{
1424
    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1425
    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1426
    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1427
    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1428
    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1429
    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1430
    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1431
    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1432
    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1433
    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1434
    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1435
    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1436
    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1437
    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1438
    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1439
    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1440
    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1441
    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1442
    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1443
    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1444
    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1445
    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1446
    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1447
    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1448
    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1449
    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1450
    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1451
    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1452
    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1453
    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1454
    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1455
    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1456
    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1457
    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1458
    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1459
    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1460
    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1461
    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1462
    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1463
    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1464
    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1465
    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1466
    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1467
    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1468
    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1469
    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1470
    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1471
    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1472
    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1473
    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1474
    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1475
    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1476
    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1477
    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1478
    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1479
    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1480
    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1481
    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1482
    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1483
    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1484
    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1485
    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1486
    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1487
    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1488
},
1489
{
1490
    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
1491
    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
1492
    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
1493
    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
1494
    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
1495
    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
1496
    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
1497
    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
1498
    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
1499
    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
1500
    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
1501
    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
1502
    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
1503
    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
1504
    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
1505
    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
1506
    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
1507
    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
1508
    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
1509
    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
1510
    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
1511
    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
1512
    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
1513
    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
1514
    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
1515
    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
1516
    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
1517
    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
1518
    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
1519
    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
1520
    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
1521
    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
1522
    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
1523
    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
1524
    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
1525
    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
1526
    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
1527
    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
1528
    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
1529
    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
1530
    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
1531
    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
1532
    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
1533
    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
1534
    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
1535
    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
1536
    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
1537
    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
1538
    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
1539
    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
1540
    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
1541
    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
1542
    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
1543
    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
1544
    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
1545
    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
1546
    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
1547
    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
1548
    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
1549
    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
1550
    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
1551
    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
1552
    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
1553
    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
1554
},
1555
{
1556
    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
1557
    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
1558
    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
1559
    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
1560
    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
1561
    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
1562
    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
1563
    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
1564
    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
1565
    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
1566
    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
1567
    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
1568
    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
1569
    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
1570
    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
1571
    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
1572
    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
1573
    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
1574
    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
1575
    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
1576
1577
    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
1578
    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
1579
    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
1580
    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
1581
    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
1582
    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
1583
    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
1584
    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
1585
    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
1586
    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
1587
    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
1588
    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
1589
    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
1590
    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
1591
    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
1592
    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
1593
    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
1594
    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
1595
    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
1596
    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
1597
    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
1598
    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
1599
    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
1600
    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
1601
    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
1602
    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
1603
    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
1604
    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
1605
    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
1606
    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
1607
    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
1608
    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
1609
    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
1610
    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
1611
    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
1612
    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
1613
    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
1614
    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
1615
    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
1616
    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
1617
    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
1618
    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
1619
    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
1620
    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
1621
},
1622
{
1623
    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
1624
    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
1625
    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
1626
    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
1627
    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
1628
    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
1629
    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
1630
    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
1631
    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
1632
    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
1633
    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
1634
    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
1635
    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
1636
    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
1637
    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
1638
    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
1639
    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
1640
    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
1641
    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
1642
    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
1643
    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
1644
    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
1645
    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
1646
    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
1647
    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
1648
    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
1649
    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
1650
    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
1651
    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
1652
    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
1653
    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
1654
    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
1655
    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
1656
    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
1657
    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
1658
    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
1659
    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
1660
    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
1661
    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
1662
    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
1663
    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
1664
    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
1665
    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
1666
    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
1667
    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
1668
    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
1669
    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
1670
    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
1671
    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
1672
    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
1673
    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
1674
    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
1675
    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
1676
    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
1677
    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
1678
    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
1679
    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
1680
    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
1681
    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
1682
    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
1683
    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
1684
    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
1685
    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
1686
    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
1687
}
1688
};
1689
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1690
#endif /* HAVE_AES_DECRYPT */
1691
#endif /* WOLFSSL_AES_SMALL_TABLES */
1692
1693
#ifdef HAVE_AES_DECRYPT
1694
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
1695
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)
1696
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1697
static const FLASH_QUALIFIER byte Td4[256] =
1698
{
1699
    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
1700
    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
1701
    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
1702
    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
1703
    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
1704
    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
1705
    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
1706
    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
1707
    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
1708
    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
1709
    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
1710
    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
1711
    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
1712
    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
1713
    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
1714
    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
1715
    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
1716
    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
1717
    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
1718
    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
1719
    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
1720
    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
1721
    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
1722
    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
1723
    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
1724
    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
1725
    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
1726
    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
1727
    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
1728
    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
1729
    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
1730
    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
1731
};
1732
#endif
1733
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1734
#endif /* HAVE_AES_DECRYPT */
1735
1736
#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
1737
1738
#ifdef WOLFSSL_AES_SMALL_TABLES
1739
static const byte Tsbox[256] = {
1740
    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
1741
    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
1742
    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
1743
    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
1744
    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
1745
    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
1746
    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
1747
    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
1748
    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
1749
    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
1750
    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
1751
    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
1752
    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
1753
    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
1754
    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
1755
    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
1756
    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
1757
    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
1758
    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
1759
    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
1760
    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
1761
    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
1762
    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
1763
    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
1764
    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
1765
    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
1766
    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
1767
    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
1768
    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
1769
    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
1770
    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
1771
    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
1772
};
1773
1774
#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
1775
1776
static WARN_UNUSED_RESULT word32 col_mul(
1777
    word32 t, int i2, int i3, int ia, int ib)
1778
{
1779
    byte t3 = GETBYTE(t, i3);
1780
    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
1781
1782
    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
1783
}
1784
1785
#if defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
1786
    defined(WOLFSSL_AES_DIRECT)
1787
static WARN_UNUSED_RESULT word32 inv_col_mul(
1788
    word32 t, int i9, int ib, int id, int ie)
1789
{
1790
    byte t9 = GETBYTE(t, i9);
1791
    byte tb = GETBYTE(t, ib);
1792
    byte td = GETBYTE(t, id);
1793
    byte te = GETBYTE(t, ie);
1794
    byte t0 = t9 ^ tb ^ td;
1795
    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
1796
}
1797
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1798
#endif /* WOLFSSL_AES_SMALL_TABLES */
1799
#endif
1800
#endif
1801
1802
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
1803
                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
1804
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM) || \
1805
      defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || defined(WOLFSSL_AES_DIRECT) || \
1806
      defined(HAVE_AESCCM)
1807
1808
1809
#ifndef WC_AES_BITSLICED
1810
1811
#ifndef WC_CACHE_LINE_SZ
1812
    #if defined(__x86_64__) || defined(_M_X64) || \
1813
       (defined(__ILP32__) && (__ILP32__ >= 1))
1814
14.6M
        #define WC_CACHE_LINE_SZ 64
1815
    #else
1816
        /* default cache line size */
1817
        #define WC_CACHE_LINE_SZ 32
1818
    #endif
1819
#endif
1820
1821
#ifndef WC_NO_CACHE_RESISTANT
1822
1823
#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
1824
    #define WOLFSSL_AES_TOUCH_LINES
1825
#endif
1826
1827
#ifndef WOLFSSL_AES_SMALL_TABLES
1828
/* load 4 Te Tables into cache by cache line stride */
1829
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
1830
215k
{
1831
215k
#ifndef WOLFSSL_AES_TOUCH_LINES
1832
215k
    word32 x = 0;
1833
215k
    int i,j;
1834
1835
1.07M
    for (i = 0; i < 4; i++) {
1836
        /* 256 elements, each one is 4 bytes */
1837
14.6M
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
1838
13.8M
            x &= Te[i][j];
1839
13.8M
        }
1840
863k
    }
1841
215k
    return x;
1842
#else
1843
    return 0;
1844
#endif
1845
215k
}
1846
#else
1847
/* load sbox into cache by cache line stride */
1848
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
1849
{
1850
#ifndef WOLFSSL_AES_TOUCH_LINES
1851
    word32 x = 0;
1852
    int i;
1853
1854
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
1855
        x &= Tsbox[i];
1856
    }
1857
    return x;
1858
#else
1859
    return 0;
1860
#endif
1861
}
1862
#endif
1863
#endif
1864
1865
#ifdef WOLFSSL_AES_TOUCH_LINES
1866
#if WC_CACHE_LINE_SZ == 128
1867
    #define WC_CACHE_LINE_BITS      5
1868
    #define WC_CACHE_LINE_MASK_HI   0xe0
1869
    #define WC_CACHE_LINE_MASK_LO   0x1f
1870
    #define WC_CACHE_LINE_ADD       0x20
1871
#elif WC_CACHE_LINE_SZ == 64
1872
    #define WC_CACHE_LINE_BITS      4
1873
    #define WC_CACHE_LINE_MASK_HI   0xf0
1874
    #define WC_CACHE_LINE_MASK_LO   0x0f
1875
    #define WC_CACHE_LINE_ADD       0x10
1876
#elif WC_CACHE_LINE_SZ == 32
1877
    #define WC_CACHE_LINE_BITS      3
1878
    #define WC_CACHE_LINE_MASK_HI   0xf8
1879
    #define WC_CACHE_LINE_MASK_LO   0x07
1880
    #define WC_CACHE_LINE_ADD       0x08
1881
#elif WC_CACHE_LINE_SZ == 16
1882
    #define WC_CACHE_LINE_BITS      2
1883
    #define WC_CACHE_LINE_MASK_HI   0xfc
1884
    #define WC_CACHE_LINE_MASK_LO   0x03
1885
    #define WC_CACHE_LINE_ADD       0x04
1886
#else
1887
    #error Cache line size not supported
1888
#endif
1889
1890
#ifndef WOLFSSL_AES_SMALL_TABLES
1891
static word32 GetTable(const word32* t, byte o)
1892
{
1893
#if WC_CACHE_LINE_SZ == 64
1894
    word32 e;
1895
    byte hi = o & 0xf0;
1896
    byte lo = o & 0x0f;
1897
1898
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1899
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1900
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1901
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1902
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1903
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1904
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1905
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1906
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1907
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1908
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1909
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1910
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1911
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1912
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1913
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1914
1915
    return e;
1916
#else
1917
    word32 e = 0;
1918
    int i;
1919
    byte hi = o & WC_CACHE_LINE_MASK_HI;
1920
    byte lo = o & WC_CACHE_LINE_MASK_LO;
1921
1922
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1923
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1924
        hi -= WC_CACHE_LINE_ADD;
1925
    }
1926
1927
    return e;
1928
#endif
1929
}
1930
#endif
1931
1932
#ifdef WOLFSSL_AES_SMALL_TABLES
1933
static byte GetTable8(const byte* t, byte o)
1934
{
1935
#if WC_CACHE_LINE_SZ == 64
1936
    byte e;
1937
    byte hi = o & 0xf0;
1938
    byte lo = o & 0x0f;
1939
1940
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1941
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1942
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1943
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1944
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1945
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1946
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1947
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1948
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1949
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1950
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1951
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1952
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1953
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1954
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1955
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1956
1957
    return e;
1958
#else
1959
    byte e = 0;
1960
    int i;
1961
    byte hi = o & WC_CACHE_LINE_MASK_HI;
1962
    byte lo = o & WC_CACHE_LINE_MASK_LO;
1963
1964
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1965
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1966
        hi -= WC_CACHE_LINE_ADD;
1967
    }
1968
1969
    return e;
1970
#endif
1971
}
1972
#endif
1973
1974
#ifndef WOLFSSL_AES_SMALL_TABLES
1975
static void GetTable_Multi(const word32* t, word32* t0, byte o0,
1976
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
1977
{
1978
    word32 e0 = 0;
1979
    word32 e1 = 0;
1980
    word32 e2 = 0;
1981
    word32 e3 = 0;
1982
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
1983
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
1984
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
1985
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
1986
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
1987
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
1988
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
1989
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
1990
    int i;
1991
1992
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1993
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
1994
        hi0 -= WC_CACHE_LINE_ADD;
1995
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
1996
        hi1 -= WC_CACHE_LINE_ADD;
1997
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
1998
        hi2 -= WC_CACHE_LINE_ADD;
1999
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2000
        hi3 -= WC_CACHE_LINE_ADD;
2001
    }
2002
    *t0 = e0;
2003
    *t1 = e1;
2004
    *t2 = e2;
2005
    *t3 = e3;
2006
}
2007
static void XorTable_Multi(const word32* t, word32* t0, byte o0,
2008
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2009
{
2010
    word32 e0 = 0;
2011
    word32 e1 = 0;
2012
    word32 e2 = 0;
2013
    word32 e3 = 0;
2014
    byte hi0 = o0 & 0xf0;
2015
    byte lo0 = o0 & 0x0f;
2016
    byte hi1 = o1 & 0xf0;
2017
    byte lo1 = o1 & 0x0f;
2018
    byte hi2 = o2 & 0xf0;
2019
    byte lo2 = o2 & 0x0f;
2020
    byte hi3 = o3 & 0xf0;
2021
    byte lo3 = o3 & 0x0f;
2022
    int i;
2023
2024
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2025
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2026
        hi0 -= WC_CACHE_LINE_ADD;
2027
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2028
        hi1 -= WC_CACHE_LINE_ADD;
2029
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2030
        hi2 -= WC_CACHE_LINE_ADD;
2031
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2032
        hi3 -= WC_CACHE_LINE_ADD;
2033
    }
2034
    *t0 ^= e0;
2035
    *t1 ^= e1;
2036
    *t2 ^= e2;
2037
    *t3 ^= e3;
2038
}
2039
static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
2040
{
2041
    word32 e = 0;
2042
    int i;
2043
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2044
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2045
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2046
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2047
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2048
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2049
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2050
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2051
2052
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2053
        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
2054
             << 24;
2055
        hi0 -= WC_CACHE_LINE_ADD;
2056
        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
2057
             << 16;
2058
        hi1 -= WC_CACHE_LINE_ADD;
2059
        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
2060
             <<  8;
2061
        hi2 -= WC_CACHE_LINE_ADD;
2062
        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
2063
             <<  0;
2064
        hi3 -= WC_CACHE_LINE_ADD;
2065
    }
2066
2067
    return e;
2068
}
2069
#endif
2070
#else
2071
2072
40.6M
#define GetTable(t, o)  t[o]
2073
#define GetTable8(t, o) t[o]
2074
#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2075
    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
2076
#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2077
    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
2078
#define GetTable8_4(t, o0, o1, o2, o3) \
2079
52.1k
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
2080
52.1k
     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
2081
#endif
2082
2083
#ifndef HAVE_CUDA
2084
/* Encrypt a block using AES.
2085
 *
2086
 * @param [in]  aes       AES object.
2087
 * @param [in]  inBlock   Block to encrypt.
2088
 * @param [out] outBlock  Encrypted block.
2089
 * @param [in]  r         Rounds divided by 2.
2090
 */
2091
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2092
        word32 r)
2093
215k
{
2094
215k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
2095
215k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
2096
215k
    const word32* rk;
2097
2098
#ifdef WC_C_DYNAMIC_FALLBACK
2099
    rk = aes->key_C_fallback;
2100
#else
2101
215k
    rk = aes->key;
2102
215k
#endif
2103
2104
    /*
2105
     * map byte array block to cipher state
2106
     * and add initial round key:
2107
     */
2108
215k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
2109
215k
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
2110
215k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
2111
215k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
2112
2113
215k
#ifdef LITTLE_ENDIAN_ORDER
2114
215k
    s0 = ByteReverseWord32(s0);
2115
215k
    s1 = ByteReverseWord32(s1);
2116
215k
    s2 = ByteReverseWord32(s2);
2117
215k
    s3 = ByteReverseWord32(s3);
2118
215k
#endif
2119
2120
    /* AddRoundKey */
2121
215k
    s0 ^= rk[0];
2122
215k
    s1 ^= rk[1];
2123
215k
    s2 ^= rk[2];
2124
215k
    s3 ^= rk[3];
2125
2126
215k
#ifndef WOLFSSL_AES_SMALL_TABLES
2127
215k
#ifndef WC_NO_CACHE_RESISTANT
2128
215k
    s0 |= PreFetchTe();
2129
215k
#endif
2130
2131
215k
#ifndef WOLFSSL_AES_TOUCH_LINES
2132
215k
#define ENC_ROUND_T_S(o)                                                       \
2133
1.19M
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
2134
1.19M
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
2135
1.19M
         rk[(o)+4];                                                            \
2136
1.19M
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
2137
1.19M
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
2138
1.19M
         rk[(o)+5];                                                            \
2139
1.19M
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
2140
1.19M
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
2141
1.19M
         rk[(o)+6];                                                            \
2142
1.19M
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
2143
1.19M
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
2144
1.19M
         rk[(o)+7]
2145
215k
#define ENC_ROUND_S_T(o)                                                       \
2146
974k
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
2147
974k
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
2148
974k
         rk[(o)+0];                                                            \
2149
974k
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
2150
974k
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
2151
974k
         rk[(o)+1];                                                            \
2152
974k
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
2153
974k
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
2154
974k
         rk[(o)+2];                                                            \
2155
974k
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
2156
974k
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
2157
974k
         rk[(o)+3]
2158
#else
2159
#define ENC_ROUND_T_S(o)                                                       \
2160
    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
2161
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
2162
    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
2163
                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
2164
    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
2165
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
2166
    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
2167
                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
2168
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
2169
2170
#define ENC_ROUND_S_T(o)                                                       \
2171
    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
2172
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
2173
    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
2174
                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
2175
    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
2176
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2177
    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
2178
                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
2179
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2180
#endif
2181
2182
215k
#ifndef WOLFSSL_AES_NO_UNROLL
2183
/* Unroll the loop. */
2184
215k
                       ENC_ROUND_T_S( 0);
2185
215k
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2186
215k
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2187
215k
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2188
215k
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2189
215k
    if (r > 5) {
2190
61.4k
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2191
61.4k
        if (r > 6) {
2192
50.2k
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2193
50.2k
        }
2194
61.4k
    }
2195
215k
    rk += r * 8;
2196
#else
2197
    /*
2198
     * Nr - 1 full rounds:
2199
     */
2200
2201
    for (;;) {
2202
        ENC_ROUND_T_S(0);
2203
2204
        rk += 8;
2205
        if (--r == 0) {
2206
            break;
2207
        }
2208
2209
        ENC_ROUND_S_T(0);
2210
    }
2211
#endif
2212
2213
    /*
2214
     * apply last round and
2215
     * map cipher state to byte array block:
2216
     */
2217
2218
215k
#ifndef WOLFSSL_AES_TOUCH_LINES
2219
215k
    s0 =
2220
215k
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2221
215k
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2222
215k
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2223
215k
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2224
215k
        rk[0];
2225
215k
    s1 =
2226
215k
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2227
215k
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2228
215k
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2229
215k
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2230
215k
        rk[1];
2231
215k
    s2 =
2232
215k
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2233
215k
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2234
215k
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2235
215k
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2236
215k
        rk[2];
2237
215k
    s3 =
2238
215k
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2239
215k
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2240
215k
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2241
215k
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2242
215k
        rk[3];
2243
#else
2244
{
2245
    word32 u0;
2246
    word32 u1;
2247
    word32 u2;
2248
    word32 u3;
2249
2250
    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
2251
    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
2252
                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
2253
    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
2254
    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
2255
    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
2256
                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
2257
    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
2258
    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
2259
    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
2260
                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
2261
    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
2262
    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
2263
    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
2264
                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
2265
    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
2266
    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
2267
}
2268
#endif
2269
#else
2270
#ifndef WC_NO_CACHE_RESISTANT
2271
    s0 |= PreFetchSBox();
2272
#endif
2273
2274
    r *= 2;
2275
    /* Two rounds at a time */
2276
    for (rk += 4; r > 1; r--, rk += 4) {
2277
        t0 =
2278
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2279
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2280
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2281
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2282
        t1 =
2283
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2284
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2285
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2286
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2287
        t2 =
2288
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2289
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2290
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2291
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2292
        t3 =
2293
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2294
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2295
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2296
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2297
2298
        s0 =
2299
            (col_mul(t0, 3, 2, 0, 1) << 24) ^
2300
            (col_mul(t0, 2, 1, 0, 3) << 16) ^
2301
            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
2302
            (col_mul(t0, 0, 3, 2, 1)      ) ^
2303
            rk[0];
2304
        s1 =
2305
            (col_mul(t1, 3, 2, 0, 1) << 24) ^
2306
            (col_mul(t1, 2, 1, 0, 3) << 16) ^
2307
            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
2308
            (col_mul(t1, 0, 3, 2, 1)      ) ^
2309
            rk[1];
2310
        s2 =
2311
            (col_mul(t2, 3, 2, 0, 1) << 24) ^
2312
            (col_mul(t2, 2, 1, 0, 3) << 16) ^
2313
            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
2314
            (col_mul(t2, 0, 3, 2, 1)      ) ^
2315
            rk[2];
2316
        s3 =
2317
            (col_mul(t3, 3, 2, 0, 1) << 24) ^
2318
            (col_mul(t3, 2, 1, 0, 3) << 16) ^
2319
            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
2320
            (col_mul(t3, 0, 3, 2, 1)      ) ^
2321
            rk[3];
2322
    }
2323
2324
    t0 =
2325
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2326
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2327
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2328
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2329
    t1 =
2330
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2331
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2332
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2333
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2334
    t2 =
2335
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2336
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2337
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2338
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2339
    t3 =
2340
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2341
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2342
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2343
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2344
    s0 = t0 ^ rk[0];
2345
    s1 = t1 ^ rk[1];
2346
    s2 = t2 ^ rk[2];
2347
    s3 = t3 ^ rk[3];
2348
#endif
2349
2350
    /* write out */
2351
215k
#ifdef LITTLE_ENDIAN_ORDER
2352
215k
    s0 = ByteReverseWord32(s0);
2353
215k
    s1 = ByteReverseWord32(s1);
2354
215k
    s2 = ByteReverseWord32(s2);
2355
215k
    s3 = ByteReverseWord32(s3);
2356
215k
#endif
2357
2358
215k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2359
215k
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2360
215k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2361
215k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2362
215k
}
2363
2364
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2365
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
2366
    !defined(MAX3266X_AES)
2367
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
2368
/* Encrypt a number of blocks using AES.
2369
 *
2370
 * @param [in]  aes  AES object.
2371
 * @param [in]  in   Block to encrypt.
2372
 * @param [out] out  Encrypted block.
2373
 * @param [in]  sz   Number of blocks to encrypt.
2374
 */
2375
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2376
816
{
2377
816
    word32 i;
2378
2379
9.97k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
2380
9.15k
        AesEncrypt_C(aes, in, out, aes->rounds >> 1);
2381
9.15k
        in += WC_AES_BLOCK_SIZE;
2382
9.15k
        out += WC_AES_BLOCK_SIZE;
2383
9.15k
    }
2384
816
}
2385
#endif
2386
#endif
2387
#else
2388
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2389
        word32 r);
2390
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2391
#endif /* HAVE_CUDA */
2392
2393
#else
2394
2395
/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
2396
 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
2397
 */
2398
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
2399
static void bs_sub_bytes(bs_word u[8])
2400
{
2401
    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
2402
    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
2403
    bs_word y20, y21;
2404
    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
2405
    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
2406
    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
2407
    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
2408
    bs_word t40, t41, t42, t43, t44, t45;
2409
    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
2410
    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
2411
    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
2412
    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
2413
    bs_word tc20, tc21, tc26;
2414
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
2415
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
2416
2417
    U0 = u[7];
2418
    U1 = u[6];
2419
    U2 = u[5];
2420
    U3 = u[4];
2421
    U4 = u[3];
2422
    U5 = u[2];
2423
    U6 = u[1];
2424
    U7 = u[0];
2425
2426
    y14 = U3 ^ U5;
2427
    y13 = U0 ^ U6;
2428
    y9 = U0 ^ U3;
2429
    y8 = U0 ^ U5;
2430
    t0 = U1 ^ U2;
2431
    y1 = t0 ^ U7;
2432
    y4 = y1 ^ U3;
2433
    y12 = y13 ^ y14;
2434
    y2 = y1 ^ U0;
2435
    y5 = y1 ^ U6;
2436
    y3 = y5 ^ y8;
2437
    t1 = U4 ^ y12;
2438
    y15 = t1 ^ U5;
2439
    y20 = t1 ^ U1;
2440
    y6 = y15 ^ U7;
2441
    y10 = y15 ^ t0;
2442
    y11 = y20 ^ y9;
2443
    y7 = U7 ^ y11;
2444
    y17 = y10 ^ y11;
2445
    y19 = y10 ^ y8;
2446
    y16 = t0 ^ y11;
2447
    y21 = y13 ^ y16;
2448
    y18 = U0 ^ y16;
2449
    t2 = y12 & y15;
2450
    t3 = y3 & y6;
2451
    t4 = t3 ^ t2;
2452
    t5 = y4 & U7;
2453
    t6 = t5 ^ t2;
2454
    t7 = y13 & y16;
2455
    t8 = y5 & y1;
2456
    t9 = t8 ^ t7;
2457
    t10 = y2 & y7;
2458
    t11 = t10 ^ t7;
2459
    t12 = y9 & y11;
2460
    t13 = y14 & y17;
2461
    t14 = t13 ^ t12;
2462
    t15 = y8 & y10;
2463
    t16 = t15 ^ t12;
2464
    t17 = t4 ^ y20;
2465
    t18 = t6 ^ t16;
2466
    t19 = t9 ^ t14;
2467
    t20 = t11 ^ t16;
2468
    t21 = t17 ^ t14;
2469
    t22 = t18 ^ y19;
2470
    t23 = t19 ^ y21;
2471
    t24 = t20 ^ y18;
2472
    t25 = t21 ^ t22;
2473
    t26 = t21 & t23;
2474
    t27 = t24 ^ t26;
2475
    t28 = t25 & t27;
2476
    t29 = t28 ^ t22;
2477
    t30 = t23 ^ t24;
2478
    t31 = t22 ^ t26;
2479
    t32 = t31 & t30;
2480
    t33 = t32 ^ t24;
2481
    t34 = t23 ^ t33;
2482
    t35 = t27 ^ t33;
2483
    t36 = t24 & t35;
2484
    t37 = t36 ^ t34;
2485
    t38 = t27 ^ t36;
2486
    t39 = t29 & t38;
2487
    t40 = t25 ^ t39;
2488
    t41 = t40 ^ t37;
2489
    t42 = t29 ^ t33;
2490
    t43 = t29 ^ t40;
2491
    t44 = t33 ^ t37;
2492
    t45 = t42 ^ t41;
2493
    z0 = t44 & y15;
2494
    z1 = t37 & y6;
2495
    z2 = t33 & U7;
2496
    z3 = t43 & y16;
2497
    z4 = t40 & y1;
2498
    z5 = t29 & y7;
2499
    z6 = t42 & y11;
2500
    z7 = t45 & y17;
2501
    z8 = t41 & y10;
2502
    z9 = t44 & y12;
2503
    z10 = t37 & y3;
2504
    z11 = t33 & y4;
2505
    z12 = t43 & y13;
2506
    z13 = t40 & y5;
2507
    z14 = t29 & y2;
2508
    z15 = t42 & y9;
2509
    z16 = t45 & y14;
2510
    z17 = t41 & y8;
2511
    tc1 = z15 ^ z16;
2512
    tc2 = z10 ^ tc1;
2513
    tc3 = z9 ^ tc2;
2514
    tc4 = z0 ^ z2;
2515
    tc5 = z1 ^ z0;
2516
    tc6 = z3 ^ z4;
2517
    tc7 = z12 ^ tc4;
2518
    tc8 = z7 ^ tc6;
2519
    tc9 = z8 ^ tc7;
2520
    tc10 = tc8 ^ tc9;
2521
    tc11 = tc6 ^ tc5;
2522
    tc12 = z3 ^ z5;
2523
    tc13 = z13 ^ tc1;
2524
    tc14 = tc4 ^ tc12;
2525
    S3 = tc3 ^ tc11;
2526
    tc16 = z6 ^ tc8;
2527
    tc17 = z14 ^ tc10;
2528
    tc18 = tc13 ^ tc14;
2529
    S7 = ~(z12 ^ tc18);
2530
    tc20 = z15 ^ tc16;
2531
    tc21 = tc2 ^ z11;
2532
    S0 = tc3 ^ tc16;
2533
    S6 = ~(tc10 ^ tc18);
2534
    S4 = tc14 ^ S3;
2535
    S1 = ~(S3 ^ tc16);
2536
    tc26 = tc17 ^ tc20;
2537
    S2 = ~(tc26 ^ z17);
2538
    S5 = tc21 ^ tc17;
2539
2540
    u[0] = S7;
2541
    u[1] = S6;
2542
    u[2] = S5;
2543
    u[3] = S4;
2544
    u[4] = S3;
2545
    u[5] = S2;
2546
    u[6] = S1;
2547
    u[7] = S0;
2548
}
2549
2550
#define BS_MASK_BIT_SET(w, j, bmask) \
2551
    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
2552
2553
#define BS_TRANS_8(t, o, w, bmask, s)                   \
2554
    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
2555
    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
2556
    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
2557
    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
2558
    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
2559
    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
2560
    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
2561
    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2562
2563
static void bs_transpose(bs_word* t, bs_word* blocks)
2564
{
2565
    bs_word bmask = 1;
2566
    int i;
2567
2568
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2569
2570
    for (i = 0; i < BS_WORD_SIZE; i++) {
2571
        int j;
2572
        int o = 0;
2573
        for (j = 0; j < BS_BLOCK_WORDS; j++) {
2574
        #ifdef LITTLE_ENDIAN_ORDER
2575
            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
2576
        #else
2577
            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
2578
        #endif
2579
    #ifdef WOLFSSL_AES_NO_UNROLL
2580
            int k;
2581
            for (k = 0; k < BS_WORD_SIZE; k++) {
2582
                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
2583
            }
2584
    #else
2585
            BS_TRANS_8(t, o, w, bmask,  0);
2586
        #if BS_WORD_SIZE >= 16
2587
            BS_TRANS_8(t, o, w, bmask,  8);
2588
        #endif
2589
        #if BS_WORD_SIZE >= 32
2590
            BS_TRANS_8(t, o, w, bmask, 16);
2591
            BS_TRANS_8(t, o, w, bmask, 24);
2592
        #endif
2593
        #if BS_WORD_SIZE >= 64
2594
            BS_TRANS_8(t, o, w, bmask, 32);
2595
            BS_TRANS_8(t, o, w, bmask, 40);
2596
            BS_TRANS_8(t, o, w, bmask, 48);
2597
            BS_TRANS_8(t, o, w, bmask, 56);
2598
        #endif
2599
    #endif
2600
            o += BS_WORD_SIZE;
2601
        }
2602
        bmask <<= 1;
2603
    }
2604
}
2605
2606
#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
2607
    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
2608
    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
2609
    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
2610
    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
2611
    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
2612
    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
2613
    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
2614
    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2615
2616
static void bs_inv_transpose(bs_word* t, bs_word* blocks)
2617
{
2618
    int o;
2619
2620
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2621
2622
    for (o = 0; o < BS_BLOCK_WORDS; o++) {
2623
        int i;
2624
        for (i = 0; i < BS_WORD_SIZE; i++) {
2625
        #ifdef LITTLE_ENDIAN_ORDER
2626
            bs_word bmask = (bs_word)1 << i;
2627
        #else
2628
            bs_word bmask = bs_bswap((bs_word)1 << i);
2629
        #endif
2630
            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
2631
    #ifdef WOLFSSL_AES_NO_UNROLL
2632
            int j;
2633
            for (j = 0; j < BS_WORD_SIZE; j++) {
2634
                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
2635
            }
2636
    #else
2637
            BS_INV_TRANS_8(t, o, w, bmask, 0);
2638
        #if BS_WORD_SIZE >= 16
2639
            BS_INV_TRANS_8(t, o, w, bmask, 8);
2640
        #endif
2641
        #if BS_WORD_SIZE >= 32
2642
            BS_INV_TRANS_8(t, o, w, bmask, 16);
2643
            BS_INV_TRANS_8(t, o, w, bmask, 24);
2644
        #endif
2645
        #if BS_WORD_SIZE >= 64
2646
            BS_INV_TRANS_8(t, o, w, bmask, 32);
2647
            BS_INV_TRANS_8(t, o, w, bmask, 40);
2648
            BS_INV_TRANS_8(t, o, w, bmask, 48);
2649
            BS_INV_TRANS_8(t, o, w, bmask, 56);
2650
        #endif
2651
    #endif
2652
        }
2653
    }
2654
}
2655
2656
#define BS_ROW_OFF_0    0
2657
#define BS_ROW_OFF_1    32
2658
#define BS_ROW_OFF_2    64
2659
#define BS_ROW_OFF_3    96
2660
2661
#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
2662
#define BS_IDX_MASK     0x7f
2663
2664
#define BS_ASSIGN_8(d, od, s, os)   \
2665
    d[(od) + 0] = s[(os) + 0];      \
2666
    d[(od) + 1] = s[(os) + 1];      \
2667
    d[(od) + 2] = s[(os) + 2];      \
2668
    d[(od) + 3] = s[(os) + 3];      \
2669
    d[(od) + 4] = s[(os) + 4];      \
2670
    d[(od) + 5] = s[(os) + 5];      \
2671
    d[(od) + 6] = s[(os) + 6];      \
2672
    d[(od) + 7] = s[(os) + 7]
2673
2674
static void bs_shift_rows(bs_word* t, bs_word* b)
2675
{
2676
    int i;
2677
2678
    for (i = 0; i < 128; i += 32) {
2679
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
2680
        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
2681
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
2682
        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
2683
    }
2684
}
2685
2686
#define BS_SHIFT_OFF_0  0
2687
#define BS_SHIFT_OFF_1  8
2688
#define BS_SHIFT_OFF_2  16
2689
#define BS_SHIFT_OFF_3  24
2690
2691
/* Shift rows and mix columns.
2692
 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
2693
 */
2694
2695
#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
2696
        of      = br0[7] ^ br1[7];                                  \
2697
        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
2698
        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
2699
        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
2700
        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
2701
        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
2702
        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
2703
        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
2704
        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
2705
2706
static void bs_shift_mix(bs_word* t, bs_word* b)
2707
{
2708
    int i;
2709
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
2710
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
2711
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
2712
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
2713
2714
    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
2715
        bs_word* br0 = b + or0;
2716
        bs_word* br1 = b + or1;
2717
        bs_word* br2 = b + or2;
2718
        bs_word* br3 = b + or3;
2719
        bs_word of;
2720
2721
        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
2722
        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
2723
        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
2724
        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
2725
2726
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2727
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2728
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2729
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2730
    }
2731
}
2732
2733
static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
2734
{
2735
    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
2736
}
2737
2738
static void bs_sub_bytes_blocks(bs_word* b)
2739
{
2740
    int i;
2741
2742
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
2743
        bs_sub_bytes(b + i);
2744
    }
2745
}
2746
2747
static const FLASH_QUALIFIER byte bs_rcon[] = {
2748
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
2749
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
2750
};
2751
2752
static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
2753
    bs_word block[AES_BLOCK_BITS];
2754
    bs_word trans[AES_BLOCK_BITS];
2755
2756
    XMEMSET(block, 0, sizeof(block));
2757
    XMEMCPY(block, in, 4);
2758
2759
    bs_transpose(trans, block);
2760
    bs_sub_bytes_blocks(trans);
2761
    bs_inv_transpose(block, trans);
2762
2763
    XMEMCPY(out, block, 4);
2764
}
2765
2766
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
2767
    /* Rotate the input 8 bits to the left */
2768
#ifdef LITTLE_ENDIAN_ORDER
2769
    *(word32*)out = rotrFixed(*(word32*)in, 8);
2770
#else
2771
    *(word32*)out = rotlFixed(*(word32*)in, 8);
2772
#endif
2773
    bs_ke_sub_bytes(out, out);
2774
    /* On just the first byte, add 2^i to the byte */
2775
    out[0] ^= bs_rcon[i];
2776
}
2777
2778
static void bs_expand_key(unsigned char *in, word32 sz) {
2779
    unsigned char t[4];
2780
    word32 o;
2781
    word8 i = 0;
2782
2783
    if (sz == 176) {
2784
        /* Total of 11 rounds - AES-128. */
2785
        for (o = 16; o < sz; o += 16) {
2786
            bs_ke_transform(t, in + o - 4, i);
2787
            i++;
2788
            *(word32*)(in + o +  0) = *(word32*)(in + o - 16) ^
2789
                                      *(word32*) t;
2790
            *(word32*)(in + o +  4) = *(word32*)(in + o - 12) ^
2791
                                      *(word32*)(in + o +  0);
2792
            *(word32*)(in + o +  8) = *(word32*)(in + o -  8) ^
2793
                                      *(word32*)(in + o +  4);
2794
            *(word32*)(in + o + 12) = *(word32*)(in + o -  4) ^
2795
                                      *(word32*)(in + o +  8);
2796
        }
2797
    }
2798
    else if (sz == 208) {
2799
        /* Total of 13 rounds - AES-192. */
2800
        for (o = 24; o < sz; o += 24) {
2801
            bs_ke_transform(t, in + o - 4, i);
2802
            i++;
2803
            *(word32*)(in + o +  0) = *(word32*)(in + o - 24) ^
2804
                                      *(word32*) t;
2805
            *(word32*)(in + o +  4) = *(word32*)(in + o - 20) ^
2806
                                      *(word32*)(in + o +  0);
2807
            *(word32*)(in + o +  8) = *(word32*)(in + o - 16) ^
2808
                                      *(word32*)(in + o +  4);
2809
            *(word32*)(in + o + 12) = *(word32*)(in + o - 12) ^
2810
                                      *(word32*)(in + o +  8);
2811
            *(word32*)(in + o + 16) = *(word32*)(in + o -  8) ^
2812
                                      *(word32*)(in + o + 12);
2813
            *(word32*)(in + o + 20) = *(word32*)(in + o -  4) ^
2814
                                      *(word32*)(in + o + 16);
2815
        }
2816
    }
2817
    else if (sz == 240) {
2818
        /* Total of 15 rounds - AES-256. */
2819
        for (o = 32; o < sz; o += 16) {
2820
            if ((o & 0x1f) == 0) {
2821
                bs_ke_transform(t, in + o - 4, i);
2822
                i++;
2823
            }
2824
            else {
2825
                bs_ke_sub_bytes(t, in + o - 4);
2826
            }
2827
            *(word32*)(in + o +  0) = *(word32*)(in + o - 32) ^
2828
                                      *(word32*) t;
2829
            *(word32*)(in + o +  4) = *(word32*)(in + o - 28) ^
2830
                                      *(word32*)(in + o +  0);
2831
            *(word32*)(in + o +  8) = *(word32*)(in + o - 24) ^
2832
                                      *(word32*)(in + o +  4);
2833
            *(word32*)(in + o + 12) = *(word32*)(in + o - 20) ^
2834
                                      *(word32*)(in + o +  8);
2835
        }
2836
    }
2837
}
2838
2839
static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
2840
    word32 rounds)
2841
{
2842
    int i;
2843
    byte bs_key[15 * WC_AES_BLOCK_SIZE];
2844
    int ksSz = (rounds + 1) * WC_AES_BLOCK_SIZE;
2845
    bs_word block[AES_BLOCK_BITS];
2846
2847
    /* Fist round. */
2848
    XMEMCPY(bs_key, key, keyLen);
2849
    bs_expand_key(bs_key, ksSz);
2850
2851
    for (i = 0; i < ksSz; i += WC_AES_BLOCK_SIZE) {
2852
        int k;
2853
2854
        XMEMCPY(block, bs_key + i, WC_AES_BLOCK_SIZE);
2855
        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
2856
            int l;
2857
            for (l = 0; l < BS_BLOCK_WORDS; l++) {
2858
                block[k + l] = block[l];
2859
            }
2860
        }
2861
        bs_transpose(rk, block);
2862
        rk += AES_BLOCK_BITS;
2863
    }
2864
}
2865
2866
static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
2867
{
2868
    word32 i;
2869
    bs_word trans[AES_BLOCK_BITS];
2870
2871
    bs_transpose(trans, state);
2872
2873
    bs_add_round_key(trans, trans, rk);
2874
    for (i = 1; i < r; i++) {
2875
        bs_sub_bytes_blocks(trans);
2876
        bs_shift_mix(state, trans);
2877
        rk += AES_BLOCK_BITS;
2878
        bs_add_round_key(trans, state, rk);
2879
    }
2880
    bs_sub_bytes_blocks(trans);
2881
    bs_shift_rows(state, trans);
2882
    rk += AES_BLOCK_BITS;
2883
    bs_add_round_key(trans, state, rk);
2884
    bs_inv_transpose(state, trans);
2885
}
2886
2887
#ifndef HAVE_CUDA
2888
/* Encrypt a block using AES.
2889
 *
2890
 * @param [in]  aes       AES object.
2891
 * @param [in]  inBlock   Block to encrypt.
2892
 * @param [out] outBlock  Encrypted block.
2893
 * @param [in]  r         Rounds divided by 2.
2894
 */
2895
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2896
        word32 r)
2897
{
2898
    bs_word state[AES_BLOCK_BITS];
2899
2900
    (void)r;
2901
2902
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
2903
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
2904
2905
    bs_encrypt(state, aes->bs_key, aes->rounds);
2906
2907
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
2908
}
2909
2910
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2911
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
2912
/* Encrypt a number of blocks using AES.
2913
 *
2914
 * @param [in]  aes  AES object.
2915
 * @param [in]  in   Block to encrypt.
2916
 * @param [out] out  Encrypted block.
2917
 * @param [in]  sz   Number of blocks to encrypt.
2918
 */
2919
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2920
{
2921
    bs_word state[AES_BLOCK_BITS];
2922
2923
    while (sz >= BS_BLOCK_SIZE) {
2924
        XMEMCPY(state, in, BS_BLOCK_SIZE);
2925
        bs_encrypt(state, aes->bs_key, aes->rounds);
2926
        XMEMCPY(out, state, BS_BLOCK_SIZE);
2927
        sz  -= BS_BLOCK_SIZE;
2928
        in  += BS_BLOCK_SIZE;
2929
        out += BS_BLOCK_SIZE;
2930
    }
2931
    if (sz > 0) {
2932
        XMEMCPY(state, in, sz);
2933
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
2934
        bs_encrypt(state, aes->bs_key, aes->rounds);
2935
        XMEMCPY(out, state, sz);
2936
    }
2937
}
2938
#endif
2939
#else
2940
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2941
        word32 r);
2942
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2943
#endif /* HAVE_CUDA */
2944
2945
#endif /* !WC_AES_BITSLICED */
2946
2947
/* this section disabled with NO_AES_192 */
2948
/* calling this one when missing NO_AES_192  */
2949
static WARN_UNUSED_RESULT int wc_AesEncrypt(
2950
    Aes* aes, const byte* inBlock, byte* outBlock)
2951
206k
{
2952
#if defined(MAX3266X_AES)
2953
    word32 keySize;
2954
#endif
2955
#if defined(MAX3266X_CB)
2956
    int ret_cb;
2957
#endif
2958
206k
    word32 r;
2959
2960
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
2961
    {
2962
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
2963
        if (ret < 0)
2964
            return ret;
2965
    }
2966
#endif
2967
2968
206k
    r = aes->rounds >> 1;
2969
2970
206k
    if (r > 7 || r == 0) {
2971
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
2972
0
        return KEYUSAGE_E;
2973
0
    }
2974
2975
#ifdef WOLFSSL_AESNI
2976
    if (aes->use_aesni) {
2977
        ASSERT_SAVED_VECTOR_REGISTERS();
2978
2979
        #ifdef DEBUG_AESNI
2980
            printf("about to aes encrypt\n");
2981
            printf("in  = %p\n", inBlock);
2982
            printf("out = %p\n", outBlock);
2983
            printf("aes->key = %p\n", aes->key);
2984
            printf("aes->rounds = %d\n", aes->rounds);
2985
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
2986
        #endif
2987
2988
        /* check alignment, decrypt doesn't need alignment */
2989
        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
2990
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
2991
            byte* tmp = (byte*)XMALLOC(WC_AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
2992
                                                      DYNAMIC_TYPE_TMP_BUFFER);
2993
            byte* tmp_align;
2994
            if (tmp == NULL)
2995
                return MEMORY_E;
2996
2997
            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
2998
2999
            XMEMCPY(tmp_align, inBlock, WC_AES_BLOCK_SIZE);
3000
            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, WC_AES_BLOCK_SIZE,
3001
                    (byte*)aes->key, (int)aes->rounds);
3002
            XMEMCPY(outBlock, tmp_align, WC_AES_BLOCK_SIZE);
3003
            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3004
            return 0;
3005
        #else
3006
            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
3007
            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
3008
            return BAD_ALIGN_E;
3009
        #endif
3010
        }
3011
3012
        AES_ECB_encrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3013
                        (int)aes->rounds);
3014
3015
        return 0;
3016
    }
3017
    else {
3018
        #ifdef DEBUG_AESNI
3019
            printf("Skipping AES-NI\n");
3020
        #endif
3021
    }
3022
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
3023
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
3024
    if (aes->use_aes_hw_crypto) {
3025
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3026
            (int)aes->rounds);
3027
        return 0;
3028
    }
3029
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
3030
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
3031
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
3032
#else
3033
    AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3034
        (const unsigned char*)aes->key, aes->rounds);
3035
#endif
3036
    return 0;
3037
#endif /* WOLFSSL_AESNI */
3038
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3039
    AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3040
    return 0;
3041
#endif
3042
3043
#if defined(WOLFSSL_IMXRT_DCP)
3044
    if (aes->keylen == 16) {
3045
        DCPAesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3046
        return 0;
3047
    }
3048
#endif
3049
3050
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3051
    if (aes->useSWCrypt == 0) {
3052
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3053
                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
3054
    }
3055
#endif
3056
3057
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3058
    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
3059
    if (wc_esp32AesSupportedKeyLen(aes)) {
3060
        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
3061
    }
3062
    else {
3063
        /* For example, the ESP32-S3 does not support HW for len = 24,
3064
         * so fall back to SW */
3065
    #ifdef DEBUG_WOLFSSL
3066
        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
3067
                      aes->keylen);
3068
    #endif
3069
    }
3070
#endif
3071
3072
#if defined(MAX3266X_AES)
3073
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3074
        return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3075
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3076
                                    outBlock, (unsigned int)keySize);
3077
    }
3078
#endif
3079
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3080
    #ifndef WOLF_CRYPTO_CB_FIND
3081
    if (aes->devId != INVALID_DEVID)
3082
    #endif
3083
    {
3084
        ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock,
3085
                                            WC_AES_BLOCK_SIZE);
3086
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3087
            return ret_cb;
3088
        /* fall-through when unavailable */
3089
    }
3090
#endif
3091
3092
206k
    AesEncrypt_C(aes, inBlock, outBlock, r);
3093
3094
206k
    return 0;
3095
206k
} /* wc_AesEncrypt */
3096
#endif
3097
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
3098
3099
#if defined(HAVE_AES_DECRYPT)
3100
#if ((defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3101
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)) && \
3102
    (defined(__aarch64__) || !defined(WOLFSSL_ARMASM))
3103
3104
#ifndef WC_AES_BITSLICED
3105
#ifndef WC_NO_CACHE_RESISTANT
3106
#ifndef WOLFSSL_AES_SMALL_TABLES
3107
/* load 4 Td Tables into cache by cache line stride */
3108
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
3109
13.0k
{
3110
13.0k
    word32 x = 0;
3111
13.0k
    int i,j;
3112
3113
65.1k
    for (i = 0; i < 4; i++) {
3114
        /* 256 elements, each one is 4 bytes */
3115
886k
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
3116
834k
            x &= Td[i][j];
3117
834k
        }
3118
52.1k
    }
3119
13.0k
    return x;
3120
13.0k
}
3121
#endif /* !WOLFSSL_AES_SMALL_TABLES */
3122
3123
/* load Td Table4 into cache by cache line stride */
3124
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
3125
13.0k
{
3126
13.0k
#ifndef WOLFSSL_AES_TOUCH_LINES
3127
13.0k
    word32 x = 0;
3128
13.0k
    int i;
3129
3130
65.1k
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
3131
52.1k
        x &= (word32)Td4[i];
3132
52.1k
    }
3133
13.0k
    return x;
3134
#else
3135
    return 0;
3136
#endif
3137
13.0k
}
3138
#endif /* !WC_NO_CACHE_RESISTANT */
3139
3140
/* Decrypt a block using AES.
3141
 *
3142
 * @param [in]  aes       AES object.
3143
 * @param [in]  inBlock   Block to encrypt.
3144
 * @param [out] outBlock  Encrypted block.
3145
 * @param [in]  r         Rounds divided by 2.
3146
 */
3147
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3148
    word32 r)
3149
13.0k
{
3150
13.0k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
3151
13.0k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
3152
13.0k
    const word32* rk;
3153
3154
#ifdef WC_C_DYNAMIC_FALLBACK
3155
    rk = aes->key_C_fallback;
3156
#else
3157
13.0k
    rk = aes->key;
3158
13.0k
#endif
3159
3160
    /*
3161
     * map byte array block to cipher state
3162
     * and add initial round key:
3163
     */
3164
13.0k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
3165
13.0k
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
3166
13.0k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
3167
13.0k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
3168
3169
13.0k
#ifdef LITTLE_ENDIAN_ORDER
3170
13.0k
    s0 = ByteReverseWord32(s0);
3171
13.0k
    s1 = ByteReverseWord32(s1);
3172
13.0k
    s2 = ByteReverseWord32(s2);
3173
13.0k
    s3 = ByteReverseWord32(s3);
3174
13.0k
#endif
3175
3176
13.0k
    s0 ^= rk[0];
3177
13.0k
    s1 ^= rk[1];
3178
13.0k
    s2 ^= rk[2];
3179
13.0k
    s3 ^= rk[3];
3180
3181
13.0k
#ifndef WOLFSSL_AES_SMALL_TABLES
3182
13.0k
#ifndef WC_NO_CACHE_RESISTANT
3183
13.0k
    s0 |= PreFetchTd();
3184
13.0k
#endif
3185
3186
13.0k
#ifndef WOLFSSL_AES_TOUCH_LINES
3187
/* Unroll the loop. */
3188
13.0k
#define DEC_ROUND_T_S(o)                                            \
3189
76.0k
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
3190
76.0k
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
3191
76.0k
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
3192
76.0k
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
3193
76.0k
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
3194
76.0k
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
3195
76.0k
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
3196
76.0k
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
3197
13.0k
#define DEC_ROUND_S_T(o)                                            \
3198
63.0k
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
3199
63.0k
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
3200
63.0k
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
3201
63.0k
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
3202
63.0k
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
3203
63.0k
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
3204
63.0k
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
3205
63.0k
         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
3206
#else
3207
#define DEC_ROUND_T_S(o)                                                       \
3208
    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
3209
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
3210
    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
3211
                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
3212
    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
3213
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
3214
    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
3215
                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
3216
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
3217
3218
#define DEC_ROUND_S_T(o)                                                       \
3219
    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
3220
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
3221
    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
3222
                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
3223
    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
3224
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
3225
    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
3226
                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
3227
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
3228
#endif
3229
3230
13.0k
#ifndef WOLFSSL_AES_NO_UNROLL
3231
13.0k
                       DEC_ROUND_T_S( 0);
3232
13.0k
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3233
13.0k
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3234
13.0k
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3235
13.0k
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3236
13.0k
    if (r > 5) {
3237
5.60k
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3238
5.60k
        if (r > 6) {
3239
5.26k
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3240
5.26k
        }
3241
5.60k
    }
3242
13.0k
    rk += r * 8;
3243
#else
3244
3245
    /*
3246
     * Nr - 1 full rounds:
3247
     */
3248
3249
    for (;;) {
3250
        DEC_ROUND_T_S(0);
3251
3252
        rk += 8;
3253
        if (--r == 0) {
3254
            break;
3255
        }
3256
3257
        DEC_ROUND_S_T(0);
3258
    }
3259
#endif
3260
    /*
3261
     * apply last round and
3262
     * map cipher state to byte array block:
3263
     */
3264
3265
13.0k
#ifndef WC_NO_CACHE_RESISTANT
3266
13.0k
    t0 |= PreFetchTd4();
3267
13.0k
#endif
3268
3269
13.0k
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3270
13.0k
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3271
13.0k
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3272
13.0k
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3273
13.0k
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3274
13.0k
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3275
13.0k
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3276
13.0k
                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
3277
#else
3278
#ifndef WC_NO_CACHE_RESISTANT
3279
    s0 |= PreFetchTd4();
3280
#endif
3281
3282
    r *= 2;
3283
    for (rk += 4; r > 1; r--, rk += 4) {
3284
        t0 =
3285
            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3286
            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3287
            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3288
            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
3289
            rk[0];
3290
        t1 =
3291
            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3292
            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3293
            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3294
            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
3295
            rk[1];
3296
        t2 =
3297
            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3298
            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3299
            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3300
            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
3301
            rk[2];
3302
        t3 =
3303
            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3304
            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3305
            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3306
            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
3307
            rk[3];
3308
3309
        s0 =
3310
            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
3311
            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
3312
            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
3313
            (inv_col_mul(t0, 1, 3, 2, 0)      );
3314
        s1 =
3315
            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
3316
            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
3317
            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
3318
            (inv_col_mul(t1, 1, 3, 2, 0)      );
3319
        s2 =
3320
            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
3321
            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
3322
            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
3323
            (inv_col_mul(t2, 1, 3, 2, 0)      );
3324
        s3 =
3325
            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
3326
            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
3327
            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
3328
            (inv_col_mul(t3, 1, 3, 2, 0)      );
3329
    }
3330
3331
    t0 =
3332
        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3333
        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3334
        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3335
        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
3336
    t1 =
3337
        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3338
        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3339
        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3340
        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
3341
    t2 =
3342
        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3343
        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3344
        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3345
        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
3346
    t3 =
3347
        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3348
        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3349
        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3350
        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
3351
    s0 = t0 ^ rk[0];
3352
    s1 = t1 ^ rk[1];
3353
    s2 = t2 ^ rk[2];
3354
    s3 = t3 ^ rk[3];
3355
#endif
3356
3357
    /* write out */
3358
13.0k
#ifdef LITTLE_ENDIAN_ORDER
3359
13.0k
    s0 = ByteReverseWord32(s0);
3360
13.0k
    s1 = ByteReverseWord32(s1);
3361
13.0k
    s2 = ByteReverseWord32(s2);
3362
13.0k
    s3 = ByteReverseWord32(s3);
3363
13.0k
#endif
3364
3365
13.0k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
3366
13.0k
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
3367
13.0k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
3368
13.0k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
3369
3370
13.0k
}
3371
3372
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3373
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
3374
    !defined(MAX3266X_AES)
3375
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
3376
/* Decrypt a number of blocks using AES.
3377
 *
3378
 * @param [in]  aes  AES object.
3379
 * @param [in]  in   Block to encrypt.
3380
 * @param [out] out  Encrypted block.
3381
 * @param [in]  sz   Number of blocks to encrypt.
3382
 */
3383
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3384
153
{
3385
153
    word32 i;
3386
3387
2.16k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
3388
2.00k
        AesDecrypt_C(aes, in, out, aes->rounds >> 1);
3389
2.00k
        in += WC_AES_BLOCK_SIZE;
3390
2.00k
        out += WC_AES_BLOCK_SIZE;
3391
2.00k
    }
3392
153
}
3393
#endif
3394
#endif
3395
3396
#else /* WC_AES_BITSLICED */
3397
3398
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
3399
static void bs_inv_sub_bytes(bs_word u[8])
3400
{
3401
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
3402
    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
3403
    bs_word RTL0, RTL1, RTL2;
3404
    bs_word sa0, sa1;
3405
    bs_word sb0, sb1;
3406
    bs_word ab0, ab1, ab2, ab3;
3407
    bs_word ab20, ab21, ab22, ab23;
3408
    bs_word al, ah, aa, bl, bh, bb;
3409
    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
3410
    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
3411
    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
3412
    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
3413
    bs_word rr1, rr2;
3414
    bs_word r10, r11;
3415
    bs_word cp1, cp2, cp3, cp4;
3416
    bs_word vr1, vr2, vr3;
3417
    bs_word pr1, pr2, pr3;
3418
    bs_word wr1, wr2, wr3;
3419
    bs_word qr1, qr2, qr3;
3420
    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
3421
    bs_word tinv10, tinv11, tinv12, tinv13;
3422
    bs_word t01, t02;
3423
    bs_word d0, d1, d2, d3;
3424
    bs_word dl, dd, dh;
3425
    bs_word sd0, sd1;
3426
    bs_word p0, p1, p2, p3, p4, p6, p7;
3427
    bs_word X11, X13, X14, X16, X18, X19;
3428
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
3429
3430
    U0 = u[7];
3431
    U1 = u[6];
3432
    U2 = u[5];
3433
    U3 = u[4];
3434
    U4 = u[3];
3435
    U5 = u[2];
3436
    U6 = u[1];
3437
    U7 = u[0];
3438
3439
    Y0 = U0 ^ U3;
3440
    Y2 = ~(U1 ^ U3);
3441
    Y4 = U0 ^ Y2;
3442
    RTL0 = U6 ^ U7;
3443
    Y1 = Y2 ^ RTL0;
3444
    Y7 = ~(U2 ^ Y1);
3445
    RTL1 = U3 ^ U4;
3446
    Y6 = ~(U7 ^ RTL1);
3447
    Y3 = Y1 ^ RTL1;
3448
    RTL2 = ~(U0 ^ U2);
3449
    Y5 = U5 ^ RTL2;
3450
    sa1 = Y0 ^ Y2;
3451
    sa0 = Y1 ^ Y3;
3452
    sb1 = Y4 ^ Y6;
3453
    sb0 = Y5 ^ Y7;
3454
    ah = Y0 ^ Y1;
3455
    al = Y2 ^ Y3;
3456
    aa = sa0 ^ sa1;
3457
    bh = Y4 ^ Y5;
3458
    bl = Y6 ^ Y7;
3459
    bb = sb0 ^ sb1;
3460
    ab20 = sa0 ^ sb0;
3461
    ab22 = al ^ bl;
3462
    ab23 = Y3 ^ Y7;
3463
    ab21 = sa1 ^ sb1;
3464
    abcd1 = ah & bh;
3465
    rr1 = Y0 & Y4;
3466
    ph11 = ab20 ^ abcd1;
3467
    t01 = Y1 & Y5;
3468
    ph01 = t01 ^ abcd1;
3469
    abcd2 = al & bl;
3470
    r1 = Y2 & Y6;
3471
    pl11 = ab22 ^ abcd2;
3472
    r2 = Y3 & Y7;
3473
    pl01 = r2 ^ abcd2;
3474
    r3 = sa0 & sb0;
3475
    vr1 = aa & bb;
3476
    pr1 = vr1 ^ r3;
3477
    wr1 = sa1 & sb1;
3478
    qr1 = wr1 ^ r3;
3479
    ab0 = ph11 ^ rr1;
3480
    ab1 = ph01 ^ ab21;
3481
    ab2 = pl11 ^ r1;
3482
    ab3 = pl01 ^ qr1;
3483
    cp1 = ab0 ^ pr1;
3484
    cp2 = ab1 ^ qr1;
3485
    cp3 = ab2 ^ pr1;
3486
    cp4 = ab3 ^ ab23;
3487
    tinv1 = cp3 ^ cp4;
3488
    tinv2 = cp3 & cp1;
3489
    tinv3 = cp2 ^ tinv2;
3490
    tinv4 = cp1 ^ cp2;
3491
    tinv5 = cp4 ^ tinv2;
3492
    tinv6 = tinv5 & tinv4;
3493
    tinv7 = tinv3 & tinv1;
3494
    d2 = cp4 ^ tinv7;
3495
    d0 = cp2 ^ tinv6;
3496
    tinv8 = cp1 & cp4;
3497
    tinv9 = tinv4 & tinv8;
3498
    tinv10 = tinv4 ^ tinv2;
3499
    d1 = tinv9 ^ tinv10;
3500
    tinv11 = cp2 & cp3;
3501
    tinv12 = tinv1 & tinv11;
3502
    tinv13 = tinv1 ^ tinv2;
3503
    d3 = tinv12 ^ tinv13;
3504
    sd1 = d1 ^ d3;
3505
    sd0 = d0 ^ d2;
3506
    dl = d0 ^ d1;
3507
    dh = d2 ^ d3;
3508
    dd = sd0 ^ sd1;
3509
    abcd3 = dh & bh;
3510
    rr2 = d3 & Y4;
3511
    t02 = d2 & Y5;
3512
    abcd4 = dl & bl;
3513
    r4 = d1 & Y6;
3514
    r5 = d0 & Y7;
3515
    r6 = sd0 & sb0;
3516
    vr2 = dd & bb;
3517
    wr2 = sd1 & sb1;
3518
    abcd5 = dh & ah;
3519
    r7 = d3 & Y0;
3520
    r8 = d2 & Y1;
3521
    abcd6 = dl & al;
3522
    r9 = d1 & Y2;
3523
    r10 = d0 & Y3;
3524
    r11 = sd0 & sa0;
3525
    vr3 = dd & aa;
3526
    wr3 = sd1 & sa1;
3527
    ph12 = rr2 ^ abcd3;
3528
    ph02 = t02 ^ abcd3;
3529
    pl12 = r4 ^ abcd4;
3530
    pl02 = r5 ^ abcd4;
3531
    pr2 = vr2 ^ r6;
3532
    qr2 = wr2 ^ r6;
3533
    p0 = ph12 ^ pr2;
3534
    p1 = ph02 ^ qr2;
3535
    p2 = pl12 ^ pr2;
3536
    p3 = pl02 ^ qr2;
3537
    ph13 = r7 ^ abcd5;
3538
    ph03 = r8 ^ abcd5;
3539
    pl13 = r9 ^ abcd6;
3540
    pl03 = r10 ^ abcd6;
3541
    pr3 = vr3 ^ r11;
3542
    qr3 = wr3 ^ r11;
3543
    p4 = ph13 ^ pr3;
3544
    S7 = ph03 ^ qr3;
3545
    p6 = pl13 ^ pr3;
3546
    p7 = pl03 ^ qr3;
3547
    S3 = p1 ^ p6;
3548
    S6 = p2 ^ p6;
3549
    S0 = p3 ^ p6;
3550
    X11 = p0 ^ p2;
3551
    S5 = S0 ^ X11;
3552
    X13 = p4 ^ p7;
3553
    X14 = X11 ^ X13;
3554
    S1 = S3 ^ X14;
3555
    X16 = p1 ^ S7;
3556
    S2 = X14 ^ X16;
3557
    X18 = p0 ^ p4;
3558
    X19 = S5 ^ X16;
3559
    S4 = X18 ^ X19;
3560
3561
    u[0] = S7;
3562
    u[1] = S6;
3563
    u[2] = S5;
3564
    u[3] = S4;
3565
    u[4] = S3;
3566
    u[5] = S2;
3567
    u[6] = S1;
3568
    u[7] = S0;
3569
}
3570
3571
static void bs_inv_shift_rows(bs_word* b)
3572
{
3573
    bs_word t[AES_BLOCK_BITS];
3574
    int i;
3575
3576
    for (i = 0; i < 128; i += 32) {
3577
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
3578
        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
3579
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
3580
        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
3581
    }
3582
3583
    XMEMCPY(b, t, sizeof(t));
3584
}
3585
3586
#define O0  0
3587
#define O1  8
3588
#define O2  16
3589
#define O3  24
3590
3591
#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
3592
    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
3593
          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
3594
    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
3595
          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
3596
    of2 =                     b[O0+7] ^             b[O1+7] ^               \
3597
                    b[O2+7] ^ b[O3+7];                                      \
3598
                                                                            \
3599
    br[0] =                                                   b[O1+0] ^     \
3600
            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
3601
    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
3602
            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
3603
    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
3604
            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
3605
    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
3606
            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
3607
    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
3608
            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
3609
    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
3610
            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
3611
    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
3612
            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
3613
    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
3614
            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
3615
3616
/* Inverse mix columns and shift rows. */
3617
static void bs_inv_mix_shift(bs_word* t, bs_word* b)
3618
{
3619
    bs_word* bp = b;
3620
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
3621
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
3622
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
3623
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
3624
    int i;
3625
3626
    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
3627
        bs_word* br;
3628
        bs_word of0;
3629
        bs_word of1;
3630
        bs_word of2;
3631
3632
        br = t + or0;
3633
        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
3634
        br = t + or1;
3635
        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
3636
        br = t + or2;
3637
        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
3638
        br = t + or3;
3639
        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
3640
3641
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3642
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3643
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3644
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3645
3646
        bp += AES_BLOCK_BITS / 4;
3647
    }
3648
}
3649
3650
static void bs_inv_sub_bytes_blocks(bs_word* b)
3651
{
3652
    int i;
3653
3654
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
3655
        bs_inv_sub_bytes(b + i);
3656
    }
3657
}
3658
3659
static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
3660
{
3661
    int i;
3662
    bs_word trans[AES_BLOCK_BITS];
3663
3664
    bs_transpose(trans, state);
3665
3666
    rk += r * AES_BLOCK_BITS;
3667
    bs_add_round_key(trans, trans, rk);
3668
    bs_inv_shift_rows(trans);
3669
    bs_inv_sub_bytes_blocks(trans);
3670
    rk -= AES_BLOCK_BITS;
3671
    bs_add_round_key(trans, trans, rk);
3672
    for (i = (int)r - 2; i >= 0; i--) {
3673
        bs_inv_mix_shift(state, trans);
3674
        bs_inv_sub_bytes_blocks(state);
3675
        rk -= AES_BLOCK_BITS;
3676
        bs_add_round_key(trans, state, rk);
3677
    }
3678
3679
    bs_inv_transpose(state, trans);
3680
}
3681
3682
#ifdef WOLFSSL_AES_DIRECT
3683
/* Decrypt a block using AES.
3684
 *
3685
 * @param [in]  aes       AES object.
3686
 * @param [in]  inBlock   Block to encrypt.
3687
 * @param [out] outBlock  Encrypted block.
3688
 * @param [in]  r         Rounds divided by 2.
3689
 */
3690
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3691
    word32 r)
3692
{
3693
    bs_word state[AES_BLOCK_BITS];
3694
3695
    (void)r;
3696
3697
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
3698
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
3699
3700
    bs_decrypt(state, aes->bs_key, aes->rounds);
3701
3702
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
3703
}
3704
#endif
3705
3706
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3707
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3708
/* Decrypt a number of blocks using AES.
3709
 *
3710
 * @param [in]  aes  AES object.
3711
 * @param [in]  in   Block to encrypt.
3712
 * @param [out] out  Encrypted block.
3713
 * @param [in]  sz   Number of blocks to encrypt.
3714
 */
3715
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3716
{
3717
    bs_word state[AES_BLOCK_BITS];
3718
3719
    while (sz >= BS_BLOCK_SIZE) {
3720
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3721
        bs_decrypt(state, aes->bs_key, aes->rounds);
3722
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3723
        sz  -= BS_BLOCK_SIZE;
3724
        in  += BS_BLOCK_SIZE;
3725
        out += BS_BLOCK_SIZE;
3726
    }
3727
    if (sz > 0) {
3728
        XMEMCPY(state, in, sz);
3729
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3730
        bs_decrypt(state, aes->bs_key, aes->rounds);
3731
        XMEMCPY(out, state, sz);
3732
    }
3733
}
3734
#endif
3735
3736
#endif /* !WC_AES_BITSLICED */
3737
#endif
3738
3739
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3740
    defined(WOLFSSL_AES_DIRECT)
3741
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
3742
#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
3743
/* Software AES - ECB Decrypt */
3744
static WARN_UNUSED_RESULT int wc_AesDecrypt(
3745
    Aes* aes, const byte* inBlock, byte* outBlock)
3746
11.0k
{
3747
#if defined(MAX3266X_AES)
3748
    word32 keySize;
3749
#endif
3750
#if defined(MAX3266X_CB)
3751
    int ret_cb;
3752
#endif
3753
11.0k
    word32 r;
3754
3755
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3756
    {
3757
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3758
        if (ret < 0)
3759
            return ret;
3760
    }
3761
#endif
3762
3763
11.0k
    r = aes->rounds >> 1;
3764
3765
11.0k
    if (r > 7 || r == 0) {
3766
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3767
0
        return KEYUSAGE_E;
3768
0
    }
3769
3770
#ifdef WOLFSSL_AESNI
3771
    if (aes->use_aesni) {
3772
        ASSERT_SAVED_VECTOR_REGISTERS();
3773
3774
        #ifdef DEBUG_AESNI
3775
            printf("about to aes decrypt\n");
3776
            printf("in  = %p\n", inBlock);
3777
            printf("out = %p\n", outBlock);
3778
            printf("aes->key = %p\n", aes->key);
3779
            printf("aes->rounds = %d\n", aes->rounds);
3780
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
3781
        #endif
3782
3783
        /* if input and output same will overwrite input iv */
3784
        if ((const byte*)aes->tmp != inBlock)
3785
            XMEMCPY(aes->tmp, inBlock, WC_AES_BLOCK_SIZE);
3786
        AES_ECB_decrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3787
                        (int)aes->rounds);
3788
        return 0;
3789
    }
3790
    else {
3791
        #ifdef DEBUG_AESNI
3792
            printf("Skipping AES-NI\n");
3793
        #endif
3794
    }
3795
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
3796
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
3797
    if (aes->use_aes_hw_crypto) {
3798
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3799
            (int)aes->rounds);
3800
        return 0;
3801
    }
3802
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
3803
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
3804
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
3805
#else
3806
    AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3807
        (const unsigned char*)aes->key, aes->rounds);
3808
#endif
3809
    return 0;
3810
#endif /* WOLFSSL_AESNI */
3811
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3812
    return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3813
#endif
3814
#if defined(WOLFSSL_IMXRT_DCP)
3815
    if (aes->keylen == 16) {
3816
        DCPAesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3817
        return 0;
3818
    }
3819
#endif
3820
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3821
    if (aes->useSWCrypt == 0) {
3822
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3823
                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
3824
    }
3825
#endif
3826
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3827
    if (wc_esp32AesSupportedKeyLen(aes)) {
3828
        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
3829
    }
3830
    else {
3831
        /* For example, the ESP32-S3 does not support HW for len = 24,
3832
         * so fall back to SW */
3833
    #ifdef DEBUG_WOLFSSL
3834
        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
3835
                        "unsupported keylen = %d", aes->keylen);
3836
    #endif
3837
    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
3838
#endif
3839
3840
#if defined(MAX3266X_AES)
3841
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3842
        return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3843
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3844
                                    outBlock, (unsigned int)keySize);
3845
    }
3846
#endif
3847
3848
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3849
    #ifndef WOLF_CRYPTO_CB_FIND
3850
    if (aes->devId != INVALID_DEVID)
3851
    #endif
3852
    {
3853
        ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock,
3854
                                            WC_AES_BLOCK_SIZE);
3855
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3856
            return ret_cb;
3857
        /* fall-through when unavailable */
3858
    }
3859
#endif
3860
3861
11.0k
    AesDecrypt_C(aes, inBlock, outBlock, r);
3862
3863
11.0k
    return 0;
3864
11.0k
} /* wc_AesDecrypt[_SW]() */
3865
#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
3866
#endif
3867
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
3868
#endif /* HAVE_AES_DECRYPT */
3869
3870
#endif /* NEED_AES_TABLES */
3871
3872
3873
3874
/* wc_AesSetKey */
3875
#if defined(STM32_CRYPTO)
3876
3877
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3878
            const byte* iv, int dir)
3879
    {
3880
        word32 *rk;
3881
3882
        (void)dir;
3883
3884
        if (aes == NULL || (keylen != 16 &&
3885
        #ifdef WOLFSSL_AES_192
3886
            keylen != 24 &&
3887
        #endif
3888
            keylen != 32)) {
3889
            return BAD_FUNC_ARG;
3890
        }
3891
3892
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3893
        {
3894
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3895
            if (ret < 0)
3896
                return ret;
3897
        }
3898
#endif
3899
3900
        rk = aes->key;
3901
        aes->keylen = keylen;
3902
        aes->rounds = keylen/4 + 6;
3903
        XMEMCPY(rk, userKey, keylen);
3904
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
3905
        ByteReverseWords(rk, rk, keylen);
3906
    #endif
3907
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
3908
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
3909
        defined(WOLFSSL_AES_CTS)
3910
        aes->left = 0;
3911
    #endif
3912
        return wc_AesSetIV(aes, iv);
3913
    }
3914
    #if defined(WOLFSSL_AES_DIRECT)
3915
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
3916
                            const byte* iv, int dir)
3917
        {
3918
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
3919
        }
3920
    #endif
3921
3922
#elif defined(HAVE_COLDFIRE_SEC)
3923
    #if defined (HAVE_THREADX)
3924
        #include "memory_pools.h"
3925
        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
3926
    #endif
3927
3928
    #define AES_BUFFER_SIZE (WC_AES_BLOCK_SIZE * 64)
3929
    static unsigned char *AESBuffIn = NULL;
3930
    static unsigned char *AESBuffOut = NULL;
3931
    static byte *secReg;
3932
    static byte *secKey;
3933
    static volatile SECdescriptorType *secDesc;
3934
3935
    static wolfSSL_Mutex Mutex_AesSEC;
3936
3937
    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
3938
    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
3939
3940
    extern volatile unsigned char __MBAR[];
3941
3942
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3943
        const byte* iv, int dir)
3944
    {
3945
        if (AESBuffIn == NULL) {
3946
        #if defined (HAVE_THREADX)
3947
            int s1, s2, s3, s4, s5;
3948
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
3949
                                  sizeof(SECdescriptorType), TX_NO_WAIT);
3950
            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
3951
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
3952
            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
3953
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
3954
            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
3955
                                  WC_AES_BLOCK_SIZE*2, TX_NO_WAIT);
3956
            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
3957
                                  WC_AES_BLOCK_SIZE, TX_NO_WAIT);
3958
3959
            if (s1 || s2 || s3 || s4 || s5)
3960
                return BAD_FUNC_ARG;
3961
        #else
3962
            #warning "Allocate non-Cache buffers"
3963
        #endif
3964
3965
            wc_InitMutex(&Mutex_AesSEC);
3966
        }
3967
3968
        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
3969
            return BAD_FUNC_ARG;
3970
3971
        if (aes == NULL)
3972
            return BAD_FUNC_ARG;
3973
3974
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3975
        {
3976
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3977
            if (ret < 0)
3978
                return ret;
3979
        }
3980
#endif
3981
3982
        aes->keylen = keylen;
3983
        aes->rounds = keylen/4 + 6;
3984
        XMEMCPY(aes->key, userKey, keylen);
3985
3986
        if (iv)
3987
            XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
3988
3989
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
3990
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
3991
        defined(WOLFSSL_AES_CTS)
3992
        aes->left = 0;
3993
    #endif
3994
3995
        return 0;
3996
    }
3997
#elif defined(FREESCALE_LTC)
3998
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
3999
        const byte* iv, int dir, int checkKeyLen)
4000
    {
4001
        if (aes == NULL)
4002
            return BAD_FUNC_ARG;
4003
4004
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4005
        {
4006
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4007
            if (ret < 0)
4008
                return ret;
4009
        }
4010
#endif
4011
4012
        if (checkKeyLen) {
4013
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4014
                return BAD_FUNC_ARG;
4015
        }
4016
        (void)dir;
4017
4018
        aes->rounds = keylen/4 + 6;
4019
        XMEMCPY(aes->key, userKey, keylen);
4020
4021
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4022
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4023
        defined(WOLFSSL_AES_CTS)
4024
        aes->left = 0;
4025
    #endif
4026
4027
        return wc_AesSetIV(aes, iv);
4028
    }
4029
4030
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4031
        const byte* iv, int dir)
4032
    {
4033
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4034
    }
4035
4036
4037
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4038
                        const byte* iv, int dir)
4039
    {
4040
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4041
    }
4042
#elif defined(FREESCALE_MMCAU)
4043
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
4044
        const byte* iv, int dir, int checkKeyLen)
4045
    {
4046
        int ret;
4047
        byte* rk;
4048
        byte* tmpKey = (byte*)userKey;
4049
        int tmpKeyDynamic = 0;
4050
        word32 alignOffset = 0;
4051
4052
        (void)dir;
4053
4054
        if (aes == NULL)
4055
            return BAD_FUNC_ARG;
4056
4057
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4058
        {
4059
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4060
            if (ret < 0)
4061
                return ret;
4062
        }
4063
#endif
4064
4065
        if (checkKeyLen) {
4066
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4067
                return BAD_FUNC_ARG;
4068
        }
4069
4070
        rk = (byte*)aes->key;
4071
        if (rk == NULL)
4072
            return BAD_FUNC_ARG;
4073
4074
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4075
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4076
        defined(WOLFSSL_AES_CTS)
4077
        aes->left = 0;
4078
    #endif
4079
4080
        aes->rounds = keylen/4 + 6;
4081
4082
    #ifdef FREESCALE_MMCAU_CLASSIC
4083
        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
4084
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
4085
            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
4086
                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
4087
            if (tmp == NULL) {
4088
                return MEMORY_E;
4089
            }
4090
            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
4091
                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
4092
            tmpKey = tmp + alignOffset;
4093
            XMEMCPY(tmpKey, userKey, keylen);
4094
            tmpKeyDynamic = 1;
4095
        #else
4096
            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
4097
            return BAD_ALIGN_E;
4098
        #endif
4099
        }
4100
    #endif
4101
4102
        ret = wolfSSL_CryptHwMutexLock();
4103
        if(ret == 0) {
4104
        #ifdef FREESCALE_MMCAU_CLASSIC
4105
            cau_aes_set_key(tmpKey, keylen*8, rk);
4106
        #else
4107
            MMCAU_AES_SetKey(tmpKey, keylen, rk);
4108
        #endif
4109
            wolfSSL_CryptHwMutexUnLock();
4110
4111
            ret = wc_AesSetIV(aes, iv);
4112
        }
4113
4114
        if (tmpKeyDynamic == 1) {
4115
            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
4116
        }
4117
4118
        return ret;
4119
    }
4120
4121
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4122
        const byte* iv, int dir)
4123
    {
4124
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4125
    }
4126
4127
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4128
                        const byte* iv, int dir)
4129
    {
4130
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4131
    }
4132
4133
#elif defined(WOLFSSL_NRF51_AES)
4134
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4135
        const byte* iv, int dir)
4136
    {
4137
        int ret;
4138
4139
        (void)dir;
4140
        (void)iv;
4141
4142
        if (aes == NULL || keylen != 16)
4143
            return BAD_FUNC_ARG;
4144
4145
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4146
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4147
        if (ret < 0)
4148
            return ret;
4149
#endif
4150
4151
        aes->keylen = keylen;
4152
        aes->rounds = keylen/4 + 6;
4153
        XMEMCPY(aes->key, userKey, keylen);
4154
        ret = nrf51_aes_set_key(userKey);
4155
4156
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4157
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4158
        defined(WOLFSSL_AES_CTS)
4159
        aes->left = 0;
4160
    #endif
4161
4162
        return ret;
4163
    }
4164
4165
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4166
                        const byte* iv, int dir)
4167
    {
4168
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4169
    }
4170
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4171
    /* This is the only definition for HW only.
4172
     * but needs to be renamed when fallback needed.
4173
     * See call in wc_AesSetKey() */
4174
    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
4175
        const byte* iv, int dir)
4176
    {
4177
        (void)dir;
4178
        (void)iv;
4179
        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
4180
        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
4181
            return BAD_FUNC_ARG;
4182
        }
4183
4184
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4185
        {
4186
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4187
            if (ret < 0)
4188
                return ret;
4189
        }
4190
#endif
4191
4192
    #if !defined(WOLFSSL_AES_128)
4193
        if (keylen == 16) {
4194
            return BAD_FUNC_ARG;
4195
        }
4196
    #endif
4197
4198
    #if !defined(WOLFSSL_AES_192)
4199
        if (keylen == 24) {
4200
            return BAD_FUNC_ARG;
4201
        }
4202
    #endif
4203
4204
    #if !defined(WOLFSSL_AES_256)
4205
        if (keylen == 32) {
4206
            return BAD_FUNC_ARG;
4207
        }
4208
    #endif
4209
4210
        aes->keylen = keylen;
4211
        aes->rounds = keylen/4 + 6;
4212
4213
        XMEMCPY(aes->key, userKey, keylen);
4214
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4215
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4216
            defined(WOLFSSL_AES_CTS)
4217
            aes->left = 0;
4218
        #endif
4219
        return wc_AesSetIV(aes, iv);
4220
    } /* wc_AesSetKey */
4221
4222
    /* end #elif ESP32 */
4223
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
4224
4225
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
4226
                    int dir)
4227
    {
4228
        SaSiError_t ret = SASI_OK;
4229
        SaSiAesIv_t iv_aes;
4230
4231
        if (aes == NULL ||
4232
           (keylen != AES_128_KEY_SIZE &&
4233
            keylen != AES_192_KEY_SIZE &&
4234
            keylen != AES_256_KEY_SIZE)) {
4235
            return BAD_FUNC_ARG;
4236
        }
4237
4238
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4239
        {
4240
            int ret2 =
4241
                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4242
            if (ret2 < 0)
4243
                return ret2;
4244
        }
4245
#endif
4246
4247
    #if defined(AES_MAX_KEY_SIZE)
4248
        if (keylen > (AES_MAX_KEY_SIZE/8)) {
4249
            return BAD_FUNC_ARG;
4250
        }
4251
    #endif
4252
        if (dir != AES_ENCRYPTION &&
4253
            dir != AES_DECRYPTION) {
4254
            return BAD_FUNC_ARG;
4255
        }
4256
4257
        if (dir == AES_ENCRYPTION) {
4258
            aes->ctx.mode = SASI_AES_ENCRYPT;
4259
            SaSi_AesInit(&aes->ctx.user_ctx,
4260
                         SASI_AES_ENCRYPT,
4261
                         SASI_AES_MODE_CBC,
4262
                         SASI_AES_PADDING_NONE);
4263
        }
4264
        else {
4265
            aes->ctx.mode = SASI_AES_DECRYPT;
4266
            SaSi_AesInit(&aes->ctx.user_ctx,
4267
                         SASI_AES_DECRYPT,
4268
                         SASI_AES_MODE_CBC,
4269
                         SASI_AES_PADDING_NONE);
4270
        }
4271
4272
        aes->keylen = keylen;
4273
        aes->rounds = keylen/4 + 6;
4274
        XMEMCPY(aes->key, userKey, keylen);
4275
4276
        aes->ctx.key.pKey = (byte*)aes->key;
4277
        aes->ctx.key.keySize= keylen;
4278
4279
        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
4280
                             SASI_AES_USER_KEY,
4281
                             &aes->ctx.key,
4282
                             sizeof(aes->ctx.key));
4283
        if (ret != SASI_OK) {
4284
            return BAD_FUNC_ARG;
4285
        }
4286
4287
        ret = wc_AesSetIV(aes, iv);
4288
4289
        if (iv)
4290
            XMEMCPY(iv_aes, iv, WC_AES_BLOCK_SIZE);
4291
        else
4292
            XMEMSET(iv_aes,  0, WC_AES_BLOCK_SIZE);
4293
4294
4295
        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
4296
        if (ret != SASI_OK) {
4297
            return ret;
4298
        }
4299
       return ret;
4300
    }
4301
    #if defined(WOLFSSL_AES_DIRECT)
4302
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4303
                            const byte* iv, int dir)
4304
        {
4305
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4306
        }
4307
    #endif
4308
4309
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
4310
    && !defined(WOLFSSL_QNX_CAAM)
4311
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4312
4313
#elif defined(WOLFSSL_AFALG)
4314
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4315
4316
#elif defined(WOLFSSL_DEVCRYPTO_AES)
4317
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
4318
4319
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4320
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
4321
4322
#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
4323
     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
4324
    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
4325
4326
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
4327
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4328
            const byte* iv, int dir)
4329
    {
4330
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4331
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4332
        defined(WOLFSSL_AES_CTS)
4333
        aes->left = 0;
4334
    #endif
4335
4336
        aes->keylen = (int)keylen;
4337
        aes->rounds = (keylen/4) + 6;
4338
4339
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4340
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
4341
#else
4342
        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
4343
4344
    #ifdef HAVE_AES_DECRYPT
4345
        if (dir == AES_DECRYPTION) {
4346
            AES_invert_key((byte*)aes->key, aes->rounds);
4347
        }
4348
    #else
4349
        (void)dir;
4350
    #endif
4351
#endif
4352
        return wc_AesSetIV(aes, iv);
4353
    }
4354
4355
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4356
            const byte* iv, int dir)
4357
    {
4358
        if ((aes == NULL) || (userKey == NULL)) {
4359
            return BAD_FUNC_ARG;
4360
        }
4361
4362
        switch (keylen) {
4363
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4364
        defined(WOLFSSL_AES_128)
4365
        case 16:
4366
    #endif
4367
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4368
        defined(WOLFSSL_AES_192)
4369
        case 24:
4370
    #endif
4371
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4372
        defined(WOLFSSL_AES_256)
4373
        case 32:
4374
    #endif
4375
            break;
4376
        default:
4377
            return BAD_FUNC_ARG;
4378
        }
4379
4380
    #ifdef WOLF_CRYPTO_CB
4381
        if (aes->devId != INVALID_DEVID) {
4382
            if (keylen > sizeof(aes->devKey)) {
4383
                return BAD_FUNC_ARG;
4384
            }
4385
            XMEMCPY(aes->devKey, userKey, keylen);
4386
        }
4387
    #endif
4388
4389
        return AesSetKey(aes, userKey, keylen, iv, dir);
4390
    }
4391
4392
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
4393
        /* AES-CTR and AES-DIRECT need to use this for key setup */
4394
        /* This function allows key sizes that are not 128/192/256 bits */
4395
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4396
                           const byte* iv, int dir)
4397
    {
4398
        if (aes == NULL) {
4399
            return BAD_FUNC_ARG;
4400
        }
4401
        if (keylen > sizeof(aes->key)) {
4402
            return BAD_FUNC_ARG;
4403
        }
4404
4405
        return AesSetKey(aes, userKey, keylen, iv, dir);
4406
    }
4407
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
4408
#else
4409
    #define NEED_SOFTWARE_AES_SETKEY
4410
#endif
4411
4412
/* Either we fell though with no HW support at all,
4413
 * or perhaps there's HW support for *some* keylengths
4414
 * and we need both HW and SW. */
4415
#ifdef NEED_SOFTWARE_AES_SETKEY
4416
4417
#ifdef NEED_AES_TABLES
4418
4419
#ifndef WC_AES_BITSLICED
4420
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM) || \
4421
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
4422
/* Set the AES key and expand.
4423
 *
4424
 * @param [in]  aes    AES object.
4425
 * @param [in]  key    Block to encrypt.
4426
 * @param [in]  keySz  Number of bytes in key.
4427
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4428
 */
4429
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4430
5.73k
{
4431
#ifdef WC_C_DYNAMIC_FALLBACK
4432
    word32* rk = aes->key_C_fallback;
4433
#else
4434
5.73k
    word32* rk = aes->key;
4435
5.73k
#endif
4436
5.73k
    word32 temp;
4437
5.73k
    unsigned int i = 0;
4438
4439
5.73k
    XMEMCPY(rk, key, keySz);
4440
5.73k
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
4441
5.73k
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
4442
5.73k
    !defined(MAX3266X_AES)
4443
    /* Always reverse words when using only SW */
4444
5.73k
    {
4445
5.73k
        ByteReverseWords(rk, rk, keySz);
4446
5.73k
    }
4447
#else
4448
    /* Sometimes reverse words when using supported HW */
4449
    #if defined(WOLFSSL_ESPIDF)
4450
        /* Some platforms may need SW fallback (e.g. AES192) */
4451
        #if defined(NEED_AES_HW_FALLBACK)
4452
        {
4453
            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
4454
            if (wc_esp32AesSupportedKeyLen(aes)) {
4455
                /* don't reverse for HW supported key lengths */
4456
            }
4457
            else {
4458
                ByteReverseWords(rk, rk, keySz);
4459
            }
4460
        }
4461
        #else
4462
            /* If we don't need SW fallback, don't need to reverse words. */
4463
        #endif /* NEED_AES_HW_FALLBACK */
4464
    #endif /* WOLFSSL_ESPIDF */
4465
#endif /* LITTLE_ENDIAN_ORDER, etc */
4466
4467
5.73k
    switch (keySz) {
4468
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
4469
0
        defined(WOLFSSL_AES_128)
4470
3.04k
    case 16:
4471
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4472
        temp = (word32)-1;
4473
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4474
    #endif
4475
30.4k
        while (1)
4476
30.4k
        {
4477
30.4k
            temp  = rk[3];
4478
30.4k
            rk[4] = rk[0] ^
4479
30.4k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4480
30.4k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4481
30.4k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4482
30.4k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4483
30.4k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4484
        #else
4485
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4486
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4487
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4488
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4489
        #endif
4490
30.4k
                rcon[i];
4491
30.4k
            rk[5] = rk[1] ^ rk[4];
4492
30.4k
            rk[6] = rk[2] ^ rk[5];
4493
30.4k
            rk[7] = rk[3] ^ rk[6];
4494
30.4k
            if (++i == 10)
4495
3.04k
                break;
4496
27.3k
            rk += 4;
4497
27.3k
        }
4498
3.04k
        break;
4499
0
#endif /* 128 */
4500
4501
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
4502
0
        defined(WOLFSSL_AES_192)
4503
827
    case 24:
4504
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4505
        temp = (word32)-1;
4506
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4507
    #endif
4508
        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
4509
6.61k
        while (1)
4510
6.61k
        {
4511
6.61k
            temp = rk[ 5];
4512
6.61k
            rk[ 6] = rk[ 0] ^
4513
6.61k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4514
6.61k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4515
6.61k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4516
6.61k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4517
6.61k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4518
        #else
4519
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4520
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4521
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4522
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4523
        #endif
4524
6.61k
                rcon[i];
4525
6.61k
            rk[ 7] = rk[ 1] ^ rk[ 6];
4526
6.61k
            rk[ 8] = rk[ 2] ^ rk[ 7];
4527
6.61k
            rk[ 9] = rk[ 3] ^ rk[ 8];
4528
6.61k
            if (++i == 8)
4529
827
                break;
4530
5.78k
            rk[10] = rk[ 4] ^ rk[ 9];
4531
5.78k
            rk[11] = rk[ 5] ^ rk[10];
4532
5.78k
            rk += 6;
4533
5.78k
        }
4534
827
        break;
4535
0
#endif /* 192 */
4536
4537
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
4538
0
        defined(WOLFSSL_AES_256)
4539
1.86k
    case 32:
4540
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4541
        temp = (word32)-1;
4542
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4543
    #endif
4544
13.0k
        while (1)
4545
13.0k
        {
4546
13.0k
            temp = rk[ 7];
4547
13.0k
            rk[ 8] = rk[ 0] ^
4548
13.0k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4549
13.0k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4550
13.0k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4551
13.0k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4552
13.0k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4553
        #else
4554
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4555
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4556
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4557
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4558
        #endif
4559
13.0k
                rcon[i];
4560
13.0k
            rk[ 9] = rk[ 1] ^ rk[ 8];
4561
13.0k
            rk[10] = rk[ 2] ^ rk[ 9];
4562
13.0k
            rk[11] = rk[ 3] ^ rk[10];
4563
13.0k
            if (++i == 7)
4564
1.86k
                break;
4565
11.1k
            temp = rk[11];
4566
11.1k
            rk[12] = rk[ 4] ^
4567
11.1k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4568
11.1k
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
4569
11.1k
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
4570
11.1k
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
4571
11.1k
                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
4572
        #else
4573
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
4574
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
4575
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
4576
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
4577
        #endif
4578
11.1k
            rk[13] = rk[ 5] ^ rk[12];
4579
11.1k
            rk[14] = rk[ 6] ^ rk[13];
4580
11.1k
            rk[15] = rk[ 7] ^ rk[14];
4581
4582
11.1k
            rk += 8;
4583
11.1k
        }
4584
1.86k
        break;
4585
5.73k
#endif /* 256 */
4586
5.73k
    } /* switch */
4587
5.73k
    ForceZero(&temp, sizeof(temp));
4588
4589
5.73k
#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
4590
5.73k
    if (dir == AES_DECRYPTION) {
4591
654
        unsigned int j;
4592
4593
#ifdef WC_C_DYNAMIC_FALLBACK
4594
        rk = aes->key_C_fallback;
4595
#else
4596
654
        rk = aes->key;
4597
654
#endif
4598
4599
        /* invert the order of the round keys: */
4600
4.31k
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
4601
3.66k
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
4602
3.66k
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
4603
3.66k
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
4604
3.66k
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
4605
3.66k
        }
4606
654
        ForceZero(&temp, sizeof(temp));
4607
654
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
4608
        /* apply the inverse MixColumn transform to all round keys but the
4609
           first and the last: */
4610
7.32k
        for (i = 1; i < aes->rounds; i++) {
4611
6.66k
            rk += 4;
4612
6.66k
            rk[0] =
4613
6.66k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
4614
6.66k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
4615
6.66k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
4616
6.66k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
4617
6.66k
            rk[1] =
4618
6.66k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
4619
6.66k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
4620
6.66k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
4621
6.66k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
4622
6.66k
            rk[2] =
4623
6.66k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
4624
6.66k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
4625
6.66k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
4626
6.66k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
4627
6.66k
            rk[3] =
4628
6.66k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
4629
6.66k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
4630
6.66k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
4631
6.66k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
4632
6.66k
        }
4633
654
    #endif
4634
654
    }
4635
#else
4636
    (void)dir;
4637
#endif /* HAVE_AES_DECRYPT */
4638
4639
#ifdef WOLFSSL_CHECK_MEM_ZERO
4640
    wc_MemZero_Check(&temp, sizeof(temp));
4641
#else
4642
5.73k
    (void)temp;
4643
5.73k
#endif
4644
5.73k
}
4645
#endif
4646
#else /* WC_AES_BITSLICED */
4647
/* Set the AES key and expand.
4648
 *
4649
 * @param [in]  aes    AES object.
4650
 * @param [in]  key    Block to encrypt.
4651
 * @param [in]  keySz  Number of bytes in key.
4652
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4653
 */
4654
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4655
{
4656
    /* No need to invert when decrypting. */
4657
    (void)dir;
4658
4659
    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
4660
}
4661
#endif /* WC_AES_BITSLICED */
4662
4663
#endif /* NEED_AES_TABLES */
4664
4665
#ifndef WOLFSSL_RISCV_ASM
4666
    /* Software AES - SetKey */
4667
    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
4668
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
4669
        int checkKeyLen)
4670
5.73k
    {
4671
5.73k
        int ret;
4672
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4673
        byte   local[32];
4674
        word32 localSz = 32;
4675
    #endif
4676
4677
5.73k
        if (aes == NULL)
4678
0
            return BAD_FUNC_ARG;
4679
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4680
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4681
        if (ret < 0)
4682
            return ret;
4683
#endif
4684
4685
5.73k
        switch (keylen) {
4686
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4687
0
        defined(WOLFSSL_AES_128)
4688
3.04k
        case 16:
4689
3.04k
    #endif
4690
3.04k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4691
3.04k
        defined(WOLFSSL_AES_192)
4692
3.86k
        case 24:
4693
3.86k
    #endif
4694
3.86k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4695
3.86k
        defined(WOLFSSL_AES_256)
4696
5.73k
        case 32:
4697
5.73k
    #endif
4698
5.73k
            break;
4699
0
        default:
4700
0
            return BAD_FUNC_ARG;
4701
5.73k
        }
4702
4703
    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
4704
        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
4705
            return WC_HW_E;
4706
        }
4707
    #endif
4708
4709
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4710
        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
4711
            keylen == (24 + WC_CAAM_BLOB_SZ) ||
4712
            keylen == (32 + WC_CAAM_BLOB_SZ)) {
4713
            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
4714
                return BAD_FUNC_ARG;
4715
            }
4716
4717
            /* set local values */
4718
            userKey = local;
4719
            keylen = localSz;
4720
        }
4721
    #endif
4722
4723
    #ifdef WOLFSSL_SECO_CAAM
4724
        /* if set to use hardware than import the key */
4725
        if (aes->devId == WOLFSSL_SECO_DEVID) {
4726
            int keyGroup = 1; /* group one was chosen arbitrarily */
4727
            unsigned int keyIdOut;
4728
            byte importiv[GCM_NONCE_MID_SZ];
4729
            int importivSz = GCM_NONCE_MID_SZ;
4730
            int keyType = 0;
4731
            WC_RNG rng;
4732
4733
            if (wc_InitRng(&rng) != 0) {
4734
                WOLFSSL_MSG("RNG init for IV failed");
4735
                return WC_HW_E;
4736
            }
4737
4738
            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
4739
                WOLFSSL_MSG("Generate IV failed");
4740
                wc_FreeRng(&rng);
4741
                return WC_HW_E;
4742
            }
4743
            wc_FreeRng(&rng);
4744
4745
            if (iv)
4746
                XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4747
            else
4748
                XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
4749
4750
            switch (keylen) {
4751
                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
4752
                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
4753
                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
4754
            }
4755
4756
            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
4757
                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
4758
            if (keyIdOut == 0) {
4759
                return WC_HW_E;
4760
            }
4761
            aes->blackKey = keyIdOut;
4762
            return 0;
4763
        }
4764
    #endif
4765
4766
5.73k
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
4767
5.73k
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
4768
5.73k
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
4769
5.73k
        #ifdef WOLF_CRYPTO_CB
4770
5.73k
        if (aes->devId != INVALID_DEVID)
4771
536
        #endif
4772
536
        {
4773
536
            if (keylen > sizeof(aes->devKey)) {
4774
0
                return BAD_FUNC_ARG;
4775
0
            }
4776
536
            XMEMCPY(aes->devKey, userKey, keylen);
4777
536
        }
4778
5.73k
    #endif
4779
4780
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
4781
        if (checkKeyLen) {
4782
            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
4783
             * all key sizes. Otherwise this condition is never true. */
4784
            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
4785
                return BAD_FUNC_ARG;
4786
            }
4787
        }
4788
    #else
4789
5.73k
        (void) checkKeyLen;
4790
5.73k
    #endif
4791
4792
5.73k
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4793
5.73k
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4794
5.73k
        defined(WOLFSSL_AES_CTS)
4795
5.73k
        aes->left = 0;
4796
5.73k
    #endif
4797
4798
5.73k
        aes->keylen = (int)keylen;
4799
5.73k
        aes->rounds = (keylen/4) + 6;
4800
5.73k
        ret = wc_AesSetIV(aes, iv);
4801
5.73k
        if (ret != 0)
4802
0
            return ret;
4803
4804
#ifdef WC_C_DYNAMIC_FALLBACK
4805
#ifdef NEED_AES_TABLES
4806
        AesSetKey_C(aes, userKey, keylen, dir);
4807
#endif /* NEED_AES_TABLES */
4808
#endif /* WC_C_DYNAMIC_FALLBACK */
4809
4810
    #ifdef WOLFSSL_AESNI
4811
4812
       /* The dynamics for determining whether AES-NI will be used are tricky.
4813
        *
4814
        * First, we check for CPU support and cache the result -- if AES-NI is
4815
        * missing, we always shortcut to the AesSetKey_C() path.
4816
        *
4817
        * Second, if the CPU supports AES-NI, we confirm on a per-call basis
4818
        * that it's safe to use in the caller context, using
4819
        * SAVE_VECTOR_REGISTERS2().  This is an always-true no-op in user-space
4820
        * builds, but has substantive logic behind it in kernel module builds.
4821
        *
4822
        * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on
4823
        * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with
4824
        * success but with AES-NI disabled (the earlier AesSetKey_C() allows
4825
        * future encrypt/decrypt calls to succeed), otherwise we fail.
4826
        *
4827
        * Upon successful return, aes->use_aesni will have a zero value if
4828
        * AES-NI is disabled, and a nonzero value if it's enabled.
4829
        *
4830
        * An additional, optional semantic is available via
4831
        * WC_FLAG_DONT_USE_VECTOR_OPS, and is used in some kernel module builds
4832
        * to let the caller inhibit AES-NI.  When this macro is defined,
4833
        * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of
4834
        * uninitialized data in aes->use_aesni.  That's why support for
4835
        * WC_FLAG_DONT_USE_VECTOR_OPS must remain optional -- wc_AesInit() was
4836
        * only added in release 3.11.0, so legacy applications inevitably call
4837
        * wc_AesSetKey() on uninitialized Aes contexts.  This must continue to
4838
        * function correctly with default build settings.
4839
        */
4840
4841
        if (checkedAESNI == 0) {
4842
            haveAESNI  = Check_CPU_support_AES();
4843
            checkedAESNI = 1;
4844
        }
4845
        if (haveAESNI
4846
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS) && !defined(WC_C_DYNAMIC_FALLBACK)
4847
            && (aes->use_aesni != WC_FLAG_DONT_USE_VECTOR_OPS)
4848
#endif
4849
            )
4850
        {
4851
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS)
4852
            if (aes->use_aesni == WC_FLAG_DONT_USE_VECTOR_OPS) {
4853
                aes->use_aesni = 0;
4854
                return 0;
4855
            }
4856
#endif
4857
            aes->use_aesni = 0;
4858
            #ifdef WOLFSSL_KERNEL_MODE
4859
            /* runtime alignment check */
4860
            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
4861
                ret = BAD_ALIGN_E;
4862
            }
4863
            else
4864
            #endif /* WOLFSSL_KERNEL_MODE */
4865
            {
4866
                ret = SAVE_VECTOR_REGISTERS2();
4867
            }
4868
            if (ret == 0) {
4869
                if (dir == AES_ENCRYPTION)
4870
                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
4871
#ifdef HAVE_AES_DECRYPT
4872
                else
4873
                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
4874
#endif
4875
4876
                RESTORE_VECTOR_REGISTERS();
4877
4878
                if (ret == 0)
4879
                    aes->use_aesni = 1;
4880
                else {
4881
#ifdef WC_C_DYNAMIC_FALLBACK
4882
                    ret = 0;
4883
#endif
4884
                }
4885
                return ret;
4886
            } else {
4887
#ifdef WC_C_DYNAMIC_FALLBACK
4888
                return 0;
4889
#else
4890
                return ret;
4891
#endif
4892
            }
4893
        }
4894
        else {
4895
            aes->use_aesni = 0;
4896
#ifdef WC_C_DYNAMIC_FALLBACK
4897
            /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C()
4898
             * above.
4899
             */
4900
            return 0;
4901
#endif
4902
        }
4903
    #endif /* WOLFSSL_AESNI */
4904
4905
    #if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
4906
        !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
4907
        Check_CPU_support_HwCrypto(aes);
4908
        if (aes->use_aes_hw_crypto) {
4909
            AES_set_key_AARCH64(userKey, keylen, (byte*)aes->key, dir);
4910
            return 0;
4911
        }
4912
    #endif
4913
4914
    #ifdef WOLFSSL_KCAPI_AES
4915
        XMEMCPY(aes->devKey, userKey, keylen);
4916
        if (aes->init != 0) {
4917
            kcapi_cipher_destroy(aes->handle);
4918
            aes->handle = NULL;
4919
            aes->init = 0;
4920
        }
4921
        (void)dir;
4922
    #endif
4923
4924
5.73k
        if (keylen > sizeof(aes->key)) {
4925
0
            return BAD_FUNC_ARG;
4926
0
        }
4927
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
4928
        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
4929
                                  ((psa_algorithm_t)0), dir);
4930
#endif
4931
4932
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
4933
        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
4934
         * instead of SE05x crypto by setting useSWCrypt */
4935
        if (aes->useSWCrypt == 0) {
4936
            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
4937
            if (ret == 0) {
4938
                ret = wc_AesSetIV(aes, iv);
4939
            }
4940
            return ret;
4941
        }
4942
#endif
4943
4944
5.73k
        XMEMCPY(aes->key, userKey, keylen);
4945
4946
5.73k
#ifndef WC_AES_BITSLICED
4947
5.73k
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
4948
5.73k
        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
4949
5.73k
        && !defined(MAX3266X_AES)
4950
4951
        /* software */
4952
5.73k
        ByteReverseWords(aes->key, aes->key, keylen);
4953
4954
    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4955
        if (wc_esp32AesSupportedKeyLen(aes)) {
4956
            /* supported lengths don't get reversed */
4957
            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
4958
        }
4959
        else {
4960
            word32* rk = aes->key;
4961
4962
            /* For example, the ESP32-S3 does not support HW for len = 24,
4963
             * so fall back to SW */
4964
        #ifdef DEBUG_WOLFSSL
4965
            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
4966
        #endif
4967
            XMEMCPY(rk, userKey, keylen);
4968
            /* When not ESP32 HW, we need to reverse endianness */
4969
            ByteReverseWords(rk, rk, keylen);
4970
        }
4971
    #endif
4972
4973
    #ifdef WOLFSSL_IMXRT_DCP
4974
        {
4975
            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
4976
            word32 temp = 0;
4977
            if (keylen == 16)
4978
                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
4979
            if (temp != 0)
4980
                return WC_HW_E;
4981
        }
4982
    #endif
4983
5.73k
#endif /* !WC_AES_BITSLICED */
4984
4985
5.73k
#ifdef NEED_AES_TABLES
4986
5.73k
        AesSetKey_C(aes, userKey, keylen, dir);
4987
5.73k
#endif /* NEED_AES_TABLES */
4988
4989
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
4990
        XMEMCPY((byte*)aes->key, userKey, keylen);
4991
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
4992
            ByteReverseWords(aes->key, aes->key, 32);
4993
        }
4994
#endif
4995
4996
    #if defined(WOLFSSL_DEVCRYPTO) && \
4997
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
4998
        aes->ctx.cfd = -1;
4999
    #endif
5000
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5001
        ForceZero(local, sizeof(local));
5002
    #endif
5003
5.73k
        return ret;
5004
5.73k
    } /* wc_AesSetKeyLocal */
5005
5006
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5007
            const byte* iv, int dir)
5008
5.27k
    {
5009
5.27k
        if (aes == NULL) {
5010
0
            return BAD_FUNC_ARG;
5011
0
        }
5012
5.27k
        if (keylen > sizeof(aes->key)) {
5013
0
            return BAD_FUNC_ARG;
5014
0
        }
5015
5016
    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
5017
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
5018
        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
5019
        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
5020
            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
5021
            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
5022
        }
5023
        else {
5024
        #if  defined(WOLFSSL_HW_METRICS)
5025
            /* It is interesting to know how many times we could not complete
5026
             * AES in hardware due to unsupported lengths. */
5027
            wc_esp32AesUnupportedLengthCountAdd();
5028
        #endif
5029
        #ifdef DEBUG_WOLFSSL
5030
            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
5031
                           keylen);
5032
        #endif
5033
        }
5034
    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
5035
5036
5.27k
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
5037
5038
5.27k
    } /* wc_AesSetKey() */
5039
#endif
5040
5041
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5042
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5043
        /* This function allows key sizes that are not 128/192/256 bits */
5044
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5045
                           const byte* iv, int dir)
5046
458
    {
5047
458
        if (aes == NULL) {
5048
0
            return BAD_FUNC_ARG;
5049
0
        }
5050
458
        if (keylen > sizeof(aes->key)) {
5051
0
            return BAD_FUNC_ARG;
5052
0
        }
5053
5054
458
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
5055
458
    }
5056
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5057
#endif /* wc_AesSetKey block */
5058
5059
5060
/* wc_AesSetIV is shared between software and hardware */
5061
int wc_AesSetIV(Aes* aes, const byte* iv)
5062
6.26k
{
5063
6.26k
    if (aes == NULL)
5064
0
        return BAD_FUNC_ARG;
5065
5066
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5067
    {
5068
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5069
        if (ret < 0)
5070
            return ret;
5071
    }
5072
#endif
5073
5074
6.26k
    if (iv)
5075
3.56k
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5076
2.70k
    else
5077
2.70k
        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
5078
5079
6.26k
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5080
6.26k
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5081
6.26k
    defined(WOLFSSL_AES_CTS)
5082
    /* Clear any unused bytes from last cipher op. */
5083
6.26k
    aes->left = 0;
5084
6.26k
#endif
5085
5086
6.26k
    return 0;
5087
6.26k
}
5088
5089
#ifdef WOLFSSL_AESNI
5090
5091
#ifdef WC_C_DYNAMIC_FALLBACK
5092
5093
#define VECTOR_REGISTERS_PUSH {                                      \
5094
        int orig_use_aesni = aes->use_aesni;                         \
5095
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
5096
            aes->use_aesni = 0;                                      \
5097
        }                                                            \
5098
        WC_DO_NOTHING
5099
5100
#define VECTOR_REGISTERS_POP                                         \
5101
        if (aes->use_aesni)                                          \
5102
            RESTORE_VECTOR_REGISTERS();                              \
5103
        else                                                         \
5104
            aes->use_aesni = orig_use_aesni;                         \
5105
    }                                                                \
5106
    WC_DO_NOTHING
5107
5108
#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
5109
5110
#define VECTOR_REGISTERS_PUSH { \
5111
        WC_DO_NOTHING
5112
5113
#define VECTOR_REGISTERS_POP                                         \
5114
    }                                                                \
5115
    WC_DO_NOTHING
5116
5117
#else
5118
5119
#define VECTOR_REGISTERS_PUSH { \
5120
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
5121
            return ret;                                                  \
5122
        }                                                                \
5123
        WC_DO_NOTHING
5124
5125
#define VECTOR_REGISTERS_POP \
5126
        if (aes->use_aesni) {                                            \
5127
            RESTORE_VECTOR_REGISTERS();                                  \
5128
        }                                                                \
5129
    }                                                                    \
5130
    WC_DO_NOTHING
5131
5132
#endif
5133
5134
#else /* !WOLFSSL_AESNI */
5135
5136
16.8k
#define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
5137
16.8k
#define VECTOR_REGISTERS_POP } WC_DO_NOTHING
5138
5139
#endif /* !WOLFSSL_AESNI */
5140
5141
5142
/* AES-DIRECT */
5143
#if defined(WOLFSSL_AES_DIRECT)
5144
    #if defined(HAVE_COLDFIRE_SEC)
5145
        #error "Coldfire SEC doesn't yet support AES direct"
5146
5147
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
5148
        !defined(WOLFSSL_QNX_CAAM)
5149
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
5150
5151
    #elif defined(WOLFSSL_AFALG)
5152
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
5153
5154
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
5155
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
5156
5157
    #else
5158
5159
        /* Allow direct access to one block encrypt */
5160
        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
5161
6.75k
        {
5162
6.75k
            int ret;
5163
5164
6.75k
            if (aes == NULL)
5165
0
                return BAD_FUNC_ARG;
5166
6.75k
            VECTOR_REGISTERS_PUSH;
5167
6.75k
            ret = wc_AesEncrypt(aes, in, out);
5168
6.75k
            VECTOR_REGISTERS_POP;
5169
6.75k
            return ret;
5170
6.75k
        }
5171
5172
        /* vector reg save/restore is explicit in all below calls to
5173
         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
5174
         * macro.
5175
         */
5176
39.0k
        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
5177
5178
        #ifdef HAVE_AES_DECRYPT
5179
        /* Allow direct access to one block decrypt */
5180
        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
5181
0
        {
5182
0
            int ret;
5183
5184
0
            if (aes == NULL)
5185
0
                return BAD_FUNC_ARG;
5186
0
            VECTOR_REGISTERS_PUSH;
5187
0
            ret = wc_AesDecrypt(aes, in, out);
5188
0
            VECTOR_REGISTERS_POP;
5189
0
            return ret;
5190
0
        }
5191
5192
86
        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
5193
5194
        #endif /* HAVE_AES_DECRYPT */
5195
    #endif /* AES direct block */
5196
#endif /* WOLFSSL_AES_DIRECT */
5197
5198
5199
/* AES-CBC */
5200
#ifdef HAVE_AES_CBC
5201
#if defined(STM32_CRYPTO)
5202
5203
#ifdef WOLFSSL_STM32U5_DHUK
5204
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5205
    {
5206
        int ret = 0;
5207
        CRYP_HandleTypeDef hcryp;
5208
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5209
5210
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5211
        if (sz % WC_AES_BLOCK_SIZE) {
5212
            return BAD_LENGTH_E;
5213
        }
5214
#endif
5215
        if (blocks == 0)
5216
            return 0;
5217
5218
        ret = wolfSSL_CryptHwMutexLock();
5219
        if (ret != 0) {
5220
            return ret;
5221
        }
5222
5223
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
5224
            CRYP_ConfigTypeDef Config;
5225
5226
            XMEMSET(&Config, 0, sizeof(Config));
5227
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen,
5228
                (const byte*)aes->dhukIV, aes->dhukIVLen);
5229
5230
            /* reconfigure for using unwrapped key now */
5231
            HAL_CRYP_GetConfig(&hcryp, &Config);
5232
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
5233
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
5234
            Config.Algorithm = CRYP_AES_CBC;
5235
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5236
            Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5237
            HAL_CRYP_SetConfig(&hcryp, &Config);
5238
        }
5239
        else {
5240
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
5241
            if (ret != 0) {
5242
                wolfSSL_CryptHwMutexUnLock();
5243
                return ret;
5244
            }
5245
            hcryp.Init.Algorithm  = CRYP_AES_CBC;
5246
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5247
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5248
            ret = HAL_CRYP_Init(&hcryp);
5249
        }
5250
5251
        if (ret == HAL_OK) {
5252
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5253
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5254
            if (ret != HAL_OK) {
5255
                ret = WC_TIMEOUT_E;
5256
            }
5257
5258
            /* store iv for next call */
5259
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5260
        }
5261
5262
        HAL_CRYP_DeInit(&hcryp);
5263
5264
        wolfSSL_CryptHwMutexUnLock();
5265
        wc_Stm32_Aes_Cleanup();
5266
5267
        return ret;
5268
    }
5269
    #ifdef HAVE_AES_DECRYPT
5270
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5271
    {
5272
        int ret = 0;
5273
        CRYP_HandleTypeDef hcryp;
5274
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5275
5276
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5277
        if (sz % WC_AES_BLOCK_SIZE) {
5278
            return BAD_LENGTH_E;
5279
        }
5280
#endif
5281
        if (blocks == 0)
5282
            return 0;
5283
5284
        ret = wolfSSL_CryptHwMutexLock();
5285
        if (ret != 0) {
5286
            return ret;
5287
        }
5288
5289
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
5290
            CRYP_ConfigTypeDef Config;
5291
5292
            XMEMSET(&Config, 0, sizeof(Config));
5293
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen,
5294
                aes->dhukIV, aes->dhukIVLen);
5295
5296
            /* reconfigure for using unwrapped key now */
5297
            HAL_CRYP_GetConfig(&hcryp, &Config);
5298
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
5299
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
5300
            Config.Algorithm = CRYP_AES_CBC;
5301
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5302
            Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5303
            HAL_CRYP_SetConfig(&hcryp, &Config);
5304
        }
5305
        else {
5306
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
5307
            if (ret != 0) {
5308
                wolfSSL_CryptHwMutexUnLock();
5309
                return ret;
5310
            }
5311
            hcryp.Init.Algorithm  = CRYP_AES_CBC;
5312
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5313
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5314
            ret = HAL_CRYP_Init(&hcryp);
5315
        }
5316
5317
        if (ret == HAL_OK) {
5318
            /* if input and output same will overwrite input iv */
5319
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5320
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5321
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5322
            if (ret != HAL_OK) {
5323
                ret = WC_TIMEOUT_E;
5324
            }
5325
5326
            /* store iv for next call */
5327
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5328
        }
5329
5330
        HAL_CRYP_DeInit(&hcryp);
5331
        wolfSSL_CryptHwMutexUnLock();
5332
        wc_Stm32_Aes_Cleanup();
5333
5334
        return ret;
5335
    }
5336
    #endif /* HAVE_AES_DECRYPT */
5337
5338
#elif defined(WOLFSSL_STM32_CUBEMX)
5339
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5340
    {
5341
        int ret = 0;
5342
        CRYP_HandleTypeDef hcryp;
5343
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5344
5345
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5346
        if (sz % WC_AES_BLOCK_SIZE) {
5347
            return BAD_LENGTH_E;
5348
        }
5349
#endif
5350
        if (blocks == 0)
5351
            return 0;
5352
5353
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
5354
        if (ret != 0)
5355
            return ret;
5356
5357
        ret = wolfSSL_CryptHwMutexLock();
5358
        if (ret != 0) {
5359
            return ret;
5360
        }
5361
5362
    #if defined(STM32_HAL_V2)
5363
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
5364
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5365
    #elif defined(STM32_CRYPTO_AES_ONLY)
5366
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
5367
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
5368
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
5369
    #endif
5370
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5371
        ret = HAL_CRYP_Init(&hcryp);
5372
5373
        if (ret == HAL_OK) {
5374
        #if defined(STM32_HAL_V2)
5375
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5376
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5377
        #elif defined(STM32_CRYPTO_AES_ONLY)
5378
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
5379
                out, STM32_HAL_TIMEOUT);
5380
        #else
5381
            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
5382
                                        blocks * WC_AES_BLOCK_SIZE,
5383
                                        out, STM32_HAL_TIMEOUT);
5384
        #endif
5385
        }
5386
        if (ret != HAL_OK) {
5387
            ret = WC_TIMEOUT_E;
5388
        }
5389
5390
        /* store iv for next call */
5391
        XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5392
5393
        HAL_CRYP_DeInit(&hcryp);
5394
5395
        wolfSSL_CryptHwMutexUnLock();
5396
        wc_Stm32_Aes_Cleanup();
5397
5398
        return ret;
5399
    }
5400
    #ifdef HAVE_AES_DECRYPT
5401
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5402
    {
5403
        int ret = 0;
5404
        CRYP_HandleTypeDef hcryp;
5405
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5406
5407
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5408
        if (sz % WC_AES_BLOCK_SIZE) {
5409
            return BAD_LENGTH_E;
5410
        }
5411
#endif
5412
        if (blocks == 0)
5413
            return 0;
5414
5415
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
5416
        if (ret != 0)
5417
            return ret;
5418
5419
        ret = wolfSSL_CryptHwMutexLock();
5420
        if (ret != 0) {
5421
            return ret;
5422
        }
5423
5424
        /* if input and output same will overwrite input iv */
5425
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5426
5427
    #if defined(STM32_HAL_V2)
5428
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
5429
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5430
    #elif defined(STM32_CRYPTO_AES_ONLY)
5431
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
5432
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
5433
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
5434
    #endif
5435
5436
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5437
        ret = HAL_CRYP_Init(&hcryp);
5438
5439
        if (ret == HAL_OK) {
5440
        #if defined(STM32_HAL_V2)
5441
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5442
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5443
        #elif defined(STM32_CRYPTO_AES_ONLY)
5444
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
5445
                out, STM32_HAL_TIMEOUT);
5446
        #else
5447
            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
5448
                                        blocks * WC_AES_BLOCK_SIZE,
5449
                out, STM32_HAL_TIMEOUT);
5450
        #endif
5451
        }
5452
        if (ret != HAL_OK) {
5453
            ret = WC_TIMEOUT_E;
5454
        }
5455
5456
        /* store iv for next call */
5457
        XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5458
5459
        HAL_CRYP_DeInit(&hcryp);
5460
        wolfSSL_CryptHwMutexUnLock();
5461
        wc_Stm32_Aes_Cleanup();
5462
5463
        return ret;
5464
    }
5465
    #endif /* HAVE_AES_DECRYPT */
5466
5467
#else /* Standard Peripheral Library */
5468
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5469
    {
5470
        int ret;
5471
        word32 *iv;
5472
        CRYP_InitTypeDef cryptInit;
5473
        CRYP_KeyInitTypeDef keyInit;
5474
        CRYP_IVInitTypeDef ivInit;
5475
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5476
5477
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5478
        if (sz % WC_AES_BLOCK_SIZE) {
5479
            return BAD_LENGTH_E;
5480
        }
5481
#endif
5482
        if (blocks == 0)
5483
            return 0;
5484
5485
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
5486
        if (ret != 0)
5487
            return ret;
5488
5489
        ret = wolfSSL_CryptHwMutexLock();
5490
        if (ret != 0) {
5491
            return ret;
5492
        }
5493
5494
        /* reset registers to their default values */
5495
        CRYP_DeInit();
5496
5497
        /* set key */
5498
        CRYP_KeyInit(&keyInit);
5499
5500
        /* set iv */
5501
        iv = aes->reg;
5502
        CRYP_IVStructInit(&ivInit);
5503
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
5504
        ivInit.CRYP_IV0Left  = iv[0];
5505
        ivInit.CRYP_IV0Right = iv[1];
5506
        ivInit.CRYP_IV1Left  = iv[2];
5507
        ivInit.CRYP_IV1Right = iv[3];
5508
        CRYP_IVInit(&ivInit);
5509
5510
        /* set direction and mode */
5511
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
5512
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
5513
        CRYP_Init(&cryptInit);
5514
5515
        /* enable crypto processor */
5516
        CRYP_Cmd(ENABLE);
5517
5518
        while (blocks--) {
5519
            /* flush IN/OUT FIFOs */
5520
            CRYP_FIFOFlush();
5521
5522
            CRYP_DataIn(*(uint32_t*)&in[0]);
5523
            CRYP_DataIn(*(uint32_t*)&in[4]);
5524
            CRYP_DataIn(*(uint32_t*)&in[8]);
5525
            CRYP_DataIn(*(uint32_t*)&in[12]);
5526
5527
            /* wait until the complete message has been processed */
5528
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5529
5530
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5531
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5532
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5533
            *(uint32_t*)&out[12] = CRYP_DataOut();
5534
5535
            /* store iv for next call */
5536
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5537
5538
            sz  -= WC_AES_BLOCK_SIZE;
5539
            in  += WC_AES_BLOCK_SIZE;
5540
            out += WC_AES_BLOCK_SIZE;
5541
        }
5542
5543
        /* disable crypto processor */
5544
        CRYP_Cmd(DISABLE);
5545
        wolfSSL_CryptHwMutexUnLock();
5546
        wc_Stm32_Aes_Cleanup();
5547
5548
        return ret;
5549
    }
5550
5551
    #ifdef HAVE_AES_DECRYPT
5552
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5553
    {
5554
        int ret;
5555
        word32 *iv;
5556
        CRYP_InitTypeDef cryptInit;
5557
        CRYP_KeyInitTypeDef keyInit;
5558
        CRYP_IVInitTypeDef ivInit;
5559
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5560
5561
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5562
        if (sz % WC_AES_BLOCK_SIZE) {
5563
            return BAD_LENGTH_E;
5564
        }
5565
#endif
5566
        if (blocks == 0)
5567
            return 0;
5568
5569
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
5570
        if (ret != 0)
5571
            return ret;
5572
5573
        ret = wolfSSL_CryptHwMutexLock();
5574
        if (ret != 0) {
5575
            return ret;
5576
        }
5577
5578
        /* if input and output same will overwrite input iv */
5579
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5580
5581
        /* reset registers to their default values */
5582
        CRYP_DeInit();
5583
5584
        /* set direction and key */
5585
        CRYP_KeyInit(&keyInit);
5586
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5587
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
5588
        CRYP_Init(&cryptInit);
5589
5590
        /* enable crypto processor */
5591
        CRYP_Cmd(ENABLE);
5592
5593
        /* wait until key has been prepared */
5594
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5595
5596
        /* set direction and mode */
5597
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5598
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
5599
        CRYP_Init(&cryptInit);
5600
5601
        /* set iv */
5602
        iv = aes->reg;
5603
        CRYP_IVStructInit(&ivInit);
5604
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
5605
        ivInit.CRYP_IV0Left  = iv[0];
5606
        ivInit.CRYP_IV0Right = iv[1];
5607
        ivInit.CRYP_IV1Left  = iv[2];
5608
        ivInit.CRYP_IV1Right = iv[3];
5609
        CRYP_IVInit(&ivInit);
5610
5611
        /* enable crypto processor */
5612
        CRYP_Cmd(ENABLE);
5613
5614
        while (blocks--) {
5615
            /* flush IN/OUT FIFOs */
5616
            CRYP_FIFOFlush();
5617
5618
            CRYP_DataIn(*(uint32_t*)&in[0]);
5619
            CRYP_DataIn(*(uint32_t*)&in[4]);
5620
            CRYP_DataIn(*(uint32_t*)&in[8]);
5621
            CRYP_DataIn(*(uint32_t*)&in[12]);
5622
5623
            /* wait until the complete message has been processed */
5624
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5625
5626
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5627
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5628
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5629
            *(uint32_t*)&out[12] = CRYP_DataOut();
5630
5631
            /* store iv for next call */
5632
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5633
5634
            in  += WC_AES_BLOCK_SIZE;
5635
            out += WC_AES_BLOCK_SIZE;
5636
        }
5637
5638
        /* disable crypto processor */
5639
        CRYP_Cmd(DISABLE);
5640
        wolfSSL_CryptHwMutexUnLock();
5641
        wc_Stm32_Aes_Cleanup();
5642
5643
        return ret;
5644
    }
5645
    #endif /* HAVE_AES_DECRYPT */
5646
#endif /* WOLFSSL_STM32_CUBEMX */
5647
5648
#elif defined(HAVE_COLDFIRE_SEC)
5649
    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
5650
        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
5651
    {
5652
        #ifdef DEBUG_WOLFSSL
5653
            int i; int stat1, stat2; int ret;
5654
        #endif
5655
5656
        int size;
5657
        volatile int v;
5658
5659
        if ((pi == NULL) || (po == NULL))
5660
            return BAD_FUNC_ARG;    /*wrong pointer*/
5661
5662
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5663
        if (sz % WC_AES_BLOCK_SIZE) {
5664
            return BAD_LENGTH_E;
5665
        }
5666
#endif
5667
5668
        wc_LockMutex(&Mutex_AesSEC);
5669
5670
        /* Set descriptor for SEC */
5671
        secDesc->length1 = 0x0;
5672
        secDesc->pointer1 = NULL;
5673
5674
        secDesc->length2 = WC_AES_BLOCK_SIZE;
5675
        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
5676
5677
        switch(aes->rounds) {
5678
            case 10: secDesc->length3 = 16; break;
5679
            case 12: secDesc->length3 = 24; break;
5680
            case 14: secDesc->length3 = 32; break;
5681
        }
5682
        XMEMCPY(secKey, aes->key, secDesc->length3);
5683
5684
        secDesc->pointer3 = (byte *)secKey;
5685
        secDesc->pointer4 = AESBuffIn;
5686
        secDesc->pointer5 = AESBuffOut;
5687
        secDesc->length6 = 0x0;
5688
        secDesc->pointer6 = NULL;
5689
        secDesc->length7 = 0x0;
5690
        secDesc->pointer7 = NULL;
5691
        secDesc->nextDescriptorPtr = NULL;
5692
5693
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5694
        size = AES_BUFFER_SIZE;
5695
#endif
5696
        while (sz) {
5697
            secDesc->header = descHeader;
5698
            XMEMCPY(secReg, aes->reg, WC_AES_BLOCK_SIZE);
5699
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5700
            sz -= AES_BUFFER_SIZE;
5701
#else
5702
            if (sz < AES_BUFFER_SIZE) {
5703
                size = sz;
5704
                sz = 0;
5705
            } else {
5706
                size = AES_BUFFER_SIZE;
5707
                sz -= AES_BUFFER_SIZE;
5708
            }
5709
#endif
5710
5711
            secDesc->length4 = size;
5712
            secDesc->length5 = size;
5713
5714
            XMEMCPY(AESBuffIn, pi, size);
5715
            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
5716
                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-WC_AES_BLOCK_SIZE]),
5717
                        WC_AES_BLOCK_SIZE);
5718
            }
5719
5720
            /* Point SEC to the location of the descriptor */
5721
            MCF_SEC_FR0 = (uint32)secDesc;
5722
            /* Initialize SEC and wait for encryption to complete */
5723
            MCF_SEC_CCCR0 = 0x0000001a;
5724
            /* poll SISR to determine when channel is complete */
5725
            v=0;
5726
5727
            while ((secDesc->header>> 24) != 0xff) v++;
5728
5729
            #ifdef DEBUG_WOLFSSL
5730
                ret = MCF_SEC_SISRH;
5731
                stat1 = MCF_SEC_AESSR;
5732
                stat2 = MCF_SEC_AESISR;
5733
                if (ret & 0xe0000000) {
5734
                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
5735
                              "AESISR=%08x\n", i, ret, stat1, stat2);
5736
                }
5737
            #endif
5738
5739
            XMEMCPY(po, AESBuffOut, size);
5740
5741
            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
5742
                XMEMCPY((void*)aes->reg, (void*)&(po[size-WC_AES_BLOCK_SIZE]),
5743
                        WC_AES_BLOCK_SIZE);
5744
            } else {
5745
                XMEMCPY((void*)aes->reg, (void*)aes->tmp, WC_AES_BLOCK_SIZE);
5746
            }
5747
5748
            pi += size;
5749
            po += size;
5750
        }
5751
5752
        wc_UnLockMutex(&Mutex_AesSEC);
5753
        return 0;
5754
    }
5755
5756
    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
5757
    {
5758
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
5759
    }
5760
5761
    #ifdef HAVE_AES_DECRYPT
5762
    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
5763
    {
5764
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
5765
    }
5766
    #endif /* HAVE_AES_DECRYPT */
5767
5768
#elif defined(FREESCALE_LTC)
5769
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5770
    {
5771
        word32 keySize;
5772
        status_t status;
5773
        byte *iv, *enc_key;
5774
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5775
5776
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5777
        if (sz % WC_AES_BLOCK_SIZE) {
5778
            return BAD_LENGTH_E;
5779
        }
5780
#endif
5781
        if (blocks == 0)
5782
            return 0;
5783
5784
        iv      = (byte*)aes->reg;
5785
        enc_key = (byte*)aes->key;
5786
5787
        status = wc_AesGetKeySize(aes, &keySize);
5788
        if (status != 0) {
5789
            return status;
5790
        }
5791
5792
        status = wolfSSL_CryptHwMutexLock();
5793
        if (status != 0)
5794
            return status;
5795
        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
5796
            iv, enc_key, keySize);
5797
        wolfSSL_CryptHwMutexUnLock();
5798
5799
        /* store iv for next call */
5800
        if (status == kStatus_Success) {
5801
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5802
        }
5803
5804
        return (status == kStatus_Success) ? 0 : -1;
5805
    }
5806
5807
    #ifdef HAVE_AES_DECRYPT
5808
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5809
    {
5810
        word32 keySize;
5811
        status_t status;
5812
        byte* iv, *dec_key;
5813
        byte temp_block[WC_AES_BLOCK_SIZE];
5814
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5815
5816
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5817
        if (sz % WC_AES_BLOCK_SIZE) {
5818
            return BAD_LENGTH_E;
5819
        }
5820
#endif
5821
        if (blocks == 0)
5822
            return 0;
5823
5824
        iv      = (byte*)aes->reg;
5825
        dec_key = (byte*)aes->key;
5826
5827
        status = wc_AesGetKeySize(aes, &keySize);
5828
        if (status != 0) {
5829
            return status;
5830
        }
5831
5832
        /* get IV for next call */
5833
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5834
5835
        status = wolfSSL_CryptHwMutexLock();
5836
        if (status != 0)
5837
            return status;
5838
        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
5839
            iv, dec_key, keySize, kLTC_EncryptKey);
5840
        wolfSSL_CryptHwMutexUnLock();
5841
5842
        /* store IV for next call */
5843
        if (status == kStatus_Success) {
5844
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
5845
        }
5846
5847
        return (status == kStatus_Success) ? 0 : -1;
5848
    }
5849
    #endif /* HAVE_AES_DECRYPT */
5850
5851
#elif defined(FREESCALE_MMCAU)
5852
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5853
    {
5854
        int offset = 0;
5855
        byte *iv;
5856
        byte temp_block[WC_AES_BLOCK_SIZE];
5857
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5858
        int ret;
5859
5860
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5861
        if (sz % WC_AES_BLOCK_SIZE) {
5862
            return BAD_LENGTH_E;
5863
        }
5864
#endif
5865
        if (blocks == 0)
5866
            return 0;
5867
5868
        iv = (byte*)aes->reg;
5869
5870
        while (blocks--) {
5871
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
5872
5873
            /* XOR block with IV for CBC */
5874
            xorbuf(temp_block, iv, WC_AES_BLOCK_SIZE);
5875
5876
            ret = wc_AesEncrypt(aes, temp_block, out + offset);
5877
            if (ret != 0)
5878
                return ret;
5879
5880
            offset += WC_AES_BLOCK_SIZE;
5881
5882
            /* store IV for next block */
5883
            XMEMCPY(iv, out + offset - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5884
        }
5885
5886
        return 0;
5887
    }
5888
    #ifdef HAVE_AES_DECRYPT
5889
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5890
    {
5891
        int ret;
5892
        int offset = 0;
5893
        byte* iv;
5894
        byte temp_block[WC_AES_BLOCK_SIZE];
5895
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5896
5897
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5898
        if (sz % WC_AES_BLOCK_SIZE) {
5899
            return BAD_LENGTH_E;
5900
        }
5901
#endif
5902
        if (blocks == 0)
5903
            return 0;
5904
5905
        iv = (byte*)aes->reg;
5906
5907
        while (blocks--) {
5908
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
5909
5910
            ret = wc_AesDecrypt(aes, in + offset, out + offset);
5911
            if (ret != 0)
5912
                return ret;
5913
5914
            /* XOR block with IV for CBC */
5915
            xorbuf(out + offset, iv, WC_AES_BLOCK_SIZE);
5916
5917
            /* store IV for next block */
5918
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
5919
5920
            offset += WC_AES_BLOCK_SIZE;
5921
        }
5922
5923
        return 0;
5924
    }
5925
    #endif /* HAVE_AES_DECRYPT */
5926
5927
#elif defined(MAX3266X_AES)
5928
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5929
    {
5930
        word32 keySize;
5931
        int status;
5932
        byte *iv;
5933
5934
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
5935
            return BAD_FUNC_ARG;
5936
        }
5937
5938
        /* Always enforce a length check */
5939
        if (sz % WC_AES_BLOCK_SIZE) {
5940
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5941
            return BAD_LENGTH_E;
5942
        #else
5943
            return BAD_FUNC_ARG;
5944
        #endif
5945
        }
5946
        if (sz == 0) {
5947
            return 0;
5948
        }
5949
5950
        iv = (byte*)aes->reg;
5951
        status = wc_AesGetKeySize(aes, &keySize);
5952
        if (status != 0) {
5953
            return status;
5954
        }
5955
5956
        status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
5957
                                        MXC_TPU_MODE_CBC, sz, out,
5958
                                        (unsigned int)keySize);
5959
        /* store iv for next call */
5960
        if (status == 0) {
5961
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5962
        }
5963
        return (status == 0) ? 0 : -1;
5964
    }
5965
5966
    #ifdef HAVE_AES_DECRYPT
5967
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5968
    {
5969
        word32 keySize;
5970
        int status;
5971
        byte *iv;
5972
        byte temp_block[WC_AES_BLOCK_SIZE];
5973
5974
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
5975
            return BAD_FUNC_ARG;
5976
        }
5977
5978
        /* Always enforce a length check */
5979
        if (sz % WC_AES_BLOCK_SIZE) {
5980
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5981
            return BAD_LENGTH_E;
5982
        #else
5983
            return BAD_FUNC_ARG;
5984
        #endif
5985
        }
5986
        if (sz == 0) {
5987
            return 0;
5988
        }
5989
5990
        iv = (byte*)aes->reg;
5991
        status = wc_AesGetKeySize(aes, &keySize);
5992
        if (status != 0) {
5993
            return status;
5994
        }
5995
5996
        /* get IV for next call */
5997
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5998
        status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
5999
                                        MXC_TPU_MODE_CBC, sz, out,
6000
                                        keySize);
6001
6002
        /* store iv for next call */
6003
        if (status == 0) {
6004
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6005
        }
6006
        return (status == 0) ? 0 : -1;
6007
    }
6008
    #endif /* HAVE_AES_DECRYPT */
6009
6010
6011
6012
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
6013
6014
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6015
    {
6016
        int ret;
6017
6018
        if (sz == 0)
6019
            return 0;
6020
6021
        /* hardware fails on input that is not a multiple of AES block size */
6022
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6023
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6024
            return BAD_LENGTH_E;
6025
#else
6026
            return BAD_FUNC_ARG;
6027
#endif
6028
        }
6029
6030
        ret = wc_Pic32AesCrypt(
6031
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6032
            out, in, sz, PIC32_ENCRYPTION,
6033
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6034
6035
        /* store iv for next call */
6036
        if (ret == 0) {
6037
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6038
        }
6039
6040
        return ret;
6041
    }
6042
    #ifdef HAVE_AES_DECRYPT
6043
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6044
    {
6045
        int ret;
6046
        byte scratch[WC_AES_BLOCK_SIZE];
6047
6048
        if (sz == 0)
6049
            return 0;
6050
6051
        /* hardware fails on input that is not a multiple of AES block size */
6052
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6053
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6054
            return BAD_LENGTH_E;
6055
#else
6056
            return BAD_FUNC_ARG;
6057
#endif
6058
        }
6059
        XMEMCPY(scratch, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6060
6061
        ret = wc_Pic32AesCrypt(
6062
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6063
            out, in, sz, PIC32_DECRYPTION,
6064
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6065
6066
        /* store iv for next call */
6067
        if (ret == 0) {
6068
            XMEMCPY((byte*)aes->reg, scratch, WC_AES_BLOCK_SIZE);
6069
        }
6070
6071
        return ret;
6072
    }
6073
    #endif /* HAVE_AES_DECRYPT */
6074
#elif defined(WOLFSSL_ESP32_CRYPT) && \
6075
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6076
6077
    /* We'll use SW for fall back:
6078
     *   unsupported key lengths
6079
     *   hardware busy */
6080
    #define NEED_SW_AESCBC
6081
    #define NEED_AESCBC_HW_FALLBACK
6082
6083
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
6084
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6085
    {
6086
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6087
    }
6088
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6089
    {
6090
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6091
    }
6092
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6093
        !defined(WOLFSSL_QNX_CAAM)
6094
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6095
6096
#elif defined(WOLFSSL_AFALG)
6097
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6098
6099
#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
6100
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
6101
6102
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
6103
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6104
6105
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
6106
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
6107
6108
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6109
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
6110
6111
#else
6112
    /* Reminder: Some HW implementations may also define this as needed.
6113
     * (e.g. for unsupported key length fallback)  */
6114
    #define NEED_SW_AESCBC
6115
#endif
6116
6117
#ifdef NEED_SW_AESCBC
6118
    /* Software AES - CBC Encrypt */
6119
6120
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6121
647
    {
6122
647
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
6123
647
        word32 blocks;
6124
647
        int ret;
6125
647
#endif
6126
6127
647
        if (aes == NULL || out == NULL || in == NULL) {
6128
0
            return BAD_FUNC_ARG;
6129
0
        }
6130
6131
647
        if (sz == 0) {
6132
0
            return 0;
6133
0
        }
6134
6135
647
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
6136
647
        blocks = sz / WC_AES_BLOCK_SIZE;
6137
647
#endif
6138
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6139
        if (sz % WC_AES_BLOCK_SIZE) {
6140
            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
6141
            return BAD_LENGTH_E;
6142
        }
6143
#endif
6144
6145
    #ifdef WOLFSSL_IMXRT_DCP
6146
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
6147
        if (aes->keylen == 16)
6148
            return DCPAesCbcEncrypt(aes, out, in, sz);
6149
    #endif
6150
6151
647
    #ifdef WOLF_CRYPTO_CB
6152
647
        #ifndef WOLF_CRYPTO_CB_FIND
6153
647
        if (aes->devId != INVALID_DEVID)
6154
0
        #endif
6155
0
        {
6156
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6157
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6158
0
                return crypto_cb_ret;
6159
            /* fall-through when unavailable */
6160
0
        }
6161
647
    #endif
6162
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
6163
        /* if async and byte count above threshold */
6164
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
6165
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
6166
        #if defined(HAVE_CAVIUM)
6167
            return NitroxAesCbcEncrypt(aes, out, in, sz);
6168
        #elif defined(HAVE_INTEL_QA)
6169
            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
6170
                (const byte*)aes->devKey, aes->keylen,
6171
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6172
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
6173
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
6174
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
6175
                sw->aes.aes = aes;
6176
                sw->aes.out = out;
6177
                sw->aes.in = in;
6178
                sw->aes.sz = sz;
6179
                return WC_PENDING_E;
6180
            }
6181
        #endif
6182
        }
6183
    #endif /* WOLFSSL_ASYNC_CRYPT */
6184
6185
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
6186
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
6187
        AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
6188
            (int)aes->rounds);
6189
#else
6190
        AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
6191
            aes->rounds, (unsigned char*)aes->reg);
6192
#endif
6193
        return 0;
6194
#else
6195
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
6196
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
6197
        if (aes->useSWCrypt == 0) {
6198
            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
6199
                                   kAlgorithm_SSS_AES_CBC);
6200
        }
6201
        else
6202
    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
6203
        if (wc_esp32AesSupportedKeyLen(aes)) {
6204
            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
6205
            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
6206
        }
6207
        else {
6208
            /* For example, the ESP32-S3 does not support HW for len = 24,
6209
             * so fall back to SW */
6210
        #ifdef DEBUG_WOLFSSL
6211
            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
6212
                          "unsupported keylen = %d", aes->keylen);
6213
        #endif
6214
        }
6215
    #elif defined(WOLFSSL_AESNI)
6216
        VECTOR_REGISTERS_PUSH;
6217
        if (aes->use_aesni) {
6218
            #ifdef DEBUG_AESNI
6219
                printf("about to aes cbc encrypt\n");
6220
                printf("in  = %p\n", in);
6221
                printf("out = %p\n", out);
6222
                printf("aes->key = %p\n", aes->key);
6223
                printf("aes->reg = %p\n", aes->reg);
6224
                printf("aes->rounds = %d\n", aes->rounds);
6225
                printf("sz = %d\n", sz);
6226
            #endif
6227
6228
            /* check alignment, decrypt doesn't need alignment */
6229
            if ((wc_ptr_t)in % AESNI_ALIGN) {
6230
            #ifndef NO_WOLFSSL_ALLOC_ALIGN
6231
                byte* tmp = (byte*)XMALLOC(sz + WC_AES_BLOCK_SIZE + AESNI_ALIGN,
6232
                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
6233
                byte* tmp_align;
6234
                if (tmp == NULL)
6235
                    ret = MEMORY_E;
6236
                else {
6237
                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
6238
                    XMEMCPY(tmp_align, in, sz);
6239
                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
6240
                                          (byte*)aes->key, (int)aes->rounds);
6241
                    /* store iv for next call */
6242
                    XMEMCPY(aes->reg, tmp_align + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6243
6244
                    XMEMCPY(out, tmp_align, sz);
6245
                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
6246
                    ret = 0;
6247
                }
6248
            #else
6249
                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
6250
                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
6251
                ret = BAD_ALIGN_E;
6252
            #endif
6253
            } else {
6254
                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6255
                                      (int)aes->rounds);
6256
                /* store iv for next call */
6257
                XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6258
6259
                ret = 0;
6260
            }
6261
        }
6262
        else
6263
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6264
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6265
        if (aes->use_aes_hw_crypto) {
6266
            AES_CBC_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
6267
                (byte*)aes->key, (int)aes->rounds);
6268
            ret = 0;
6269
        }
6270
        else
6271
    #endif
6272
647
        {
6273
647
            ret = 0;
6274
5.39k
            while (blocks--) {
6275
4.74k
                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
6276
4.74k
                ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
6277
4.74k
                if (ret != 0)
6278
0
                    break;
6279
4.74k
                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
6280
6281
4.74k
                out += WC_AES_BLOCK_SIZE;
6282
4.74k
                in  += WC_AES_BLOCK_SIZE;
6283
4.74k
            }
6284
647
        }
6285
6286
    #ifdef WOLFSSL_AESNI
6287
        VECTOR_REGISTERS_POP;
6288
    #endif
6289
6290
647
        return ret;
6291
647
#endif
6292
647
    } /* wc_AesCbcEncrypt */
6293
6294
#ifdef HAVE_AES_DECRYPT
6295
    /* Software AES - CBC Decrypt */
6296
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6297
396
    {
6298
396
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
6299
396
        word32 blocks;
6300
396
        int ret;
6301
396
#endif
6302
6303
396
        if (aes == NULL || out == NULL || in == NULL) {
6304
0
            return BAD_FUNC_ARG;
6305
0
        }
6306
6307
396
        if (sz == 0) {
6308
0
            return 0;
6309
0
        }
6310
6311
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
6312
        if (wc_esp32AesSupportedKeyLen(aes)) {
6313
            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
6314
            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
6315
        }
6316
        else {
6317
            /* For example, the ESP32-S3 does not support HW for len = 24,
6318
             * so fall back to SW */
6319
        #ifdef DEBUG_WOLFSSL
6320
            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
6321
                          "unsupported keylen = %d", aes->keylen);
6322
        #endif
6323
        }
6324
    #endif
6325
6326
396
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
6327
396
        blocks = sz / WC_AES_BLOCK_SIZE;
6328
396
#endif
6329
396
        if (sz % WC_AES_BLOCK_SIZE) {
6330
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6331
            return BAD_LENGTH_E;
6332
#else
6333
0
            return BAD_FUNC_ARG;
6334
0
#endif
6335
0
        }
6336
6337
    #ifdef WOLFSSL_IMXRT_DCP
6338
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
6339
        if (aes->keylen == 16)
6340
            return DCPAesCbcDecrypt(aes, out, in, sz);
6341
    #endif
6342
6343
396
    #ifdef WOLF_CRYPTO_CB
6344
396
        #ifndef WOLF_CRYPTO_CB_FIND
6345
396
        if (aes->devId != INVALID_DEVID)
6346
0
        #endif
6347
0
        {
6348
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6349
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6350
0
                return crypto_cb_ret;
6351
            /* fall-through when unavailable */
6352
0
        }
6353
396
    #endif
6354
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
6355
        /* if async and byte count above threshold */
6356
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
6357
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
6358
        #if defined(HAVE_CAVIUM)
6359
            return NitroxAesCbcDecrypt(aes, out, in, sz);
6360
        #elif defined(HAVE_INTEL_QA)
6361
            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
6362
                (const byte*)aes->devKey, aes->keylen,
6363
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6364
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
6365
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
6366
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
6367
                sw->aes.aes = aes;
6368
                sw->aes.out = out;
6369
                sw->aes.in = in;
6370
                sw->aes.sz = sz;
6371
                return WC_PENDING_E;
6372
            }
6373
        #endif
6374
        }
6375
    #endif
6376
6377
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
6378
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
6379
        if (aes->useSWCrypt == 0) {
6380
            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
6381
                                   kAlgorithm_SSS_AES_CBC);
6382
        }
6383
    #endif
6384
6385
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
6386
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
6387
        AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
6388
            (int)aes->rounds);
6389
#else
6390
        AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
6391
            aes->rounds, (unsigned char*)aes->reg);
6392
#endif
6393
        return 0;
6394
#else
6395
396
        VECTOR_REGISTERS_PUSH;
6396
6397
    #ifdef WOLFSSL_AESNI
6398
        if (aes->use_aesni) {
6399
            #ifdef DEBUG_AESNI
6400
                printf("about to aes cbc decrypt\n");
6401
                printf("in  = %p\n", in);
6402
                printf("out = %p\n", out);
6403
                printf("aes->key = %p\n", aes->key);
6404
                printf("aes->reg = %p\n", aes->reg);
6405
                printf("aes->rounds = %d\n", aes->rounds);
6406
                printf("sz = %d\n", sz);
6407
            #endif
6408
6409
            /* if input and output same will overwrite input iv */
6410
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6411
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
6412
            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6413
                            aes->rounds);
6414
            #elif defined(WOLFSSL_AESNI_BY6)
6415
            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6416
                            aes->rounds);
6417
            #else /* WOLFSSL_AESNI_BYx */
6418
            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6419
                            (int)aes->rounds);
6420
            #endif /* WOLFSSL_AESNI_BYx */
6421
            /* store iv for next call */
6422
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6423
            ret = 0;
6424
        }
6425
        else
6426
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6427
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6428
        if (aes->use_aes_hw_crypto) {
6429
            AES_CBC_decrypt_AARCH64(in, out, sz, (byte*)aes->reg,
6430
                (byte*)aes->key, (int)aes->rounds);
6431
            ret = 0;
6432
        }
6433
        else
6434
    #endif
6435
396
        {
6436
396
            ret = 0;
6437
#ifdef WC_AES_BITSLICED
6438
            if (in != out) {
6439
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
6440
6441
                while (blocks > BS_WORD_SIZE) {
6442
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
6443
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6444
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
6445
                              WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
6446
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
6447
                            WC_AES_BLOCK_SIZE);
6448
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6449
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6450
                    blocks -= BS_WORD_SIZE;
6451
                }
6452
                if (blocks > 0) {
6453
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
6454
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6455
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
6456
                              WC_AES_BLOCK_SIZE * (blocks - 1));
6457
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (blocks - 1)),
6458
                            WC_AES_BLOCK_SIZE);
6459
                    blocks = 0;
6460
                }
6461
            }
6462
            else {
6463
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
6464
                int i;
6465
6466
                while (blocks > BS_WORD_SIZE) {
6467
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
6468
                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * WC_AES_BLOCK_SIZE,
6469
                            WC_AES_BLOCK_SIZE);
6470
                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
6471
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
6472
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
6473
                                  WC_AES_BLOCK_SIZE);
6474
                    }
6475
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6476
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6477
6478
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6479
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6480
                    blocks -= BS_WORD_SIZE;
6481
                }
6482
                if (blocks > 0) {
6483
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
6484
                    XMEMCPY(aes->tmp, in + (blocks - 1) * WC_AES_BLOCK_SIZE,
6485
                            WC_AES_BLOCK_SIZE);
6486
                    for (i = blocks-1; i >= 1; i--) {
6487
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
6488
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
6489
                                  WC_AES_BLOCK_SIZE);
6490
                    }
6491
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6492
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6493
6494
                    blocks = 0;
6495
                }
6496
            }
6497
#else
6498
11.3k
            while (blocks--) {
6499
10.9k
                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
6500
10.9k
                ret = wc_AesDecrypt(aes, in, out);
6501
10.9k
                if (ret != 0)
6502
0
                    return ret;
6503
10.9k
                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6504
                /* store iv for next call */
6505
10.9k
                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6506
6507
10.9k
                out += WC_AES_BLOCK_SIZE;
6508
10.9k
                in  += WC_AES_BLOCK_SIZE;
6509
10.9k
            }
6510
396
#endif
6511
396
        }
6512
6513
396
        VECTOR_REGISTERS_POP;
6514
6515
396
        return ret;
6516
396
#endif
6517
396
    }
6518
#endif /* HAVE_AES_DECRYPT */
6519
6520
#endif /* AES-CBC block */
6521
#endif /* HAVE_AES_CBC */
6522
6523
/* AES-CTR */
6524
#if defined(WOLFSSL_AES_COUNTER)
6525
6526
    #ifdef STM32_CRYPTO
6527
        #define NEED_AES_CTR_SOFT
6528
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
6529
6530
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
6531
        {
6532
            int ret = 0;
6533
        #ifdef WOLFSSL_STM32_CUBEMX
6534
            CRYP_HandleTypeDef hcryp;
6535
            #ifdef STM32_HAL_V2
6536
            word32 iv[WC_AES_BLOCK_SIZE/sizeof(word32)];
6537
            #endif
6538
        #else
6539
            word32 *iv;
6540
            CRYP_InitTypeDef cryptInit;
6541
            CRYP_KeyInitTypeDef keyInit;
6542
            CRYP_IVInitTypeDef ivInit;
6543
        #endif
6544
6545
        #ifdef WOLFSSL_STM32_CUBEMX
6546
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6547
            if (ret != 0) {
6548
                return ret;
6549
            }
6550
6551
            ret = wolfSSL_CryptHwMutexLock();
6552
            if (ret != 0) {
6553
                return ret;
6554
            }
6555
6556
        #if defined(STM32_HAL_V2)
6557
            hcryp.Init.Algorithm  = CRYP_AES_CTR;
6558
            ByteReverseWords(iv, aes->reg, WC_AES_BLOCK_SIZE);
6559
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
6560
        #elif defined(STM32_CRYPTO_AES_ONLY)
6561
            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
6562
            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
6563
            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6564
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6565
        #else
6566
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6567
        #endif
6568
            HAL_CRYP_Init(&hcryp);
6569
6570
        #if defined(STM32_HAL_V2)
6571
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, WC_AES_BLOCK_SIZE,
6572
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6573
        #elif defined(STM32_CRYPTO_AES_ONLY)
6574
            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
6575
                out, STM32_HAL_TIMEOUT);
6576
        #else
6577
            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
6578
                out, STM32_HAL_TIMEOUT);
6579
        #endif
6580
            if (ret != HAL_OK) {
6581
                ret = WC_TIMEOUT_E;
6582
            }
6583
            HAL_CRYP_DeInit(&hcryp);
6584
6585
        #else /* Standard Peripheral Library */
6586
            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6587
            if (ret != 0) {
6588
                return ret;
6589
            }
6590
6591
            ret = wolfSSL_CryptHwMutexLock();
6592
            if (ret != 0) {
6593
                return ret;
6594
            }
6595
6596
            /* reset registers to their default values */
6597
            CRYP_DeInit();
6598
6599
            /* set key */
6600
            CRYP_KeyInit(&keyInit);
6601
6602
            /* set iv */
6603
            iv = aes->reg;
6604
            CRYP_IVStructInit(&ivInit);
6605
            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
6606
            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
6607
            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
6608
            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
6609
            CRYP_IVInit(&ivInit);
6610
6611
            /* set direction and mode */
6612
            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
6613
            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
6614
            CRYP_Init(&cryptInit);
6615
6616
            /* enable crypto processor */
6617
            CRYP_Cmd(ENABLE);
6618
6619
            /* flush IN/OUT FIFOs */
6620
            CRYP_FIFOFlush();
6621
6622
            CRYP_DataIn(*(uint32_t*)&in[0]);
6623
            CRYP_DataIn(*(uint32_t*)&in[4]);
6624
            CRYP_DataIn(*(uint32_t*)&in[8]);
6625
            CRYP_DataIn(*(uint32_t*)&in[12]);
6626
6627
            /* wait until the complete message has been processed */
6628
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6629
6630
            *(uint32_t*)&out[0]  = CRYP_DataOut();
6631
            *(uint32_t*)&out[4]  = CRYP_DataOut();
6632
            *(uint32_t*)&out[8]  = CRYP_DataOut();
6633
            *(uint32_t*)&out[12] = CRYP_DataOut();
6634
6635
            /* disable crypto processor */
6636
            CRYP_Cmd(DISABLE);
6637
        #endif /* WOLFSSL_STM32_CUBEMX */
6638
6639
            wolfSSL_CryptHwMutexUnLock();
6640
            wc_Stm32_Aes_Cleanup();
6641
            return ret;
6642
        }
6643
6644
6645
    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
6646
6647
        #define NEED_AES_CTR_SOFT
6648
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
6649
6650
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
6651
        {
6652
            word32 tmpIv[WC_AES_BLOCK_SIZE / sizeof(word32)];
6653
            XMEMCPY(tmpIv, aes->reg, WC_AES_BLOCK_SIZE);
6654
            return wc_Pic32AesCrypt(
6655
                aes->key, aes->keylen, tmpIv, WC_AES_BLOCK_SIZE,
6656
                out, in, WC_AES_BLOCK_SIZE,
6657
                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
6658
        }
6659
6660
    #elif defined(HAVE_COLDFIRE_SEC)
6661
        #error "Coldfire SEC doesn't currently support AES-CTR mode"
6662
6663
    #elif defined(FREESCALE_LTC)
6664
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6665
        {
6666
            int ret = 0;
6667
            word32 keySize;
6668
            byte *iv, *enc_key;
6669
            byte* tmp;
6670
6671
            if (aes == NULL || out == NULL || in == NULL) {
6672
                return BAD_FUNC_ARG;
6673
            }
6674
6675
            /* consume any unused bytes left in aes->tmp */
6676
            tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
6677
            while (aes->left && sz) {
6678
                *(out++) = *(in++) ^ *(tmp++);
6679
                aes->left--;
6680
                sz--;
6681
            }
6682
6683
            if (sz) {
6684
                iv      = (byte*)aes->reg;
6685
                enc_key = (byte*)aes->key;
6686
6687
                ret = wc_AesGetKeySize(aes, &keySize);
6688
                if (ret != 0)
6689
                    return ret;
6690
6691
                ret = wolfSSL_CryptHwMutexLock();
6692
                if (ret != 0)
6693
                    return ret;
6694
                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
6695
                    iv, enc_key, keySize, (byte*)aes->tmp,
6696
                    (uint32_t*)&aes->left);
6697
                wolfSSL_CryptHwMutexUnLock();
6698
            }
6699
6700
            return ret;
6701
        }
6702
6703
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6704
        !defined(WOLFSSL_QNX_CAAM)
6705
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6706
6707
    #elif defined(WOLFSSL_AFALG)
6708
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6709
6710
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
6711
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6712
6713
    #elif defined(WOLFSSL_ESP32_CRYPT) && \
6714
        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6715
        /* esp32 doesn't support CRT mode by hw.     */
6716
        /* use aes ecnryption plus sw implementation */
6717
        #define NEED_AES_CTR_SOFT
6718
6719
    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6720
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
6721
    #else
6722
6723
        /* Use software based AES counter */
6724
        #define NEED_AES_CTR_SOFT
6725
    #endif
6726
6727
    #ifdef NEED_AES_CTR_SOFT
6728
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6729
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
6730
        /* Increment AES counter */
6731
        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
6732
4.47k
        {
6733
            /* in network byte order so start at end and work back */
6734
4.47k
            int i;
6735
5.12k
            for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
6736
5.12k
                if (++inOutCtr[i])  /* we're done unless we overflow */
6737
4.47k
                    return;
6738
5.12k
            }
6739
4.47k
        }
6740
    #endif
6741
6742
        /* Software AES - CTR Encrypt */
6743
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6744
737
        {
6745
737
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6746
737
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
6747
737
            byte scratch[WC_AES_BLOCK_SIZE];
6748
737
    #endif
6749
737
    #if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
6750
737
            int ret = 0;
6751
737
    #endif
6752
737
            word32 processed;
6753
6754
737
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6755
737
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
6756
737
            XMEMSET(scratch, 0, sizeof(scratch));
6757
737
    #endif
6758
6759
737
            if (aes == NULL || out == NULL || in == NULL) {
6760
0
                return BAD_FUNC_ARG;
6761
0
            }
6762
6763
737
        #ifdef WOLF_CRYPTO_CB
6764
737
            #ifndef WOLF_CRYPTO_CB_FIND
6765
737
            if (aes->devId != INVALID_DEVID)
6766
0
            #endif
6767
0
            {
6768
0
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
6769
0
                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6770
0
                    return crypto_cb_ret;
6771
                /* fall-through when unavailable */
6772
0
            }
6773
737
        #endif
6774
6775
            /* consume any unused bytes left in aes->tmp */
6776
737
            processed = min(aes->left, sz);
6777
737
            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
6778
737
                      processed);
6779
737
            out += processed;
6780
737
            in += processed;
6781
737
            aes->left -= processed;
6782
737
            sz -= processed;
6783
6784
    #if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
6785
    #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
6786
            AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
6787
                (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
6788
    #else
6789
            {
6790
                word32 numBlocks;
6791
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
6792
                /* consume any unused bytes left in aes->tmp */
6793
                while ((aes->left != 0) && (sz != 0)) {
6794
                   *(out++) = *(in++) ^ *(tmp++);
6795
                   aes->left--;
6796
                   sz--;
6797
                }
6798
6799
                /* do as many block size ops as possible */
6800
                numBlocks = sz / WC_AES_BLOCK_SIZE;
6801
                if (numBlocks > 0) {
6802
                    AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
6803
                        (byte*)aes->key, aes->rounds, (byte*)aes->reg);
6804
6805
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
6806
                    out += numBlocks * WC_AES_BLOCK_SIZE;
6807
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
6808
                }
6809
6810
                /* handle non block size remaining */
6811
                if (sz) {
6812
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
6813
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
6814
6815
                    AES_CTR_encrypt(zeros, (byte*)aes->tmp, WC_AES_BLOCK_SIZE,
6816
                        (byte*)aes->key, aes->rounds, (byte*)aes->reg);
6817
6818
                    aes->left = WC_AES_BLOCK_SIZE;
6819
                    tmp = (byte*)aes->tmp;
6820
6821
                    while (sz--) {
6822
                        *(out++) = *(in++) ^ *(tmp++);
6823
                        aes->left--;
6824
                    }
6825
                }
6826
            }
6827
        #endif
6828
            return 0;
6829
    #else
6830
        #if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6831
            !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6832
            if (aes->use_aes_hw_crypto) {
6833
                AES_CTR_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
6834
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
6835
                return 0;
6836
            }
6837
        #endif
6838
6839
737
            VECTOR_REGISTERS_PUSH;
6840
6841
737
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
6842
737
            !defined(XTRANSFORM_AESCTRBLOCK)
6843
737
            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
6844
222
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
6845
222
                byte* counter = (byte*)aes->reg;
6846
222
                byte* c = out;
6847
3.94k
                while (blocks--) {
6848
3.71k
                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
6849
3.71k
                    c += WC_AES_BLOCK_SIZE;
6850
3.71k
                    IncrementAesCounter(counter);
6851
3.71k
                }
6852
6853
                /* reset number of blocks and then do encryption */
6854
222
                blocks = sz / WC_AES_BLOCK_SIZE;
6855
222
                wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
6856
222
                xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
6857
222
                in += WC_AES_BLOCK_SIZE * blocks;
6858
222
                out += WC_AES_BLOCK_SIZE * blocks;
6859
222
                sz -= blocks * WC_AES_BLOCK_SIZE;
6860
222
            }
6861
515
            else
6862
515
        #endif
6863
515
            {
6864
            #ifdef WOLFSSL_CHECK_MEM_ZERO
6865
                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
6866
                    WC_AES_BLOCK_SIZE);
6867
            #endif
6868
                /* do as many block size ops as possible */
6869
944
                while (sz >= WC_AES_BLOCK_SIZE) {
6870
                #ifdef XTRANSFORM_AESCTRBLOCK
6871
                    XTRANSFORM_AESCTRBLOCK(aes, out, in);
6872
                #else
6873
429
                    ret = wc_AesEncrypt(aes, (byte*)aes->reg, scratch);
6874
429
                    if (ret != 0)
6875
0
                        break;
6876
429
                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
6877
429
                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
6878
429
                #endif
6879
429
                    IncrementAesCounter((byte*)aes->reg);
6880
6881
429
                    out += WC_AES_BLOCK_SIZE;
6882
429
                    in  += WC_AES_BLOCK_SIZE;
6883
429
                    sz  -= WC_AES_BLOCK_SIZE;
6884
429
                    aes->left = 0;
6885
429
                }
6886
515
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
6887
515
            }
6888
6889
            /* handle non block size remaining and store unused byte count in left */
6890
737
            if ((ret == 0) && sz) {
6891
330
                ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
6892
330
                if (ret == 0) {
6893
330
                    IncrementAesCounter((byte*)aes->reg);
6894
330
                    aes->left = WC_AES_BLOCK_SIZE - sz;
6895
330
                    xorbufout(out, in, aes->tmp, sz);
6896
330
                }
6897
330
            }
6898
6899
737
            if (ret < 0)
6900
0
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
6901
6902
        #ifdef WOLFSSL_CHECK_MEM_ZERO
6903
            wc_MemZero_Check(scratch, WC_AES_BLOCK_SIZE);
6904
        #endif
6905
6906
737
            VECTOR_REGISTERS_POP;
6907
6908
737
            return ret;
6909
737
    #endif
6910
737
        }
6911
6912
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
6913
                                        const byte* iv, int dir)
6914
0
        {
6915
0
            if (aes == NULL) {
6916
0
                return BAD_FUNC_ARG;
6917
0
            }
6918
0
            if (len > sizeof(aes->key)) {
6919
0
                return BAD_FUNC_ARG;
6920
0
            }
6921
6922
0
            return wc_AesSetKey(aes, key, len, iv, dir);
6923
0
        }
6924
6925
    #endif /* NEED_AES_CTR_SOFT */
6926
6927
#endif /* WOLFSSL_AES_COUNTER */
6928
#endif /* !WOLFSSL_RISCV_ASM */
6929
6930
6931
/*
6932
 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
6933
 * of two parts in order:
6934
 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
6935
 *      to the implicit IV.
6936
 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
6937
 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
6938
 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
6939
 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
6940
 * block counter during the encryption.
6941
 */
6942
6943
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
6944
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
6945
2.01k
{
6946
2.01k
    int i;
6947
2.42k
    for (i = (int)ctrSz - 1; i >= 0; i--) {
6948
2.42k
        if (++ctr[i])
6949
2.01k
            break;
6950
2.42k
    }
6951
2.01k
}
6952
#endif /* HAVE_AESGCM || HAVE_AESCCM */
6953
6954
6955
#ifdef HAVE_AESGCM
6956
6957
#ifdef WOLFSSL_AESGCM_STREAM
6958
    /* Access initialization counter data. */
6959
3.77k
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
6960
    /* Access counter data. */
6961
4.60k
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
6962
    /* Access tag data. */
6963
16.0k
    #define AES_TAG(aes)            ((aes)->streamData + 2 * WC_AES_BLOCK_SIZE)
6964
    /* Access last GHASH block. */
6965
    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE)
6966
    /* Access last encrypted block. */
6967
17.6k
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
6968
6969
8.00k
    #define GHASH_ONE_BLOCK     GHASH_ONE_BLOCK_SW
6970
#endif
6971
6972
#if defined(HAVE_COLDFIRE_SEC)
6973
    #error "Coldfire SEC doesn't currently support AES-GCM mode"
6974
6975
#endif
6976
6977
#if defined(WOLFSSL_RISCV_ASM)
6978
    /* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
6979
6980
#elif defined(WOLFSSL_AFALG)
6981
    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
6982
6983
#elif defined(WOLFSSL_KCAPI_AES)
6984
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
6985
6986
#elif defined(WOLFSSL_DEVCRYPTO_AES)
6987
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6988
6989
#else /* software + AESNI implementation */
6990
6991
#if !defined(FREESCALE_LTC_AES_GCM)
6992
static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
6993
44.2k
{
6994
44.2k
    int i;
6995
6996
    /* in network byte order so start at end and work back */
6997
44.3k
    for (i = WC_AES_BLOCK_SIZE - 1; i >= WC_AES_BLOCK_SIZE - CTR_SZ; i--) {
6998
44.3k
        if (++inOutCtr[i])  /* we're done unless we overflow */
6999
44.2k
            return;
7000
44.3k
    }
7001
44.2k
}
7002
#endif /* !FREESCALE_LTC_AES_GCM */
7003
7004
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
7005
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7006
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
7007
7008
static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
7009
5.07k
{
7010
    /* Multiply the sz by 8 */
7011
5.07k
    word32 szHi = (sz >> (8*sizeof(sz) - 3));
7012
5.07k
    sz <<= 3;
7013
7014
    /* copy over the words of the sz into the destination buffer */
7015
5.07k
    buf[0] = (byte)(szHi >> 24);
7016
5.07k
    buf[1] = (byte)(szHi >> 16);
7017
5.07k
    buf[2] = (byte)(szHi >>  8);
7018
5.07k
    buf[3] = (byte)szHi;
7019
5.07k
    buf[4] = (byte)(sz >> 24);
7020
5.07k
    buf[5] = (byte)(sz >> 16);
7021
5.07k
    buf[6] = (byte)(sz >>  8);
7022
5.07k
    buf[7] = (byte)sz;
7023
5.07k
}
7024
7025
7026
static WC_INLINE void RIGHTSHIFTX(byte* x)
7027
5.25k
{
7028
5.25k
    int i;
7029
5.25k
    int carryIn = 0;
7030
5.25k
    volatile byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
7031
7032
89.4k
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
7033
84.1k
        int carryOut = (x[i] & 0x01) << 7;
7034
84.1k
        x[i] = (byte) ((x[i] >> 1) | carryIn);
7035
84.1k
        carryIn = carryOut;
7036
84.1k
    }
7037
5.25k
    x[0] ^= borrow;
7038
5.25k
}
7039
7040
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
7041
7042
7043
#ifdef GCM_TABLE
7044
7045
void GenerateM0(Gcm* gcm)
7046
{
7047
    int i, j;
7048
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
7049
7050
    XMEMCPY(m[128], gcm->H, WC_AES_BLOCK_SIZE);
7051
7052
    for (i = 64; i > 0; i /= 2) {
7053
        XMEMCPY(m[i], m[i*2], WC_AES_BLOCK_SIZE);
7054
        RIGHTSHIFTX(m[i]);
7055
    }
7056
7057
    for (i = 2; i < 256; i *= 2) {
7058
        for (j = 1; j < i; j++) {
7059
            XMEMCPY(m[i+j], m[i], WC_AES_BLOCK_SIZE);
7060
            xorbuf(m[i+j], m[j], WC_AES_BLOCK_SIZE);
7061
        }
7062
    }
7063
7064
    XMEMSET(m[0], 0, WC_AES_BLOCK_SIZE);
7065
}
7066
7067
#elif defined(GCM_TABLE_4BIT)
7068
7069
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU)
7070
static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
7071
28.0k
{
7072
28.0k
    int i;
7073
448k
    for (i = 15; i > 0; i--)
7074
420k
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
7075
28.0k
    r8[0] = (byte)(z8[0] >> 4);
7076
28.0k
}
7077
#endif
7078
7079
void GenerateM0(Gcm* gcm)
7080
1.75k
{
7081
1.75k
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU)
7082
1.75k
    int i;
7083
1.75k
#endif
7084
1.75k
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
7085
7086
    /* 0 times -> 0x0 */
7087
1.75k
    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
7088
    /* 1 times -> 0x8 */
7089
1.75k
    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
7090
    /* 2 times -> 0x4 */
7091
1.75k
    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
7092
1.75k
    RIGHTSHIFTX(m[0x4]);
7093
    /* 4 times -> 0x2 */
7094
1.75k
    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
7095
1.75k
    RIGHTSHIFTX(m[0x2]);
7096
    /* 8 times -> 0x1 */
7097
1.75k
    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
7098
1.75k
    RIGHTSHIFTX(m[0x1]);
7099
7100
    /* 0x3 */
7101
1.75k
    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
7102
1.75k
    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
7103
7104
    /* 0x5 -> 0x7 */
7105
1.75k
    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
7106
1.75k
    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
7107
1.75k
    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
7108
1.75k
    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
7109
1.75k
    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
7110
1.75k
    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
7111
7112
    /* 0x9 -> 0xf */
7113
1.75k
    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
7114
1.75k
    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
7115
1.75k
    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
7116
1.75k
    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
7117
1.75k
    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
7118
1.75k
    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
7119
1.75k
    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
7120
1.75k
    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
7121
1.75k
    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
7122
1.75k
    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
7123
1.75k
    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
7124
1.75k
    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
7125
1.75k
    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
7126
1.75k
    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
7127
7128
#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
7129
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7130
    for (i = 0; i < 16; i++) {
7131
        word32* m32 = (word32*)gcm->M0[i];
7132
        m32[0] = ByteReverseWord32(m32[0]);
7133
        m32[1] = ByteReverseWord32(m32[1]);
7134
        m32[2] = ByteReverseWord32(m32[2]);
7135
        m32[3] = ByteReverseWord32(m32[3]);
7136
    }
7137
#endif
7138
7139
1.75k
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU)
7140
29.8k
    for (i = 0; i < 16; i++) {
7141
28.0k
        Shift4_M0(m[16+i], m[i]);
7142
28.0k
    }
7143
1.75k
#endif
7144
1.75k
}
7145
7146
#endif /* GCM_TABLE */
7147
#endif
7148
7149
#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
7150
    #define HAVE_INTEL_AVX1
7151
    #define HAVE_INTEL_AVX2
7152
#endif
7153
7154
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \
7155
    defined(WC_C_DYNAMIC_FALLBACK)
7156
void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m)
7157
                           XASM_LINK("GCM_generate_m0_aesni");
7158
#ifdef HAVE_INTEL_AVX1
7159
void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m)
7160
                          XASM_LINK("GCM_generate_m0_avx1");
7161
#endif
7162
#ifdef HAVE_INTEL_AVX2
7163
void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
7164
                          XASM_LINK("GCM_generate_m0_avx2");
7165
#endif
7166
#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */
7167
7168
/* Software AES - GCM SetKey */
7169
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
7170
1.75k
{
7171
1.75k
    int  ret;
7172
1.75k
    byte iv[WC_AES_BLOCK_SIZE];
7173
7174
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
7175
        byte   local[32];
7176
        word32 localSz = 32;
7177
7178
        if (len == (16 + WC_CAAM_BLOB_SZ) ||
7179
          len == (24 + WC_CAAM_BLOB_SZ) ||
7180
          len == (32 + WC_CAAM_BLOB_SZ)) {
7181
            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
7182
                 return BAD_FUNC_ARG;
7183
            }
7184
7185
            /* set local values */
7186
            key = local;
7187
            len = localSz;
7188
        }
7189
    #endif
7190
7191
1.75k
    if (!((len == 16) || (len == 24) || (len == 32)))
7192
0
        return BAD_FUNC_ARG;
7193
7194
1.75k
    if (aes == NULL || key == NULL) {
7195
#ifdef WOLFSSL_IMX6_CAAM_BLOB
7196
        ForceZero(local, sizeof(local));
7197
#endif
7198
0
        return BAD_FUNC_ARG;
7199
0
    }
7200
1.75k
#ifdef OPENSSL_EXTRA
7201
1.75k
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
7202
1.75k
    aes->gcm.aadLen = 0;
7203
1.75k
#endif
7204
1.75k
    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
7205
1.75k
    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
7206
1.75k
#ifdef WOLFSSL_AESGCM_STREAM
7207
1.75k
    aes->gcmKeySet = 1;
7208
1.75k
#endif
7209
    #if defined(WOLFSSL_SECO_CAAM)
7210
        if (aes->devId == WOLFSSL_SECO_DEVID) {
7211
            return ret;
7212
        }
7213
    #endif /* WOLFSSL_SECO_CAAM */
7214
7215
    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
7216
        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
7217
        return ret;
7218
    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
7219
7220
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
7221
    if (ret == 0) {
7222
    #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7223
        AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
7224
    #else
7225
        AES_ECB_encrypt(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
7226
            (const unsigned char*)aes->key, aes->rounds);
7227
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
7228
            GenerateM0(&aes->gcm);
7229
        #endif /* GCM_TABLE */
7230
    #endif
7231
    }
7232
#else
7233
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
7234
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7235
    if (ret == 0 && aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
7236
        AES_GCM_set_key_AARCH64(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
7237
    }
7238
    else
7239
#endif
7240
1.75k
#if !defined(FREESCALE_LTC_AES_GCM)
7241
1.75k
    if (ret == 0) {
7242
1.75k
        VECTOR_REGISTERS_PUSH;
7243
        /* AES-NI code generates its own H value, but generate it here too, to
7244
         * assure pure-C fallback is always usable.
7245
         */
7246
1.75k
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
7247
1.75k
        VECTOR_REGISTERS_POP;
7248
1.75k
    }
7249
1.75k
    if (ret == 0) {
7250
1.75k
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
7251
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT)
7252
        if (aes->use_aesni) {
7253
    #if defined(WC_C_DYNAMIC_FALLBACK)
7254
        #ifdef HAVE_INTEL_AVX2
7255
            if (IS_INTEL_AVX2(intel_flags)) {
7256
                GCM_generate_m0_avx2(aes->gcm.H, (byte*)aes->gcm.M0);
7257
            }
7258
            else
7259
        #endif
7260
        #if defined(HAVE_INTEL_AVX1)
7261
            if (IS_INTEL_AVX1(intel_flags)) {
7262
                GCM_generate_m0_avx1(aes->gcm.H, (byte*)aes->gcm.M0);
7263
            }
7264
            else
7265
        #endif
7266
            {
7267
                GCM_generate_m0_aesni(aes->gcm.H, (byte*)aes->gcm.M0);
7268
            }
7269
    #endif
7270
        }
7271
        else
7272
#endif
7273
1.75k
        {
7274
1.75k
            GenerateM0(&aes->gcm);
7275
1.75k
        }
7276
1.75k
#endif /* GCM_TABLE || GCM_TABLE_4BIT */
7277
1.75k
    }
7278
1.75k
#endif /* FREESCALE_LTC_AES_GCM */
7279
1.75k
#endif
7280
7281
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
7282
    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
7283
#endif
7284
7285
1.75k
#ifdef WOLF_CRYPTO_CB
7286
1.75k
    if (aes->devId != INVALID_DEVID) {
7287
0
        XMEMCPY(aes->devKey, key, len);
7288
0
    }
7289
1.75k
#endif
7290
7291
#ifdef WOLFSSL_IMX6_CAAM_BLOB
7292
    ForceZero(local, sizeof(local));
7293
#endif
7294
1.75k
    return ret;
7295
1.75k
}
7296
7297
7298
#ifdef WOLFSSL_AESNI
7299
7300
void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
7301
                     const unsigned char* addt, const unsigned char* ivec,
7302
                     unsigned char *tag, word32 nbytes,
7303
                     word32 abytes, word32 ibytes,
7304
                     word32 tbytes, const unsigned char* key, int nr)
7305
                     XASM_LINK("AES_GCM_encrypt_aesni");
7306
#ifdef HAVE_INTEL_AVX1
7307
void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
7308
                          const unsigned char* addt, const unsigned char* ivec,
7309
                          unsigned char *tag, word32 nbytes,
7310
                          word32 abytes, word32 ibytes,
7311
                          word32 tbytes, const unsigned char* key,
7312
                          int nr)
7313
                          XASM_LINK("AES_GCM_encrypt_avx1");
7314
#ifdef HAVE_INTEL_AVX2
7315
void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
7316
                          const unsigned char* addt, const unsigned char* ivec,
7317
                          unsigned char *tag, word32 nbytes,
7318
                          word32 abytes, word32 ibytes,
7319
                          word32 tbytes, const unsigned char* key,
7320
                          int nr)
7321
                          XASM_LINK("AES_GCM_encrypt_avx2");
7322
#endif /* HAVE_INTEL_AVX2 */
7323
#endif /* HAVE_INTEL_AVX1 */
7324
7325
#ifdef HAVE_AES_DECRYPT
7326
void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
7327
                     const unsigned char* addt, const unsigned char* ivec,
7328
                     const unsigned char *tag, word32 nbytes, word32 abytes,
7329
                     word32 ibytes, word32 tbytes, const unsigned char* key,
7330
                     int nr, int* res)
7331
                     XASM_LINK("AES_GCM_decrypt_aesni");
7332
#ifdef HAVE_INTEL_AVX1
7333
void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
7334
                          const unsigned char* addt, const unsigned char* ivec,
7335
                          const unsigned char *tag, word32 nbytes,
7336
                          word32 abytes, word32 ibytes, word32 tbytes,
7337
                          const unsigned char* key, int nr, int* res)
7338
                          XASM_LINK("AES_GCM_decrypt_avx1");
7339
#ifdef HAVE_INTEL_AVX2
7340
void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
7341
                          const unsigned char* addt, const unsigned char* ivec,
7342
                          const unsigned char *tag, word32 nbytes,
7343
                          word32 abytes, word32 ibytes, word32 tbytes,
7344
                          const unsigned char* key, int nr, int* res)
7345
                          XASM_LINK("AES_GCM_decrypt_avx2");
7346
#endif /* HAVE_INTEL_AVX2 */
7347
#endif /* HAVE_INTEL_AVX1 */
7348
#endif /* HAVE_AES_DECRYPT */
7349
7350
#endif /* WOLFSSL_AESNI */
7351
7352
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
7353
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7354
#if defined(GCM_SMALL)
7355
static void GMULT(byte* X, byte* Y)
7356
{
7357
    byte Z[WC_AES_BLOCK_SIZE];
7358
    byte V[WC_AES_BLOCK_SIZE];
7359
    int i, j;
7360
7361
    XMEMSET(Z, 0, WC_AES_BLOCK_SIZE);
7362
    XMEMCPY(V, X, WC_AES_BLOCK_SIZE);
7363
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++)
7364
    {
7365
        byte y = Y[i];
7366
        for (j = 0; j < 8; j++)
7367
        {
7368
            if (y & 0x80) {
7369
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
7370
            }
7371
7372
            RIGHTSHIFTX(V);
7373
            y = y << 1;
7374
        }
7375
    }
7376
    XMEMCPY(X, Z, WC_AES_BLOCK_SIZE);
7377
}
7378
7379
7380
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7381
    word32 cSz, byte* s, word32 sSz)
7382
{
7383
    byte x[WC_AES_BLOCK_SIZE];
7384
    byte scratch[WC_AES_BLOCK_SIZE];
7385
    word32 blocks, partial;
7386
    byte* h;
7387
7388
    if (gcm == NULL) {
7389
        return;
7390
    }
7391
7392
    h = gcm->H;
7393
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
7394
7395
    /* Hash in A, the Additional Authentication Data */
7396
    if (aSz != 0 && a != NULL) {
7397
        blocks = aSz / WC_AES_BLOCK_SIZE;
7398
        partial = aSz % WC_AES_BLOCK_SIZE;
7399
        while (blocks--) {
7400
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
7401
            GMULT(x, h);
7402
            a += WC_AES_BLOCK_SIZE;
7403
        }
7404
        if (partial != 0) {
7405
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7406
            XMEMCPY(scratch, a, partial);
7407
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7408
            GMULT(x, h);
7409
        }
7410
    }
7411
7412
    /* Hash in C, the Ciphertext */
7413
    if (cSz != 0 && c != NULL) {
7414
        blocks = cSz / WC_AES_BLOCK_SIZE;
7415
        partial = cSz % WC_AES_BLOCK_SIZE;
7416
        while (blocks--) {
7417
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
7418
            GMULT(x, h);
7419
            c += WC_AES_BLOCK_SIZE;
7420
        }
7421
        if (partial != 0) {
7422
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7423
            XMEMCPY(scratch, c, partial);
7424
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7425
            GMULT(x, h);
7426
        }
7427
    }
7428
7429
    /* Hash in the lengths of A and C in bits */
7430
    FlattenSzInBits(&scratch[0], aSz);
7431
    FlattenSzInBits(&scratch[8], cSz);
7432
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7433
    GMULT(x, h);
7434
7435
    /* Copy the result into s. */
7436
    XMEMCPY(s, x, sSz);
7437
}
7438
7439
#ifdef WOLFSSL_AESGCM_STREAM
7440
/* No extra initialization for small implementation.
7441
 *
7442
 * @param [in] aes  AES GCM object.
7443
 */
7444
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7445
7446
/* GHASH one block of data..
7447
 *
7448
 * XOR block into tag and GMULT with H.
7449
 *
7450
 * @param [in, out] aes    AES GCM object.
7451
 * @param [in]      block  Block of AAD or cipher text.
7452
 */
7453
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
7454
    do {                                                \
7455
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
7456
        GMULT(AES_TAG(aes), (aes)->gcm.H);              \
7457
    }                                                   \
7458
    while (0)
7459
#endif /* WOLFSSL_AESGCM_STREAM */
7460
7461
#ifdef WOLFSSL_ARMASM
7462
#define GCM_GMULT_LEN(gcm, x, a, len) \
7463
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
7464
#endif
7465
7466
#elif defined(GCM_TABLE)
7467
7468
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
7469
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7470
#define GCM_GMULT_LEN(gcm, x, a, len) \
7471
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
7472
#else
7473
ALIGN16 static const byte R[256][2] = {
7474
    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
7475
    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
7476
    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
7477
    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
7478
    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
7479
    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
7480
    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
7481
    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
7482
    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
7483
    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
7484
    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
7485
    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
7486
    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
7487
    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
7488
    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
7489
    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
7490
    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
7491
    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
7492
    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
7493
    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
7494
    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
7495
    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
7496
    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
7497
    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
7498
    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
7499
    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
7500
    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
7501
    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
7502
    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
7503
    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
7504
    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
7505
    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
7506
    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
7507
    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
7508
    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
7509
    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
7510
    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
7511
    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
7512
    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
7513
    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
7514
    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
7515
    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
7516
    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
7517
    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
7518
    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
7519
    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
7520
    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
7521
    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
7522
    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
7523
    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
7524
    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
7525
    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
7526
    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
7527
    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
7528
    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
7529
    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
7530
    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
7531
    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
7532
    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
7533
    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
7534
    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
7535
    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
7536
    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
7537
    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
7538
7539
7540
static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE])
7541
{
7542
#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
7543
    int i, j;
7544
    byte Z[WC_AES_BLOCK_SIZE];
7545
    byte a;
7546
7547
    XMEMSET(Z, 0, sizeof(Z));
7548
7549
    for (i = 15; i > 0; i--) {
7550
        xorbuf(Z, m[x[i]], WC_AES_BLOCK_SIZE);
7551
        a = Z[15];
7552
7553
        for (j = 15; j > 0; j--) {
7554
            Z[j] = Z[j-1];
7555
        }
7556
7557
        Z[0]  = R[a][0];
7558
        Z[1] ^= R[a][1];
7559
    }
7560
    xorbuf(Z, m[x[0]], WC_AES_BLOCK_SIZE);
7561
7562
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
7563
#elif defined(WC_32BIT_CPU)
7564
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
7565
    byte a;
7566
    word32* pZ;
7567
    word32* pm;
7568
    word32* px = (word32*)(x);
7569
    int i;
7570
7571
    pZ = (word32*)(Z + 15 + 1);
7572
    pm = (word32*)(m[x[15]]);
7573
    pZ[0] = pm[0];
7574
    pZ[1] = pm[1];
7575
    pZ[2] = pm[2];
7576
    pZ[3] = pm[3];
7577
    a = Z[16 + 15];
7578
    Z[15]  = R[a][0];
7579
    Z[16] ^= R[a][1];
7580
    for (i = 14; i > 0; i--) {
7581
        pZ = (word32*)(Z + i + 1);
7582
        pm = (word32*)(m[x[i]]);
7583
        pZ[0] ^= pm[0];
7584
        pZ[1] ^= pm[1];
7585
        pZ[2] ^= pm[2];
7586
        pZ[3] ^= pm[3];
7587
        a = Z[16 + i];
7588
        Z[i]    = R[a][0];
7589
        Z[i+1] ^= R[a][1];
7590
    }
7591
    pZ = (word32*)(Z + 1);
7592
    pm = (word32*)(m[x[0]]);
7593
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
7594
    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
7595
#else
7596
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
7597
    byte a;
7598
    word64* pZ;
7599
    word64* pm;
7600
    word64* px = (word64*)(x);
7601
    int i;
7602
7603
    pZ = (word64*)(Z + 15 + 1);
7604
    pm = (word64*)(m[x[15]]);
7605
    pZ[0] = pm[0];
7606
    pZ[1] = pm[1];
7607
    a = Z[16 + 15];
7608
    Z[15]  = R[a][0];
7609
    Z[16] ^= R[a][1];
7610
    for (i = 14; i > 0; i--) {
7611
        pZ = (word64*)(Z + i + 1);
7612
        pm = (word64*)(m[x[i]]);
7613
        pZ[0] ^= pm[0];
7614
        pZ[1] ^= pm[1];
7615
        a = Z[16 + i];
7616
        Z[i]    = R[a][0];
7617
        Z[i+1] ^= R[a][1];
7618
    }
7619
    pZ = (word64*)(Z + 1);
7620
    pm = (word64*)(m[x[0]]);
7621
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
7622
#endif
7623
}
7624
#endif
7625
7626
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7627
    word32 cSz, byte* s, word32 sSz)
7628
{
7629
    byte x[WC_AES_BLOCK_SIZE];
7630
    byte scratch[WC_AES_BLOCK_SIZE];
7631
    word32 blocks, partial;
7632
7633
    if (gcm == NULL) {
7634
        return;
7635
    }
7636
7637
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
7638
7639
    /* Hash in A, the Additional Authentication Data */
7640
    if (aSz != 0 && a != NULL) {
7641
        blocks = aSz / WC_AES_BLOCK_SIZE;
7642
        partial = aSz % WC_AES_BLOCK_SIZE;
7643
    #ifdef GCM_GMULT_LEN
7644
        if (blocks > 0) {
7645
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
7646
            a += blocks * WC_AES_BLOCK_SIZE;
7647
        }
7648
        if (partial != 0) {
7649
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7650
            XMEMCPY(scratch, a, partial);
7651
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
7652
        }
7653
    #else
7654
        while (blocks--) {
7655
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
7656
            GMULT(x, gcm->M0);
7657
            a += WC_AES_BLOCK_SIZE;
7658
        }
7659
        if (partial != 0) {
7660
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7661
            XMEMCPY(scratch, a, partial);
7662
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7663
            GMULT(x, gcm->M0);
7664
        }
7665
    #endif
7666
    }
7667
7668
    /* Hash in C, the Ciphertext */
7669
    if (cSz != 0 && c != NULL) {
7670
        blocks = cSz / WC_AES_BLOCK_SIZE;
7671
        partial = cSz % WC_AES_BLOCK_SIZE;
7672
    #ifdef GCM_GMULT_LEN
7673
        if (blocks > 0) {
7674
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
7675
            c += blocks * WC_AES_BLOCK_SIZE;
7676
        }
7677
        if (partial != 0) {
7678
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7679
            XMEMCPY(scratch, c, partial);
7680
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
7681
        }
7682
    #else
7683
        while (blocks--) {
7684
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
7685
            GMULT(x, gcm->M0);
7686
            c += WC_AES_BLOCK_SIZE;
7687
        }
7688
        if (partial != 0) {
7689
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7690
            XMEMCPY(scratch, c, partial);
7691
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7692
            GMULT(x, gcm->M0);
7693
        }
7694
    #endif
7695
    }
7696
7697
    /* Hash in the lengths of A and C in bits */
7698
    FlattenSzInBits(&scratch[0], aSz);
7699
    FlattenSzInBits(&scratch[8], cSz);
7700
#ifdef GCM_GMULT_LEN
7701
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
7702
#else
7703
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7704
    GMULT(x, gcm->M0);
7705
#endif
7706
7707
    /* Copy the result into s. */
7708
    XMEMCPY(s, x, sSz);
7709
}
7710
7711
#ifdef WOLFSSL_AESGCM_STREAM
7712
/* No extra initialization for table implementation.
7713
 *
7714
 * @param [in] aes  AES GCM object.
7715
 */
7716
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7717
7718
/* GHASH one block of data..
7719
 *
7720
 * XOR block into tag and GMULT with H using pre-computed table.
7721
 *
7722
 * @param [in, out] aes    AES GCM object.
7723
 * @param [in]      block  Block of AAD or cipher text.
7724
 */
7725
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
7726
    do {                                                \
7727
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
7728
        GMULT(AES_TAG(aes), aes->gcm.M0);               \
7729
    }                                                   \
7730
    while (0)
7731
#endif /* WOLFSSL_AESGCM_STREAM */
7732
/* end GCM_TABLE */
7733
#elif defined(GCM_TABLE_4BIT)
7734
7735
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
7736
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7737
#define GCM_GMULT_LEN(gcm, x, a, len) \
7738
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
7739
#else
7740
/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
7741
 *  R shifts right a reverse bit pair of bytes such that:
7742
 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
7743
 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
7744
 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
7745
 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
7746
 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
7747
 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
7748
 *  To calculate te rest, XOR result for each bit.
7749
 *   e.g. 6 = 4 ^ 2 => 48,c0
7750
 *
7751
 * Second half is same values rotated by 4-bits.
7752
 */
7753
#if defined(BIG_ENDIAN_ORDER) || defined(WC_16BIT_CPU)
7754
static const byte R[16][2] = {
7755
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
7756
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
7757
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
7758
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
7759
};
7760
#else
7761
static const word16 R[32] = {
7762
          0x0000,       0x201c,       0x4038,       0x6024,
7763
          0x8070,       0xa06c,       0xc048,       0xe054,
7764
          0x00e1,       0x20fd,       0x40d9,       0x60c5,
7765
          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
7766
7767
          0x0000,       0xc201,       0x8403,       0x4602,
7768
          0x0807,       0xca06,       0x8c04,       0x4e05,
7769
          0x100e,       0xd20f,       0x940d,       0x560c,
7770
          0x1809,       0xda08,       0x9c0a,       0x5e0b,
7771
};
7772
#endif
7773
7774
/* Multiply in GF(2^128) defined by polynomial:
7775
 *   x^128 + x^7 + x^2 + x^1 + 1.
7776
 *
7777
 * H: hash key = encrypt(key, 0)
7778
 * x = x * H in field
7779
 *
7780
 * x: cumulative result
7781
 * m: 4-bit table
7782
 *    [0..15] * H
7783
 */
7784
#if defined(BIG_ENDIAN_ORDER) || defined(WC_16BIT_CPU)
7785
static void GMULT(byte *x, byte m[16][WC_AES_BLOCK_SIZE])
7786
{
7787
    int i, j, n;
7788
    byte Z[WC_AES_BLOCK_SIZE];
7789
    byte a;
7790
7791
    XMEMSET(Z, 0, sizeof(Z));
7792
7793
    for (i = 15; i >= 0; i--) {
7794
        for (n = 0; n < 2; n++) {
7795
            if (n == 0)
7796
                xorbuf(Z, m[x[i] & 0xf], WC_AES_BLOCK_SIZE);
7797
            else {
7798
                xorbuf(Z, m[x[i] >> 4], WC_AES_BLOCK_SIZE);
7799
                if (i == 0)
7800
                    break;
7801
            }
7802
            a = Z[15] & 0xf;
7803
7804
            for (j = 15; j > 0; j--)
7805
                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
7806
            Z[0] >>= 4;
7807
7808
            Z[0] ^= R[a][0];
7809
            Z[1] ^= R[a][1];
7810
        }
7811
    }
7812
7813
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
7814
}
7815
#elif defined(WC_32BIT_CPU)
7816
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
7817
{
7818
    int i;
7819
    word32 z8[4] = {0, 0, 0, 0};
7820
    byte a;
7821
    word32* x8 = (word32*)x;
7822
    word32* m8;
7823
    byte xi;
7824
    word32 n7, n6, n5, n4, n3, n2, n1, n0;
7825
7826
    for (i = 15; i > 0; i--) {
7827
        xi = x[i];
7828
7829
        /* XOR in (msn * H) */
7830
        m8 = (word32*)m[xi & 0xf];
7831
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
7832
7833
        /* Cache top byte for remainder calculations - lost in rotate. */
7834
        a = (byte)(z8[3] >> 24);
7835
7836
        /* Rotate Z by 8-bits */
7837
        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
7838
        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
7839
        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
7840
        z8[0] <<= 8;
7841
7842
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
7843
        z8[0] ^= (word32)R[16 + (a & 0xf)];
7844
7845
        xi >>= 4;
7846
        /* XOR in next significant nibble (XORed with H) * remainder */
7847
        m8 = (word32*)m[xi];
7848
        a ^= (byte)(m8[3] >> 20);
7849
        z8[0] ^= (word32)R[a >> 4];
7850
7851
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
7852
        m8 = (word32*)m[16 + xi];
7853
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
7854
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
7855
    }
7856
7857
    xi = x[0];
7858
7859
    /* XOR in most significant nibble * H */
7860
    m8 = (word32*)m[xi & 0xf];
7861
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
7862
7863
    /* Cache top byte for remainder calculations - lost in rotate. */
7864
    a = (z8[3] >> 24) & 0xf;
7865
7866
    /* Rotate z by 4-bits */
7867
    n7 = z8[3] & 0xf0f0f0f0ULL;
7868
    n6 = z8[3] & 0x0f0f0f0fULL;
7869
    n5 = z8[2] & 0xf0f0f0f0ULL;
7870
    n4 = z8[2] & 0x0f0f0f0fULL;
7871
    n3 = z8[1] & 0xf0f0f0f0ULL;
7872
    n2 = z8[1] & 0x0f0f0f0fULL;
7873
    n1 = z8[0] & 0xf0f0f0f0ULL;
7874
    n0 = z8[0] & 0x0f0f0f0fULL;
7875
    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
7876
    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
7877
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
7878
    z8[0] = (n1 >> 4) | (n0 << 12);
7879
7880
    /* XOR in most significant nibble * remainder */
7881
    z8[0] ^= (word32)R[a];
7882
    /* XOR in next significant nibble * H */
7883
    m8 = (word32*)m[xi >> 4];
7884
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
7885
7886
    /* Write back result. */
7887
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
7888
}
7889
#else
7890
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
7891
52.1k
{
7892
52.1k
    int i;
7893
52.1k
    word64 z8[2] = {0, 0};
7894
52.1k
    byte a;
7895
52.1k
    word64* x8 = (word64*)x;
7896
52.1k
    word64* m8;
7897
52.1k
    word64 n0, n1, n2, n3;
7898
52.1k
    byte xi;
7899
7900
835k
    for (i = 15; i > 0; i--) {
7901
782k
        xi = x[i];
7902
7903
        /* XOR in (msn * H) */
7904
782k
        m8 = (word64*)m[xi & 0xf];
7905
782k
        z8[0] ^= m8[0];
7906
782k
        z8[1] ^= m8[1];
7907
7908
        /* Cache top byte for remainder calculations - lost in rotate. */
7909
782k
        a = (byte)(z8[1] >> 56);
7910
7911
        /* Rotate Z by 8-bits */
7912
782k
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
7913
782k
        z8[0] <<= 8;
7914
7915
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
7916
782k
        m8 = (word64*)m[16 + (xi >> 4)];
7917
782k
        z8[0] ^= m8[0];
7918
782k
        z8[1] ^= m8[1];
7919
7920
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
7921
782k
        z8[0] ^= (word64)R[16 + (a & 0xf)];
7922
        /* XOR in next significant nibble (XORed with H) * remainder */
7923
782k
        m8 = (word64*)m[xi >> 4];
7924
782k
        a ^= (byte)(m8[1] >> 52);
7925
782k
        z8[0] ^= (word64)R[a >> 4];
7926
782k
    }
7927
7928
52.1k
    xi = x[0];
7929
7930
    /* XOR in most significant nibble * H */
7931
52.1k
    m8 = (word64*)m[xi & 0xf];
7932
52.1k
    z8[0] ^= m8[0];
7933
52.1k
    z8[1] ^= m8[1];
7934
7935
    /* Cache top byte for remainder calculations - lost in rotate. */
7936
52.1k
    a = (z8[1] >> 56) & 0xf;
7937
7938
    /* Rotate z by 4-bits */
7939
52.1k
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
7940
52.1k
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
7941
52.1k
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
7942
52.1k
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
7943
52.1k
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
7944
52.1k
    z8[0] = (n1 >> 4) | (n0 << 12);
7945
7946
    /* XOR in next significant nibble * H */
7947
52.1k
    m8 = (word64*)m[xi >> 4];
7948
52.1k
    z8[0] ^= m8[0];
7949
52.1k
    z8[1] ^= m8[1];
7950
    /* XOR in most significant nibble * remainder */
7951
52.1k
    z8[0] ^= (word64)R[a];
7952
7953
    /* Write back result. */
7954
52.1k
    x8[0] = z8[0];
7955
52.1k
    x8[1] = z8[1];
7956
52.1k
}
7957
#endif
7958
#endif
7959
7960
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7961
    word32 cSz, byte* s, word32 sSz)
7962
1.56k
{
7963
1.56k
    byte x[WC_AES_BLOCK_SIZE];
7964
1.56k
    byte scratch[WC_AES_BLOCK_SIZE];
7965
1.56k
    word32 blocks, partial;
7966
7967
1.56k
    if (gcm == NULL) {
7968
0
        return;
7969
0
    }
7970
7971
1.56k
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
7972
7973
    /* Hash in A, the Additional Authentication Data */
7974
1.56k
    if (aSz != 0 && a != NULL) {
7975
1.56k
        blocks = aSz / WC_AES_BLOCK_SIZE;
7976
1.56k
        partial = aSz % WC_AES_BLOCK_SIZE;
7977
    #ifdef GCM_GMULT_LEN
7978
        if (blocks > 0) {
7979
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
7980
            a += blocks * WC_AES_BLOCK_SIZE;
7981
        }
7982
        if (partial != 0) {
7983
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7984
            XMEMCPY(scratch, a, partial);
7985
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
7986
        }
7987
    #else
7988
1.56k
        while (blocks--) {
7989
0
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
7990
0
            GMULT(x, gcm->M0);
7991
0
            a += WC_AES_BLOCK_SIZE;
7992
0
        }
7993
1.56k
        if (partial != 0) {
7994
1.56k
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7995
1.56k
            XMEMCPY(scratch, a, partial);
7996
1.56k
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7997
1.56k
            GMULT(x, gcm->M0);
7998
1.56k
        }
7999
1.56k
    #endif
8000
1.56k
    }
8001
8002
    /* Hash in C, the Ciphertext */
8003
1.56k
    if (cSz != 0 && c != NULL) {
8004
1.55k
        blocks = cSz / WC_AES_BLOCK_SIZE;
8005
1.55k
        partial = cSz % WC_AES_BLOCK_SIZE;
8006
    #ifdef GCM_GMULT_LEN
8007
        if (blocks > 0) {
8008
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
8009
            c += blocks * WC_AES_BLOCK_SIZE;
8010
        }
8011
        if (partial != 0) {
8012
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8013
            XMEMCPY(scratch, c, partial);
8014
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8015
        }
8016
    #else
8017
41.1k
        while (blocks--) {
8018
39.5k
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
8019
39.5k
            GMULT(x, gcm->M0);
8020
39.5k
            c += WC_AES_BLOCK_SIZE;
8021
39.5k
        }
8022
1.55k
        if (partial != 0) {
8023
1.46k
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8024
1.46k
            XMEMCPY(scratch, c, partial);
8025
1.46k
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8026
1.46k
            GMULT(x, gcm->M0);
8027
1.46k
        }
8028
1.55k
    #endif
8029
1.55k
    }
8030
8031
    /* Hash in the lengths of A and C in bits */
8032
1.56k
    FlattenSzInBits(&scratch[0], aSz);
8033
1.56k
    FlattenSzInBits(&scratch[8], cSz);
8034
#ifdef GCM_GMULT_LEN
8035
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8036
#else
8037
1.56k
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8038
1.56k
    GMULT(x, gcm->M0);
8039
1.56k
#endif
8040
8041
    /* Copy the result into s. */
8042
1.56k
    XMEMCPY(s, x, sSz);
8043
1.56k
}
8044
8045
#ifdef WOLFSSL_AESGCM_STREAM
8046
/* No extra initialization for 4-bit table implementation.
8047
 *
8048
 * @param [in] aes  AES GCM object.
8049
 */
8050
3.77k
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8051
8052
/* GHASH one block of data..
8053
 *
8054
 * XOR block into tag and GMULT with H using pre-computed table.
8055
 *
8056
 * @param [in, out] aes    AES GCM object.
8057
 * @param [in]      block  Block of AAD or cipher text.
8058
 */
8059
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
8060
8.00k
    do {                                                \
8061
8.00k
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
8062
8.00k
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
8063
8.00k
    }                                                   \
8064
8.00k
    while (0)
8065
#endif /* WOLFSSL_AESGCM_STREAM */
8066
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
8067
8068
#if !defined(FREESCALE_LTC_AES_GCM)
8069
static void GMULT(word64* X, word64* Y)
8070
{
8071
    word64 Z[2] = {0,0};
8072
    word64 V[2];
8073
    int i, j;
8074
    word64 v1;
8075
    V[0] = X[0];  V[1] = X[1];
8076
8077
    for (i = 0; i < 2; i++)
8078
    {
8079
        word64 y = Y[i];
8080
        for (j = 0; j < 64; j++)
8081
        {
8082
#ifndef AES_GCM_GMULT_NCT
8083
            word64 mask = 0 - (y >> 63);
8084
            Z[0] ^= V[0] & mask;
8085
            Z[1] ^= V[1] & mask;
8086
#else
8087
            if (y & 0x8000000000000000ULL) {
8088
                Z[0] ^= V[0];
8089
                Z[1] ^= V[1];
8090
            }
8091
#endif
8092
8093
            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
8094
            V[1] >>= 1;
8095
            V[1] |= V[0] << 63;
8096
            V[0] >>= 1;
8097
            V[0] ^= v1;
8098
            y <<= 1;
8099
        }
8100
    }
8101
    X[0] = Z[0];
8102
    X[1] = Z[1];
8103
}
8104
8105
8106
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8107
    word32 cSz, byte* s, word32 sSz)
8108
{
8109
    word64 x[2] = {0,0};
8110
    word32 blocks, partial;
8111
    word64 bigH[2];
8112
8113
    if (gcm == NULL) {
8114
        return;
8115
    }
8116
8117
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
8118
    #ifdef LITTLE_ENDIAN_ORDER
8119
        ByteReverseWords64(bigH, bigH, WC_AES_BLOCK_SIZE);
8120
    #endif
8121
8122
    /* Hash in A, the Additional Authentication Data */
8123
    if (aSz != 0 && a != NULL) {
8124
        word64 bigA[2];
8125
        blocks = aSz / WC_AES_BLOCK_SIZE;
8126
        partial = aSz % WC_AES_BLOCK_SIZE;
8127
        while (blocks--) {
8128
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
8129
            #ifdef LITTLE_ENDIAN_ORDER
8130
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
8131
            #endif
8132
            x[0] ^= bigA[0];
8133
            x[1] ^= bigA[1];
8134
            GMULT(x, bigH);
8135
            a += WC_AES_BLOCK_SIZE;
8136
        }
8137
        if (partial != 0) {
8138
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
8139
            XMEMCPY(bigA, a, partial);
8140
            #ifdef LITTLE_ENDIAN_ORDER
8141
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
8142
            #endif
8143
            x[0] ^= bigA[0];
8144
            x[1] ^= bigA[1];
8145
            GMULT(x, bigH);
8146
        }
8147
#ifdef OPENSSL_EXTRA
8148
        /* store AAD partial tag for next call */
8149
        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
8150
        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
8151
        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
8152
        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
8153
#endif
8154
    }
8155
8156
    /* Hash in C, the Ciphertext */
8157
    if (cSz != 0 && c != NULL) {
8158
        word64 bigC[2];
8159
        blocks = cSz / WC_AES_BLOCK_SIZE;
8160
        partial = cSz % WC_AES_BLOCK_SIZE;
8161
#ifdef OPENSSL_EXTRA
8162
        /* Start from last AAD partial tag */
8163
        if(gcm->aadLen) {
8164
            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
8165
            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
8166
         }
8167
#endif
8168
        while (blocks--) {
8169
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
8170
            #ifdef LITTLE_ENDIAN_ORDER
8171
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
8172
            #endif
8173
            x[0] ^= bigC[0];
8174
            x[1] ^= bigC[1];
8175
            GMULT(x, bigH);
8176
            c += WC_AES_BLOCK_SIZE;
8177
        }
8178
        if (partial != 0) {
8179
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
8180
            XMEMCPY(bigC, c, partial);
8181
            #ifdef LITTLE_ENDIAN_ORDER
8182
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
8183
            #endif
8184
            x[0] ^= bigC[0];
8185
            x[1] ^= bigC[1];
8186
            GMULT(x, bigH);
8187
        }
8188
    }
8189
8190
    /* Hash in the lengths in bits of A and C */
8191
    {
8192
        word64 len[2];
8193
        len[0] = aSz; len[1] = cSz;
8194
#ifdef OPENSSL_EXTRA
8195
        if (gcm->aadLen)
8196
            len[0] = (word64)gcm->aadLen;
8197
#endif
8198
        /* Lengths are in bytes. Convert to bits. */
8199
        len[0] *= 8;
8200
        len[1] *= 8;
8201
8202
        x[0] ^= len[0];
8203
        x[1] ^= len[1];
8204
        GMULT(x, bigH);
8205
    }
8206
    #ifdef LITTLE_ENDIAN_ORDER
8207
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
8208
    #endif
8209
    XMEMCPY(s, x, sSz);
8210
}
8211
#endif /* !FREESCALE_LTC_AES_GCM */
8212
8213
#ifdef WOLFSSL_AESGCM_STREAM
8214
8215
#ifdef LITTLE_ENDIAN_ORDER
8216
8217
/* No extra initialization for small implementation.
8218
 *
8219
 * @param [in] aes  AES GCM object.
8220
 */
8221
#define GHASH_INIT_EXTRA(aes)                                               \
8222
    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, WC_AES_BLOCK_SIZE)
8223
8224
/* GHASH one block of data..
8225
 *
8226
 * XOR block into tag and GMULT with H.
8227
 *
8228
 * @param [in, out] aes    AES GCM object.
8229
 * @param [in]      block  Block of AAD or cipher text.
8230
 */
8231
#define GHASH_ONE_BLOCK_SW(aes, block)                              \
8232
    do {                                                            \
8233
        word64* x = (word64*)AES_TAG(aes);                          \
8234
        word64* h = (word64*)aes->gcm.H;                            \
8235
        word64 block64[2];                                          \
8236
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);                 \
8237
        ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE);    \
8238
        x[0] ^= block64[0];                                         \
8239
        x[1] ^= block64[1];                                         \
8240
        GMULT(x, h);                                                \
8241
    }                                                               \
8242
    while (0)
8243
8244
#ifdef OPENSSL_EXTRA
8245
/* GHASH in AAD and cipher text lengths in bits.
8246
 *
8247
 * Convert tag back to little-endian.
8248
 *
8249
 * @param [in, out] aes  AES GCM object.
8250
 */
8251
#define GHASH_LEN_BLOCK(aes)                            \
8252
    do {                                                \
8253
        word64* x = (word64*)AES_TAG(aes);              \
8254
        word64* h = (word64*)aes->gcm.H;                \
8255
        word64 len[2];                                  \
8256
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8257
        if (aes->gcm.aadLen)                            \
8258
            len[0] = (word64)aes->gcm.aadLen;           \
8259
        /* Lengths are in bytes. Convert to bits. */    \
8260
        len[0] *= 8;                                    \
8261
        len[1] *= 8;                                    \
8262
                                                        \
8263
        x[0] ^= len[0];                                 \
8264
        x[1] ^= len[1];                                 \
8265
        GMULT(x, h);                                    \
8266
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
8267
    }                                                   \
8268
    while (0)
8269
#else
8270
/* GHASH in AAD and cipher text lengths in bits.
8271
 *
8272
 * Convert tag back to little-endian.
8273
 *
8274
 * @param [in, out] aes  AES GCM object.
8275
 */
8276
#define GHASH_LEN_BLOCK(aes)                            \
8277
    do {                                                \
8278
        word64* x = (word64*)AES_TAG(aes);              \
8279
        word64* h = (word64*)aes->gcm.H;                \
8280
        word64 len[2];                                  \
8281
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8282
        /* Lengths are in bytes. Convert to bits. */    \
8283
        len[0] *= 8;                                    \
8284
        len[1] *= 8;                                    \
8285
                                                        \
8286
        x[0] ^= len[0];                                 \
8287
        x[1] ^= len[1];                                 \
8288
        GMULT(x, h);                                    \
8289
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
8290
    }                                                   \
8291
    while (0)
8292
#endif
8293
8294
#else
8295
8296
/* No extra initialization for small implementation.
8297
 *
8298
 * @param [in] aes  AES GCM object.
8299
 */
8300
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8301
8302
/* GHASH one block of data..
8303
 *
8304
 * XOR block into tag and GMULT with H.
8305
 *
8306
 * @param [in, out] aes    AES GCM object.
8307
 * @param [in]      block  Block of AAD or cipher text.
8308
 */
8309
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
8310
    do {                                                \
8311
        word64* x = (word64*)AES_TAG(aes);              \
8312
        word64* h = (word64*)aes->gcm.H;                \
8313
        word64 block64[2];                              \
8314
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);        \
8315
        x[0] ^= block64[0];                             \
8316
        x[1] ^= block64[1];                             \
8317
        GMULT(x, h);                                    \
8318
    }                                                   \
8319
    while (0)
8320
8321
#ifdef OPENSSL_EXTRA
8322
/* GHASH in AAD and cipher text lengths in bits.
8323
 *
8324
 * Convert tag back to little-endian.
8325
 *
8326
 * @param [in, out] aes  AES GCM object.
8327
 */
8328
#define GHASH_LEN_BLOCK(aes)                            \
8329
    do {                                                \
8330
        word64* x = (word64*)AES_TAG(aes);              \
8331
        word64* h = (word64*)aes->gcm.H;                \
8332
        word64 len[2];                                  \
8333
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8334
        if (aes->gcm.aadLen)                            \
8335
            len[0] = (word64)aes->gcm.aadLen;           \
8336
        /* Lengths are in bytes. Convert to bits. */    \
8337
        len[0] *= 8;                                    \
8338
        len[1] *= 8;                                    \
8339
                                                        \
8340
        x[0] ^= len[0];                                 \
8341
        x[1] ^= len[1];                                 \
8342
        GMULT(x, h);                                    \
8343
    }                                                   \
8344
    while (0)
8345
#else
8346
/* GHASH in AAD and cipher text lengths in bits.
8347
 *
8348
 * Convert tag back to little-endian.
8349
 *
8350
 * @param [in, out] aes  AES GCM object.
8351
 */
8352
#define GHASH_LEN_BLOCK(aes)                            \
8353
    do {                                                \
8354
        word64* x = (word64*)AES_TAG(aes);              \
8355
        word64* h = (word64*)aes->gcm.H;                \
8356
        word64 len[2];                                  \
8357
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8358
        /* Lengths are in bytes. Convert to bits. */    \
8359
        len[0] *= 8;                                    \
8360
        len[1] *= 8;                                    \
8361
                                                        \
8362
        x[0] ^= len[0];                                 \
8363
        x[1] ^= len[1];                                 \
8364
        GMULT(x, h);                                    \
8365
    }                                                   \
8366
    while (0)
8367
#endif
8368
8369
#endif /* !LITTLE_ENDIAN_ORDER */
8370
8371
#endif /* WOLFSSL_AESGCM_STREAM */
8372
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
8373
#else /* GCM_WORD32 */
8374
8375
static void GMULT(word32* X, word32* Y)
8376
{
8377
    word32 Z[4] = {0,0,0,0};
8378
    word32 V[4];
8379
    int i, j;
8380
8381
    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
8382
8383
    for (i = 0; i < 4; i++)
8384
    {
8385
        word32 y = Y[i];
8386
        for (j = 0; j < 32; j++)
8387
        {
8388
            if (y & 0x80000000) {
8389
                Z[0] ^= V[0];
8390
                Z[1] ^= V[1];
8391
                Z[2] ^= V[2];
8392
                Z[3] ^= V[3];
8393
            }
8394
8395
            if (V[3] & 0x00000001) {
8396
                V[3] >>= 1;
8397
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
8398
                V[2] >>= 1;
8399
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
8400
                V[1] >>= 1;
8401
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
8402
                V[0] >>= 1;
8403
                V[0] ^= 0xE1000000;
8404
            } else {
8405
                V[3] >>= 1;
8406
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
8407
                V[2] >>= 1;
8408
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
8409
                V[1] >>= 1;
8410
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
8411
                V[0] >>= 1;
8412
            }
8413
            y <<= 1;
8414
        }
8415
    }
8416
    X[0] = Z[0];
8417
    X[1] = Z[1];
8418
    X[2] = Z[2];
8419
    X[3] = Z[3];
8420
}
8421
8422
8423
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8424
    word32 cSz, byte* s, word32 sSz)
8425
{
8426
    word32 x[4] = {0,0,0,0};
8427
    word32 blocks, partial;
8428
    word32 bigH[4];
8429
8430
    if (gcm == NULL) {
8431
        return;
8432
    }
8433
8434
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
8435
    #ifdef LITTLE_ENDIAN_ORDER
8436
        ByteReverseWords(bigH, bigH, WC_AES_BLOCK_SIZE);
8437
    #endif
8438
8439
    /* Hash in A, the Additional Authentication Data */
8440
    if (aSz != 0 && a != NULL) {
8441
        word32 bigA[4];
8442
        blocks = aSz / WC_AES_BLOCK_SIZE;
8443
        partial = aSz % WC_AES_BLOCK_SIZE;
8444
        while (blocks--) {
8445
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
8446
            #ifdef LITTLE_ENDIAN_ORDER
8447
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
8448
            #endif
8449
            x[0] ^= bigA[0];
8450
            x[1] ^= bigA[1];
8451
            x[2] ^= bigA[2];
8452
            x[3] ^= bigA[3];
8453
            GMULT(x, bigH);
8454
            a += WC_AES_BLOCK_SIZE;
8455
        }
8456
        if (partial != 0) {
8457
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
8458
            XMEMCPY(bigA, a, partial);
8459
            #ifdef LITTLE_ENDIAN_ORDER
8460
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
8461
            #endif
8462
            x[0] ^= bigA[0];
8463
            x[1] ^= bigA[1];
8464
            x[2] ^= bigA[2];
8465
            x[3] ^= bigA[3];
8466
            GMULT(x, bigH);
8467
        }
8468
    }
8469
8470
    /* Hash in C, the Ciphertext */
8471
    if (cSz != 0 && c != NULL) {
8472
        word32 bigC[4];
8473
        blocks = cSz / WC_AES_BLOCK_SIZE;
8474
        partial = cSz % WC_AES_BLOCK_SIZE;
8475
        while (blocks--) {
8476
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
8477
            #ifdef LITTLE_ENDIAN_ORDER
8478
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
8479
            #endif
8480
            x[0] ^= bigC[0];
8481
            x[1] ^= bigC[1];
8482
            x[2] ^= bigC[2];
8483
            x[3] ^= bigC[3];
8484
            GMULT(x, bigH);
8485
            c += WC_AES_BLOCK_SIZE;
8486
        }
8487
        if (partial != 0) {
8488
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
8489
            XMEMCPY(bigC, c, partial);
8490
            #ifdef LITTLE_ENDIAN_ORDER
8491
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
8492
            #endif
8493
            x[0] ^= bigC[0];
8494
            x[1] ^= bigC[1];
8495
            x[2] ^= bigC[2];
8496
            x[3] ^= bigC[3];
8497
            GMULT(x, bigH);
8498
        }
8499
    }
8500
8501
    /* Hash in the lengths in bits of A and C */
8502
    {
8503
        word32 len[4];
8504
8505
        /* Lengths are in bytes. Convert to bits. */
8506
        len[0] = (aSz >> (8*sizeof(aSz) - 3));
8507
        len[1] = aSz << 3;
8508
        len[2] = (cSz >> (8*sizeof(cSz) - 3));
8509
        len[3] = cSz << 3;
8510
8511
        x[0] ^= len[0];
8512
        x[1] ^= len[1];
8513
        x[2] ^= len[2];
8514
        x[3] ^= len[3];
8515
        GMULT(x, bigH);
8516
    }
8517
    #ifdef LITTLE_ENDIAN_ORDER
8518
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
8519
    #endif
8520
    XMEMCPY(s, x, sSz);
8521
}
8522
8523
#ifdef WOLFSSL_AESGCM_STREAM
8524
#ifdef LITTLE_ENDIAN_ORDER
8525
/* Little-endian 32-bit word implementation requires byte reversal of H.
8526
 *
8527
 * H is all-zeros block encrypted with key.
8528
 *
8529
 * @param [in, out] aes  AES GCM object.
8530
 */
8531
#define GHASH_INIT_EXTRA(aes) \
8532
    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, WC_AES_BLOCK_SIZE)
8533
8534
/* GHASH one block of data..
8535
 *
8536
 * XOR block, in big-endian form, into tag and GMULT with H.
8537
 *
8538
 * @param [in, out] aes    AES GCM object.
8539
 * @param [in]      block  Block of AAD or cipher text.
8540
 */
8541
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
8542
    do {                                                        \
8543
        word32* x = (word32*)AES_TAG(aes);                      \
8544
        word32* h = (word32*)aes->gcm.H;                        \
8545
        word32 bigEnd[4];                                       \
8546
        XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE);              \
8547
        ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE);    \
8548
        x[0] ^= bigEnd[0];                                      \
8549
        x[1] ^= bigEnd[1];                                      \
8550
        x[2] ^= bigEnd[2];                                      \
8551
        x[3] ^= bigEnd[3];                                      \
8552
        GMULT(x, h);                                            \
8553
    }                                                           \
8554
    while (0)
8555
8556
/* GHASH in AAD and cipher text lengths in bits.
8557
 *
8558
 * Convert tag back to little-endian.
8559
 *
8560
 * @param [in, out] aes  AES GCM object.
8561
 */
8562
#define GHASH_LEN_BLOCK(aes)                                \
8563
    do {                                                    \
8564
        word32 len[4];                                      \
8565
        word32* x = (word32*)AES_TAG(aes);                  \
8566
        word32* h = (word32*)aes->gcm.H;                    \
8567
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
8568
        len[1] = aes->aSz << 3;                             \
8569
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
8570
        len[3] = aes->cSz << 3;                             \
8571
        x[0] ^= len[0];                                     \
8572
        x[1] ^= len[1];                                     \
8573
        x[2] ^= len[2];                                     \
8574
        x[3] ^= len[3];                                     \
8575
        GMULT(x, h);                                        \
8576
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);          \
8577
    }                                                       \
8578
    while (0)
8579
#else
8580
/* No extra initialization for 32-bit word implementation.
8581
 *
8582
 * @param [in] aes  AES GCM object.
8583
 */
8584
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8585
8586
/* GHASH one block of data..
8587
 *
8588
 * XOR block into tag and GMULT with H.
8589
 *
8590
 * @param [in, out] aes    AES GCM object.
8591
 * @param [in]      block  Block of AAD or cipher text.
8592
 */
8593
#define GHASH_ONE_BLOCK_SW(aes, block)                      \
8594
    do {                                                    \
8595
        word32* x = (word32*)AES_TAG(aes);                  \
8596
        word32* h = (word32*)aes->gcm.H;                    \
8597
        word32 block32[4];                                  \
8598
        XMEMCPY(block32, block, WC_AES_BLOCK_SIZE);         \
8599
        x[0] ^= block32[0];                                 \
8600
        x[1] ^= block32[1];                                 \
8601
        x[2] ^= block32[2];                                 \
8602
        x[3] ^= block32[3];                                 \
8603
        GMULT(x, h);                                        \
8604
    }                                                       \
8605
    while (0)
8606
8607
/* GHASH in AAD and cipher text lengths in bits.
8608
 *
8609
 * @param [in, out] aes  AES GCM object.
8610
 */
8611
#define GHASH_LEN_BLOCK(aes)                                \
8612
    do {                                                    \
8613
        word32 len[4];                                      \
8614
        word32* x = (word32*)AES_TAG(aes);                  \
8615
        word32* h = (word32*)aes->gcm.H;                    \
8616
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
8617
        len[1] = aes->aSz << 3;                             \
8618
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
8619
        len[3] = aes->cSz << 3;                             \
8620
        x[0] ^= len[0];                                     \
8621
        x[1] ^= len[1];                                     \
8622
        x[2] ^= len[2];                                     \
8623
        x[3] ^= len[3];                                     \
8624
        GMULT(x, h);                                        \
8625
    }                                                       \
8626
    while (0)
8627
#endif /* LITTLE_ENDIAN_ORDER */
8628
#endif /* WOLFSSL_AESGCM_STREAM */
8629
#endif /* end GCM_WORD32 */
8630
#endif
8631
8632
#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
8633
#ifdef WOLFSSL_AESGCM_STREAM
8634
#ifndef GHASH_LEN_BLOCK
8635
/* Hash in the lengths of the AAD and cipher text in bits.
8636
 *
8637
 * Default implementation.
8638
 *
8639
 * @param [in, out] aes  AES GCM object.
8640
 */
8641
#define GHASH_LEN_BLOCK(aes)                      \
8642
978
    do {                                          \
8643
978
        byte scratch[WC_AES_BLOCK_SIZE];          \
8644
978
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
8645
978
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
8646
978
        GHASH_ONE_BLOCK(aes, scratch);            \
8647
978
    }                                             \
8648
978
    while (0)
8649
#endif
8650
8651
/* Initialize a GHASH for streaming operations.
8652
 *
8653
 * @param [in, out] aes  AES GCM object.
8654
 */
8655
2.80k
static void GHASH_INIT(Aes* aes) {
8656
    /* Set tag to all zeros as initial value. */
8657
2.80k
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
8658
    /* Reset counts of AAD and cipher text. */
8659
2.80k
    aes->aOver = 0;
8660
2.80k
    aes->cOver = 0;
8661
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
8662
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8663
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
8664
        ; /* Don't do extra initialization. */
8665
    }
8666
    else
8667
#endif
8668
2.80k
    {
8669
        /* Extra initialization based on implementation. */
8670
2.80k
        GHASH_INIT_EXTRA(aes);
8671
2.80k
    }
8672
2.80k
}
8673
8674
/* Update the GHASH with AAD and/or cipher text.
8675
 *
8676
 * @param [in,out] aes   AES GCM object.
8677
 * @param [in]     a     Additional authentication data buffer.
8678
 * @param [in]     aSz   Size of data in AAD buffer.
8679
 * @param [in]     c     Cipher text buffer.
8680
 * @param [in]     cSz   Size of data in cipher text buffer.
8681
 */
8682
static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
8683
    word32 cSz)
8684
18.8k
{
8685
18.8k
    word32 blocks;
8686
18.8k
    word32 partial;
8687
8688
    /* Hash in A, the Additional Authentication Data */
8689
18.8k
    if (aSz != 0 && a != NULL) {
8690
        /* Update count of AAD we have hashed. */
8691
683
        aes->aSz += aSz;
8692
        /* Check if we have unprocessed data. */
8693
683
        if (aes->aOver > 0) {
8694
            /* Calculate amount we can use - fill up the block. */
8695
425
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
8696
425
            if (sz > aSz) {
8697
184
                sz = (byte)aSz;
8698
184
            }
8699
            /* Copy extra into last GHASH block array and update count. */
8700
425
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
8701
425
            aes->aOver = (byte)(aes->aOver + sz);
8702
425
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
8703
                /* We have filled up the block and can process. */
8704
241
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
8705
                /* Reset count. */
8706
241
                aes->aOver = 0;
8707
241
            }
8708
            /* Used up some data. */
8709
425
            aSz -= sz;
8710
425
            a += sz;
8711
425
        }
8712
8713
        /* Calculate number of blocks of AAD and the leftover. */
8714
683
        blocks = aSz / WC_AES_BLOCK_SIZE;
8715
683
        partial = aSz % WC_AES_BLOCK_SIZE;
8716
        /* GHASH full blocks now. */
8717
4.15k
        while (blocks--) {
8718
3.47k
            GHASH_ONE_BLOCK(aes, a);
8719
3.47k
            a += WC_AES_BLOCK_SIZE;
8720
3.47k
        }
8721
683
        if (partial != 0) {
8722
            /* Cache the partial block. */
8723
430
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
8724
430
            aes->aOver = (byte)partial;
8725
430
        }
8726
683
    }
8727
18.8k
    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
8728
        /* No more AAD coming and we have a partial block. */
8729
        /* Fill the rest of the block with zeros. */
8730
91
        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
8731
91
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
8732
        /* GHASH last AAD block. */
8733
91
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
8734
        /* Clear partial count for next time through. */
8735
91
        aes->aOver = 0;
8736
91
    }
8737
8738
    /* Hash in C, the Ciphertext */
8739
18.8k
    if (cSz != 0 && c != NULL) {
8740
        /* Update count of cipher text we have hashed. */
8741
2.38k
        aes->cSz += cSz;
8742
2.38k
        if (aes->cOver > 0) {
8743
            /* Calculate amount we can use - fill up the block. */
8744
1.39k
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
8745
1.39k
            if (sz > cSz) {
8746
914
                sz = (byte)cSz;
8747
914
            }
8748
1.39k
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
8749
            /* Update count of unused encrypted counter. */
8750
1.39k
            aes->cOver = (byte)(aes->cOver + sz);
8751
1.39k
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
8752
                /* We have filled up the block and can process. */
8753
482
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
8754
                /* Reset count. */
8755
482
                aes->cOver = 0;
8756
482
            }
8757
            /* Used up some data. */
8758
1.39k
            cSz -= sz;
8759
1.39k
            c += sz;
8760
1.39k
        }
8761
8762
        /* Calculate number of blocks of cipher text and the leftover. */
8763
2.38k
        blocks = cSz / WC_AES_BLOCK_SIZE;
8764
2.38k
        partial = cSz % WC_AES_BLOCK_SIZE;
8765
        /* GHASH full blocks now. */
8766
4.60k
        while (blocks--) {
8767
2.21k
            GHASH_ONE_BLOCK(aes, c);
8768
2.21k
            c += WC_AES_BLOCK_SIZE;
8769
2.21k
        }
8770
2.38k
        if (partial != 0) {
8771
            /* Cache the partial block. */
8772
945
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
8773
945
            aes->cOver = (byte)partial;
8774
945
        }
8775
2.38k
    }
8776
18.8k
}
8777
8778
/* Finalize the GHASH calculation.
8779
 *
8780
 * Complete hashing cipher text and hash the AAD and cipher text lengths.
8781
 *
8782
 * @param [in, out] aes  AES GCM object.
8783
 * @param [out]     s    Authentication tag.
8784
 * @param [in]      sSz  Size of authentication tag required.
8785
 */
8786
static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
8787
978
{
8788
    /* AAD block incomplete when > 0 */
8789
978
    byte over = aes->aOver;
8790
8791
978
    if (aes->cOver > 0) {
8792
        /* Cipher text block incomplete. */
8793
445
        over = aes->cOver;
8794
445
    }
8795
978
    if (over > 0) {
8796
        /* Zeroize the unused part of the block. */
8797
528
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
8798
528
            (size_t)WC_AES_BLOCK_SIZE - over);
8799
        /* Hash the last block of cipher text. */
8800
528
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
8801
528
    }
8802
    /* Hash in the lengths of AAD and cipher text in bits */
8803
978
    GHASH_LEN_BLOCK(aes);
8804
    /* Copy the result into s. */
8805
978
    XMEMCPY(s, AES_TAG(aes), sSz);
8806
    /* reset aes->gcm.H in case of reuse */
8807
978
    GHASH_INIT_EXTRA(aes);
8808
978
}
8809
#endif /* WOLFSSL_AESGCM_STREAM */
8810
8811
8812
#ifdef FREESCALE_LTC_AES_GCM
8813
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
8814
                   const byte* iv, word32 ivSz,
8815
                   byte* authTag, word32 authTagSz,
8816
                   const byte* authIn, word32 authInSz)
8817
{
8818
    status_t status;
8819
    word32 keySize;
8820
8821
    /* argument checks */
8822
    if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE || ivSz == 0) {
8823
        return BAD_FUNC_ARG;
8824
    }
8825
8826
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
8827
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
8828
        return BAD_FUNC_ARG;
8829
    }
8830
8831
    status = wc_AesGetKeySize(aes, &keySize);
8832
    if (status)
8833
        return status;
8834
8835
    status = wolfSSL_CryptHwMutexLock();
8836
    if (status != 0)
8837
        return status;
8838
8839
    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
8840
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
8841
    wolfSSL_CryptHwMutexUnLock();
8842
8843
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
8844
}
8845
8846
#else
8847
8848
#ifdef STM32_CRYPTO_AES_GCM
8849
8850
/* this function supports inline encrypt */
8851
static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
8852
                                  Aes* aes, byte* out, const byte* in, word32 sz,
8853
                                  const byte* iv, word32 ivSz,
8854
                                  byte* authTag, word32 authTagSz,
8855
                                  const byte* authIn, word32 authInSz)
8856
{
8857
    int ret;
8858
#ifdef WOLFSSL_STM32_CUBEMX
8859
    CRYP_HandleTypeDef hcryp;
8860
#else
8861
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
8862
#endif
8863
    word32 keySize;
8864
#ifdef WOLFSSL_STM32_CUBEMX
8865
    int status = HAL_OK;
8866
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
8867
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
8868
#else
8869
    int status = SUCCESS;
8870
#endif
8871
    word32 partial = sz % WC_AES_BLOCK_SIZE;
8872
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
8873
    word32 ctrInit[WC_AES_BLOCK_SIZE/sizeof(word32)];
8874
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
8875
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
8876
    byte* authInPadded = NULL;
8877
    int authPadSz, wasAlloc = 0, useSwGhash = 0;
8878
8879
    ret = wc_AesGetKeySize(aes, &keySize);
8880
    if (ret != 0)
8881
        return ret;
8882
8883
#ifdef WOLFSSL_STM32_CUBEMX
8884
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
8885
    if (ret != 0)
8886
        return ret;
8887
#endif
8888
8889
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
8890
    if (ivSz == GCM_NONCE_MID_SZ) {
8891
        byte* pCtr = (byte*)ctr;
8892
        XMEMCPY(ctr, iv, ivSz);
8893
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
8894
    }
8895
    else {
8896
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
8897
    }
8898
    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
8899
8900
    /* Authentication buffer */
8901
#if STM_CRYPT_HEADER_WIDTH == 1
8902
    authPadSz = 0; /* CubeHAL supports byte mode */
8903
#else
8904
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
8905
#endif
8906
#ifdef WOLFSSL_STM32MP13
8907
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
8908
     * minimum of 16 bytes for the auth */
8909
    if ((authInSz > 0) && (authInSz < 16)) {
8910
        authPadSz = 16 - authInSz;
8911
    }
8912
#endif
8913
    if (authPadSz != 0) {
8914
        if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) {
8915
            authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
8916
        }
8917
        if (authPadSz <= sizeof(authhdr)) {
8918
            authInPadded = (byte*)authhdr;
8919
        }
8920
        else {
8921
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
8922
                DYNAMIC_TYPE_TMP_BUFFER);
8923
            if (authInPadded == NULL) {
8924
                wolfSSL_CryptHwMutexUnLock();
8925
                return MEMORY_E;
8926
            }
8927
            wasAlloc = 1;
8928
        }
8929
        XMEMSET(authInPadded, 0, authPadSz);
8930
        XMEMCPY(authInPadded, authIn, authInSz);
8931
    } else {
8932
        authPadSz = authInSz;
8933
        authInPadded = (byte*)authIn;
8934
    }
8935
8936
    /* for cases where hardware cannot be used for authTag calculate it */
8937
    /* if IV is not 12 calculate GHASH using software */
8938
    if (ivSz != GCM_NONCE_MID_SZ
8939
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
8940
        /* or hardware that does not support partial block */
8941
        || sz == 0 || partial != 0
8942
    #endif
8943
    #if STM_CRYPT_HEADER_WIDTH == 4
8944
        /* or authIn is not a multiple of 4  */
8945
        || authPadSz != authInSz
8946
    #endif
8947
    ) {
8948
        useSwGhash = 1;
8949
    }
8950
8951
    /* Hardware requires counter + 1 */
8952
    IncrementGcmCounter((byte*)ctr);
8953
8954
    ret = wolfSSL_CryptHwMutexLock();
8955
    if (ret != 0) {
8956
        return ret;
8957
    }
8958
8959
#ifdef WOLFSSL_STM32_CUBEMX
8960
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8961
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
8962
8963
#if defined(STM32_HAL_V2)
8964
    hcryp.Init.Algorithm = CRYP_AES_GCM;
8965
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
8966
    #ifdef CRYP_KEYIVCONFIG_ONCE
8967
    /* allows repeated calls to HAL_CRYP_Encrypt */
8968
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
8969
    #endif
8970
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
8971
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8972
    HAL_CRYP_Init(&hcryp);
8973
8974
    #ifndef CRYP_KEYIVCONFIG_ONCE
8975
    /* GCM payload phase - can handle partial blocks */
8976
    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
8977
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
8978
    #else
8979
    /* GCM payload phase - blocks */
8980
    if (blocks) {
8981
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
8982
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
8983
    }
8984
    /* GCM payload phase - partial remainder */
8985
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
8986
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8987
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
8988
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
8989
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
8990
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
8991
    }
8992
    #endif
8993
    if (status == HAL_OK && !useSwGhash) {
8994
        /* Compute the authTag */
8995
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
8996
            STM32_HAL_TIMEOUT);
8997
    }
8998
#elif defined(STM32_CRYPTO_AES_ONLY)
8999
    /* Set the CRYP parameters */
9000
    hcryp.Init.HeaderSize = authPadSz;
9001
    if (authPadSz == 0)
9002
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
9003
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
9004
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
9005
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
9006
    HAL_CRYP_Init(&hcryp);
9007
9008
    /* GCM init phase */
9009
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9010
    if (status == HAL_OK) {
9011
        /* GCM header phase */
9012
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
9013
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9014
    }
9015
    if (status == HAL_OK) {
9016
        /* GCM payload phase - blocks */
9017
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
9018
        if (blocks) {
9019
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
9020
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9021
        }
9022
    }
9023
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
9024
        /* GCM payload phase - partial remainder */
9025
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9026
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9027
        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
9028
                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
9029
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9030
    }
9031
    if (status == HAL_OK && !useSwGhash) {
9032
        /* GCM final phase */
9033
        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
9034
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
9035
    }
9036
#else
9037
    hcryp.Init.HeaderSize = authPadSz;
9038
    HAL_CRYP_Init(&hcryp);
9039
    if (blocks) {
9040
        /* GCM payload phase - blocks */
9041
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
9042
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9043
    }
9044
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
9045
        /* GCM payload phase - partial remainder */
9046
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9047
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9048
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
9049
            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
9050
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9051
    }
9052
    if (status == HAL_OK && !useSwGhash) {
9053
        /* Compute the authTag */
9054
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
9055
    }
9056
#endif
9057
9058
    if (status != HAL_OK)
9059
        ret = AES_GCM_AUTH_E;
9060
    HAL_CRYP_DeInit(&hcryp);
9061
9062
#else /* Standard Peripheral Library */
9063
    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
9064
    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
9065
                         (uint8_t*)keyCopy,      keySize * 8,
9066
                         (uint8_t*)in,           sz,
9067
                         (uint8_t*)authInPadded, authInSz,
9068
                         (uint8_t*)out,          (uint8_t*)tag);
9069
    if (status != SUCCESS)
9070
        ret = AES_GCM_AUTH_E;
9071
#endif /* WOLFSSL_STM32_CUBEMX */
9072
    wolfSSL_CryptHwMutexUnLock();
9073
    wc_Stm32_Aes_Cleanup();
9074
9075
    if (ret == 0) {
9076
        /* return authTag */
9077
        if (authTag) {
9078
            if (useSwGhash) {
9079
                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
9080
                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
9081
                if (ret == 0) {
9082
                    xorbuf(authTag, tag, authTagSz);
9083
                }
9084
            }
9085
            else {
9086
                /* use hardware calculated tag */
9087
                XMEMCPY(authTag, tag, authTagSz);
9088
            }
9089
        }
9090
    }
9091
9092
    /* Free memory */
9093
    if (wasAlloc) {
9094
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
9095
    }
9096
9097
    return ret;
9098
}
9099
9100
#endif /* STM32_CRYPTO_AES_GCM */
9101
9102
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
9103
#ifdef WOLFSSL_AESNI
9104
/* For performance reasons, this code needs to be not inlined. */
9105
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
9106
                      Aes* aes, byte* out, const byte* in, word32 sz,
9107
                      const byte* iv, word32 ivSz,
9108
                      byte* authTag, word32 authTagSz,
9109
                      const byte* authIn, word32 authInSz);
9110
#else
9111
static
9112
#endif
9113
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
9114
                      Aes* aes, byte* out, const byte* in, word32 sz,
9115
                      const byte* iv, word32 ivSz,
9116
                      byte* authTag, word32 authTagSz,
9117
                      const byte* authIn, word32 authInSz)
9118
761
{
9119
761
    int ret = 0;
9120
761
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
9121
761
    word32 partial = sz % WC_AES_BLOCK_SIZE;
9122
761
    const byte* p = in;
9123
761
    byte* c = out;
9124
761
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
9125
761
    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
9126
761
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
9127
9128
761
    if (ivSz == GCM_NONCE_MID_SZ) {
9129
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
9130
761
        XMEMCPY(counter, iv, ivSz);
9131
761
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
9132
761
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
9133
761
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
9134
761
    }
9135
0
    else {
9136
        /* Counter is GHASH of IV. */
9137
0
#ifdef OPENSSL_EXTRA
9138
0
        word32 aadTemp = aes->gcm.aadLen;
9139
0
        aes->gcm.aadLen = 0;
9140
0
#endif
9141
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
9142
0
#ifdef OPENSSL_EXTRA
9143
0
        aes->gcm.aadLen = aadTemp;
9144
0
#endif
9145
0
    }
9146
761
    XMEMCPY(initialCounter, counter, WC_AES_BLOCK_SIZE);
9147
9148
#ifdef WOLFSSL_PIC32MZ_CRYPT
9149
    if (blocks) {
9150
        /* use initial IV for HW, but don't use it below */
9151
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
9152
9153
        ret = wc_Pic32AesCrypt(
9154
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
9155
            out, in, (blocks * WC_AES_BLOCK_SIZE),
9156
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
9157
        if (ret != 0)
9158
            return ret;
9159
    }
9160
    /* process remainder using partial handling */
9161
#endif
9162
9163
761
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
9164
    /* some hardware acceleration can gain performance from doing AES encryption
9165
     * of the whole buffer at once */
9166
761
    if (c != p && blocks > 0) { /* can not handle inline encryption */
9167
0
        while (blocks--) {
9168
0
            IncrementGcmCounter(counter);
9169
0
            XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
9170
0
            c += WC_AES_BLOCK_SIZE;
9171
0
        }
9172
9173
        /* reset number of blocks and then do encryption */
9174
0
        blocks = sz / WC_AES_BLOCK_SIZE;
9175
0
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
9176
0
        xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
9177
0
        p += WC_AES_BLOCK_SIZE * blocks;
9178
0
    }
9179
761
    else
9180
761
#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
9181
761
    {
9182
30.0k
        while (blocks--) {
9183
29.2k
            IncrementGcmCounter(counter);
9184
29.2k
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
9185
29.2k
            ret = wc_AesEncrypt(aes, counter, scratch);
9186
29.2k
            if (ret != 0)
9187
0
                return ret;
9188
29.2k
            xorbufout(c, scratch, p, WC_AES_BLOCK_SIZE);
9189
29.2k
        #endif
9190
29.2k
            p += WC_AES_BLOCK_SIZE;
9191
29.2k
            c += WC_AES_BLOCK_SIZE;
9192
29.2k
        }
9193
761
    }
9194
9195
761
    if (partial != 0) {
9196
703
        IncrementGcmCounter(counter);
9197
703
        ret = wc_AesEncrypt(aes, counter, scratch);
9198
703
        if (ret != 0)
9199
0
            return ret;
9200
703
        xorbufout(c, scratch, p, partial);
9201
703
    }
9202
761
    if (authTag) {
9203
761
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
9204
761
        ret = wc_AesEncrypt(aes, initialCounter, scratch);
9205
761
        if (ret != 0)
9206
0
            return ret;
9207
761
        xorbuf(authTag, scratch, authTagSz);
9208
761
#ifdef OPENSSL_EXTRA
9209
761
        if (!in && !sz)
9210
            /* store AAD size for next call */
9211
0
            aes->gcm.aadLen = authInSz;
9212
761
#endif
9213
761
    }
9214
9215
761
    return ret;
9216
761
}
9217
#elif defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
9218
static int AES_GCM_encrypt_AARCH32(Aes* aes, byte* out, const byte* in,
9219
    word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
9220
    const byte* authIn, word32 authInSz)
9221
{
9222
    word32 blocks;
9223
    word32 partial;
9224
    byte counter[WC_AES_BLOCK_SIZE];
9225
    byte initialCounter[WC_AES_BLOCK_SIZE];
9226
    byte x[WC_AES_BLOCK_SIZE];
9227
    byte scratch[WC_AES_BLOCK_SIZE];
9228
9229
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
9230
    if (ivSz == GCM_NONCE_MID_SZ) {
9231
        XMEMCPY(initialCounter, iv, ivSz);
9232
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
9233
    }
9234
    else {
9235
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
9236
    }
9237
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
9238
9239
    /* Hash in the Additional Authentication Data */
9240
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9241
    if (authInSz != 0 && authIn != NULL) {
9242
        blocks = authInSz / WC_AES_BLOCK_SIZE;
9243
        partial = authInSz % WC_AES_BLOCK_SIZE;
9244
        if (blocks > 0) {
9245
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
9246
            authIn += blocks * WC_AES_BLOCK_SIZE;
9247
        }
9248
        if (partial != 0) {
9249
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9250
            XMEMCPY(scratch, authIn, partial);
9251
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9252
        }
9253
    }
9254
9255
    /* do as many blocks as possible */
9256
    blocks = sz / WC_AES_BLOCK_SIZE;
9257
    partial = sz % WC_AES_BLOCK_SIZE;
9258
    if (blocks > 0) {
9259
        AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
9260
            (const unsigned char*)aes->key, aes->rounds, counter);
9261
        GCM_GMULT_LEN(&aes->gcm, x, out, blocks * WC_AES_BLOCK_SIZE);
9262
        in += blocks * WC_AES_BLOCK_SIZE;
9263
        out += blocks * WC_AES_BLOCK_SIZE;
9264
    }
9265
    /* take care of partial block sizes leftover */
9266
    if (partial != 0) {
9267
        AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
9268
            (const unsigned char*)aes->key, aes->rounds, counter);
9269
        XMEMCPY(out, scratch, partial);
9270
9271
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9272
        XMEMCPY(scratch, out, partial);
9273
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9274
    }
9275
9276
    /* Hash in the lengths of A and C in bits */
9277
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9278
    FlattenSzInBits(&scratch[0], authInSz);
9279
    FlattenSzInBits(&scratch[8], sz);
9280
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9281
    if (authTagSz > WC_AES_BLOCK_SIZE) {
9282
        XMEMCPY(authTag, x, WC_AES_BLOCK_SIZE);
9283
    }
9284
    else {
9285
        /* authTagSz can be smaller than WC_AES_BLOCK_SIZE */
9286
        XMEMCPY(authTag, x, authTagSz);
9287
    }
9288
9289
    /* Auth tag calculation. */
9290
    AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
9291
        (const unsigned char*)aes->key, aes->rounds);
9292
    xorbuf(authTag, scratch, authTagSz);
9293
9294
    return 0;
9295
}
9296
#endif
9297
9298
/* Software AES - GCM Encrypt */
9299
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
9300
                   const byte* iv, word32 ivSz,
9301
                   byte* authTag, word32 authTagSz,
9302
                   const byte* authIn, word32 authInSz)
9303
761
{
9304
761
    int ret;
9305
9306
    /* argument checks */
9307
761
    if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE || ivSz == 0 ||
9308
761
        ((authTagSz > 0) && (authTag == NULL)) ||
9309
761
        ((authInSz > 0) && (authIn == NULL)))
9310
0
    {
9311
0
        return BAD_FUNC_ARG;
9312
0
    }
9313
9314
761
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
9315
0
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
9316
0
        return BAD_FUNC_ARG;
9317
0
    }
9318
9319
761
#ifdef WOLF_CRYPTO_CB
9320
761
    #ifndef WOLF_CRYPTO_CB_FIND
9321
761
    if (aes->devId != INVALID_DEVID)
9322
0
    #endif
9323
0
    {
9324
0
        int crypto_cb_ret =
9325
0
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
9326
0
                                      authTagSz, authIn, authInSz);
9327
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
9328
0
            return crypto_cb_ret;
9329
        /* fall-through when unavailable */
9330
0
    }
9331
761
#endif
9332
9333
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
9334
    /* if async and byte count above threshold */
9335
    /* only 12-byte IV is supported in HW */
9336
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
9337
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
9338
    #if defined(HAVE_CAVIUM)
9339
        #ifdef HAVE_CAVIUM_V
9340
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
9341
            return NitroxAesGcmEncrypt(aes, out, in, sz,
9342
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
9343
                authTag, authTagSz, authIn, authInSz);
9344
        }
9345
        #endif
9346
    #elif defined(HAVE_INTEL_QA)
9347
        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
9348
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
9349
            authTag, authTagSz, authIn, authInSz);
9350
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
9351
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
9352
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
9353
            sw->aes.aes = aes;
9354
            sw->aes.out = out;
9355
            sw->aes.in = in;
9356
            sw->aes.sz = sz;
9357
            sw->aes.iv = iv;
9358
            sw->aes.ivSz = ivSz;
9359
            sw->aes.authTag = authTag;
9360
            sw->aes.authTagSz = authTagSz;
9361
            sw->aes.authIn = authIn;
9362
            sw->aes.authInSz = authInSz;
9363
            return WC_PENDING_E;
9364
        }
9365
    #endif
9366
    }
9367
#endif /* WOLFSSL_ASYNC_CRYPT */
9368
9369
#ifdef WOLFSSL_SILABS_SE_ACCEL
9370
    return wc_AesGcmEncrypt_silabs(
9371
        aes, out, in, sz,
9372
        iv, ivSz,
9373
        authTag, authTagSz,
9374
        authIn, authInSz);
9375
#endif
9376
9377
#ifdef STM32_CRYPTO_AES_GCM
9378
    return wc_AesGcmEncrypt_STM32(
9379
        aes, out, in, sz, iv, ivSz,
9380
        authTag, authTagSz, authIn, authInSz);
9381
#endif /* STM32_CRYPTO_AES_GCM */
9382
9383
761
    VECTOR_REGISTERS_PUSH;
9384
9385
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
9386
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
9387
    AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
9388
        authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
9389
        aes->rounds);
9390
    ret = 0;
9391
#else
9392
    ret = AES_GCM_encrypt_AARCH32(aes, out, in, sz, iv, ivSz, authTag,
9393
        authTagSz, authIn, authInSz);
9394
#endif
9395
#else
9396
#ifdef WOLFSSL_AESNI
9397
    if (aes->use_aesni) {
9398
#ifdef HAVE_INTEL_AVX2
9399
        if (IS_INTEL_AVX2(intel_flags)) {
9400
            AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
9401
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
9402
            ret = 0;
9403
        }
9404
        else
9405
#endif
9406
#if defined(HAVE_INTEL_AVX1)
9407
        if (IS_INTEL_AVX1(intel_flags)) {
9408
            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
9409
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
9410
            ret = 0;
9411
        } else
9412
#endif
9413
        {
9414
            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
9415
                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
9416
            ret = 0;
9417
        }
9418
    }
9419
    else
9420
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
9421
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
9422
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
9423
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
9424
        if (aes->use_sha3_hw_crypto) {
9425
            AES_GCM_encrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
9426
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
9427
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
9428
        }
9429
        else
9430
    #endif
9431
        {
9432
            AES_GCM_encrypt_AARCH64(in, out, sz, iv, ivSz, authTag, authTagSz,
9433
                authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
9434
                (byte*)aes->reg, aes->rounds);
9435
        }
9436
        ret = 0;
9437
    }
9438
    else
9439
#endif /* WOLFSSL_AESNI */
9440
761
    {
9441
761
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
9442
761
                                authIn, authInSz);
9443
761
    }
9444
761
#endif
9445
9446
761
    VECTOR_REGISTERS_POP;
9447
9448
761
    return ret;
9449
761
}
9450
#endif
9451
9452
9453
/* AES GCM Decrypt */
9454
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
9455
#ifdef FREESCALE_LTC_AES_GCM
9456
int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
9457
                   const byte* iv, word32 ivSz,
9458
                   const byte* authTag, word32 authTagSz,
9459
                   const byte* authIn, word32 authInSz)
9460
{
9461
    int ret;
9462
    word32 keySize;
9463
    status_t status;
9464
9465
    /* argument checks */
9466
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
9467
     * in and out are don't cares, as this is is the GMAC case. */
9468
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
9469
        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE || authTagSz == 0 ||
9470
        ivSz == 0 || ((authInSz > 0) && (authIn == NULL)))
9471
    {
9472
        return BAD_FUNC_ARG;
9473
    }
9474
9475
    ret = wc_AesGetKeySize(aes, &keySize);
9476
    if (ret != 0) {
9477
        return ret;
9478
    }
9479
9480
    status = wolfSSL_CryptHwMutexLock();
9481
    if (status != 0)
9482
        return status;
9483
9484
    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
9485
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
9486
    wolfSSL_CryptHwMutexUnLock();
9487
9488
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
9489
}
9490
9491
#else
9492
9493
#ifdef STM32_CRYPTO_AES_GCM
9494
/* this function supports inline decrypt */
9495
static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
9496
                                  Aes* aes, byte* out,
9497
                                  const byte* in, word32 sz,
9498
                                  const byte* iv, word32 ivSz,
9499
                                  const byte* authTag, word32 authTagSz,
9500
                                  const byte* authIn, word32 authInSz)
9501
{
9502
    int ret;
9503
#ifdef WOLFSSL_STM32_CUBEMX
9504
    int status = HAL_OK;
9505
    CRYP_HandleTypeDef hcryp;
9506
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
9507
#else
9508
    int status = SUCCESS;
9509
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
9510
#endif
9511
    word32 keySize;
9512
    word32 partial = sz % WC_AES_BLOCK_SIZE;
9513
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
9514
    word32 tagExpected[WC_AES_BLOCK_SIZE/sizeof(word32)];
9515
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
9516
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
9517
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
9518
    byte* authInPadded = NULL;
9519
    int authPadSz, wasAlloc = 0, tagComputed = 0;
9520
9521
    ret = wc_AesGetKeySize(aes, &keySize);
9522
    if (ret != 0)
9523
        return ret;
9524
9525
#ifdef WOLFSSL_STM32_CUBEMX
9526
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
9527
    if (ret != 0)
9528
        return ret;
9529
#endif
9530
9531
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
9532
    if (ivSz == GCM_NONCE_MID_SZ) {
9533
        byte* pCtr = (byte*)ctr;
9534
        XMEMCPY(ctr, iv, ivSz);
9535
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
9536
    }
9537
    else {
9538
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
9539
    }
9540
9541
    /* Make copy of expected authTag, which could get corrupted in some
9542
     * Cube HAL versions without proper partial block support.
9543
     * For TLS blocks the authTag is after the output buffer, so save it */
9544
    XMEMCPY(tagExpected, authTag, authTagSz);
9545
9546
    /* Authentication buffer */
9547
#if STM_CRYPT_HEADER_WIDTH == 1
9548
    authPadSz = 0; /* CubeHAL supports byte mode */
9549
#else
9550
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
9551
#endif
9552
#ifdef WOLFSSL_STM32MP13
9553
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
9554
     * minimum of 16 bytes for the auth */
9555
    if ((authInSz > 0) && (authInSz < 16)) {
9556
        authPadSz = 16 - authInSz;
9557
    }
9558
#else
9559
    if (authPadSz != 0) {
9560
        authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
9561
    }
9562
    else {
9563
        authPadSz = authInSz;
9564
    }
9565
#endif
9566
9567
    /* for cases where hardware cannot be used for authTag calculate it */
9568
    /* if IV is not 12 calculate GHASH using software */
9569
    if (ivSz != GCM_NONCE_MID_SZ
9570
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
9571
        /* or hardware that does not support partial block */
9572
        || sz == 0 || partial != 0
9573
    #endif
9574
    #if STM_CRYPT_HEADER_WIDTH == 4
9575
        /* or authIn is not a multiple of 4  */
9576
        || authPadSz != authInSz
9577
    #endif
9578
    ) {
9579
        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
9580
        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
9581
        if (ret != 0)
9582
            return ret;
9583
        xorbuf(tag, partialBlock, sizeof(tag));
9584
        tagComputed = 1;
9585
    }
9586
9587
    /* if using hardware for authentication tag make sure its aligned and zero padded */
9588
    if (authPadSz != authInSz && !tagComputed) {
9589
        if (authPadSz <= sizeof(authhdr)) {
9590
            authInPadded = (byte*)authhdr;
9591
        }
9592
        else {
9593
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
9594
                DYNAMIC_TYPE_TMP_BUFFER);
9595
            if (authInPadded == NULL) {
9596
                wolfSSL_CryptHwMutexUnLock();
9597
                return MEMORY_E;
9598
            }
9599
            wasAlloc = 1;
9600
        }
9601
        XMEMSET(authInPadded, 0, authPadSz);
9602
        XMEMCPY(authInPadded, authIn, authInSz);
9603
    } else {
9604
        authInPadded = (byte*)authIn;
9605
    }
9606
9607
    /* Hardware requires counter + 1 */
9608
    IncrementGcmCounter((byte*)ctr);
9609
9610
    ret = wolfSSL_CryptHwMutexLock();
9611
    if (ret != 0) {
9612
        return ret;
9613
    }
9614
9615
#ifdef WOLFSSL_STM32_CUBEMX
9616
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
9617
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
9618
9619
#if defined(STM32_HAL_V2)
9620
    hcryp.Init.Algorithm = CRYP_AES_GCM;
9621
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
9622
    #ifdef CRYP_KEYIVCONFIG_ONCE
9623
    /* allows repeated calls to HAL_CRYP_Decrypt */
9624
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
9625
    #endif
9626
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
9627
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
9628
    HAL_CRYP_Init(&hcryp);
9629
9630
    #ifndef CRYP_KEYIVCONFIG_ONCE
9631
    /* GCM payload phase - can handle partial blocks */
9632
    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
9633
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
9634
    #else
9635
    /* GCM payload phase - blocks */
9636
    if (blocks) {
9637
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
9638
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
9639
    }
9640
    /* GCM payload phase - partial remainder */
9641
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
9642
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9643
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9644
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
9645
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
9646
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9647
    }
9648
    #endif
9649
    if (status == HAL_OK && !tagComputed) {
9650
        /* Compute the authTag */
9651
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
9652
            STM32_HAL_TIMEOUT);
9653
    }
9654
#elif defined(STM32_CRYPTO_AES_ONLY)
9655
    /* Set the CRYP parameters */
9656
    hcryp.Init.HeaderSize = authPadSz;
9657
    if (authPadSz == 0)
9658
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
9659
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
9660
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
9661
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
9662
    HAL_CRYP_Init(&hcryp);
9663
9664
    /* GCM init phase */
9665
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9666
    if (status == HAL_OK) {
9667
        /* GCM header phase */
9668
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
9669
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9670
    }
9671
    if (status == HAL_OK) {
9672
        /* GCM payload phase - blocks */
9673
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
9674
        if (blocks) {
9675
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
9676
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9677
        }
9678
    }
9679
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
9680
        /* GCM payload phase - partial remainder */
9681
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9682
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9683
        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
9684
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
9685
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9686
    }
9687
    if (status == HAL_OK && tagComputed == 0) {
9688
        /* GCM final phase */
9689
        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
9690
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
9691
    }
9692
#else
9693
    hcryp.Init.HeaderSize = authPadSz;
9694
    HAL_CRYP_Init(&hcryp);
9695
    if (blocks) {
9696
        /* GCM payload phase - blocks */
9697
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
9698
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9699
    }
9700
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
9701
        /* GCM payload phase - partial remainder */
9702
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9703
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9704
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
9705
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
9706
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9707
    }
9708
    if (status == HAL_OK && tagComputed == 0) {
9709
        /* Compute the authTag */
9710
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
9711
    }
9712
#endif
9713
9714
    if (status != HAL_OK)
9715
        ret = AES_GCM_AUTH_E;
9716
9717
    HAL_CRYP_DeInit(&hcryp);
9718
9719
#else /* Standard Peripheral Library */
9720
    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
9721
9722
    /* Input size and auth size need to be the actual sizes, even though
9723
     * they are not block aligned, because this length (in bits) is used
9724
     * in the final GHASH. */
9725
    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
9726
    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
9727
                         (uint8_t*)keyCopy,      keySize * 8,
9728
                         (uint8_t*)in,           sz,
9729
                         (uint8_t*)authInPadded, authInSz,
9730
                         (uint8_t*)out,          (uint8_t*)partialBlock);
9731
    if (status != SUCCESS)
9732
        ret = AES_GCM_AUTH_E;
9733
    if (tagComputed == 0)
9734
        XMEMCPY(tag, partialBlock, authTagSz);
9735
#endif /* WOLFSSL_STM32_CUBEMX */
9736
    wolfSSL_CryptHwMutexUnLock();
9737
    wc_Stm32_Aes_Cleanup();
9738
9739
    /* Check authentication tag */
9740
    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
9741
        ret = AES_GCM_AUTH_E;
9742
    }
9743
9744
    /* Free memory */
9745
    if (wasAlloc) {
9746
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
9747
    }
9748
9749
    return ret;
9750
}
9751
9752
#endif /* STM32_CRYPTO_AES_GCM */
9753
9754
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
9755
#ifdef WOLFSSL_AESNI
9756
/* For performance reasons, this code needs to be not inlined. */
9757
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
9758
                      Aes* aes, byte* out, const byte* in, word32 sz,
9759
                      const byte* iv, word32 ivSz,
9760
                      const byte* authTag, word32 authTagSz,
9761
                      const byte* authIn, word32 authInSz);
9762
#else
9763
static
9764
#endif
9765
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
9766
                      Aes* aes, byte* out, const byte* in, word32 sz,
9767
                      const byte* iv, word32 ivSz,
9768
                      const byte* authTag, word32 authTagSz,
9769
                      const byte* authIn, word32 authInSz)
9770
800
{
9771
800
    int ret;
9772
800
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
9773
800
    word32 partial = sz % WC_AES_BLOCK_SIZE;
9774
800
    const byte* c = in;
9775
800
    byte* p = out;
9776
800
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
9777
800
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
9778
800
    ALIGN16 byte Tprime[WC_AES_BLOCK_SIZE];
9779
800
    ALIGN16 byte EKY0[WC_AES_BLOCK_SIZE];
9780
800
    volatile sword32 res;
9781
9782
800
    if (ivSz == GCM_NONCE_MID_SZ) {
9783
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
9784
800
        XMEMCPY(counter, iv, ivSz);
9785
800
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
9786
800
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
9787
800
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
9788
800
    }
9789
0
    else {
9790
        /* Counter is GHASH of IV. */
9791
0
#ifdef OPENSSL_EXTRA
9792
0
        word32 aadTemp = aes->gcm.aadLen;
9793
0
        aes->gcm.aadLen = 0;
9794
0
#endif
9795
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
9796
0
#ifdef OPENSSL_EXTRA
9797
0
        aes->gcm.aadLen = aadTemp;
9798
0
#endif
9799
0
    }
9800
9801
    /* Calc the authTag again using received auth data and the cipher text */
9802
800
    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
9803
800
    ret = wc_AesEncrypt(aes, counter, EKY0);
9804
800
    if (ret != 0)
9805
0
        return ret;
9806
800
    xorbuf(Tprime, EKY0, sizeof(Tprime));
9807
#ifdef WC_AES_GCM_DEC_AUTH_EARLY
9808
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
9809
     * the pairwise bytes in the strings.
9810
     */
9811
    res = ConstantCompare(authTag, Tprime, authTagSz);
9812
    /* convert positive retval from ConstantCompare() to all-1s word, in
9813
     * constant time.
9814
     */
9815
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
9816
    ret = res & AES_GCM_AUTH_E;
9817
    if (ret != 0)
9818
        return ret;
9819
#endif
9820
9821
800
#ifdef OPENSSL_EXTRA
9822
800
    if (!out) {
9823
        /* authenticated, non-confidential data */
9824
        /* store AAD size for next call */
9825
0
        aes->gcm.aadLen = authInSz;
9826
0
    }
9827
800
#endif
9828
9829
#if defined(WOLFSSL_PIC32MZ_CRYPT)
9830
    if (blocks) {
9831
        /* use initial IV for HW, but don't use it below */
9832
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
9833
9834
        ret = wc_Pic32AesCrypt(
9835
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
9836
            out, in, (blocks * WC_AES_BLOCK_SIZE),
9837
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
9838
        if (ret != 0)
9839
            return ret;
9840
    }
9841
    /* process remainder using partial handling */
9842
#endif
9843
9844
800
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
9845
    /* some hardware acceleration can gain performance from doing AES encryption
9846
     * of the whole buffer at once */
9847
800
    if (c != p && blocks > 0) { /* can not handle inline decryption */
9848
0
        while (blocks--) {
9849
0
            IncrementGcmCounter(counter);
9850
0
            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
9851
0
            p += WC_AES_BLOCK_SIZE;
9852
0
        }
9853
9854
        /* reset number of blocks and then do encryption */
9855
0
        blocks = sz / WC_AES_BLOCK_SIZE;
9856
9857
0
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
9858
0
        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
9859
0
        c += WC_AES_BLOCK_SIZE * blocks;
9860
0
    }
9861
800
    else
9862
800
#endif /* HAVE_AES_ECB && !PIC32MZ */
9863
800
    {
9864
11.1k
        while (blocks--) {
9865
10.3k
            IncrementGcmCounter(counter);
9866
10.3k
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
9867
10.3k
            ret = wc_AesEncrypt(aes, counter, scratch);
9868
10.3k
            if (ret != 0)
9869
0
                return ret;
9870
10.3k
            xorbufout(p, scratch, c, WC_AES_BLOCK_SIZE);
9871
10.3k
        #endif
9872
10.3k
            p += WC_AES_BLOCK_SIZE;
9873
10.3k
            c += WC_AES_BLOCK_SIZE;
9874
10.3k
        }
9875
800
    }
9876
9877
800
    if (partial != 0) {
9878
759
        IncrementGcmCounter(counter);
9879
759
        ret = wc_AesEncrypt(aes, counter, scratch);
9880
759
        if (ret != 0)
9881
0
            return ret;
9882
759
        xorbuf(scratch, c, partial);
9883
759
        XMEMCPY(p, scratch, partial);
9884
759
    }
9885
9886
800
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
9887
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
9888
     * the pairwise bytes in the strings.
9889
     */
9890
800
    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
9891
    /* convert positive retval from ConstantCompare() to all-1s word, in
9892
     * constant time.
9893
     */
9894
800
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
9895
    /* now use res as a mask for constant time return of ret, unless tag
9896
     * mismatch, whereupon AES_GCM_AUTH_E is returned.
9897
     */
9898
800
    ret = (ret & ~res) | (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
9899
800
#endif
9900
800
    return ret;
9901
800
}
9902
#elif defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
9903
static int AES_GCM_decrypt_AARCH32(Aes* aes, byte* out, const byte* in,
9904
    word32 sz, const byte* iv, word32 ivSz, const byte* authTag,
9905
    word32 authTagSz, const byte* authIn, word32 authInSz)
9906
{
9907
    word32 blocks;
9908
    word32 partial;
9909
    byte counter[WC_AES_BLOCK_SIZE];
9910
    byte initialCounter[WC_AES_BLOCK_SIZE];
9911
    byte scratch[WC_AES_BLOCK_SIZE];
9912
    byte x[WC_AES_BLOCK_SIZE];
9913
9914
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
9915
    if (ivSz == GCM_NONCE_MID_SZ) {
9916
        XMEMCPY(initialCounter, iv, ivSz);
9917
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
9918
    }
9919
    else {
9920
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
9921
    }
9922
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
9923
9924
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9925
    /* Hash in the Additional Authentication Data */
9926
    if (authInSz != 0 && authIn != NULL) {
9927
        blocks = authInSz / WC_AES_BLOCK_SIZE;
9928
        partial = authInSz % WC_AES_BLOCK_SIZE;
9929
        if (blocks > 0) {
9930
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
9931
            authIn += blocks * WC_AES_BLOCK_SIZE;
9932
        }
9933
        if (partial != 0) {
9934
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9935
            XMEMCPY(scratch, authIn, partial);
9936
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9937
        }
9938
    }
9939
9940
    blocks = sz / WC_AES_BLOCK_SIZE;
9941
    partial = sz % WC_AES_BLOCK_SIZE;
9942
    /* do as many blocks as possible */
9943
    if (blocks > 0) {
9944
        GCM_GMULT_LEN(&aes->gcm, x, in, blocks * WC_AES_BLOCK_SIZE);
9945
9946
        AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
9947
            (const unsigned char*)aes->key, aes->rounds, counter);
9948
        in += blocks * WC_AES_BLOCK_SIZE;
9949
        out += blocks * WC_AES_BLOCK_SIZE;
9950
    }
9951
    if (partial != 0) {
9952
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9953
        XMEMCPY(scratch, in, partial);
9954
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9955
9956
        AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
9957
            (const unsigned char*)aes->key, aes->rounds, counter);
9958
        XMEMCPY(out, scratch, partial);
9959
    }
9960
9961
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9962
    FlattenSzInBits(&scratch[0], authInSz);
9963
    FlattenSzInBits(&scratch[8], sz);
9964
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9965
    AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
9966
        (const unsigned char*)aes->key, aes->rounds);
9967
    xorbuf(x, scratch, authTagSz);
9968
    if (authTag != NULL) {
9969
        if (ConstantCompare(authTag, x, authTagSz) != 0) {
9970
            return AES_GCM_AUTH_E;
9971
        }
9972
    }
9973
9974
    return 0;
9975
}
9976
#endif
9977
9978
/* Software AES - GCM Decrypt */
9979
int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
9980
                     const byte* iv, word32 ivSz,
9981
                     const byte* authTag, word32 authTagSz,
9982
                     const byte* authIn, word32 authInSz)
9983
800
{
9984
800
    int ret;
9985
#ifdef WOLFSSL_AESNI
9986
    int res = WC_NO_ERR_TRACE(AES_GCM_AUTH_E);
9987
#endif
9988
9989
    /* argument checks */
9990
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
9991
     * in and out are don't cares, as this is is the GMAC case. */
9992
800
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
9993
800
        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE || authTagSz == 0 ||
9994
800
        ivSz == 0) {
9995
9996
0
        return BAD_FUNC_ARG;
9997
0
    }
9998
9999
800
#ifdef WOLF_CRYPTO_CB
10000
800
    #ifndef WOLF_CRYPTO_CB_FIND
10001
800
    if (aes->devId != INVALID_DEVID)
10002
0
    #endif
10003
0
    {
10004
0
        int crypto_cb_ret =
10005
0
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
10006
0
                                      authTag, authTagSz, authIn, authInSz);
10007
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
10008
0
            return crypto_cb_ret;
10009
        /* fall-through when unavailable */
10010
0
    }
10011
800
#endif
10012
10013
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
10014
    /* if async and byte count above threshold */
10015
    /* only 12-byte IV is supported in HW */
10016
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
10017
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
10018
    #if defined(HAVE_CAVIUM)
10019
        #ifdef HAVE_CAVIUM_V
10020
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
10021
            return NitroxAesGcmDecrypt(aes, out, in, sz,
10022
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10023
                authTag, authTagSz, authIn, authInSz);
10024
        }
10025
        #endif
10026
    #elif defined(HAVE_INTEL_QA)
10027
        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
10028
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10029
            authTag, authTagSz, authIn, authInSz);
10030
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
10031
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
10032
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
10033
            sw->aes.aes = aes;
10034
            sw->aes.out = out;
10035
            sw->aes.in = in;
10036
            sw->aes.sz = sz;
10037
            sw->aes.iv = iv;
10038
            sw->aes.ivSz = ivSz;
10039
            sw->aes.authTag = (byte*)authTag;
10040
            sw->aes.authTagSz = authTagSz;
10041
            sw->aes.authIn = authIn;
10042
            sw->aes.authInSz = authInSz;
10043
            return WC_PENDING_E;
10044
        }
10045
    #endif
10046
    }
10047
#endif /* WOLFSSL_ASYNC_CRYPT */
10048
10049
#ifdef WOLFSSL_SILABS_SE_ACCEL
10050
    return wc_AesGcmDecrypt_silabs(
10051
        aes, out, in, sz, iv, ivSz,
10052
        authTag, authTagSz, authIn, authInSz);
10053
10054
#endif
10055
10056
#ifdef STM32_CRYPTO_AES_GCM
10057
    /* The STM standard peripheral library API's doesn't support partial blocks */
10058
    return wc_AesGcmDecrypt_STM32(
10059
        aes, out, in, sz, iv, ivSz,
10060
        authTag, authTagSz, authIn, authInSz);
10061
#endif /* STM32_CRYPTO_AES_GCM */
10062
10063
800
    VECTOR_REGISTERS_PUSH;
10064
10065
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
10066
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
10067
    ret = AES_GCM_decrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
10068
        authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
10069
        (byte*)aes->reg, aes->rounds);
10070
#else
10071
    ret = AES_GCM_decrypt_AARCH32(aes, out, in, sz, iv, ivSz, authTag,
10072
        authTagSz, authIn, authInSz);
10073
#endif
10074
#else
10075
#ifdef WOLFSSL_AESNI
10076
    if (aes->use_aesni) {
10077
#ifdef HAVE_INTEL_AVX2
10078
        if (IS_INTEL_AVX2(intel_flags)) {
10079
            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10080
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
10081
            if (res == 0)
10082
                ret = AES_GCM_AUTH_E;
10083
            else
10084
                ret = 0;
10085
        }
10086
        else
10087
#endif
10088
#if defined(HAVE_INTEL_AVX1)
10089
        if (IS_INTEL_AVX1(intel_flags)) {
10090
            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10091
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
10092
            if (res == 0)
10093
                ret = AES_GCM_AUTH_E;
10094
            else
10095
                ret = 0;
10096
        }
10097
        else
10098
#endif
10099
        {
10100
            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10101
                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
10102
            if (res == 0)
10103
                ret = AES_GCM_AUTH_E;
10104
            else
10105
                ret = 0;
10106
        }
10107
    }
10108
    else
10109
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10110
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10111
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10112
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
10113
        if (aes->use_sha3_hw_crypto) {
10114
            ret = AES_GCM_decrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
10115
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
10116
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
10117
        }
10118
        else
10119
    #endif
10120
        {
10121
            ret = AES_GCM_decrypt_AARCH64(in, out, sz, iv, ivSz, authTag,
10122
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
10123
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
10124
        }
10125
    }
10126
    else
10127
#endif /* WOLFSSL_AESNI */
10128
800
    {
10129
800
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
10130
800
                                                             authIn, authInSz);
10131
800
    }
10132
800
#endif
10133
10134
800
    VECTOR_REGISTERS_POP;
10135
10136
800
    return ret;
10137
800
}
10138
#endif
10139
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
10140
10141
#ifdef WOLFSSL_AESGCM_STREAM
10142
10143
/* Initialize the AES GCM cipher with an IV. C implementation.
10144
 *
10145
 * @param [in, out] aes   AES object.
10146
 * @param [in]      iv    IV/nonce buffer.
10147
 * @param [in]      ivSz  Length of IV/nonce data.
10148
 */
10149
static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
10150
2.80k
{
10151
2.80k
    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
10152
2.80k
    int ret;
10153
10154
2.80k
    if (ivSz == GCM_NONCE_MID_SZ) {
10155
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
10156
2.80k
        XMEMCPY(counter, iv, ivSz);
10157
2.80k
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
10158
2.80k
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
10159
2.80k
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
10160
2.80k
    }
10161
0
    else {
10162
        /* Counter is GHASH of IV. */
10163
0
    #ifdef OPENSSL_EXTRA
10164
0
        word32 aadTemp = aes->gcm.aadLen;
10165
0
        aes->gcm.aadLen = 0;
10166
0
    #endif
10167
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
10168
0
    #ifdef OPENSSL_EXTRA
10169
0
        aes->gcm.aadLen = aadTemp;
10170
0
    #endif
10171
0
    }
10172
10173
    /* Copy in the counter for use with cipher. */
10174
2.80k
    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
10175
    /* Encrypt initial counter into a buffer for GCM. */
10176
2.80k
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
10177
2.80k
    if (ret != 0)
10178
0
        return ret;
10179
    /* Reset state fields. */
10180
2.80k
    aes->over = 0;
10181
2.80k
    aes->aSz = 0;
10182
2.80k
    aes->cSz = 0;
10183
    /* Initialization for GHASH. */
10184
2.80k
    GHASH_INIT(aes);
10185
10186
2.80k
    return 0;
10187
2.80k
}
10188
10189
/* Update the AES GCM cipher with data. C implementation.
10190
 *
10191
 * Only enciphers data.
10192
 *
10193
 * @param [in, out] aes  AES object.
10194
 * @param [in]      out  Cipher text or plaintext buffer.
10195
 * @param [in]      in   Plaintext or cipher text buffer.
10196
 * @param [in]      sz   Length of data.
10197
 */
10198
static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
10199
    Aes* aes, byte* out, const byte* in, word32 sz)
10200
18.8k
{
10201
18.8k
    word32 blocks;
10202
18.8k
    word32 partial;
10203
18.8k
    int ret;
10204
10205
    /* Check if previous encrypted block was not used up. */
10206
18.8k
    if (aes->over > 0) {
10207
14.7k
        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
10208
14.7k
        if (pSz > sz) pSz = (byte)sz;
10209
10210
        /* Use some/all of last encrypted block. */
10211
14.7k
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
10212
14.7k
        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
10213
10214
        /* Some data used. */
10215
14.7k
        sz  -= pSz;
10216
14.7k
        in  += pSz;
10217
14.7k
        out += pSz;
10218
14.7k
    }
10219
10220
    /* Calculate the number of blocks needing to be encrypted and any leftover.
10221
     */
10222
18.8k
    blocks  = sz / WC_AES_BLOCK_SIZE;
10223
18.8k
    partial = sz & (WC_AES_BLOCK_SIZE - 1);
10224
10225
18.8k
#if defined(HAVE_AES_ECB)
10226
    /* Some hardware acceleration can gain performance from doing AES encryption
10227
     * of the whole buffer at once.
10228
     * Overwrites the cipher text before using plaintext - no inline encryption.
10229
     */
10230
18.8k
    if ((out != in) && blocks > 0) {
10231
374
        word32 b;
10232
        /* Place incrementing counter blocks into cipher text. */
10233
2.08k
        for (b = 0; b < blocks; b++) {
10234
1.70k
            IncrementGcmCounter(AES_COUNTER(aes));
10235
1.70k
            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
10236
1.70k
        }
10237
10238
        /* Encrypt counter blocks. */
10239
374
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
10240
        /* XOR in plaintext. */
10241
374
        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
10242
        /* Skip over processed data. */
10243
374
        in += WC_AES_BLOCK_SIZE * blocks;
10244
374
        out += WC_AES_BLOCK_SIZE * blocks;
10245
374
    }
10246
18.4k
    else
10247
18.4k
#endif /* HAVE_AES_ECB */
10248
18.4k
    {
10249
        /* Encrypt block by block. */
10250
18.9k
        while (blocks--) {
10251
505
            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
10252
505
            IncrementGcmCounter(AES_COUNTER(aes));
10253
            /* Encrypt counter into a buffer. */
10254
505
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
10255
505
            if (ret != 0)
10256
0
                return ret;
10257
            /* XOR plain text into encrypted counter into cipher text buffer. */
10258
505
            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
10259
            /* Data complete. */
10260
505
            in  += WC_AES_BLOCK_SIZE;
10261
505
            out += WC_AES_BLOCK_SIZE;
10262
505
        }
10263
18.4k
    }
10264
10265
18.8k
    if (partial != 0) {
10266
        /* Generate an extra block and use up as much as needed. */
10267
945
        IncrementGcmCounter(AES_COUNTER(aes));
10268
        /* Encrypt counter into cache. */
10269
945
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
10270
945
        if (ret != 0)
10271
0
            return ret;
10272
        /* XOR plain text into encrypted counter into cipher text buffer. */
10273
945
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
10274
        /* Keep amount of encrypted block used. */
10275
945
        aes->over = (byte)partial;
10276
945
    }
10277
10278
18.8k
    return 0;
10279
18.8k
}
10280
10281
/* Calculates authentication tag for AES GCM. C implementation.
10282
 *
10283
 * @param [in, out] aes        AES object.
10284
 * @param [out]     authTag    Buffer to store authentication tag in.
10285
 * @param [in]      authTagSz  Length of tag to create.
10286
 */
10287
static WARN_UNUSED_RESULT int AesGcmFinal_C(
10288
    Aes* aes, byte* authTag, word32 authTagSz)
10289
978
{
10290
    /* Calculate authentication tag. */
10291
978
    GHASH_FINAL(aes, authTag, authTagSz);
10292
    /* XOR in as much of encrypted counter as is required. */
10293
978
    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
10294
978
#ifdef OPENSSL_EXTRA
10295
    /* store AAD size for next call */
10296
978
    aes->gcm.aadLen = aes->aSz;
10297
978
#endif
10298
    /* Zeroize last block to protect sensitive data. */
10299
978
    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
10300
10301
978
    return 0;
10302
978
}
10303
10304
#ifdef WOLFSSL_AESNI
10305
10306
#ifdef __cplusplus
10307
    extern "C" {
10308
#endif
10309
10310
/* Assembly code implementations in: aes_gcm_asm.S */
10311
#ifdef HAVE_INTEL_AVX2
10312
extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
10313
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
10314
    unsigned char* counter, unsigned char* initCtr);
10315
extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
10316
    unsigned int abytes, unsigned char* tag, unsigned char* h);
10317
extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
10318
    unsigned char* out, const unsigned char* in, unsigned char* counter);
10319
extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
10320
    unsigned char* tag, unsigned char* h);
10321
10322
extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
10323
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10324
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10325
extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
10326
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10327
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
10328
#endif
10329
#ifdef HAVE_INTEL_AVX1
10330
extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
10331
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
10332
    unsigned char* counter, unsigned char* initCtr);
10333
extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
10334
    unsigned int abytes, unsigned char* tag, unsigned char* h);
10335
extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
10336
    unsigned char* out, const unsigned char* in, unsigned char* counter);
10337
extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
10338
    unsigned char* tag, unsigned char* h);
10339
10340
extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
10341
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10342
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10343
extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
10344
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10345
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
10346
#endif
10347
extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
10348
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
10349
    unsigned char* counter, unsigned char* initCtr);
10350
extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
10351
    unsigned int abytes, unsigned char* tag, unsigned char* h);
10352
extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
10353
    unsigned char* out, const unsigned char* in, unsigned char* counter);
10354
extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
10355
    unsigned char* tag, unsigned char* h);
10356
10357
extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
10358
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10359
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10360
extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
10361
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10362
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
10363
10364
#ifdef __cplusplus
10365
    } /* extern "C" */
10366
#endif
10367
10368
/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
10369
 *
10370
 * @param [in, out] aes   AES object.
10371
 * @param [in]      iv    IV/nonce buffer.
10372
 * @param [in]      ivSz  Length of IV/nonce data.
10373
 */
10374
static WARN_UNUSED_RESULT int AesGcmInit_aesni(
10375
    Aes* aes, const byte* iv, word32 ivSz)
10376
{
10377
    ASSERT_SAVED_VECTOR_REGISTERS();
10378
10379
    /* Reset state fields. */
10380
    aes->over = 0;
10381
    aes->aSz = 0;
10382
    aes->cSz = 0;
10383
    /* Set tag to all zeros as initial value. */
10384
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
10385
    /* Reset counts of AAD and cipher text. */
10386
    aes->aOver = 0;
10387
    aes->cOver = 0;
10388
10389
#ifdef HAVE_INTEL_AVX2
10390
    if (IS_INTEL_AVX2(intel_flags)) {
10391
        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
10392
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
10393
    }
10394
    else
10395
#endif
10396
#ifdef HAVE_INTEL_AVX1
10397
    if (IS_INTEL_AVX1(intel_flags)) {
10398
        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
10399
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
10400
    }
10401
    else
10402
#endif
10403
    {
10404
        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
10405
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
10406
    }
10407
10408
    return 0;
10409
}
10410
10411
/* Update the AES GCM for encryption with authentication data.
10412
 *
10413
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
10414
 *
10415
 * @param [in, out] aes   AES object.
10416
 * @param [in]      a     Buffer holding authentication data.
10417
 * @param [in]      aSz   Length of authentication data in bytes.
10418
 * @param [in]      endA  Whether no more authentication data is expected.
10419
 */
10420
static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
10421
    Aes* aes, const byte* a, word32 aSz, int endA)
10422
{
10423
    word32 blocks;
10424
    int partial;
10425
10426
    ASSERT_SAVED_VECTOR_REGISTERS();
10427
10428
    if (aSz != 0 && a != NULL) {
10429
        /* Total count of AAD updated. */
10430
        aes->aSz += aSz;
10431
        /* Check if we have unprocessed data. */
10432
        if (aes->aOver > 0) {
10433
            /* Calculate amount we can use - fill up the block. */
10434
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10435
            if (sz > aSz) {
10436
                sz = (byte)aSz;
10437
            }
10438
            /* Copy extra into last GHASH block array and update count. */
10439
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
10440
            aes->aOver = (byte)(aes->aOver + sz);
10441
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
10442
                /* We have filled up the block and can process. */
10443
            #ifdef HAVE_INTEL_AVX2
10444
                if (IS_INTEL_AVX2(intel_flags)) {
10445
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
10446
                                             aes->gcm.H);
10447
                }
10448
                else
10449
            #endif
10450
            #ifdef HAVE_INTEL_AVX1
10451
                if (IS_INTEL_AVX1(intel_flags)) {
10452
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
10453
                                             aes->gcm.H);
10454
                }
10455
                else
10456
            #endif
10457
                {
10458
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
10459
                                              aes->gcm.H);
10460
                }
10461
                /* Reset count. */
10462
                aes->aOver = 0;
10463
            }
10464
            /* Used up some data. */
10465
            aSz -= sz;
10466
            a += sz;
10467
        }
10468
10469
        /* Calculate number of blocks of AAD and the leftover. */
10470
        blocks = aSz / WC_AES_BLOCK_SIZE;
10471
        partial = aSz % WC_AES_BLOCK_SIZE;
10472
        if (blocks > 0) {
10473
            /* GHASH full blocks now. */
10474
        #ifdef HAVE_INTEL_AVX2
10475
            if (IS_INTEL_AVX2(intel_flags)) {
10476
                AES_GCM_aad_update_avx2(a, blocks * WC_AES_BLOCK_SIZE,
10477
                                        AES_TAG(aes), aes->gcm.H);
10478
            }
10479
            else
10480
        #endif
10481
        #ifdef HAVE_INTEL_AVX1
10482
            if (IS_INTEL_AVX1(intel_flags)) {
10483
                AES_GCM_aad_update_avx1(a, blocks * WC_AES_BLOCK_SIZE,
10484
                                        AES_TAG(aes), aes->gcm.H);
10485
            }
10486
            else
10487
        #endif
10488
            {
10489
                AES_GCM_aad_update_aesni(a, blocks * WC_AES_BLOCK_SIZE,
10490
                                         AES_TAG(aes), aes->gcm.H);
10491
            }
10492
            /* Skip over to end of AAD blocks. */
10493
            a += blocks * WC_AES_BLOCK_SIZE;
10494
        }
10495
        if (partial != 0) {
10496
            /* Cache the partial block. */
10497
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
10498
            aes->aOver = (byte)partial;
10499
        }
10500
    }
10501
    if (endA && (aes->aOver > 0)) {
10502
        /* No more AAD coming and we have a partial block. */
10503
        /* Fill the rest of the block with zeros. */
10504
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
10505
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
10506
        /* GHASH last AAD block. */
10507
    #ifdef HAVE_INTEL_AVX2
10508
        if (IS_INTEL_AVX2(intel_flags)) {
10509
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
10510
                                     aes->gcm.H);
10511
        }
10512
        else
10513
    #endif
10514
    #ifdef HAVE_INTEL_AVX1
10515
        if (IS_INTEL_AVX1(intel_flags)) {
10516
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
10517
                                     aes->gcm.H);
10518
        }
10519
        else
10520
    #endif
10521
        {
10522
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
10523
                                      aes->gcm.H);
10524
        }
10525
        /* Clear partial count for next time through. */
10526
        aes->aOver = 0;
10527
    }
10528
10529
    return 0;
10530
}
10531
10532
/* Update the AES GCM for encryption with data and/or authentication data.
10533
 *
10534
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
10535
 *
10536
 * @param [in, out] aes  AES object.
10537
 * @param [out]     c    Buffer to hold cipher text.
10538
 * @param [in]      p    Buffer holding plaintext.
10539
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
10540
 * @param [in]      a    Buffer holding authentication data.
10541
 * @param [in]      aSz  Length of authentication data in bytes.
10542
 */
10543
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
10544
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
10545
{
10546
    word32 blocks;
10547
    int partial;
10548
    int ret;
10549
10550
    ASSERT_SAVED_VECTOR_REGISTERS();
10551
10552
    /* Hash in A, the Authentication Data */
10553
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
10554
    if (ret != 0)
10555
        return ret;
10556
10557
    /* Encrypt plaintext and Hash in C, the Cipher text */
10558
    if (cSz != 0 && c != NULL) {
10559
        /* Update count of cipher text we have hashed. */
10560
        aes->cSz += cSz;
10561
        if (aes->cOver > 0) {
10562
            /* Calculate amount we can use - fill up the block. */
10563
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
10564
            if (sz > cSz) {
10565
                sz = (byte)cSz;
10566
            }
10567
            /* Encrypt some of the plaintext. */
10568
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
10569
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
10570
            /* Update count of unused encrypted counter. */
10571
            aes->cOver = (byte)(aes->cOver + sz);
10572
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
10573
                /* We have filled up the block and can process. */
10574
            #ifdef HAVE_INTEL_AVX2
10575
                if (IS_INTEL_AVX2(intel_flags)) {
10576
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
10577
                                             aes->gcm.H);
10578
                }
10579
                else
10580
            #endif
10581
            #ifdef HAVE_INTEL_AVX1
10582
                if (IS_INTEL_AVX1(intel_flags)) {
10583
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
10584
                                             aes->gcm.H);
10585
                }
10586
                else
10587
            #endif
10588
                {
10589
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
10590
                                              aes->gcm.H);
10591
                }
10592
                /* Reset count. */
10593
                aes->cOver = 0;
10594
            }
10595
            /* Used up some data. */
10596
            cSz -= sz;
10597
            p += sz;
10598
            c += sz;
10599
        }
10600
10601
        /* Calculate number of blocks of plaintext and the leftover. */
10602
        blocks = cSz / WC_AES_BLOCK_SIZE;
10603
        partial = cSz % WC_AES_BLOCK_SIZE;
10604
        if (blocks > 0) {
10605
            /* Encrypt and GHASH full blocks now. */
10606
        #ifdef HAVE_INTEL_AVX2
10607
            if (IS_INTEL_AVX2(intel_flags)) {
10608
                AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
10609
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
10610
                    AES_COUNTER(aes));
10611
            }
10612
            else
10613
        #endif
10614
        #ifdef HAVE_INTEL_AVX1
10615
            if (IS_INTEL_AVX1(intel_flags)) {
10616
                AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
10617
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
10618
                    AES_COUNTER(aes));
10619
            }
10620
            else
10621
        #endif
10622
            {
10623
                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
10624
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
10625
                    AES_COUNTER(aes));
10626
            }
10627
            /* Skip over to end of blocks. */
10628
            p += blocks * WC_AES_BLOCK_SIZE;
10629
            c += blocks * WC_AES_BLOCK_SIZE;
10630
        }
10631
        if (partial != 0) {
10632
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
10633
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
10634
        #ifdef HAVE_INTEL_AVX2
10635
            if (IS_INTEL_AVX2(intel_flags)) {
10636
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
10637
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
10638
            }
10639
            else
10640
        #endif
10641
        #ifdef HAVE_INTEL_AVX1
10642
            if (IS_INTEL_AVX1(intel_flags)) {
10643
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
10644
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
10645
            }
10646
            else
10647
        #endif
10648
            {
10649
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
10650
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
10651
            }
10652
            /* XOR the remaining plaintext to calculate cipher text.
10653
             * Keep cipher text for GHASH of last partial block.
10654
             */
10655
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
10656
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
10657
            /* Update count of the block used. */
10658
            aes->cOver = (byte)partial;
10659
        }
10660
    }
10661
    return 0;
10662
}
10663
10664
/* Finalize the AES GCM for encryption and calculate the authentication tag.
10665
 *
10666
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
10667
 *
10668
 * @param [in, out] aes        AES object.
10669
 * @param [in]      authTag    Buffer to hold authentication tag.
10670
 * @param [in]      authTagSz  Length of authentication tag in bytes.
10671
 * @return  0 on success.
10672
 */
10673
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
10674
    Aes* aes, byte* authTag, word32 authTagSz)
10675
{
10676
    /* AAD block incomplete when > 0 */
10677
    byte over = aes->aOver;
10678
10679
    ASSERT_SAVED_VECTOR_REGISTERS();
10680
10681
    if (aes->cOver > 0) {
10682
        /* Cipher text block incomplete. */
10683
        over = aes->cOver;
10684
    }
10685
    if (over > 0) {
10686
        /* Fill the rest of the block with zeros. */
10687
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
10688
        /* GHASH last cipher block. */
10689
    #ifdef HAVE_INTEL_AVX2
10690
        if (IS_INTEL_AVX2(intel_flags)) {
10691
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
10692
                                     aes->gcm.H);
10693
        }
10694
        else
10695
    #endif
10696
    #ifdef HAVE_INTEL_AVX1
10697
        if (IS_INTEL_AVX1(intel_flags)) {
10698
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
10699
                                     aes->gcm.H);
10700
        }
10701
        else
10702
    #endif
10703
        {
10704
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
10705
                                      aes->gcm.H);
10706
        }
10707
    }
10708
    /* Calculate the authentication tag. */
10709
#ifdef HAVE_INTEL_AVX2
10710
    if (IS_INTEL_AVX2(intel_flags)) {
10711
        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
10712
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
10713
    }
10714
    else
10715
#endif
10716
#ifdef HAVE_INTEL_AVX1
10717
    if (IS_INTEL_AVX1(intel_flags)) {
10718
        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
10719
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
10720
    }
10721
    else
10722
#endif
10723
    {
10724
        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
10725
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
10726
    }
10727
10728
    return 0;
10729
}
10730
10731
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
10732
10733
#ifdef __cplusplus
10734
    extern "C" {
10735
#endif
10736
10737
/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
10738
#ifdef HAVE_INTEL_AVX2
10739
extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
10740
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10741
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10742
extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
10743
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10744
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
10745
#endif
10746
#ifdef HAVE_INTEL_AVX1
10747
extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
10748
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10749
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10750
extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
10751
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10752
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
10753
#endif
10754
extern void AES_GCM_decrypt_update_aesni(const unsigned char* key, int nr,
10755
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10756
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10757
extern void AES_GCM_decrypt_final_aesni(unsigned char* tag,
10758
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10759
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
10760
10761
#ifdef __cplusplus
10762
    } /* extern "C" */
10763
#endif
10764
10765
/* Update the AES GCM for decryption with data and/or authentication data.
10766
 *
10767
 * @param [in, out] aes  AES object.
10768
 * @param [out]     p    Buffer to hold plaintext.
10769
 * @param [in]      c    Buffer holding cipher text.
10770
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
10771
 * @param [in]      a    Buffer holding authentication data.
10772
 * @param [in]      aSz  Length of authentication data in bytes.
10773
 */
10774
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
10775
    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
10776
{
10777
    word32 blocks;
10778
    int partial;
10779
    int ret;
10780
10781
    ASSERT_SAVED_VECTOR_REGISTERS();
10782
10783
    /* Hash in A, the Authentication Data */
10784
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
10785
    if (ret != 0)
10786
        return ret;
10787
10788
    /* Hash in C, the Cipher text, and decrypt. */
10789
    if (cSz != 0 && p != NULL) {
10790
        /* Update count of cipher text we have hashed. */
10791
        aes->cSz += cSz;
10792
        if (aes->cOver > 0) {
10793
            /* Calculate amount we can use - fill up the block. */
10794
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
10795
            if (sz > cSz) {
10796
                sz = (byte)cSz;
10797
            }
10798
            /* Keep a copy of the cipher text for GHASH. */
10799
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
10800
            /* Decrypt some of the cipher text. */
10801
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
10802
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
10803
            /* Update count of unused encrypted counter. */
10804
            aes->cOver = (byte)(aes->cOver + sz);
10805
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
10806
                /* We have filled up the block and can process. */
10807
            #ifdef HAVE_INTEL_AVX2
10808
                if (IS_INTEL_AVX2(intel_flags)) {
10809
                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
10810
                                             aes->gcm.H);
10811
                }
10812
                else
10813
            #endif
10814
            #ifdef HAVE_INTEL_AVX1
10815
                if (IS_INTEL_AVX1(intel_flags)) {
10816
                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
10817
                                             aes->gcm.H);
10818
                }
10819
                else
10820
            #endif
10821
                {
10822
                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
10823
                                              aes->gcm.H);
10824
                }
10825
                /* Reset count. */
10826
                aes->cOver = 0;
10827
            }
10828
            /* Used up some data. */
10829
            cSz -= sz;
10830
            c += sz;
10831
            p += sz;
10832
        }
10833
10834
        /* Calculate number of blocks of plaintext and the leftover. */
10835
        blocks = cSz / WC_AES_BLOCK_SIZE;
10836
        partial = cSz % WC_AES_BLOCK_SIZE;
10837
        if (blocks > 0) {
10838
            /* Decrypt and GHASH full blocks now. */
10839
        #ifdef HAVE_INTEL_AVX2
10840
            if (IS_INTEL_AVX2(intel_flags)) {
10841
                AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
10842
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
10843
                    AES_COUNTER(aes));
10844
            }
10845
            else
10846
        #endif
10847
        #ifdef HAVE_INTEL_AVX1
10848
            if (IS_INTEL_AVX1(intel_flags)) {
10849
                AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
10850
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
10851
                    AES_COUNTER(aes));
10852
            }
10853
            else
10854
        #endif
10855
            {
10856
                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
10857
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
10858
                    AES_COUNTER(aes));
10859
            }
10860
            /* Skip over to end of blocks. */
10861
            c += blocks * WC_AES_BLOCK_SIZE;
10862
            p += blocks * WC_AES_BLOCK_SIZE;
10863
        }
10864
        if (partial != 0) {
10865
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
10866
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
10867
        #ifdef HAVE_INTEL_AVX2
10868
            if (IS_INTEL_AVX2(intel_flags)) {
10869
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
10870
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
10871
            }
10872
            else
10873
        #endif
10874
        #ifdef HAVE_INTEL_AVX1
10875
            if (IS_INTEL_AVX1(intel_flags)) {
10876
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
10877
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
10878
            }
10879
            else
10880
        #endif
10881
            {
10882
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
10883
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
10884
            }
10885
            /* Keep cipher text for GHASH of last partial block. */
10886
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
10887
            /* XOR the remaining cipher text to calculate plaintext. */
10888
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
10889
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
10890
            /* Update count of the block used. */
10891
            aes->cOver = (byte)partial;
10892
        }
10893
    }
10894
10895
    return 0;
10896
}
10897
10898
/* Finalize the AES GCM for decryption and check the authentication tag.
10899
 *
10900
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
10901
 *
10902
 * @param [in, out] aes        AES object.
10903
 * @param [in]      authTag    Buffer holding authentication tag.
10904
 * @param [in]      authTagSz  Length of authentication tag in bytes.
10905
 * @return  0 on success.
10906
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
10907
 *          value.
10908
 */
10909
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
10910
    Aes* aes, const byte* authTag, word32 authTagSz)
10911
{
10912
    int ret = 0;
10913
    int res;
10914
    /* AAD block incomplete when > 0 */
10915
    byte over = aes->aOver;
10916
    byte *lastBlock = AES_LASTGBLOCK(aes);
10917
10918
    ASSERT_SAVED_VECTOR_REGISTERS();
10919
10920
    if (aes->cOver > 0) {
10921
        /* Cipher text block incomplete. */
10922
        over = aes->cOver;
10923
        lastBlock = AES_LASTBLOCK(aes);
10924
    }
10925
    if (over > 0) {
10926
        /* Zeroize the unused part of the block. */
10927
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
10928
        /* Hash the last block of cipher text. */
10929
    #ifdef HAVE_INTEL_AVX2
10930
        if (IS_INTEL_AVX2(intel_flags)) {
10931
            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
10932
        }
10933
        else
10934
    #endif
10935
    #ifdef HAVE_INTEL_AVX1
10936
        if (IS_INTEL_AVX1(intel_flags)) {
10937
            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
10938
        }
10939
        else
10940
    #endif
10941
        {
10942
            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
10943
        }
10944
    }
10945
    /* Calculate and compare the authentication tag. */
10946
#ifdef HAVE_INTEL_AVX2
10947
    if (IS_INTEL_AVX2(intel_flags)) {
10948
        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
10949
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
10950
    }
10951
    else
10952
#endif
10953
#ifdef HAVE_INTEL_AVX1
10954
    if (IS_INTEL_AVX1(intel_flags)) {
10955
        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
10956
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
10957
    }
10958
    else
10959
#endif
10960
    {
10961
        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
10962
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
10963
    }
10964
10965
    /* Return error code when calculated doesn't match input. */
10966
    if (res == 0) {
10967
        ret = AES_GCM_AUTH_E;
10968
    }
10969
    return ret;
10970
}
10971
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
10972
#endif /* WOLFSSL_AESNI */
10973
10974
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10975
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10976
/* Initialize the AES GCM cipher with an IV. Aarch64 HW Crypto implementations.
10977
 *
10978
 * @param [in, out] aes   AES object.
10979
 * @param [in]      iv    IV/nonce buffer.
10980
 * @param [in]      ivSz  Length of IV/nonce data.
10981
 */
10982
static WARN_UNUSED_RESULT int AesGcmInit_AARCH64(Aes* aes, const byte* iv,
10983
    word32 ivSz)
10984
{
10985
    /* Reset state fields. */
10986
    aes->over = 0;
10987
    aes->aSz = 0;
10988
    aes->cSz = 0;
10989
    /* Set tag to all zeros as initial value. */
10990
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
10991
    /* Reset counts of AAD and cipher text. */
10992
    aes->aOver = 0;
10993
    aes->cOver = 0;
10994
10995
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
10996
    if (aes->use_sha3_hw_crypto) {
10997
        AES_GCM_init_AARCH64_EOR3((byte*)aes->key, (int)aes->rounds, iv, ivSz,
10998
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
10999
    }
11000
    else
11001
#endif
11002
    {
11003
        AES_GCM_init_AARCH64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11004
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11005
    }
11006
11007
    return 0;
11008
}
11009
11010
/* Update the AES GCM for encryption with authentication data.
11011
 *
11012
 * Implementation uses AARCH64 optimized assembly code.
11013
 *
11014
 * @param [in, out] aes   AES object.
11015
 * @param [in]      a     Buffer holding authentication data.
11016
 * @param [in]      aSz   Length of authentication data in bytes.
11017
 * @param [in]      endA  Whether no more authentication data is expected.
11018
 */
11019
static WARN_UNUSED_RESULT int AesGcmAadUpdate_AARCH64(
11020
    Aes* aes, const byte* a, word32 aSz, int endA)
11021
{
11022
    word32 blocks;
11023
    int partial;
11024
11025
    if (aSz != 0 && a != NULL) {
11026
        /* Total count of AAD updated. */
11027
        aes->aSz += aSz;
11028
        /* Check if we have unprocessed data. */
11029
        if (aes->aOver > 0) {
11030
            /* Calculate amount we can use - fill up the block. */
11031
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
11032
            if (sz > aSz) {
11033
                sz = (byte)aSz;
11034
            }
11035
            /* Copy extra into last GHASH block array and update count. */
11036
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
11037
            aes->aOver = (byte)(aes->aOver + sz);
11038
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
11039
                /* We have filled up the block and can process. */
11040
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11041
                if (aes->use_sha3_hw_crypto) {
11042
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
11043
                        AES_TAG(aes), aes->gcm.H);
11044
                }
11045
                else
11046
            #endif
11047
                {
11048
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
11049
                        AES_TAG(aes), aes->gcm.H);
11050
                }
11051
                /* Reset count. */
11052
                aes->aOver = 0;
11053
            }
11054
            /* Used up some data. */
11055
            aSz -= sz;
11056
            a += sz;
11057
        }
11058
11059
        /* Calculate number of blocks of AAD and the leftover. */
11060
        blocks = aSz / WC_AES_BLOCK_SIZE;
11061
        partial = aSz % WC_AES_BLOCK_SIZE;
11062
        if (blocks > 0) {
11063
            /* GHASH full blocks now. */
11064
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11065
            if (aes->use_sha3_hw_crypto) {
11066
                AES_GCM_aad_update_AARCH64_EOR3(a, blocks * WC_AES_BLOCK_SIZE,
11067
                    AES_TAG(aes), aes->gcm.H);
11068
            }
11069
            else
11070
        #endif
11071
            {
11072
                AES_GCM_aad_update_AARCH64(a, blocks * WC_AES_BLOCK_SIZE,
11073
                    AES_TAG(aes), aes->gcm.H);
11074
            }
11075
            /* Skip over to end of AAD blocks. */
11076
            a += blocks * WC_AES_BLOCK_SIZE;
11077
        }
11078
        if (partial != 0) {
11079
            /* Cache the partial block. */
11080
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
11081
            aes->aOver = (byte)partial;
11082
        }
11083
    }
11084
    if (endA && (aes->aOver > 0)) {
11085
        /* No more AAD coming and we have a partial block. */
11086
        /* Fill the rest of the block with zeros. */
11087
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
11088
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
11089
        /* GHASH last AAD block. */
11090
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11091
        if (aes->use_sha3_hw_crypto) {
11092
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
11093
                AES_TAG(aes), aes->gcm.H);
11094
        }
11095
        else
11096
    #endif
11097
        {
11098
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
11099
                AES_TAG(aes), aes->gcm.H);
11100
        }
11101
        /* Clear partial count for next time through. */
11102
        aes->aOver = 0;
11103
    }
11104
11105
    return 0;
11106
}
11107
11108
/* Update the AES GCM for encryption with data and/or authentication data.
11109
 *
11110
 * Implementation uses AARCH64 optimized assembly code.
11111
 *
11112
 * @param [in, out] aes  AES object.
11113
 * @param [out]     c    Buffer to hold cipher text.
11114
 * @param [in]      p    Buffer holding plaintext.
11115
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11116
 * @param [in]      a    Buffer holding authentication data.
11117
 * @param [in]      aSz  Length of authentication data in bytes.
11118
 */
11119
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_AARCH64(
11120
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
11121
{
11122
    word32 blocks;
11123
    int partial;
11124
    int ret;
11125
11126
    /* Hash in A, the Authentication Data */
11127
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, (cSz > 0) && (c != NULL));
11128
    if (ret != 0)
11129
        return ret;
11130
11131
    /* Encrypt plaintext and Hash in C, the Cipher text */
11132
    if (cSz != 0 && c != NULL) {
11133
        /* Update count of cipher text we have hashed. */
11134
        aes->cSz += cSz;
11135
        if (aes->cOver > 0) {
11136
            /* Calculate amount we can use - fill up the block. */
11137
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11138
            if (sz > cSz) {
11139
                sz = (byte)cSz;
11140
            }
11141
            /* Encrypt some of the plaintext. */
11142
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
11143
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11144
            /* Update count of unused encrypted counter. */
11145
            aes->cOver = (byte)(aes->cOver + sz);
11146
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11147
                /* We have filled up the block and can process. */
11148
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11149
                if (aes->use_sha3_hw_crypto) {
11150
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
11151
                        AES_TAG(aes), aes->gcm.H);
11152
                }
11153
                else
11154
            #endif
11155
                {
11156
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
11157
                        AES_TAG(aes), aes->gcm.H);
11158
                }
11159
                /* Reset count. */
11160
                aes->cOver = 0;
11161
            }
11162
            /* Used up some data. */
11163
            cSz -= sz;
11164
            p += sz;
11165
            c += sz;
11166
        }
11167
11168
        /* Calculate number of blocks of plaintext and the leftover. */
11169
        blocks = cSz / WC_AES_BLOCK_SIZE;
11170
        partial = cSz % WC_AES_BLOCK_SIZE;
11171
        if (blocks > 0) {
11172
            /* Encrypt and GHASH full blocks now. */
11173
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11174
            if (aes->use_sha3_hw_crypto) {
11175
                AES_GCM_encrypt_update_AARCH64_EOR3((byte*)aes->key,
11176
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
11177
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11178
            }
11179
            else
11180
        #endif
11181
            {
11182
                AES_GCM_encrypt_update_AARCH64((byte*)aes->key,
11183
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
11184
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11185
            }
11186
            /* Skip over to end of blocks. */
11187
            p += blocks * WC_AES_BLOCK_SIZE;
11188
            c += blocks * WC_AES_BLOCK_SIZE;
11189
        }
11190
        if (partial != 0) {
11191
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
11192
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11193
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11194
            if (aes->use_sha3_hw_crypto) {
11195
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
11196
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
11197
                    AES_COUNTER(aes));
11198
            }
11199
            else
11200
        #endif
11201
            {
11202
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
11203
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11204
            }
11205
            /* XOR the remaining plaintext to calculate cipher text.
11206
             * Keep cipher text for GHASH of last partial block.
11207
             */
11208
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
11209
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
11210
            /* Update count of the block used. */
11211
            aes->cOver = (byte)partial;
11212
        }
11213
    }
11214
    return 0;
11215
}
11216
11217
/* Finalize the AES GCM for encryption and calculate the authentication tag.
11218
 *
11219
 * Calls ARCH64 optimized assembly code.
11220
 *
11221
 * @param [in, out] aes        AES object.
11222
 * @param [in]      authTag    Buffer to hold authentication tag.
11223
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11224
 * @return  0 on success.
11225
 */
11226
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_AARCH64(Aes* aes,
11227
    byte* authTag, word32 authTagSz)
11228
{
11229
    /* AAD block incomplete when > 0 */
11230
    byte over = aes->aOver;
11231
11232
    ASSERT_SAVED_VECTOR_REGISTERS();
11233
11234
    if (aes->cOver > 0) {
11235
        /* Cipher text block incomplete. */
11236
        over = aes->cOver;
11237
    }
11238
    if (over > 0) {
11239
        /* Fill the rest of the block with zeros. */
11240
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
11241
            (size_t)WC_AES_BLOCK_SIZE - over);
11242
        /* GHASH last cipher block. */
11243
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11244
        if (aes->use_sha3_hw_crypto) {
11245
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes), AES_TAG(aes),
11246
                aes->gcm.H);
11247
        }
11248
        else
11249
    #endif
11250
        {
11251
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes), AES_TAG(aes),
11252
                aes->gcm.H);
11253
        }
11254
    }
11255
    /* Calculate the authentication tag. */
11256
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11257
    if (aes->use_sha3_hw_crypto) {
11258
        AES_GCM_encrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
11259
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11260
    }
11261
    else
11262
#endif
11263
    {
11264
        AES_GCM_encrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
11265
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11266
    }
11267
11268
    return 0;
11269
}
11270
11271
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
11272
/* Update the AES GCM for decryption with data and/or authentication data.
11273
 *
11274
 * @param [in, out] aes  AES object.
11275
 * @param [out]     p    Buffer to hold plaintext.
11276
 * @param [in]      c    Buffer holding cipher text.
11277
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11278
 * @param [in]      a    Buffer holding authentication data.
11279
 * @param [in]      aSz  Length of authentication data in bytes.
11280
 */
11281
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_AARCH64(Aes* aes, byte* p,
11282
    const byte* c, word32 cSz, const byte* a, word32 aSz)
11283
{
11284
    word32 blocks;
11285
    int partial;
11286
    int ret;
11287
11288
    /* Hash in A, the Authentication Data */
11289
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, cSz > 0);
11290
    if (ret != 0)
11291
        return ret;
11292
11293
    /* Hash in C, the Cipher text, and decrypt. */
11294
    if (cSz != 0 && p != NULL) {
11295
        /* Update count of cipher text we have hashed. */
11296
        aes->cSz += cSz;
11297
        if (aes->cOver > 0) {
11298
            /* Calculate amount we can use - fill up the block. */
11299
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11300
            if (sz > cSz) {
11301
                sz = (byte)cSz;
11302
            }
11303
            /* Keep a copy of the cipher text for GHASH. */
11304
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
11305
            /* Decrypt some of the cipher text. */
11306
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
11307
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11308
            /* Update count of unused encrypted counter. */
11309
            aes->cOver = (byte)(aes->cOver + sz);
11310
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11311
                /* We have filled up the block and can process. */
11312
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11313
                if (aes->use_sha3_hw_crypto) {
11314
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTBLOCK(aes),
11315
                        AES_TAG(aes), aes->gcm.H);
11316
                }
11317
                else
11318
            #endif
11319
                {
11320
                    AES_GCM_ghash_block_AARCH64(AES_LASTBLOCK(aes),
11321
                        AES_TAG(aes), aes->gcm.H);
11322
                }
11323
                /* Reset count. */
11324
                aes->cOver = 0;
11325
            }
11326
            /* Used up some data. */
11327
            cSz -= sz;
11328
            c += sz;
11329
            p += sz;
11330
        }
11331
11332
        /* Calculate number of blocks of plaintext and the leftover. */
11333
        blocks = cSz / WC_AES_BLOCK_SIZE;
11334
        partial = cSz % WC_AES_BLOCK_SIZE;
11335
        if (blocks > 0) {
11336
            /* Decrypt and GHASH full blocks now. */
11337
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11338
            if (aes->use_sha3_hw_crypto) {
11339
                AES_GCM_decrypt_update_AARCH64_EOR3((byte*)aes->key,
11340
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
11341
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11342
            }
11343
            else
11344
        #endif
11345
            {
11346
                AES_GCM_decrypt_update_AARCH64((byte*)aes->key,
11347
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
11348
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11349
            }
11350
            /* Skip over to end of blocks. */
11351
            c += blocks * WC_AES_BLOCK_SIZE;
11352
            p += blocks * WC_AES_BLOCK_SIZE;
11353
        }
11354
        if (partial != 0) {
11355
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
11356
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11357
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11358
            if (aes->use_sha3_hw_crypto) {
11359
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
11360
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
11361
                    AES_COUNTER(aes));
11362
            }
11363
            else
11364
        #endif
11365
            {
11366
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
11367
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11368
            }
11369
            /* Keep cipher text for GHASH of last partial block. */
11370
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
11371
            /* XOR the remaining cipher text to calculate plaintext. */
11372
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
11373
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
11374
            /* Update count of the block used. */
11375
            aes->cOver = (byte)partial;
11376
        }
11377
    }
11378
11379
    return 0;
11380
}
11381
11382
/* Finalize the AES GCM for decryption and check the authentication tag.
11383
 *
11384
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
11385
 *
11386
 * @param [in, out] aes        AES object.
11387
 * @param [in]      authTag    Buffer holding authentication tag.
11388
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11389
 * @return  0 on success.
11390
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
11391
 *          value.
11392
 */
11393
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_AARCH64(
11394
    Aes* aes, const byte* authTag, word32 authTagSz)
11395
{
11396
    int ret = 0;
11397
    int res;
11398
    /* AAD block incomplete when > 0 */
11399
    byte over = aes->aOver;
11400
    byte *lastBlock = AES_LASTGBLOCK(aes);
11401
11402
    ASSERT_SAVED_VECTOR_REGISTERS();
11403
11404
    if (aes->cOver > 0) {
11405
        /* Cipher text block incomplete. */
11406
        over = aes->cOver;
11407
        lastBlock = AES_LASTBLOCK(aes);
11408
    }
11409
    if (over > 0) {
11410
        /* Zeroize the unused part of the block. */
11411
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
11412
        /* Hash the last block of cipher text. */
11413
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11414
        if (aes->use_sha3_hw_crypto) {
11415
            AES_GCM_ghash_block_AARCH64_EOR3(lastBlock, AES_TAG(aes),
11416
                aes->gcm.H);
11417
        }
11418
        else
11419
    #endif
11420
        {
11421
            AES_GCM_ghash_block_AARCH64(lastBlock, AES_TAG(aes), aes->gcm.H);
11422
        }
11423
    }
11424
    /* Calculate and compare the authentication tag. */
11425
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11426
    if (aes->use_sha3_hw_crypto) {
11427
        AES_GCM_decrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
11428
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11429
    }
11430
    else
11431
#endif
11432
    {
11433
        AES_GCM_decrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
11434
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11435
    }
11436
11437
    /* Return error code when calculated doesn't match input. */
11438
    if (res == 0) {
11439
        ret = AES_GCM_AUTH_E;
11440
    }
11441
    return ret;
11442
}
11443
#endif
11444
#endif
11445
11446
/* Initialize an AES GCM cipher for encryption or decryption.
11447
 *
11448
 * Must call wc_AesInit() before calling this function.
11449
 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
11450
 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
11451
 *
11452
 * @param [in, out] aes   AES object.
11453
 * @param [in]      key   Buffer holding key.
11454
 * @param [in]      len   Length of key in bytes.
11455
 * @param [in]      iv    Buffer holding IV/nonce.
11456
 * @param [in]      ivSz  Length of IV/nonce in bytes.
11457
 * @return  0 on success.
11458
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
11459
 *          is NULL, or the IV is NULL and no previous IV has been set.
11460
 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
11461
 */
11462
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
11463
    word32 ivSz)
11464
2.80k
{
11465
2.80k
    int ret = 0;
11466
11467
    /* Check validity of parameters. */
11468
2.80k
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
11469
2.80k
            ((ivSz == 0) && (iv != NULL)) ||
11470
2.80k
            ((ivSz > 0) && (iv == NULL))) {
11471
0
        ret = BAD_FUNC_ARG;
11472
0
    }
11473
11474
2.80k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
11475
2.80k
    if ((ret == 0) && (aes->streamData == NULL)) {
11476
        /* Allocate buffers for streaming. */
11477
1.04k
        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
11478
1.04k
        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
11479
1.04k
                                                              DYNAMIC_TYPE_AES);
11480
1.04k
        if (aes->streamData == NULL) {
11481
0
            ret = MEMORY_E;
11482
0
        }
11483
1.04k
    }
11484
2.80k
#endif
11485
11486
    /* Set the key if passed in. */
11487
2.80k
    if ((ret == 0) && (key != NULL)) {
11488
1.04k
        ret = wc_AesGcmSetKey(aes, key, len);
11489
1.04k
    }
11490
11491
2.80k
    if (ret == 0) {
11492
        /* Set the IV passed in if it is smaller than a block. */
11493
2.80k
        if ((iv != NULL) && (ivSz <= WC_AES_BLOCK_SIZE)) {
11494
2.80k
            XMEMMOVE((byte*)aes->reg, iv, ivSz);
11495
2.80k
            aes->nonceSz = ivSz;
11496
2.80k
        }
11497
        /* No IV passed in, check for cached IV. */
11498
2.80k
        if ((iv == NULL) && (aes->nonceSz != 0)) {
11499
            /* Use the cached copy. */
11500
0
            iv = (byte*)aes->reg;
11501
0
            ivSz = aes->nonceSz;
11502
0
        }
11503
11504
2.80k
        if (iv != NULL) {
11505
            /* Initialize with the IV. */
11506
11507
        #ifdef WOLFSSL_AESNI
11508
            if (aes->use_aesni) {
11509
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
11510
                ret = AesGcmInit_aesni(aes, iv, ivSz);
11511
                RESTORE_VECTOR_REGISTERS();
11512
            }
11513
            else
11514
        #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11515
              !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11516
            if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11517
                ret = AesGcmInit_AARCH64(aes, iv, ivSz);
11518
            }
11519
            else
11520
        #endif /* WOLFSSL_AESNI */
11521
2.80k
            {
11522
2.80k
                ret = AesGcmInit_C(aes, iv, ivSz);
11523
2.80k
            }
11524
11525
2.80k
            if (ret == 0)
11526
2.80k
                aes->nonceSet = 1;
11527
2.80k
        }
11528
2.80k
    }
11529
11530
2.80k
    return ret;
11531
2.80k
}
11532
11533
/* Initialize an AES GCM cipher for encryption.
11534
 *
11535
 * Must call wc_AesInit() before calling this function.
11536
 *
11537
 * @param [in, out] aes   AES object.
11538
 * @param [in]      key   Buffer holding key.
11539
 * @param [in]      len   Length of key in bytes.
11540
 * @param [in]      iv    Buffer holding IV/nonce.
11541
 * @param [in]      ivSz  Length of IV/nonce in bytes.
11542
 * @return  0 on success.
11543
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
11544
 *          is NULL, or the IV is NULL and no previous IV has been set.
11545
 */
11546
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
11547
    word32 ivSz)
11548
0
{
11549
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
11550
0
}
11551
11552
/* Initialize an AES GCM cipher for encryption. Get IV.
11553
 *
11554
 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
11555
 * function.
11556
 * Must call wc_AesInit() before calling this function.
11557
 *
11558
 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
11559
 *
11560
 * @param [in, out] aes   AES object.
11561
 * @param [in]      key   Buffer holding key.
11562
 * @param [in]      len   Length of key in bytes.
11563
 * @param [in]      iv    Buffer holding IV/nonce.
11564
 * @param [in]      ivSz  Length of IV/nonce in bytes.
11565
 * @return  0 on success.
11566
 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
11567
 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
11568
 *          nonce size.
11569
 */
11570
int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
11571
    word32 ivOutSz)
11572
0
{
11573
0
    int ret;
11574
11575
    /* Check validity of parameters. */
11576
0
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
11577
0
        ret = BAD_FUNC_ARG;
11578
0
    }
11579
0
    else {
11580
        /* Copy out the IV including generated part for decryption. */
11581
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
11582
        /* Initialize AES GCM cipher with key and cached Iv. */
11583
0
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
11584
0
    }
11585
11586
0
    return ret;
11587
0
}
11588
11589
/* Update the AES GCM for encryption with data and/or authentication data.
11590
 *
11591
 * All the AAD must be passed to update before the plaintext.
11592
 * Last part of AAD can be passed with first part of plaintext.
11593
 *
11594
 * Must set key and IV before calling this function.
11595
 * Must call wc_AesGcmInit() before calling this function.
11596
 *
11597
 * @param [in, out] aes       AES object.
11598
 * @param [out]     out       Buffer to hold cipher text.
11599
 * @param [in]      in        Buffer holding plaintext.
11600
 * @param [in]      sz        Length of plaintext in bytes.
11601
 * @param [in]      authIn    Buffer holding authentication data.
11602
 * @param [in]      authInSz  Length of authentication data in bytes.
11603
 * @return  0 on success.
11604
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
11605
 *          is NULL.
11606
 */
11607
int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
11608
    const byte* authIn, word32 authInSz)
11609
15.5k
{
11610
15.5k
    int ret = 0;
11611
11612
    /* Check validity of parameters. */
11613
15.5k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
11614
2.05k
            ((out == NULL) || (in == NULL)))) {
11615
0
        ret = BAD_FUNC_ARG;
11616
0
    }
11617
11618
    /* Check key has been set. */
11619
15.5k
    if ((ret == 0) && (!aes->gcmKeySet)) {
11620
0
        ret = MISSING_KEY;
11621
0
    }
11622
    /* Check IV has been set. */
11623
15.5k
    if ((ret == 0) && (!aes->nonceSet)) {
11624
0
        ret = MISSING_IV;
11625
0
    }
11626
11627
15.5k
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
11628
647
        aes->invokeCtr[0]++;
11629
647
        if (aes->invokeCtr[0] == 0) {
11630
0
            aes->invokeCtr[1]++;
11631
0
            if (aes->invokeCtr[1] == 0)
11632
0
                ret = AES_GCM_OVERFLOW_E;
11633
0
        }
11634
647
    }
11635
11636
15.5k
    if (ret == 0) {
11637
        /* Encrypt with AAD and/or plaintext. */
11638
11639
    #ifdef WOLFSSL_AESNI
11640
        if (aes->use_aesni) {
11641
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
11642
            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
11643
            RESTORE_VECTOR_REGISTERS();
11644
        }
11645
        else
11646
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11647
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11648
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11649
            ret = AesGcmEncryptUpdate_AARCH64(aes, out, in, sz, authIn,
11650
                authInSz);
11651
        }
11652
        else
11653
    #endif
11654
15.5k
        {
11655
            /* Encrypt the plaintext. */
11656
15.5k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
11657
15.5k
            if (ret == 0) {
11658
                /* Update the authentication tag with any authentication data and the
11659
                 * new cipher text. */
11660
15.5k
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
11661
15.5k
            }
11662
15.5k
        }
11663
15.5k
    }
11664
11665
15.5k
    return ret;
11666
15.5k
}
11667
11668
/* Finalize the AES GCM for encryption and return the authentication tag.
11669
 *
11670
 * Must set key and IV before calling this function.
11671
 * Must call wc_AesGcmInit() before calling this function.
11672
 *
11673
 * @param [in, out] aes        AES object.
11674
 * @param [out]     authTag    Buffer to hold authentication tag.
11675
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11676
 * @return  0 on success.
11677
 */
11678
int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
11679
555
{
11680
555
    int ret = 0;
11681
11682
    /* Check validity of parameters. */
11683
555
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
11684
555
            (authTagSz == 0)) {
11685
0
        ret = BAD_FUNC_ARG;
11686
0
    }
11687
11688
    /* Check key has been set. */
11689
555
    if ((ret == 0) && (!aes->gcmKeySet)) {
11690
0
        ret = MISSING_KEY;
11691
0
    }
11692
    /* Check IV has been set. */
11693
555
    if ((ret == 0) && (!aes->nonceSet)) {
11694
0
        ret = MISSING_IV;
11695
0
    }
11696
11697
555
    if (ret == 0) {
11698
        /* Calculate authentication tag. */
11699
    #ifdef WOLFSSL_AESNI
11700
        if (aes->use_aesni) {
11701
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
11702
            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
11703
            RESTORE_VECTOR_REGISTERS();
11704
        }
11705
        else
11706
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11707
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11708
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11709
            ret = AesGcmEncryptFinal_AARCH64(aes, authTag, authTagSz);
11710
        }
11711
        else
11712
    #endif
11713
555
        {
11714
555
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
11715
555
        }
11716
555
    }
11717
11718
555
    if ((ret == 0) && aes->ctrSet) {
11719
555
        IncCtr((byte*)aes->reg, aes->nonceSz);
11720
555
    }
11721
11722
555
    return ret;
11723
555
}
11724
11725
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
11726
/* Initialize an AES GCM cipher for decryption.
11727
 *
11728
 * Must call wc_AesInit() before calling this function.
11729
 *
11730
 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
11731
 * instead.
11732
 *
11733
 * @param [in, out] aes   AES object.
11734
 * @param [in]      key   Buffer holding key.
11735
 * @param [in]      len   Length of key in bytes.
11736
 * @param [in]      iv    Buffer holding IV/nonce.
11737
 * @param [in]      ivSz  Length of IV/nonce in bytes.
11738
 * @return  0 on success.
11739
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
11740
 *          is NULL, or the IV is NULL and no previous IV has been set.
11741
 */
11742
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
11743
    word32 ivSz)
11744
0
{
11745
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
11746
0
}
11747
11748
/* Update the AES GCM for decryption with data and/or authentication data.
11749
 *
11750
 * All the AAD must be passed to update before the cipher text.
11751
 * Last part of AAD can be passed with first part of cipher text.
11752
 *
11753
 * Must set key and IV before calling this function.
11754
 * Must call wc_AesGcmInit() before calling this function.
11755
 *
11756
 * @param [in, out] aes       AES object.
11757
 * @param [out]     out       Buffer to hold plaintext.
11758
 * @param [in]      in        Buffer holding cipher text.
11759
 * @param [in]      sz        Length of cipher text in bytes.
11760
 * @param [in]      authIn    Buffer holding authentication data.
11761
 * @param [in]      authInSz  Length of authentication data in bytes.
11762
 * @return  0 on success.
11763
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
11764
 *          is NULL.
11765
 */
11766
int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
11767
    const byte* authIn, word32 authInSz)
11768
3.25k
{
11769
3.25k
    int ret = 0;
11770
11771
    /* Check validity of parameters. */
11772
3.25k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
11773
335
            ((out == NULL) || (in == NULL)))) {
11774
0
        ret = BAD_FUNC_ARG;
11775
0
    }
11776
11777
    /* Check key has been set. */
11778
3.25k
    if ((ret == 0) && (!aes->gcmKeySet)) {
11779
0
        ret = MISSING_KEY;
11780
0
    }
11781
    /* Check IV has been set. */
11782
3.25k
    if ((ret == 0) && (!aes->nonceSet)) {
11783
0
        ret = MISSING_IV;
11784
0
    }
11785
11786
3.25k
    if (ret == 0) {
11787
        /* Decrypt with AAD and/or cipher text. */
11788
    #ifdef WOLFSSL_AESNI
11789
        if (aes->use_aesni) {
11790
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
11791
            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
11792
            RESTORE_VECTOR_REGISTERS();
11793
        }
11794
        else
11795
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11796
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11797
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11798
            ret = AesGcmDecryptUpdate_AARCH64(aes, out, in, sz, authIn,
11799
                authInSz);
11800
        }
11801
        else
11802
    #endif
11803
3.25k
        {
11804
            /* Update the authentication tag with any authentication data and
11805
             * cipher text. */
11806
3.25k
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
11807
            /* Decrypt the cipher text. */
11808
3.25k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
11809
3.25k
        }
11810
3.25k
    }
11811
11812
3.25k
    return ret;
11813
3.25k
}
11814
11815
/* Finalize the AES GCM for decryption and check the authentication tag.
11816
 *
11817
 * Must set key and IV before calling this function.
11818
 * Must call wc_AesGcmInit() before calling this function.
11819
 *
11820
 * @param [in, out] aes        AES object.
11821
 * @param [in]      authTag    Buffer holding authentication tag.
11822
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11823
 * @return  0 on success.
11824
 */
11825
int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
11826
423
{
11827
423
    int ret = 0;
11828
11829
    /* Check validity of parameters. */
11830
423
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
11831
423
            (authTagSz == 0)) {
11832
0
        ret = BAD_FUNC_ARG;
11833
0
    }
11834
11835
    /* Check key has been set. */
11836
423
    if ((ret == 0) && (!aes->gcmKeySet)) {
11837
0
        ret = MISSING_KEY;
11838
0
    }
11839
    /* Check IV has been set. */
11840
423
    if ((ret == 0) && (!aes->nonceSet)) {
11841
0
        ret = MISSING_IV;
11842
0
    }
11843
11844
423
    if (ret == 0) {
11845
        /* Calculate authentication tag and compare with one passed in.. */
11846
    #ifdef WOLFSSL_AESNI
11847
        if (aes->use_aesni) {
11848
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
11849
            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
11850
            RESTORE_VECTOR_REGISTERS();
11851
        }
11852
        else
11853
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11854
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11855
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11856
            ret = AesGcmDecryptFinal_AARCH64(aes, authTag, authTagSz);
11857
        }
11858
        else
11859
    #endif
11860
423
        {
11861
423
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
11862
            /* Calculate authentication tag. */
11863
423
            ret = AesGcmFinal_C(aes, calcTag, authTagSz);
11864
423
            if (ret == 0) {
11865
                /* Check calculated tag matches the one passed in. */
11866
423
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
11867
196
                    ret = AES_GCM_AUTH_E;
11868
196
                }
11869
423
            }
11870
423
        }
11871
423
    }
11872
11873
423
    return ret;
11874
423
}
11875
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
11876
#endif /* WOLFSSL_AESGCM_STREAM */
11877
#endif /* WOLFSSL_XILINX_CRYPT */
11878
#endif /* end of block for AESGCM implementation selection */
11879
11880
11881
/* Common to all, abstract functions that build off of lower level AESGCM
11882
 * functions */
11883
#ifndef WC_NO_RNG
11884
11885
2.58k
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
11886
2.58k
    return (ivSz == GCM_NONCE_MIN_SZ ||
11887
2.58k
            ivSz == GCM_NONCE_MID_SZ ||
11888
0
            ivSz == GCM_NONCE_MAX_SZ);
11889
2.58k
}
11890
11891
11892
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
11893
2.51k
{
11894
2.51k
    int ret = 0;
11895
11896
2.51k
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
11897
0
        ret = BAD_FUNC_ARG;
11898
0
    }
11899
11900
2.51k
    if (ret == 0) {
11901
2.51k
        XMEMCPY((byte*)aes->reg, iv, ivSz);
11902
11903
        /* If the IV is 96, allow for a 2^64 invocation counter.
11904
         * For any other size for the nonce, limit the invocation
11905
         * counter to 32-bits. (SP 800-38D 8.3) */
11906
2.51k
        aes->invokeCtr[0] = 0;
11907
2.51k
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
11908
2.51k
    #ifdef WOLFSSL_AESGCM_STREAM
11909
2.51k
        aes->ctrSet = 1;
11910
2.51k
    #endif
11911
2.51k
        aes->nonceSz = ivSz;
11912
2.51k
    }
11913
11914
2.51k
    return ret;
11915
2.51k
}
11916
11917
11918
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
11919
                   const byte* ivFixed, word32 ivFixedSz,
11920
                   WC_RNG* rng)
11921
68
{
11922
68
    int ret = 0;
11923
11924
68
    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
11925
68
        (ivFixed == NULL && ivFixedSz != 0) ||
11926
68
        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
11927
11928
0
        ret = BAD_FUNC_ARG;
11929
0
    }
11930
11931
68
    if (ret == 0) {
11932
68
        byte* iv = (byte*)aes->reg;
11933
11934
68
        if (ivFixedSz)
11935
68
            XMEMCPY(iv, ivFixed, ivFixedSz);
11936
11937
68
        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
11938
68
    }
11939
11940
68
    if (ret == 0) {
11941
        /* If the IV is 96, allow for a 2^64 invocation counter.
11942
         * For any other size for the nonce, limit the invocation
11943
         * counter to 32-bits. (SP 800-38D 8.3) */
11944
66
        aes->invokeCtr[0] = 0;
11945
66
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
11946
66
    #ifdef WOLFSSL_AESGCM_STREAM
11947
66
        aes->ctrSet = 1;
11948
66
    #endif
11949
66
        aes->nonceSz = ivSz;
11950
66
    }
11951
11952
68
    return ret;
11953
68
}
11954
11955
11956
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
11957
                        byte* ivOut, word32 ivOutSz,
11958
                        byte* authTag, word32 authTagSz,
11959
                        const byte* authIn, word32 authInSz)
11960
761
{
11961
761
    int ret = 0;
11962
11963
761
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
11964
761
        ivOut == NULL || ivOutSz != aes->nonceSz ||
11965
761
        (authIn == NULL && authInSz != 0)) {
11966
11967
0
        ret = BAD_FUNC_ARG;
11968
0
    }
11969
11970
761
    if (ret == 0) {
11971
761
        aes->invokeCtr[0]++;
11972
761
        if (aes->invokeCtr[0] == 0) {
11973
0
            aes->invokeCtr[1]++;
11974
0
            if (aes->invokeCtr[1] == 0)
11975
0
                ret = AES_GCM_OVERFLOW_E;
11976
0
        }
11977
761
    }
11978
11979
761
    if (ret == 0) {
11980
761
        XMEMCPY(ivOut, aes->reg, ivOutSz);
11981
761
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
11982
761
                               (byte*)aes->reg, ivOutSz,
11983
761
                               authTag, authTagSz,
11984
761
                               authIn, authInSz);
11985
761
        if (ret == 0)
11986
761
            IncCtr((byte*)aes->reg, ivOutSz);
11987
761
    }
11988
11989
761
    return ret;
11990
761
}
11991
11992
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
11993
            const byte* authIn, word32 authInSz,
11994
            byte* authTag, word32 authTagSz, WC_RNG* rng)
11995
0
{
11996
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
11997
0
    int ret;
11998
11999
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
12000
0
        authTag == NULL || authTagSz == 0 || rng == NULL) {
12001
12002
0
        return BAD_FUNC_ARG;
12003
0
    }
12004
12005
0
#ifdef WOLFSSL_SMALL_STACK
12006
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
12007
#else
12008
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12009
#endif
12010
0
    if (ret != 0)
12011
0
        return ret;
12012
12013
0
    ret = wc_AesGcmSetKey(aes, key, keySz);
12014
0
    if (ret == 0)
12015
0
        ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
12016
0
    if (ret == 0)
12017
0
        ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
12018
0
                                  authTag, authTagSz, authIn, authInSz);
12019
12020
0
#ifdef WOLFSSL_SMALL_STACK
12021
0
    wc_AesDelete(aes, NULL);
12022
#else
12023
    wc_AesFree(aes);
12024
#endif
12025
12026
0
    return ret;
12027
0
}
12028
12029
int wc_GmacVerify(const byte* key, word32 keySz,
12030
                  const byte* iv, word32 ivSz,
12031
                  const byte* authIn, word32 authInSz,
12032
                  const byte* authTag, word32 authTagSz)
12033
0
{
12034
0
    int ret;
12035
0
#ifdef HAVE_AES_DECRYPT
12036
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
12037
12038
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
12039
0
        authTag == NULL || authTagSz == 0 || authTagSz > WC_AES_BLOCK_SIZE) {
12040
12041
0
        return BAD_FUNC_ARG;
12042
0
    }
12043
12044
0
#ifdef WOLFSSL_SMALL_STACK
12045
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
12046
#else
12047
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12048
#endif
12049
0
    if (ret == 0) {
12050
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
12051
0
        if (ret == 0)
12052
0
            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
12053
0
                                  authTag, authTagSz, authIn, authInSz);
12054
12055
0
    }
12056
0
#ifdef WOLFSSL_SMALL_STACK
12057
0
    wc_AesDelete(aes, NULL);
12058
#else
12059
    wc_AesFree(aes);
12060
#endif
12061
#else
12062
    (void)key;
12063
    (void)keySz;
12064
    (void)iv;
12065
    (void)ivSz;
12066
    (void)authIn;
12067
    (void)authInSz;
12068
    (void)authTag;
12069
    (void)authTagSz;
12070
    ret = NOT_COMPILED_IN;
12071
#endif
12072
0
    return ret;
12073
0
}
12074
12075
#endif /* WC_NO_RNG */
12076
12077
12078
int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
12079
0
{
12080
0
    if (gmac == NULL || key == NULL) {
12081
0
        return BAD_FUNC_ARG;
12082
0
    }
12083
0
    return wc_AesGcmSetKey(&gmac->aes, key, len);
12084
0
}
12085
12086
12087
int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
12088
                              const byte* authIn, word32 authInSz,
12089
                              byte* authTag, word32 authTagSz)
12090
0
{
12091
0
    if (gmac == NULL) {
12092
0
        return BAD_FUNC_ARG;
12093
0
    }
12094
12095
0
    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
12096
0
                                         authTag, authTagSz, authIn, authInSz);
12097
0
}
12098
12099
#endif /* HAVE_AESGCM */
12100
12101
#ifdef HAVE_AESCCM
12102
12103
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
12104
552
{
12105
552
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
12106
0
        return BAD_FUNC_ARG;
12107
12108
552
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
12109
552
}
12110
12111
12112
/* Checks if the tag size is an accepted value based on RFC 3610 section 2
12113
 * returns 0 if tag size is ok
12114
 */
12115
int wc_AesCcmCheckTagSize(int sz)
12116
2.81k
{
12117
    /* values here are from RFC 3610 section 2 */
12118
2.81k
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
12119
2.30k
            && sz != 16) {
12120
0
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
12121
0
        return BAD_FUNC_ARG;
12122
0
    }
12123
2.81k
    return 0;
12124
2.81k
}
12125
12126
#if defined(WOLFSSL_RISCV_ASM)
12127
    /* implementation located in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
12128
12129
#elif defined(HAVE_COLDFIRE_SEC)
12130
    #error "Coldfire SEC doesn't currently support AES-CCM mode"
12131
12132
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
12133
        !defined(WOLFSSL_QNX_CAAM)
12134
    /* implemented in wolfcrypt/src/port/caam_aes.c */
12135
12136
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
12137
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
12138
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12139
                   const byte* nonce, word32 nonceSz,
12140
                   byte* authTag, word32 authTagSz,
12141
                   const byte* authIn, word32 authInSz)
12142
{
12143
    return wc_AesCcmEncrypt_silabs(
12144
        aes, out, in, inSz,
12145
        nonce, nonceSz,
12146
        authTag, authTagSz,
12147
        authIn, authInSz);
12148
}
12149
12150
#ifdef HAVE_AES_DECRYPT
12151
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12152
                   const byte* nonce, word32 nonceSz,
12153
                   const byte* authTag, word32 authTagSz,
12154
                   const byte* authIn, word32 authInSz)
12155
{
12156
    return wc_AesCcmDecrypt_silabs(
12157
        aes, out, in, inSz,
12158
        nonce, nonceSz,
12159
        authTag, authTagSz,
12160
        authIn, authInSz);
12161
}
12162
#endif
12163
#elif defined(FREESCALE_LTC)
12164
12165
/* return 0 on success */
12166
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12167
                   const byte* nonce, word32 nonceSz,
12168
                   byte* authTag, word32 authTagSz,
12169
                   const byte* authIn, word32 authInSz)
12170
{
12171
    byte *key;
12172
    word32 keySize;
12173
    status_t status;
12174
12175
    /* sanity check on arguments */
12176
    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
12177
     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
12178
     * don't allow it here either.
12179
     */
12180
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
12181
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
12182
        return BAD_FUNC_ARG;
12183
    }
12184
12185
    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
12186
        return BAD_FUNC_ARG;
12187
    }
12188
12189
    key = (byte*)aes->key;
12190
12191
    status = wc_AesGetKeySize(aes, &keySize);
12192
    if (status != 0) {
12193
        return status;
12194
    }
12195
12196
    status = wolfSSL_CryptHwMutexLock();
12197
    if (status != 0)
12198
        return status;
12199
12200
    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
12201
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
12202
    wolfSSL_CryptHwMutexUnLock();
12203
12204
    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
12205
}
12206
12207
#ifdef HAVE_AES_DECRYPT
12208
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12209
                   const byte* nonce, word32 nonceSz,
12210
                   const byte* authTag, word32 authTagSz,
12211
                   const byte* authIn, word32 authInSz)
12212
{
12213
    byte *key;
12214
    word32 keySize;
12215
    status_t status;
12216
12217
    /* sanity check on arguments */
12218
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
12219
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
12220
        return BAD_FUNC_ARG;
12221
    }
12222
12223
    key = (byte*)aes->key;
12224
12225
    status = wc_AesGetKeySize(aes, &keySize);
12226
    if (status != 0) {
12227
        return status;
12228
    }
12229
12230
    status = wolfSSL_CryptHwMutexLock();
12231
    if (status != 0)
12232
        return status;
12233
    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
12234
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
12235
    wolfSSL_CryptHwMutexUnLock();
12236
12237
    if (status != kStatus_Success) {
12238
        XMEMSET(out, 0, inSz);
12239
        return AES_CCM_AUTH_E;
12240
    }
12241
    return 0;
12242
}
12243
#endif /* HAVE_AES_DECRYPT */
12244
12245
#else
12246
12247
/* Software CCM */
12248
static WARN_UNUSED_RESULT int roll_x(
12249
    Aes* aes, const byte* in, word32 inSz, byte* out)
12250
2.81k
{
12251
2.81k
    int ret;
12252
12253
    /* process the bulk of the data */
12254
48.1k
    while (inSz >= WC_AES_BLOCK_SIZE) {
12255
45.3k
        xorbuf(out, in, WC_AES_BLOCK_SIZE);
12256
45.3k
        in += WC_AES_BLOCK_SIZE;
12257
45.3k
        inSz -= WC_AES_BLOCK_SIZE;
12258
12259
45.3k
        ret = wc_AesEncrypt(aes, out, out);
12260
45.3k
        if (ret != 0)
12261
0
            return ret;
12262
45.3k
    }
12263
12264
    /* process remainder of the data */
12265
2.81k
    if (inSz > 0) {
12266
2.72k
        xorbuf(out, in, inSz);
12267
2.72k
        ret = wc_AesEncrypt(aes, out, out);
12268
2.72k
        if (ret != 0)
12269
0
            return ret;
12270
2.72k
    }
12271
12272
2.81k
    return 0;
12273
2.81k
}
12274
12275
static WARN_UNUSED_RESULT int roll_auth(
12276
    Aes* aes, const byte* in, word32 inSz, byte* out)
12277
2.81k
{
12278
2.81k
    word32 authLenSz;
12279
2.81k
    word32 remainder;
12280
2.81k
    int ret;
12281
12282
    /* encode the length in */
12283
2.81k
    if (inSz <= 0xFEFF) {
12284
2.81k
        authLenSz = 2;
12285
2.81k
        out[0] ^= (byte)(inSz >> 8);
12286
2.81k
        out[1] ^= (byte)inSz;
12287
2.81k
    }
12288
0
    else {
12289
0
        authLenSz = 6;
12290
0
        out[0] ^= 0xFF;
12291
0
        out[1] ^= 0xFE;
12292
0
        out[2] ^= (byte)(inSz >> 24);
12293
0
        out[3] ^= (byte)(inSz >> 16);
12294
0
        out[4] ^= (byte)(inSz >>  8);
12295
0
        out[5] ^= (byte)inSz;
12296
0
    }
12297
    /* Note, the protocol handles auth data up to 2^64, but we are
12298
     * using 32-bit sizes right now, so the bigger data isn't handled
12299
     * else {}
12300
     */
12301
12302
    /* start fill out the rest of the first block */
12303
2.81k
    remainder = WC_AES_BLOCK_SIZE - authLenSz;
12304
2.81k
    if (inSz >= remainder) {
12305
        /* plenty of bulk data to fill the remainder of this block */
12306
0
        xorbuf(out + authLenSz, in, remainder);
12307
0
        inSz -= remainder;
12308
0
        in += remainder;
12309
0
    }
12310
2.81k
    else {
12311
        /* not enough bulk data, copy what is available, and pad zero */
12312
2.81k
        xorbuf(out + authLenSz, in, inSz);
12313
2.81k
        inSz = 0;
12314
2.81k
    }
12315
2.81k
    ret = wc_AesEncrypt(aes, out, out);
12316
12317
2.81k
    if ((ret == 0) && (inSz > 0)) {
12318
0
        ret = roll_x(aes, in, inSz, out);
12319
0
    }
12320
12321
2.81k
    return ret;
12322
2.81k
}
12323
12324
12325
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
12326
45.3k
{
12327
45.3k
    word32 i;
12328
12329
45.4k
    for (i = 0; i < lenSz; i++) {
12330
45.4k
        if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
12331
45.4k
    }
12332
45.3k
}
12333
12334
#ifdef WOLFSSL_AESNI
12335
static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
12336
{
12337
    word32 i;
12338
12339
    /* B+1 = B */
12340
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 1, B, WC_AES_BLOCK_SIZE);
12341
    /* B+2,B+3 = B,B+1 */
12342
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 2, B, WC_AES_BLOCK_SIZE * 2);
12343
12344
    for (i = 0; i < lenSz; i++) {
12345
        if (++B[WC_AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
12346
    }
12347
    B[WC_AES_BLOCK_SIZE * 3 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 3 - 1] + 2U);
12348
    if (B[WC_AES_BLOCK_SIZE * 3 - 1] < 2U) {
12349
        for (i = 1; i < lenSz; i++) {
12350
            if (++B[WC_AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
12351
        }
12352
    }
12353
    B[WC_AES_BLOCK_SIZE * 4 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 4 - 1] + 3U);
12354
    if (B[WC_AES_BLOCK_SIZE * 4 - 1] < 3U) {
12355
        for (i = 1; i < lenSz; i++) {
12356
            if (++B[WC_AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
12357
        }
12358
    }
12359
}
12360
12361
static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
12362
{
12363
    word32 i;
12364
12365
    B[WC_AES_BLOCK_SIZE - 1] = (byte)(B[WC_AES_BLOCK_SIZE - 1] + 4U);
12366
    if (B[WC_AES_BLOCK_SIZE - 1] < 4U) {
12367
        for (i = 1; i < lenSz; i++) {
12368
            if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) break;
12369
        }
12370
    }
12371
}
12372
#endif
12373
12374
/* Software AES - CCM Encrypt */
12375
/* return 0 on success */
12376
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12377
                   const byte* nonce, word32 nonceSz,
12378
                   byte* authTag, word32 authTagSz,
12379
                   const byte* authIn, word32 authInSz)
12380
698
{
12381
#ifdef WOLFSSL_AESNI
12382
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
12383
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
12384
#else
12385
698
    byte A[WC_AES_BLOCK_SIZE];
12386
698
    byte B[WC_AES_BLOCK_SIZE];
12387
698
#endif
12388
698
    byte lenSz;
12389
698
    word32 i;
12390
698
    byte mask = 0xFF;
12391
698
    const word32 wordSz = (word32)sizeof(word32);
12392
698
    int ret;
12393
12394
    /* sanity check on arguments */
12395
698
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
12396
698
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
12397
698
            authTagSz > WC_AES_BLOCK_SIZE)
12398
0
        return BAD_FUNC_ARG;
12399
12400
    /* Sanity check on authIn to prevent segfault in xorbuf() where
12401
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
12402
698
    if (authIn == NULL && authInSz > 0)
12403
0
        return BAD_FUNC_ARG;
12404
12405
    /* sanity check on tag size */
12406
698
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
12407
0
        return BAD_FUNC_ARG;
12408
0
    }
12409
12410
698
#ifdef WOLF_CRYPTO_CB
12411
698
    #ifndef WOLF_CRYPTO_CB_FIND
12412
698
    if (aes->devId != INVALID_DEVID)
12413
0
    #endif
12414
0
    {
12415
0
        int crypto_cb_ret =
12416
0
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
12417
0
                                      authTag, authTagSz, authIn, authInSz);
12418
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
12419
0
            return crypto_cb_ret;
12420
        /* fall-through when unavailable */
12421
0
    }
12422
698
#endif
12423
12424
698
    XMEMSET(A, 0, sizeof(A));
12425
698
    XMEMCPY(B+1, nonce, nonceSz);
12426
698
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
12427
698
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
12428
698
                  + (8 * (((byte)authTagSz - 2) / 2))
12429
698
                  + (lenSz - 1));
12430
2.79k
    for (i = 0; i < lenSz; i++) {
12431
2.09k
        if (mask && i >= wordSz)
12432
0
            mask = 0x00;
12433
2.09k
        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
12434
2.09k
    }
12435
12436
#ifdef WOLFSSL_CHECK_MEM_ZERO
12437
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
12438
#endif
12439
12440
698
    VECTOR_REGISTERS_PUSH;
12441
698
    ret = wc_AesEncrypt(aes, B, A);
12442
#ifdef WOLFSSL_CHECK_MEM_ZERO
12443
    if (ret == 0)
12444
        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
12445
#endif
12446
12447
698
    if ((ret == 0) && (authInSz > 0))
12448
698
        ret = roll_auth(aes, authIn, authInSz, A);
12449
12450
698
    if ((ret == 0) && (inSz > 0))
12451
698
        ret = roll_x(aes, in, inSz, A);
12452
12453
698
    if (ret == 0) {
12454
698
        XMEMCPY(authTag, A, authTagSz);
12455
12456
698
        B[0] = (byte)(lenSz - 1U);
12457
2.79k
        for (i = 0; i < lenSz; i++)
12458
2.09k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
12459
698
        ret = wc_AesEncrypt(aes, B, A);
12460
698
    }
12461
12462
698
    if (ret == 0) {
12463
698
        xorbuf(authTag, A, authTagSz);
12464
698
        B[15] = 1;
12465
698
    }
12466
#ifdef WOLFSSL_AESNI
12467
    if ((ret == 0) && aes->use_aesni) {
12468
        while (inSz >= WC_AES_BLOCK_SIZE * 4) {
12469
            AesCcmCtrIncSet4(B, lenSz);
12470
12471
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
12472
                            (int)aes->rounds);
12473
12474
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
12475
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE * 4);
12476
12477
            inSz -= WC_AES_BLOCK_SIZE * 4;
12478
            in += WC_AES_BLOCK_SIZE * 4;
12479
            out += WC_AES_BLOCK_SIZE * 4;
12480
12481
            AesCcmCtrInc4(B, lenSz);
12482
        }
12483
    }
12484
#endif
12485
698
    if (ret == 0) {
12486
36.3k
        while (inSz >= WC_AES_BLOCK_SIZE) {
12487
35.6k
            ret = wc_AesEncrypt(aes, B, A);
12488
35.6k
            if (ret != 0)
12489
0
                break;
12490
35.6k
            xorbuf(A, in, WC_AES_BLOCK_SIZE);
12491
35.6k
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
12492
12493
35.6k
            AesCcmCtrInc(B, lenSz);
12494
35.6k
            inSz -= WC_AES_BLOCK_SIZE;
12495
35.6k
            in += WC_AES_BLOCK_SIZE;
12496
35.6k
            out += WC_AES_BLOCK_SIZE;
12497
35.6k
        }
12498
698
    }
12499
698
    if ((ret == 0) && (inSz > 0)) {
12500
634
        ret = wc_AesEncrypt(aes, B, A);
12501
634
    }
12502
698
    if ((ret == 0) && (inSz > 0)) {
12503
634
        xorbuf(A, in, inSz);
12504
634
        XMEMCPY(out, A, inSz);
12505
634
    }
12506
12507
698
    ForceZero(A, sizeof(A));
12508
698
    ForceZero(B, sizeof(B));
12509
12510
#ifdef WOLFSSL_CHECK_MEM_ZERO
12511
    wc_MemZero_Check(A, sizeof(A));
12512
    wc_MemZero_Check(B, sizeof(B));
12513
#endif
12514
12515
698
    VECTOR_REGISTERS_POP;
12516
12517
698
    return ret;
12518
698
}
12519
12520
#ifdef HAVE_AES_DECRYPT
12521
/* Software AES - CCM Decrypt */
12522
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12523
                   const byte* nonce, word32 nonceSz,
12524
                   const byte* authTag, word32 authTagSz,
12525
                   const byte* authIn, word32 authInSz)
12526
2.12k
{
12527
#ifdef WOLFSSL_AESNI
12528
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
12529
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
12530
#else
12531
2.12k
    byte A[WC_AES_BLOCK_SIZE];
12532
2.12k
    byte B[WC_AES_BLOCK_SIZE];
12533
2.12k
#endif
12534
2.12k
    byte* o;
12535
2.12k
    byte lenSz;
12536
2.12k
    word32 i, oSz;
12537
2.12k
    byte mask = 0xFF;
12538
2.12k
    const word32 wordSz = (word32)sizeof(word32);
12539
2.12k
    int ret = 0;
12540
12541
    /* sanity check on arguments */
12542
2.12k
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
12543
2.12k
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
12544
2.12k
        authTagSz > WC_AES_BLOCK_SIZE)
12545
0
        return BAD_FUNC_ARG;
12546
12547
    /* Sanity check on authIn to prevent segfault in xorbuf() where
12548
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
12549
2.12k
    if (authIn == NULL && authInSz > 0)
12550
0
        return BAD_FUNC_ARG;
12551
12552
    /* sanity check on tag size */
12553
2.12k
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
12554
0
        return BAD_FUNC_ARG;
12555
0
    }
12556
12557
2.12k
#ifdef WOLF_CRYPTO_CB
12558
2.12k
    #ifndef WOLF_CRYPTO_CB_FIND
12559
2.12k
    if (aes->devId != INVALID_DEVID)
12560
0
    #endif
12561
0
    {
12562
0
        int crypto_cb_ret =
12563
0
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
12564
0
            authTag, authTagSz, authIn, authInSz);
12565
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
12566
0
            return crypto_cb_ret;
12567
        /* fall-through when unavailable */
12568
0
    }
12569
2.12k
#endif
12570
12571
2.12k
    o = out;
12572
2.12k
    oSz = inSz;
12573
2.12k
    XMEMSET(A, 0, sizeof A);
12574
2.12k
    XMEMCPY(B+1, nonce, nonceSz);
12575
2.12k
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
12576
12577
2.12k
    B[0] = (byte)(lenSz - 1U);
12578
8.48k
    for (i = 0; i < lenSz; i++)
12579
6.36k
        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
12580
2.12k
    B[15] = 1;
12581
12582
#ifdef WOLFSSL_CHECK_MEM_ZERO
12583
    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
12584
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
12585
#endif
12586
12587
2.12k
    VECTOR_REGISTERS_PUSH;
12588
12589
#ifdef WOLFSSL_AESNI
12590
    if (aes->use_aesni) {
12591
        while (oSz >= WC_AES_BLOCK_SIZE * 4) {
12592
            AesCcmCtrIncSet4(B, lenSz);
12593
12594
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
12595
                            (int)aes->rounds);
12596
12597
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
12598
            XMEMCPY(o, A, WC_AES_BLOCK_SIZE * 4);
12599
12600
            oSz -= WC_AES_BLOCK_SIZE * 4;
12601
            in += WC_AES_BLOCK_SIZE * 4;
12602
            o += WC_AES_BLOCK_SIZE * 4;
12603
12604
            AesCcmCtrInc4(B, lenSz);
12605
        }
12606
    }
12607
#endif
12608
12609
11.7k
    while (oSz >= WC_AES_BLOCK_SIZE) {
12610
9.67k
        ret = wc_AesEncrypt(aes, B, A);
12611
9.67k
        if (ret != 0)
12612
0
            break;
12613
9.67k
        xorbuf(A, in, WC_AES_BLOCK_SIZE);
12614
9.67k
        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
12615
9.67k
        AesCcmCtrInc(B, lenSz);
12616
9.67k
        oSz -= WC_AES_BLOCK_SIZE;
12617
9.67k
        in += WC_AES_BLOCK_SIZE;
12618
9.67k
        o += WC_AES_BLOCK_SIZE;
12619
9.67k
    }
12620
12621
2.12k
    if ((ret == 0) && (inSz > 0))
12622
2.11k
        ret = wc_AesEncrypt(aes, B, A);
12623
12624
2.12k
    if ((ret == 0) && (inSz > 0)) {
12625
2.11k
        xorbuf(A, in, oSz);
12626
2.11k
        XMEMCPY(o, A, oSz);
12627
8.46k
        for (i = 0; i < lenSz; i++)
12628
6.34k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
12629
2.11k
        ret = wc_AesEncrypt(aes, B, A);
12630
2.11k
    }
12631
12632
2.12k
    if (ret == 0) {
12633
2.12k
        o = out;
12634
2.12k
        oSz = inSz;
12635
12636
2.12k
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
12637
2.12k
                      + (8 * (((byte)authTagSz - 2) / 2))
12638
2.12k
                      + (lenSz - 1));
12639
8.48k
        for (i = 0; i < lenSz; i++) {
12640
6.36k
            if (mask && i >= wordSz)
12641
0
                mask = 0x00;
12642
6.36k
            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
12643
6.36k
        }
12644
12645
2.12k
        ret = wc_AesEncrypt(aes, B, A);
12646
2.12k
    }
12647
12648
2.12k
    if (ret == 0) {
12649
2.12k
        if (authInSz > 0)
12650
2.12k
            ret = roll_auth(aes, authIn, authInSz, A);
12651
2.12k
    }
12652
2.12k
    if ((ret == 0) && (inSz > 0))
12653
2.11k
        ret = roll_x(aes, o, oSz, A);
12654
12655
2.12k
    if (ret == 0) {
12656
2.12k
        B[0] = (byte)(lenSz - 1U);
12657
8.48k
        for (i = 0; i < lenSz; i++)
12658
6.36k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
12659
2.12k
        ret = wc_AesEncrypt(aes, B, B);
12660
2.12k
    }
12661
12662
2.12k
    if (ret == 0)
12663
2.12k
        xorbuf(A, B, authTagSz);
12664
12665
2.12k
    if (ret == 0) {
12666
2.12k
        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
12667
            /* If the authTag check fails, don't keep the decrypted data.
12668
             * Unfortunately, you need the decrypted data to calculate the
12669
             * check value. */
12670
            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
12671
                        defined(ACVP_VECTOR_TESTING)
12672
            WOLFSSL_MSG("Preserve output for vector responses");
12673
            #else
12674
2.12k
            if (inSz > 0)
12675
2.11k
                XMEMSET(out, 0, inSz);
12676
2.12k
            #endif
12677
2.12k
            ret = AES_CCM_AUTH_E;
12678
2.12k
        }
12679
2.12k
    }
12680
12681
2.12k
    ForceZero(A, sizeof(A));
12682
2.12k
    ForceZero(B, sizeof(B));
12683
2.12k
    o = NULL;
12684
12685
#ifdef WOLFSSL_CHECK_MEM_ZERO
12686
    wc_MemZero_Check(A, sizeof(A));
12687
    wc_MemZero_Check(B, sizeof(B));
12688
#endif
12689
12690
2.12k
    VECTOR_REGISTERS_POP;
12691
12692
2.12k
    return ret;
12693
2.12k
}
12694
12695
#endif /* HAVE_AES_DECRYPT */
12696
#endif /* software CCM */
12697
12698
/* abstract functions that call lower level AESCCM functions */
12699
#ifndef WC_NO_RNG
12700
12701
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
12702
685
{
12703
685
    int ret = 0;
12704
12705
685
    if (aes == NULL || nonce == NULL ||
12706
685
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
12707
12708
0
        ret = BAD_FUNC_ARG;
12709
0
    }
12710
12711
685
    if (ret == 0) {
12712
685
        XMEMCPY(aes->reg, nonce, nonceSz);
12713
685
        aes->nonceSz = nonceSz;
12714
12715
        /* Invocation counter should be 2^61 */
12716
685
        aes->invokeCtr[0] = 0;
12717
685
        aes->invokeCtr[1] = 0xE0000000;
12718
685
    }
12719
12720
685
    return ret;
12721
685
}
12722
12723
12724
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
12725
                        byte* ivOut, word32 ivOutSz,
12726
                        byte* authTag, word32 authTagSz,
12727
                        const byte* authIn, word32 authInSz)
12728
698
{
12729
698
    int ret = 0;
12730
12731
698
    if (aes == NULL || out == NULL ||
12732
698
        (in == NULL && sz != 0) ||
12733
698
        ivOut == NULL ||
12734
698
        (authIn == NULL && authInSz != 0) ||
12735
698
        (ivOutSz != aes->nonceSz)) {
12736
12737
0
        ret = BAD_FUNC_ARG;
12738
0
    }
12739
12740
698
    if (ret == 0) {
12741
698
        aes->invokeCtr[0]++;
12742
698
        if (aes->invokeCtr[0] == 0) {
12743
0
            aes->invokeCtr[1]++;
12744
0
            if (aes->invokeCtr[1] == 0)
12745
0
                ret = AES_CCM_OVERFLOW_E;
12746
0
        }
12747
698
    }
12748
12749
698
    if (ret == 0) {
12750
698
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
12751
698
                               (byte*)aes->reg, aes->nonceSz,
12752
698
                               authTag, authTagSz,
12753
698
                               authIn, authInSz);
12754
698
        if (ret == 0) {
12755
698
            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
12756
698
            IncCtr((byte*)aes->reg, aes->nonceSz);
12757
698
        }
12758
698
    }
12759
12760
698
    return ret;
12761
698
}
12762
12763
#endif /* WC_NO_RNG */
12764
12765
#endif /* HAVE_AESCCM */
12766
12767
#ifndef WC_NO_CONSTRUCTORS
12768
Aes* wc_AesNew(void* heap, int devId, int *result_code)
12769
0
{
12770
0
    int ret;
12771
0
    Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
12772
0
    if (aes == NULL) {
12773
0
        ret = MEMORY_E;
12774
0
    }
12775
0
    else {
12776
0
        ret = wc_AesInit(aes, heap, devId);
12777
0
        if (ret != 0) {
12778
0
            XFREE(aes, heap, DYNAMIC_TYPE_AES);
12779
0
            aes = NULL;
12780
0
        }
12781
0
    }
12782
12783
0
    if (result_code != NULL)
12784
0
        *result_code = ret;
12785
12786
0
    return aes;
12787
0
}
12788
12789
int wc_AesDelete(Aes *aes, Aes** aes_p)
12790
0
{
12791
0
    if (aes == NULL)
12792
0
        return BAD_FUNC_ARG;
12793
0
    wc_AesFree(aes);
12794
0
    XFREE(aes, aes->heap, DYNAMIC_TYPE_AES);
12795
0
    if (aes_p != NULL)
12796
0
        *aes_p = NULL;
12797
0
    return 0;
12798
0
}
12799
#endif /* !WC_NO_CONSTRUCTORS */
12800
12801
/* Initialize Aes */
12802
int wc_AesInit(Aes* aes, void* heap, int devId)
12803
6.44k
{
12804
6.44k
    int ret = 0;
12805
12806
6.44k
    if (aes == NULL)
12807
0
        return BAD_FUNC_ARG;
12808
12809
6.44k
    XMEMSET(aes, 0, sizeof(*aes));
12810
12811
6.44k
    aes->heap = heap;
12812
12813
6.44k
#if defined(WOLF_CRYPTO_CB) || defined(WOLFSSL_STM32U5_DHUK)
12814
6.44k
    aes->devId = devId;
12815
#else
12816
    (void)devId;
12817
#endif
12818
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
12819
    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
12820
                                                        aes->heap, devId);
12821
#endif /* WOLFSSL_ASYNC_CRYPT */
12822
12823
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
12824
    aes->alFd = WC_SOCK_NOTSET;
12825
    aes->rdFd = WC_SOCK_NOTSET;
12826
#endif
12827
#if defined(WOLFSSL_DEVCRYPTO) && \
12828
   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
12829
    aes->ctx.cfd = -1;
12830
#endif
12831
#if defined(WOLFSSL_IMXRT_DCP)
12832
    DCPAesInit(aes);
12833
#endif
12834
12835
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
12836
    ret = wc_psa_aes_init(aes);
12837
#endif
12838
12839
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
12840
    if (ret == 0)
12841
        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
12842
#endif
12843
12844
6.44k
    return ret;
12845
6.44k
}
12846
12847
#ifdef WOLF_PRIVATE_KEY_ID
12848
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
12849
0
{
12850
0
    int ret = 0;
12851
12852
0
    if (aes == NULL)
12853
0
        ret = BAD_FUNC_ARG;
12854
0
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
12855
0
        ret = BUFFER_E;
12856
12857
0
    if (ret == 0)
12858
0
        ret = wc_AesInit(aes, heap, devId);
12859
0
    if (ret == 0) {
12860
0
        XMEMCPY(aes->id, id, (size_t)len);
12861
0
        aes->idLen = len;
12862
0
        aes->labelLen = 0;
12863
0
    }
12864
12865
0
    return ret;
12866
0
}
12867
12868
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
12869
0
{
12870
0
    int ret = 0;
12871
0
    size_t labelLen = 0;
12872
12873
0
    if (aes == NULL || label == NULL)
12874
0
        ret = BAD_FUNC_ARG;
12875
0
    if (ret == 0) {
12876
0
        labelLen = XSTRLEN(label);
12877
0
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
12878
0
            ret = BUFFER_E;
12879
0
    }
12880
12881
0
    if (ret == 0)
12882
0
        ret = wc_AesInit(aes, heap, devId);
12883
0
    if (ret == 0) {
12884
0
        XMEMCPY(aes->label, label, labelLen);
12885
0
        aes->labelLen = (int)labelLen;
12886
0
        aes->idLen = 0;
12887
0
    }
12888
12889
0
    return ret;
12890
0
}
12891
#endif
12892
12893
/* Free Aes resources */
12894
void wc_AesFree(Aes* aes)
12895
331k
{
12896
331k
    if (aes == NULL) {
12897
325k
        return;
12898
325k
    }
12899
12900
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
12901
    (void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
12902
#endif
12903
12904
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
12905
    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
12906
#endif /* WOLFSSL_ASYNC_CRYPT */
12907
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
12908
    if (aes->rdFd > 0) { /* negative is error case */
12909
        close(aes->rdFd);
12910
        aes->rdFd = WC_SOCK_NOTSET;
12911
    }
12912
    if (aes->alFd > 0) {
12913
        close(aes->alFd);
12914
        aes->alFd = WC_SOCK_NOTSET;
12915
    }
12916
#endif /* WOLFSSL_AFALG */
12917
#ifdef WOLFSSL_KCAPI_AES
12918
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
12919
    if (aes->init == 1) {
12920
        kcapi_cipher_destroy(aes->handle);
12921
    }
12922
    aes->init = 0;
12923
    aes->handle = NULL;
12924
#endif
12925
#if defined(WOLFSSL_DEVCRYPTO) && \
12926
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
12927
    wc_DevCryptoFree(&aes->ctx);
12928
#endif
12929
6.44k
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
12930
6.44k
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
12931
6.44k
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
12932
6.44k
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
12933
6.44k
#endif
12934
#if defined(WOLFSSL_IMXRT_DCP)
12935
    DCPAesFree(aes);
12936
#endif
12937
6.44k
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
12938
6.44k
    !defined(WOLFSSL_AESNI)
12939
6.44k
    if (aes->streamData != NULL) {
12940
1.04k
        ForceZero(aes->streamData, aes->streamData_sz);
12941
1.04k
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
12942
1.04k
        aes->streamData = NULL;
12943
1.04k
    }
12944
6.44k
#endif
12945
12946
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
12947
    if (aes->useSWCrypt == 0) {
12948
        se050_aes_free(aes);
12949
    }
12950
#endif
12951
12952
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
12953
    wc_psa_aes_free(aes);
12954
#endif
12955
12956
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
12957
    wc_MAXQ10XX_AesFree(aes);
12958
#endif
12959
12960
#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
12961
    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
12962
    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
12963
    wc_fspsm_Aesfree(aes);
12964
#endif
12965
12966
6.44k
    ForceZero(aes, sizeof(Aes));
12967
12968
#ifdef WOLFSSL_CHECK_MEM_ZERO
12969
    wc_MemZero_Check(aes, sizeof(Aes));
12970
#endif
12971
6.44k
}
12972
12973
int wc_AesGetKeySize(Aes* aes, word32* keySize)
12974
0
{
12975
0
    int ret = 0;
12976
12977
0
    if (aes == NULL || keySize == NULL) {
12978
0
        return BAD_FUNC_ARG;
12979
0
    }
12980
12981
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
12982
    return wc_psa_aes_get_key_size(aes, keySize);
12983
#endif
12984
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
12985
    *keySize = aes->ctx.key.keySize;
12986
    return ret;
12987
#endif
12988
0
    switch (aes->rounds) {
12989
0
#ifdef WOLFSSL_AES_128
12990
0
    case 10:
12991
0
        *keySize = 16;
12992
0
        break;
12993
0
#endif
12994
0
#ifdef WOLFSSL_AES_192
12995
0
    case 12:
12996
0
        *keySize = 24;
12997
0
        break;
12998
0
#endif
12999
0
#ifdef WOLFSSL_AES_256
13000
0
    case 14:
13001
0
        *keySize = 32;
13002
0
        break;
13003
0
#endif
13004
0
    default:
13005
0
        *keySize = 0;
13006
0
        ret = BAD_FUNC_ARG;
13007
0
    }
13008
13009
0
    return ret;
13010
0
}
13011
13012
#endif /* !WOLFSSL_TI_CRYPT */
13013
13014
/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
13015
 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
13016
 */
13017
#ifndef VECTOR_REGISTERS_PUSH
13018
    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
13019
#endif
13020
#ifndef VECTOR_REGISTERS_POP
13021
    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
13022
#endif
13023
13024
#ifdef HAVE_AES_ECB
13025
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
13026
        !defined(WOLFSSL_QNX_CAAM)
13027
    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
13028
13029
#elif defined(WOLFSSL_AFALG)
13030
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
13031
13032
#elif defined(WOLFSSL_DEVCRYPTO_AES)
13033
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
13034
13035
#elif defined(WOLFSSL_RISCV_ASM)
13036
    /* implemented in wolfcrypt/src/port/riscv/riscv-64-aes.c */
13037
13038
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
13039
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
13040
13041
#elif defined(MAX3266X_AES)
13042
13043
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13044
{
13045
    int status;
13046
    word32 keySize;
13047
13048
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13049
        return BAD_FUNC_ARG;
13050
13051
    status = wc_AesGetKeySize(aes, &keySize);
13052
    if (status != 0) {
13053
        return status;
13054
    }
13055
13056
    status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key,
13057
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
13058
13059
    return status;
13060
}
13061
13062
#ifdef HAVE_AES_DECRYPT
13063
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13064
{
13065
    int status;
13066
    word32 keySize;
13067
13068
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13069
        return BAD_FUNC_ARG;
13070
13071
    status = wc_AesGetKeySize(aes, &keySize);
13072
    if (status != 0) {
13073
        return status;
13074
    }
13075
13076
    status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key,
13077
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
13078
13079
    return status;
13080
}
13081
#endif /* HAVE_AES_DECRYPT */
13082
13083
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
13084
13085
/* Software AES - ECB */
13086
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13087
{
13088
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13089
        return BAD_FUNC_ARG;
13090
13091
    return AES_ECB_encrypt(aes, in, out, sz);
13092
}
13093
13094
13095
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13096
{
13097
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13098
        return BAD_FUNC_ARG;
13099
13100
    return AES_ECB_decrypt(aes, in, out, sz);
13101
}
13102
13103
#else
13104
13105
/* Software AES - ECB */
13106
static WARN_UNUSED_RESULT int _AesEcbEncrypt(
13107
    Aes* aes, byte* out, const byte* in, word32 sz)
13108
816
{
13109
816
    int ret = 0;
13110
13111
816
#ifdef WOLF_CRYPTO_CB
13112
816
    #ifndef WOLF_CRYPTO_CB_FIND
13113
816
    if (aes->devId != INVALID_DEVID)
13114
71
    #endif
13115
71
    {
13116
71
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
13117
71
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13118
0
            return ret;
13119
71
        ret = 0;
13120
        /* fall-through when unavailable */
13121
71
    }
13122
816
#endif
13123
#ifdef WOLFSSL_IMXRT_DCP
13124
    if (aes->keylen == 16)
13125
        return DCPAesEcbEncrypt(aes, out, in, sz);
13126
#endif
13127
13128
816
    VECTOR_REGISTERS_PUSH;
13129
13130
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
13131
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
13132
    AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
13133
#else
13134
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
13135
#endif
13136
#else
13137
#ifdef WOLFSSL_AESNI
13138
    if (aes->use_aesni) {
13139
        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
13140
    }
13141
    else
13142
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13143
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13144
    if (aes->use_aes_hw_crypto) {
13145
        AES_encrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
13146
            (int)aes->rounds);
13147
    }
13148
    else
13149
#endif
13150
816
    {
13151
816
#if defined(NEED_AES_TABLES)
13152
816
        AesEncryptBlocks_C(aes, in, out, sz);
13153
#else
13154
        word32 i;
13155
13156
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
13157
            ret = wc_AesEncryptDirect(aes, out, in);
13158
            if (ret != 0)
13159
                break;
13160
            in += WC_AES_BLOCK_SIZE;
13161
            out += WC_AES_BLOCK_SIZE;
13162
        }
13163
#endif
13164
816
    }
13165
816
#endif
13166
13167
816
    VECTOR_REGISTERS_POP;
13168
13169
816
    return ret;
13170
816
}
13171
13172
#ifdef HAVE_AES_DECRYPT
13173
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
13174
    Aes* aes, byte* out, const byte* in, word32 sz)
13175
153
{
13176
153
    int ret = 0;
13177
13178
153
#ifdef WOLF_CRYPTO_CB
13179
153
    #ifndef WOLF_CRYPTO_CB_FIND
13180
153
    if (aes->devId != INVALID_DEVID)
13181
119
    #endif
13182
119
    {
13183
119
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
13184
119
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13185
0
            return ret;
13186
119
        ret = 0;
13187
        /* fall-through when unavailable */
13188
119
    }
13189
153
#endif
13190
#ifdef WOLFSSL_IMXRT_DCP
13191
    if (aes->keylen == 16)
13192
        return DCPAesEcbDecrypt(aes, out, in, sz);
13193
#endif
13194
13195
153
    VECTOR_REGISTERS_PUSH;
13196
13197
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
13198
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
13199
    AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
13200
#else
13201
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
13202
#endif
13203
#else
13204
#ifdef WOLFSSL_AESNI
13205
    if (aes->use_aesni) {
13206
        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
13207
    }
13208
    else
13209
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13210
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13211
    if (aes->use_aes_hw_crypto) {
13212
        AES_decrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
13213
            (int)aes->rounds);
13214
    }
13215
    else
13216
#endif
13217
153
    {
13218
153
#if defined(NEED_AES_TABLES)
13219
153
        AesDecryptBlocks_C(aes, in, out, sz);
13220
#else
13221
        word32 i;
13222
13223
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
13224
            ret = wc_AesDecryptDirect(aes, out, in);
13225
            if (ret != 0)
13226
                break;
13227
            in += WC_AES_BLOCK_SIZE;
13228
            out += WC_AES_BLOCK_SIZE;
13229
        }
13230
#endif
13231
153
    }
13232
153
#endif
13233
13234
153
    VECTOR_REGISTERS_POP;
13235
13236
153
    return ret;
13237
153
}
13238
#endif
13239
13240
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13241
745
{
13242
745
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13243
0
      return BAD_FUNC_ARG;
13244
745
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
13245
0
        return BAD_LENGTH_E;
13246
0
    }
13247
13248
745
    return _AesEcbEncrypt(aes, out, in, sz);
13249
745
}
13250
13251
#ifdef HAVE_AES_DECRYPT
13252
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13253
34
{
13254
34
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13255
0
      return BAD_FUNC_ARG;
13256
34
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
13257
0
        return BAD_LENGTH_E;
13258
0
    }
13259
13260
34
    return _AesEcbDecrypt(aes, out, in, sz);
13261
34
}
13262
#endif /* HAVE_AES_DECRYPT */
13263
#endif
13264
#endif /* HAVE_AES_ECB */
13265
13266
#if defined(WOLFSSL_AES_CFB)
13267
/* Feedback AES mode
13268
 *
13269
 * aes structure holding key to use for encryption
13270
 * out buffer to hold result of encryption (must be at least as large as input
13271
 *     buffer)
13272
 * in  buffer to encrypt
13273
 * sz  size of input buffer
13274
 * mode flag to specify AES mode
13275
 *
13276
 * returns 0 on success and negative error values on failure
13277
 */
13278
/* Software AES - CFB Encrypt */
13279
static WARN_UNUSED_RESULT int AesCfbEncrypt_C(Aes* aes, byte* out,
13280
    const byte* in, word32 sz)
13281
0
{
13282
0
    int ret = 0;
13283
0
    word32 processed;
13284
13285
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
13286
0
        return BAD_FUNC_ARG;
13287
0
    }
13288
0
    if (sz == 0) {
13289
0
        return 0;
13290
0
    }
13291
13292
0
    if (aes->left > 0) {
13293
        /* consume any unused bytes left in aes->tmp */
13294
0
        processed = min(aes->left, sz);
13295
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
13296
0
            processed);
13297
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out,
13298
0
            processed);
13299
0
        aes->left -= processed;
13300
0
        out += processed;
13301
0
        in += processed;
13302
0
        sz -= processed;
13303
0
    }
13304
13305
0
    VECTOR_REGISTERS_PUSH;
13306
13307
0
    while (sz >= WC_AES_BLOCK_SIZE) {
13308
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->reg, (byte*)aes->reg);
13309
0
        if (ret != 0) {
13310
0
            break;
13311
0
        }
13312
0
        xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
13313
0
        XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
13314
0
        out += WC_AES_BLOCK_SIZE;
13315
0
        in  += WC_AES_BLOCK_SIZE;
13316
0
        sz  -= WC_AES_BLOCK_SIZE;
13317
0
    }
13318
13319
    /* encrypt left over data */
13320
0
    if ((ret == 0) && sz) {
13321
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
13322
0
        if (ret == 0) {
13323
0
            xorbufout(out, in, aes->tmp, sz);
13324
0
            XMEMCPY(aes->reg, out, sz);
13325
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
13326
0
        }
13327
0
    }
13328
13329
0
    VECTOR_REGISTERS_POP;
13330
13331
0
    return ret;
13332
0
}
13333
13334
13335
#if defined(HAVE_AES_DECRYPT)
13336
/* CFB 128
13337
 *
13338
 * aes structure holding key to use for decryption
13339
 * out buffer to hold result of decryption (must be at least as large as input
13340
 *     buffer)
13341
 * in  buffer to decrypt
13342
 * sz  size of input buffer
13343
 *
13344
 * returns 0 on success and negative error values on failure
13345
 */
13346
/* Software AES - CFB Decrypt */
13347
static WARN_UNUSED_RESULT int AesCfbDecrypt_C(Aes* aes, byte* out,
13348
    const byte* in, word32 sz, byte mode)
13349
0
{
13350
0
    int ret = 0;
13351
0
    word32 processed;
13352
13353
0
    (void)mode;
13354
13355
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
13356
0
        return BAD_FUNC_ARG;
13357
0
    }
13358
0
    if (sz == 0) {
13359
0
        return 0;
13360
0
    }
13361
13362
0
    if (aes->left > 0) {
13363
        /* consume any unused bytes left in aes->tmp */
13364
0
        processed = min(aes->left, sz);
13365
        /* copy input over to aes->reg */
13366
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, processed);
13367
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
13368
0
            processed);
13369
0
        aes->left -= processed;
13370
0
        out += processed;
13371
0
        in += processed;
13372
0
        sz -= processed;
13373
0
    }
13374
13375
0
    VECTOR_REGISTERS_PUSH;
13376
13377
    #if !defined(WOLFSSL_SMALL_STACK) && defined(HAVE_AES_ECB) && \
13378
        !defined(WOLFSSL_PIC32MZ_CRYPT) && \
13379
        (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
13380
    {
13381
        ALIGN16 byte tmp[4 * WC_AES_BLOCK_SIZE];
13382
        while (sz >= 4 * WC_AES_BLOCK_SIZE) {
13383
            XMEMCPY(tmp, aes->reg, WC_AES_BLOCK_SIZE);
13384
            XMEMCPY(tmp + WC_AES_BLOCK_SIZE, in, 3 * WC_AES_BLOCK_SIZE);
13385
            XMEMCPY(aes->reg, in + 3 * WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
13386
            ret = wc_AesEcbEncrypt(aes, tmp, tmp, 4 * WC_AES_BLOCK_SIZE);
13387
            if (ret != 0) {
13388
                break;
13389
            }
13390
            xorbufout(out, in, tmp, 4 * WC_AES_BLOCK_SIZE);
13391
            out += 4 * WC_AES_BLOCK_SIZE;
13392
            in  += 4 * WC_AES_BLOCK_SIZE;
13393
            sz  -= 4 * WC_AES_BLOCK_SIZE;
13394
        }
13395
    }
13396
    #endif
13397
0
    while (sz >= WC_AES_BLOCK_SIZE) {
13398
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
13399
0
        if (ret != 0) {
13400
0
            break;
13401
0
        }
13402
0
        XMEMCPY((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
13403
0
        xorbufout(out, in, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
13404
0
        out += WC_AES_BLOCK_SIZE;
13405
0
        in  += WC_AES_BLOCK_SIZE;
13406
0
        sz  -= WC_AES_BLOCK_SIZE;
13407
0
    }
13408
13409
    /* decrypt left over data */
13410
0
    if ((ret == 0) && sz) {
13411
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
13412
0
        if (ret == 0) {
13413
0
            XMEMCPY(aes->reg, in, sz);
13414
0
            xorbufout(out, in, aes->tmp, sz);
13415
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
13416
0
        }
13417
0
    }
13418
13419
0
    VECTOR_REGISTERS_POP;
13420
13421
0
    return ret;
13422
0
}
13423
#endif /* HAVE_AES_DECRYPT */
13424
13425
/* CFB 128
13426
 *
13427
 * aes structure holding key to use for encryption
13428
 * out buffer to hold result of encryption (must be at least as large as input
13429
 *     buffer)
13430
 * in  buffer to encrypt
13431
 * sz  size of input buffer
13432
 *
13433
 * returns 0 on success and negative error values on failure
13434
 */
13435
/* Software AES - CFB Encrypt */
13436
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13437
0
{
13438
0
    return AesCfbEncrypt_C(aes, out, in, sz);
13439
0
}
13440
13441
13442
#ifdef HAVE_AES_DECRYPT
13443
/* CFB 128
13444
 *
13445
 * aes structure holding key to use for decryption
13446
 * out buffer to hold result of decryption (must be at least as large as input
13447
 *     buffer)
13448
 * in  buffer to decrypt
13449
 * sz  size of input buffer
13450
 *
13451
 * returns 0 on success and negative error values on failure
13452
 */
13453
/* Software AES - CFB Decrypt */
13454
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13455
0
{
13456
0
    return AesCfbDecrypt_C(aes, out, in, sz, AES_CFB_MODE);
13457
0
}
13458
#endif /* HAVE_AES_DECRYPT */
13459
13460
#ifndef WOLFSSL_NO_AES_CFB_1_8
13461
/* shift the whole WC_AES_BLOCK_SIZE array left by 8 or 1 bits */
13462
static void shiftLeftArray(byte* ary, byte shift)
13463
37.5k
{
13464
37.5k
    int i;
13465
13466
37.5k
    if (shift == WOLFSSL_BIT_SIZE) {
13467
        /* shifting over by 8 bits */
13468
45.3k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
13469
42.5k
            ary[i] = ary[i+1];
13470
42.5k
        }
13471
2.83k
        ary[i] = 0;
13472
2.83k
    }
13473
34.7k
    else {
13474
        /* shifting over by 7 or less bits */
13475
555k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
13476
520k
            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
13477
520k
            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
13478
520k
            ary[i] = (byte)((ary[i] << shift) + carry);
13479
520k
        }
13480
34.7k
        ary[i] = (byte)(ary[i] << shift);
13481
34.7k
    }
13482
37.5k
}
13483
13484
13485
/* returns 0 on success and negative values on failure */
13486
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
13487
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
13488
302
{
13489
302
    byte *pt;
13490
302
    int ret = 0;
13491
13492
302
    if (aes == NULL || out == NULL || in == NULL) {
13493
0
        return BAD_FUNC_ARG;
13494
0
    }
13495
13496
302
    if (sz == 0) {
13497
0
        return 0;
13498
0
    }
13499
13500
302
    VECTOR_REGISTERS_PUSH;
13501
13502
3.13k
    while (sz > 0) {
13503
2.83k
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
13504
2.83k
        if (ret != 0)
13505
0
            break;
13506
2.83k
        if (dir == AES_DECRYPTION) {
13507
1.45k
            pt = (byte*)aes->reg;
13508
13509
            /* LSB + CAT */
13510
1.45k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
13511
1.45k
            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
13512
1.45k
        }
13513
13514
        /* MSB + XOR */
13515
    #ifdef BIG_ENDIAN_ORDER
13516
        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
13517
    #endif
13518
2.83k
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
13519
2.83k
        if (dir == AES_ENCRYPTION) {
13520
1.38k
            pt = (byte*)aes->reg;
13521
13522
            /* LSB + CAT */
13523
1.38k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
13524
1.38k
            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
13525
1.38k
        }
13526
13527
2.83k
        out += 1;
13528
2.83k
        in  += 1;
13529
2.83k
        sz  -= 1;
13530
2.83k
    }
13531
13532
302
    VECTOR_REGISTERS_POP;
13533
13534
302
    return ret;
13535
302
}
13536
13537
13538
/* returns 0 on success and negative values on failure */
13539
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
13540
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
13541
525
{
13542
525
    byte tmp;
13543
525
    byte cur = 0; /* hold current work in order to handle inline in=out */
13544
525
    byte* pt;
13545
525
    int bit = 7;
13546
525
    int ret = 0;
13547
13548
525
    if (aes == NULL || out == NULL || in == NULL) {
13549
0
        return BAD_FUNC_ARG;
13550
0
    }
13551
13552
525
    if (sz == 0) {
13553
0
        return 0;
13554
0
    }
13555
13556
525
    VECTOR_REGISTERS_PUSH;
13557
13558
35.2k
    while (sz > 0) {
13559
34.7k
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
13560
34.7k
        if (ret != 0)
13561
0
            break;
13562
34.7k
        if (dir == AES_DECRYPTION) {
13563
16.6k
            pt = (byte*)aes->reg;
13564
13565
            /* LSB + CAT */
13566
16.6k
            tmp = (byte)((0X01U << bit) & in[0]);
13567
16.6k
            tmp = (byte)(tmp >> bit);
13568
16.6k
            tmp &= 0x01;
13569
16.6k
            shiftLeftArray((byte*)aes->reg, 1);
13570
16.6k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
13571
16.6k
        }
13572
13573
        /* MSB  + XOR */
13574
34.7k
        tmp = (byte)((0X01U << bit) & in[0]);
13575
34.7k
        pt = (byte*)aes->tmp;
13576
34.7k
        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
13577
34.7k
        tmp &= 0x01;
13578
34.7k
        cur = (byte)(cur | (tmp << bit));
13579
13580
13581
34.7k
        if (dir == AES_ENCRYPTION) {
13582
18.0k
            pt = (byte*)aes->reg;
13583
13584
            /* LSB + CAT */
13585
18.0k
            shiftLeftArray((byte*)aes->reg, 1);
13586
18.0k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
13587
18.0k
        }
13588
13589
34.7k
        bit--;
13590
34.7k
        if (bit < 0) {
13591
4.34k
            out[0] = cur;
13592
4.34k
            out += 1;
13593
4.34k
            in  += 1;
13594
4.34k
            sz  -= 1;
13595
4.34k
            bit = 7U;
13596
4.34k
            cur = 0;
13597
4.34k
        }
13598
30.3k
        else {
13599
30.3k
            sz -= 1;
13600
30.3k
        }
13601
34.7k
    }
13602
13603
525
    if (ret == 0) {
13604
525
        if (bit >= 0 && bit < 7) {
13605
0
            out[0] = cur;
13606
0
        }
13607
525
    }
13608
13609
525
    VECTOR_REGISTERS_POP;
13610
13611
525
    return ret;
13612
525
}
13613
13614
13615
/* CFB 1
13616
 *
13617
 * aes structure holding key to use for encryption
13618
 * out buffer to hold result of encryption (must be at least as large as input
13619
 *     buffer)
13620
 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
13621
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
13622
 *
13623
 * returns 0 on success and negative values on failure
13624
 */
13625
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13626
395
{
13627
395
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
13628
395
}
13629
13630
13631
/* CFB 8
13632
 *
13633
 * aes structure holding key to use for encryption
13634
 * out buffer to hold result of encryption (must be at least as large as input
13635
 *     buffer)
13636
 * in  buffer to encrypt
13637
 * sz  size of input buffer
13638
 *
13639
 * returns 0 on success and negative values on failure
13640
 */
13641
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13642
205
{
13643
205
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
13644
205
}
13645
#ifdef HAVE_AES_DECRYPT
13646
13647
/* CFB 1
13648
 *
13649
 * aes structure holding key to use for encryption
13650
 * out buffer to hold result of encryption (must be at least as large as input
13651
 *     buffer)
13652
 * in  buffer to encrypt
13653
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
13654
 *
13655
 * returns 0 on success and negative values on failure
13656
 */
13657
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13658
130
{
13659
130
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
13660
130
}
13661
13662
13663
/* CFB 8
13664
 *
13665
 * aes structure holding key to use for encryption
13666
 * out buffer to hold result of encryption (must be at least as large as input
13667
 *     buffer)
13668
 * in  buffer to encrypt
13669
 * sz  size of input buffer
13670
 *
13671
 * returns 0 on success and negative values on failure
13672
 */
13673
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13674
97
{
13675
97
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
13676
97
}
13677
#endif /* HAVE_AES_DECRYPT */
13678
#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
13679
#endif /* WOLFSSL_AES_CFB */
13680
13681
#ifdef WOLFSSL_AES_OFB
13682
/* OFB AES mode
13683
 *
13684
 * aes structure holding key to use for encryption
13685
 * out buffer to hold result of encryption (must be at least as large as input
13686
 *     buffer)
13687
 * in  buffer to encrypt
13688
 * sz  size of input buffer
13689
 *
13690
 * returns 0 on success and negative error values on failure
13691
 */
13692
/* Software AES - OFB Encrypt/Decrypt */
13693
static WARN_UNUSED_RESULT int AesOfbCrypt_C(Aes* aes, byte* out, const byte* in,
13694
    word32 sz)
13695
994
{
13696
994
    int ret = 0;
13697
994
    word32 processed;
13698
13699
994
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
13700
0
        return BAD_FUNC_ARG;
13701
0
    }
13702
994
    if (sz == 0) {
13703
0
        return 0;
13704
0
    }
13705
13706
994
    if (aes->left > 0) {
13707
        /* consume any unused bytes left in aes->tmp */
13708
547
        processed = min(aes->left, sz);
13709
547
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
13710
547
            processed);
13711
547
        aes->left -= processed;
13712
547
        out += processed;
13713
547
        in += processed;
13714
547
        sz -= processed;
13715
547
    }
13716
13717
994
    VECTOR_REGISTERS_PUSH;
13718
13719
1.82k
    while (sz >= WC_AES_BLOCK_SIZE) {
13720
833
        ret = wc_AesEncryptDirect(aes, (byte*)aes->reg, (byte*)aes->reg);
13721
833
        if (ret != 0) {
13722
0
            break;
13723
0
        }
13724
833
        xorbufout(out, in, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
13725
833
        out += WC_AES_BLOCK_SIZE;
13726
833
        in  += WC_AES_BLOCK_SIZE;
13727
833
        sz  -= WC_AES_BLOCK_SIZE;
13728
833
    }
13729
13730
    /* encrypt left over data */
13731
994
    if ((ret == 0) && sz) {
13732
315
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
13733
315
        if (ret == 0) {
13734
315
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
13735
315
            xorbufout(out, in, aes->tmp, sz);
13736
315
            aes->left = WC_AES_BLOCK_SIZE - sz;
13737
315
        }
13738
315
    }
13739
13740
994
    VECTOR_REGISTERS_POP;
13741
13742
994
    return ret;
13743
994
}
13744
13745
/* OFB
13746
 *
13747
 * aes structure holding key to use for encryption
13748
 * out buffer to hold result of encryption (must be at least as large as input
13749
 *     buffer)
13750
 * in  buffer to encrypt
13751
 * sz  size of input buffer
13752
 *
13753
 * returns 0 on success and negative error values on failure
13754
 */
13755
/* Software AES - OFB Encrypt */
13756
int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13757
775
{
13758
775
    return AesOfbCrypt_C(aes, out, in, sz);
13759
775
}
13760
13761
13762
#ifdef HAVE_AES_DECRYPT
13763
/* OFB
13764
 *
13765
 * aes structure holding key to use for decryption
13766
 * out buffer to hold result of decryption (must be at least as large as input
13767
 *     buffer)
13768
 * in  buffer to decrypt
13769
 * sz  size of input buffer
13770
 *
13771
 * returns 0 on success and negative error values on failure
13772
 */
13773
/* Software AES - OFB Decrypt */
13774
int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13775
219
{
13776
219
    return AesOfbCrypt_C(aes, out, in, sz);
13777
219
}
13778
#endif /* HAVE_AES_DECRYPT */
13779
#endif /* WOLFSSL_AES_OFB */
13780
13781
13782
#ifdef HAVE_AES_KEYWRAP
13783
13784
/* Initialize key wrap counter with value */
13785
static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
13786
0
{
13787
0
    word32 i;
13788
0
    word32 bytes;
13789
13790
0
    bytes = sizeof(word32);
13791
0
    for (i = 0; i < sizeof(word32); i++) {
13792
0
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
13793
0
        bytes--;
13794
0
    }
13795
0
}
13796
13797
/* Increment key wrap counter */
13798
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
13799
0
{
13800
0
    int i;
13801
13802
    /* in network byte order so start at end and work back */
13803
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
13804
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
13805
0
            return;
13806
0
    }
13807
0
}
13808
13809
/* Decrement key wrap counter */
13810
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
13811
0
{
13812
0
    int i;
13813
13814
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
13815
0
        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
13816
0
            return;
13817
0
    }
13818
0
}
13819
13820
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
13821
        word32 outSz, const byte* iv)
13822
0
{
13823
0
    word32 i;
13824
0
    byte* r;
13825
0
    int j;
13826
0
    int ret = 0;
13827
13828
0
    byte t[KEYWRAP_BLOCK_SIZE];
13829
0
    byte tmp[WC_AES_BLOCK_SIZE];
13830
13831
    /* n must be at least 2 64-bit blocks, output size is (n + 1) 8 bytes (64-bit) */
13832
0
    if (aes == NULL || in  == NULL || inSz < 2*KEYWRAP_BLOCK_SIZE ||
13833
0
        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
13834
0
        return BAD_FUNC_ARG;
13835
13836
    /* input must be multiple of 64-bits */
13837
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
13838
0
        return BAD_FUNC_ARG;
13839
13840
0
    r = out + 8;
13841
0
    XMEMCPY(r, in, inSz);
13842
0
    XMEMSET(t, 0, sizeof(t));
13843
13844
    /* user IV is optional */
13845
0
    if (iv == NULL) {
13846
0
        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
13847
0
    } else {
13848
0
        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
13849
0
    }
13850
13851
0
    VECTOR_REGISTERS_PUSH;
13852
13853
0
    for (j = 0; j <= 5; j++) {
13854
0
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
13855
            /* load R[i] */
13856
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
13857
13858
0
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
13859
0
            if (ret != 0)
13860
0
                break;
13861
13862
            /* calculate new A */
13863
0
            IncrementKeyWrapCounter(t);
13864
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
13865
13866
            /* save R[i] */
13867
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
13868
0
            r += KEYWRAP_BLOCK_SIZE;
13869
0
        }
13870
0
        if (ret != 0)
13871
0
            break;
13872
0
        r = out + KEYWRAP_BLOCK_SIZE;
13873
0
    }
13874
13875
0
    VECTOR_REGISTERS_POP;
13876
13877
0
    if (ret != 0)
13878
0
        return ret;
13879
13880
    /* C[0] = A */
13881
0
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
13882
13883
0
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
13884
0
}
13885
13886
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
13887
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
13888
                  byte* out, word32 outSz, const byte* iv)
13889
0
{
13890
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
13891
0
    int ret;
13892
13893
0
    if (key == NULL)
13894
0
        return BAD_FUNC_ARG;
13895
13896
0
#ifdef WOLFSSL_SMALL_STACK
13897
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
13898
0
                              DYNAMIC_TYPE_AES)) == NULL)
13899
0
        return MEMORY_E;
13900
0
#endif
13901
13902
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
13903
0
    if (ret != 0)
13904
0
        goto out;
13905
13906
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
13907
0
    if (ret != 0) {
13908
0
        wc_AesFree(aes);
13909
0
        goto out;
13910
0
    }
13911
13912
0
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
13913
13914
0
    wc_AesFree(aes);
13915
13916
0
  out:
13917
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
13918
13919
0
    return ret;
13920
0
}
13921
13922
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
13923
        word32 outSz, const byte* iv)
13924
0
{
13925
0
    byte* r;
13926
0
    word32 i, n;
13927
0
    int j;
13928
0
    int ret = 0;
13929
13930
0
    byte t[KEYWRAP_BLOCK_SIZE];
13931
0
    byte tmp[WC_AES_BLOCK_SIZE];
13932
13933
0
    const byte* expIv;
13934
0
    const byte defaultIV[] = {
13935
0
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
13936
0
    };
13937
13938
0
    if (aes == NULL || in == NULL || inSz < 3 * KEYWRAP_BLOCK_SIZE ||
13939
0
        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
13940
0
        return BAD_FUNC_ARG;
13941
13942
    /* input must be multiple of 64-bits */
13943
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
13944
0
        return BAD_FUNC_ARG;
13945
13946
    /* user IV optional */
13947
0
    if (iv != NULL)
13948
0
        expIv = iv;
13949
0
    else
13950
0
        expIv = defaultIV;
13951
13952
    /* A = C[0], R[i] = C[i] */
13953
0
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
13954
0
    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
13955
0
    XMEMSET(t, 0, sizeof(t));
13956
13957
0
    VECTOR_REGISTERS_PUSH;
13958
13959
    /* initialize counter to 6n */
13960
0
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
13961
0
    InitKeyWrapCounter(t, 6 * n);
13962
13963
0
    for (j = 5; j >= 0; j--) {
13964
0
        for (i = n; i >= 1; i--) {
13965
13966
            /* calculate A */
13967
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
13968
0
            DecrementKeyWrapCounter(t);
13969
13970
            /* load R[i], starting at end of R */
13971
0
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
13972
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
13973
0
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
13974
0
            if (ret != 0)
13975
0
                break;
13976
13977
            /* save R[i] */
13978
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
13979
0
        }
13980
0
        if (ret != 0)
13981
0
            break;
13982
0
    }
13983
13984
0
    VECTOR_REGISTERS_POP;
13985
13986
0
    if (ret != 0)
13987
0
        return ret;
13988
13989
    /* verify IV */
13990
0
    if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
13991
0
        return BAD_KEYWRAP_IV_E;
13992
13993
0
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
13994
0
}
13995
13996
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
13997
                    byte* out, word32 outSz, const byte* iv)
13998
0
{
13999
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
14000
0
    int ret;
14001
14002
0
    (void)iv;
14003
14004
0
    if (key == NULL)
14005
0
        return BAD_FUNC_ARG;
14006
14007
0
#ifdef WOLFSSL_SMALL_STACK
14008
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
14009
0
                              DYNAMIC_TYPE_AES)) == NULL)
14010
0
        return MEMORY_E;
14011
0
#endif
14012
14013
14014
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14015
0
    if (ret != 0)
14016
0
        goto out;
14017
14018
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
14019
0
    if (ret != 0) {
14020
0
        wc_AesFree(aes);
14021
0
        goto out;
14022
0
    }
14023
14024
0
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
14025
14026
0
    wc_AesFree(aes);
14027
14028
0
  out:
14029
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
14030
14031
0
    return ret;
14032
0
}
14033
14034
#endif /* HAVE_AES_KEYWRAP */
14035
14036
#ifdef WOLFSSL_AES_XTS
14037
14038
/* Galois Field to use */
14039
560
#define GF_XTS 0x87
14040
14041
/* Set up keys for encryption and/or decryption.
14042
 *
14043
 * aes   buffer holding aes subkeys
14044
 * heap  heap hint to use for memory. Can be NULL
14045
 * devId id to use with async crypto. Can be 0
14046
 *
14047
 * return 0 on success
14048
 */
14049
int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
14050
345
{
14051
345
    int    ret = 0;
14052
14053
345
    if (aes == NULL) {
14054
0
        return BAD_FUNC_ARG;
14055
0
    }
14056
14057
345
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
14058
0
        return ret;
14059
0
    }
14060
345
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
14061
0
        (void)wc_AesFree(&aes->tweak);
14062
0
        return ret;
14063
0
    }
14064
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14065
    if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) {
14066
        (void)wc_AesFree(&aes->tweak);
14067
        (void)wc_AesFree(&aes->aes);
14068
        return ret;
14069
    }
14070
#endif
14071
14072
345
    return 0;
14073
345
}
14074
14075
/* Set up keys for encryption and/or decryption.
14076
 *
14077
 * aes   buffer holding aes subkeys
14078
 * key   AES key for encrypt/decrypt and tweak process (concatenated)
14079
 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
14080
 *       32 for a 16 byte key.
14081
 * dir   direction: AES_ENCRYPTION, AES_DECRYPTION, or
14082
 *       AES_ENCRYPTION_AND_DECRYPTION
14083
 *
14084
 * return 0 on success
14085
 */
14086
int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
14087
268
{
14088
268
    word32 keySz;
14089
268
    int    ret = 0;
14090
14091
268
    if (aes == NULL || key == NULL) {
14092
0
        return BAD_FUNC_ARG;
14093
0
    }
14094
14095
268
    if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION)
14096
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14097
        && (dir != AES_ENCRYPTION_AND_DECRYPTION)
14098
#endif
14099
268
        )
14100
0
    {
14101
0
        return BAD_FUNC_ARG;
14102
0
    }
14103
14104
268
    if ((len != (AES_128_KEY_SIZE*2)) &&
14105
87
#ifndef HAVE_FIPS
14106
        /* XTS-384 not allowed by FIPS and can not be treated like
14107
         * RSA-4096 bit keys back in the day, can not vendor affirm
14108
         * the use of 2 concatenated 192-bit keys (XTS-384) */
14109
87
        (len != (AES_192_KEY_SIZE*2)) &&
14110
87
#endif
14111
87
        (len != (AES_256_KEY_SIZE*2)))
14112
0
    {
14113
0
        WOLFSSL_MSG("Unsupported key size");
14114
0
        return WC_KEY_SIZE_E;
14115
0
    }
14116
14117
268
    keySz = len/2;
14118
14119
#ifdef HAVE_FIPS
14120
    if (XMEMCMP(key, key + keySz, keySz) == 0) {
14121
        WOLFSSL_MSG("FIPS AES-XTS main and tweak keys must differ");
14122
        return BAD_FUNC_ARG;
14123
    }
14124
#endif
14125
14126
268
    if (dir == AES_ENCRYPTION
14127
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14128
        || dir == AES_ENCRYPTION_AND_DECRYPTION
14129
#endif
14130
268
        )
14131
146
    {
14132
146
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
14133
146
    }
14134
14135
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14136
    if ((ret == 0) && ((dir == AES_DECRYPTION)
14137
                       || (dir == AES_ENCRYPTION_AND_DECRYPTION)))
14138
        ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION);
14139
#else
14140
268
    if (dir == AES_DECRYPTION)
14141
122
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
14142
268
#endif
14143
14144
268
    if (ret == 0)
14145
268
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
14146
268
                AES_ENCRYPTION);
14147
14148
#ifdef WOLFSSL_AESNI
14149
    if (ret == 0) {
14150
        /* With WC_C_DYNAMIC_FALLBACK, the main and tweak keys could have
14151
         * conflicting _aesni status, but the AES-XTS asm implementations need
14152
         * them to all be AESNI.  If any aren't, disable AESNI on all.
14153
         */
14154
    #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14155
        if ((((dir == AES_ENCRYPTION) ||
14156
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
14157
             && (aes->aes.use_aesni != aes->tweak.use_aesni))
14158
            ||
14159
            (((dir == AES_DECRYPTION) ||
14160
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
14161
             && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)))
14162
        {
14163
        #ifdef WC_C_DYNAMIC_FALLBACK
14164
            aes->aes.use_aesni = 0;
14165
            aes->aes_decrypt.use_aesni = 0;
14166
            aes->tweak.use_aesni = 0;
14167
        #else
14168
            ret = SYSLIB_FAILED_E;
14169
        #endif
14170
        }
14171
    #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
14172
        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
14173
        #ifdef WC_C_DYNAMIC_FALLBACK
14174
            aes->aes.use_aesni = 0;
14175
            aes->tweak.use_aesni = 0;
14176
        #else
14177
            ret = SYSLIB_FAILED_E;
14178
        #endif
14179
        }
14180
    #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
14181
    }
14182
#endif /* WOLFSSL_AESNI */
14183
14184
268
    return ret;
14185
268
}
14186
14187
/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
14188
 *
14189
 * Note: is up to user to call wc_AesXtsFree when done.
14190
 *
14191
 * return 0 on success
14192
 */
14193
int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
14194
        void* heap, int devId)
14195
0
{
14196
0
    int    ret = 0;
14197
14198
0
    if (aes == NULL || key == NULL) {
14199
0
        return BAD_FUNC_ARG;
14200
0
    }
14201
14202
0
    ret = wc_AesXtsInit(aes, heap, devId);
14203
0
    if (ret != 0)
14204
0
        return ret;
14205
14206
0
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
14207
14208
0
    if (ret != 0)
14209
0
        wc_AesXtsFree(aes);
14210
14211
0
    return ret;
14212
0
}
14213
14214
14215
/* This is used to free up resources used by Aes structs
14216
 *
14217
 * aes AES keys to free
14218
 *
14219
 * return 0 on success
14220
 */
14221
int wc_AesXtsFree(XtsAes* aes)
14222
345
{
14223
345
    if (aes != NULL) {
14224
345
        wc_AesFree(&aes->aes);
14225
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14226
        wc_AesFree(&aes->aes_decrypt);
14227
#endif
14228
345
        wc_AesFree(&aes->tweak);
14229
345
    }
14230
14231
345
    return 0;
14232
345
}
14233
14234
14235
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
14236
 * instead of a byte array. This just converts the word64 to a byte array and
14237
 * calls wc_AesXtsEncrypt.
14238
 *
14239
 * aes    AES keys to use for block encrypt/decrypt
14240
 * out    output buffer to hold cipher text
14241
 * in     input plain text buffer to encrypt
14242
 * sz     size of both out and in buffers
14243
 * sector value to use for tweak
14244
 *
14245
 * returns 0 on success
14246
 */
14247
int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
14248
        word32 sz, word64 sector)
14249
0
{
14250
0
    byte* pt;
14251
0
    byte  i[WC_AES_BLOCK_SIZE];
14252
14253
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
14254
#ifdef BIG_ENDIAN_ORDER
14255
    sector = ByteReverseWord64(sector);
14256
#endif
14257
0
    pt = (byte*)&sector;
14258
0
    XMEMCPY(i, pt, sizeof(word64));
14259
14260
0
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
14261
0
}
14262
14263
#ifdef HAVE_AES_DECRYPT
14264
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
14265
 * instead of a byte array. This just converts the word64 to a byte array.
14266
 *
14267
 * aes    AES keys to use for block encrypt/decrypt
14268
 * out    output buffer to hold plain text
14269
 * in     input cipher text buffer to encrypt
14270
 * sz     size of both out and in buffers
14271
 * sector value to use for tweak
14272
 *
14273
 * returns 0 on success
14274
 */
14275
int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
14276
        word64 sector)
14277
0
{
14278
0
    byte* pt;
14279
0
    byte  i[WC_AES_BLOCK_SIZE];
14280
14281
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
14282
#ifdef BIG_ENDIAN_ORDER
14283
    sector = ByteReverseWord64(sector);
14284
#endif
14285
0
    pt = (byte*)&sector;
14286
0
    XMEMCPY(i, pt, sizeof(word64));
14287
14288
0
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
14289
0
}
14290
#endif
14291
14292
#ifdef WOLFSSL_AESNI
14293
14294
#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
14295
    #define USE_INTEL_SPEEDUP
14296
#endif
14297
14298
#if defined(USE_INTEL_SPEEDUP)
14299
    #define HAVE_INTEL_AVX1
14300
    #define HAVE_INTEL_AVX2
14301
#endif /* USE_INTEL_SPEEDUP */
14302
14303
void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
14304
                     const unsigned char* i, const unsigned char* key,
14305
                     const unsigned char* key2, int nr)
14306
                     XASM_LINK("AES_XTS_encrypt_aesni");
14307
#ifdef WOLFSSL_AESXTS_STREAM
14308
void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
14309
                     int tweak_nr)
14310
                     XASM_LINK("AES_XTS_init_aesni");
14311
void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
14312
                     const unsigned char* key, unsigned char *i, int nr)
14313
                     XASM_LINK("AES_XTS_encrypt_update_aesni");
14314
#endif
14315
#ifdef HAVE_INTEL_AVX1
14316
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
14317
                     word32 sz, const unsigned char* i,
14318
                     const unsigned char* key, const unsigned char* key2,
14319
                     int nr)
14320
                     XASM_LINK("AES_XTS_encrypt_avx1");
14321
#ifdef WOLFSSL_AESXTS_STREAM
14322
void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
14323
                     int tweak_nr)
14324
                     XASM_LINK("AES_XTS_init_avx1");
14325
void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
14326
                     const unsigned char* key, unsigned char *i, int nr)
14327
                     XASM_LINK("AES_XTS_encrypt_update_avx1");
14328
#endif
14329
#endif /* HAVE_INTEL_AVX1 */
14330
14331
#ifdef HAVE_AES_DECRYPT
14332
void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
14333
                     const unsigned char* i, const unsigned char* key,
14334
                     const unsigned char* key2, int nr)
14335
                     XASM_LINK("AES_XTS_decrypt_aesni");
14336
#ifdef WOLFSSL_AESXTS_STREAM
14337
void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
14338
                     const unsigned char* key, unsigned char *i, int nr)
14339
                     XASM_LINK("AES_XTS_decrypt_update_aesni");
14340
#endif
14341
#ifdef HAVE_INTEL_AVX1
14342
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
14343
                     word32 sz, const unsigned char* i,
14344
                     const unsigned char* key, const unsigned char* key2,
14345
                     int nr)
14346
                     XASM_LINK("AES_XTS_decrypt_avx1");
14347
#ifdef WOLFSSL_AESXTS_STREAM
14348
void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
14349
                     const unsigned char* key, unsigned char *i, int nr)
14350
                     XASM_LINK("AES_XTS_decrypt_update_avx1");
14351
#endif
14352
#endif /* HAVE_INTEL_AVX1 */
14353
#endif /* HAVE_AES_DECRYPT */
14354
14355
#endif /* WOLFSSL_AESNI */
14356
14357
#ifdef HAVE_AES_ECB
14358
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM) || \
14359
      defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14360
/* helper function for encrypting / decrypting full buffer at once */
14361
static WARN_UNUSED_RESULT int _AesXtsHelper(
14362
    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
14363
190
{
14364
190
    word32 outSz   = sz;
14365
190
    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
14366
190
    byte*  pt      = out;
14367
14368
190
    outSz -= WC_AES_BLOCK_SIZE;
14369
14370
652
    while (outSz > 0) {
14371
462
        word32 j;
14372
462
        byte carry = 0;
14373
14374
        /* multiply by shift left and propagate carry */
14375
7.36k
        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
14376
6.90k
            byte tmpC;
14377
14378
6.90k
            tmpC   = (pt[j] >> 7) & 0x01;
14379
6.90k
            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
14380
6.90k
            carry  = tmpC;
14381
6.90k
        }
14382
462
        if (carry) {
14383
229
            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
14384
229
        }
14385
14386
462
        pt += WC_AES_BLOCK_SIZE;
14387
462
    }
14388
14389
190
    xorbuf(out, in, totalSz);
14390
190
#ifndef WOLFSSL_RISCV_ASM
14391
190
    if (dir == AES_ENCRYPTION) {
14392
71
        return _AesEcbEncrypt(aes, out, out, totalSz);
14393
71
    }
14394
119
    else {
14395
119
        return _AesEcbDecrypt(aes, out, out, totalSz);
14396
119
    }
14397
#else
14398
    if (dir == AES_ENCRYPTION) {
14399
        return wc_AesEcbEncrypt(aes, out, out, totalSz);
14400
    }
14401
    else {
14402
        return wc_AesEcbDecrypt(aes, out, out, totalSz);
14403
    }
14404
#endif
14405
190
}
14406
#endif
14407
#endif /* HAVE_AES_ECB */
14408
14409
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
14410
 *
14411
 * xaes  AES keys to use for block encrypt/decrypt
14412
 * out   output buffer to hold cipher text
14413
 * in    input plain text buffer to encrypt
14414
 * sz    size of both out and in buffers
14415
 * i     value to use for tweak
14416
 *
14417
 * returns 0 on success
14418
 */
14419
/* Software AES - XTS Encrypt  */
14420
14421
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM) || \
14422
      defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14423
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
14424
                                  word32 sz,
14425
                                  byte *i);
14426
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
14427
        const byte* i)
14428
113
{
14429
113
    int ret;
14430
113
    byte tweak_block[WC_AES_BLOCK_SIZE];
14431
14432
113
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
14433
113
    if (ret != 0)
14434
0
        return ret;
14435
14436
113
    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
14437
113
}
14438
14439
#ifdef WOLFSSL_AESXTS_STREAM
14440
14441
/* Block-streaming AES-XTS tweak setup.
14442
 *
14443
 * xaes  AES keys to use for block encrypt/decrypt
14444
 * i     readwrite value to use for tweak
14445
 *
14446
 * returns 0 on success
14447
 */
14448
static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
14449
    return wc_AesEncryptDirect(&xaes->tweak, i, i);
14450
}
14451
14452
#endif /* WOLFSSL_AESXTS_STREAM */
14453
14454
/* Block-streaming AES-XTS.
14455
 *
14456
 * Supply block-aligned input data with successive calls.  Final call need not
14457
 * be block aligned.
14458
 *
14459
 * xaes  AES keys to use for block encrypt/decrypt
14460
 * out   output buffer to hold cipher text
14461
 * in    input plain text buffer to encrypt
14462
 * sz    size of both out and in buffers
14463
 *
14464
 * returns 0 on success
14465
 */
14466
/* Software AES - XTS Encrypt  */
14467
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
14468
                                  word32 sz,
14469
                                  byte *i)
14470
113
{
14471
113
    int ret = 0;
14472
113
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
14473
113
    Aes *aes = &xaes->aes;
14474
14475
113
#ifdef HAVE_AES_ECB
14476
    /* encrypt all of buffer at once when possible */
14477
113
    if (in != out) { /* can not handle inline */
14478
71
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
14479
71
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
14480
0
            return ret;
14481
71
    }
14482
113
#endif
14483
14484
442
    while (blocks > 0) {
14485
329
        word32 j;
14486
329
        byte carry = 0;
14487
14488
329
#ifdef HAVE_AES_ECB
14489
329
        if (in == out)
14490
92
#endif
14491
92
        { /* check for if inline */
14492
92
            byte buf[WC_AES_BLOCK_SIZE];
14493
14494
92
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
14495
92
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
14496
92
            ret = wc_AesEncryptDirect(aes, out, buf);
14497
92
            if (ret != 0)
14498
0
                return ret;
14499
92
        }
14500
329
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
14501
14502
        /* multiply by shift left and propagate carry */
14503
5.59k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
14504
5.26k
            byte tmpC;
14505
14506
5.26k
            tmpC   = (i[j] >> 7) & 0x01;
14507
5.26k
            i[j] = (byte)((i[j] << 1) + carry);
14508
5.26k
            carry  = tmpC;
14509
5.26k
        }
14510
329
        if (carry) {
14511
161
            i[0] ^= GF_XTS;
14512
161
        }
14513
14514
329
        in  += WC_AES_BLOCK_SIZE;
14515
329
        out += WC_AES_BLOCK_SIZE;
14516
329
        sz  -= WC_AES_BLOCK_SIZE;
14517
329
        blocks--;
14518
329
    }
14519
14520
    /* stealing operation of XTS to handle left overs */
14521
113
    if (sz > 0) {
14522
38
        byte buf[WC_AES_BLOCK_SIZE];
14523
14524
38
        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
14525
38
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
14526
0
            return BUFFER_E;
14527
0
        }
14528
38
        if (in != out) {
14529
31
            XMEMCPY(out, buf, sz);
14530
31
            XMEMCPY(buf, in, sz);
14531
31
        }
14532
7
        else {
14533
7
            byte buf2[WC_AES_BLOCK_SIZE];
14534
14535
7
            XMEMCPY(buf2, buf, sz);
14536
7
            XMEMCPY(buf, in, sz);
14537
7
            XMEMCPY(out, buf2, sz);
14538
7
        }
14539
14540
38
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
14541
38
        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
14542
38
        if (ret == 0)
14543
38
            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
14544
38
    }
14545
14546
113
    return ret;
14547
113
}
14548
#endif
14549
14550
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
14551
 *
14552
 * xaes  AES keys to use for block encrypt/decrypt
14553
 * out   output buffer to hold cipher text
14554
 * in    input plain text buffer to encrypt
14555
 * sz    size of both out and in buffers
14556
 * i     value to use for tweak
14557
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
14558
 *       adds a sanity check on how the user calls the function.
14559
 *
14560
 * returns 0 on success
14561
 */
14562
int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
14563
        const byte* i, word32 iSz)
14564
123
{
14565
123
    int ret;
14566
14567
123
    Aes *aes;
14568
14569
123
    if (xaes == NULL || out == NULL || in == NULL) {
14570
0
        return BAD_FUNC_ARG;
14571
0
    }
14572
14573
#if FIPS_VERSION3_GE(6,0,0)
14574
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
14575
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
14576
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
14577
     */
14578
    if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
14579
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
14580
        return BAD_FUNC_ARG;
14581
    }
14582
#endif
14583
14584
123
    aes = &xaes->aes;
14585
14586
123
    if (aes->keylen == 0) {
14587
0
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
14588
0
        return BAD_FUNC_ARG;
14589
0
    }
14590
14591
123
    if (iSz < WC_AES_BLOCK_SIZE) {
14592
0
        return BAD_FUNC_ARG;
14593
0
    }
14594
14595
123
    if (sz < WC_AES_BLOCK_SIZE) {
14596
10
        WOLFSSL_MSG("Plain text input too small for encryption");
14597
10
        return BAD_FUNC_ARG;
14598
10
    }
14599
14600
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14601
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14602
    AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
14603
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
14604
    ret = 0;
14605
#else
14606
#ifdef WOLFSSL_AESNI
14607
    if (aes->use_aesni) {
14608
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
14609
#if defined(HAVE_INTEL_AVX1)
14610
        if (IS_INTEL_AVX1(intel_flags)) {
14611
            AES_XTS_encrypt_avx1(in, out, sz, i,
14612
                                 (const byte*)aes->key,
14613
                                 (const byte*)xaes->tweak.key,
14614
                                 (int)aes->rounds);
14615
            ret = 0;
14616
        }
14617
        else
14618
#endif
14619
        {
14620
            AES_XTS_encrypt_aesni(in, out, sz, i,
14621
                                  (const byte*)aes->key,
14622
                                  (const byte*)xaes->tweak.key,
14623
                                  (int)aes->rounds);
14624
            ret = 0;
14625
        }
14626
        RESTORE_VECTOR_REGISTERS();
14627
    }
14628
    else
14629
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14630
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14631
    if (aes->use_aes_hw_crypto) {
14632
        AES_XTS_encrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
14633
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
14634
        ret = 0;
14635
    }
14636
    else
14637
#endif
14638
113
    {
14639
113
        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
14640
113
    }
14641
113
#endif
14642
14643
113
    return ret;
14644
123
}
14645
14646
#ifdef WOLFSSL_AESXTS_STREAM
14647
14648
/* Block-streaming AES-XTS.
14649
 *
14650
 * xaes  AES keys to use for block encrypt/decrypt
14651
 * i     readwrite value to use for tweak
14652
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
14653
 *       adds a sanity check on how the user calls the function.
14654
 *
14655
 * returns 0 on success
14656
 */
14657
int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
14658
                         struct XtsAesStreamData *stream)
14659
{
14660
    int ret;
14661
14662
    Aes *aes;
14663
14664
    if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
14665
        return BAD_FUNC_ARG;
14666
    }
14667
14668
    if (iSz < WC_AES_BLOCK_SIZE) {
14669
        return BAD_FUNC_ARG;
14670
    }
14671
14672
    aes = &xaes->aes;
14673
14674
    if (aes->keylen == 0) {
14675
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
14676
        return BAD_FUNC_ARG;
14677
    }
14678
14679
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
14680
    stream->bytes_crypted_with_this_tweak = 0;
14681
14682
    {
14683
#ifdef WOLFSSL_AESNI
14684
        if (aes->use_aesni) {
14685
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14686
#if defined(HAVE_INTEL_AVX1)
14687
            if (IS_INTEL_AVX1(intel_flags)) {
14688
                AES_XTS_init_avx1(stream->tweak_block,
14689
                                  (const byte*)xaes->tweak.key,
14690
                                  (int)xaes->tweak.rounds);
14691
                ret = 0;
14692
            }
14693
            else
14694
#endif
14695
            {
14696
                AES_XTS_init_aesni(stream->tweak_block,
14697
                                   (const byte*)xaes->tweak.key,
14698
                                   (int)xaes->tweak.rounds);
14699
                ret = 0;
14700
            }
14701
            RESTORE_VECTOR_REGISTERS();
14702
        }
14703
        else
14704
#endif /* WOLFSSL_AESNI */
14705
        {
14706
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
14707
        }
14708
    }
14709
14710
    return ret;
14711
}
14712
14713
/* Block-streaming AES-XTS
14714
 *
14715
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
14716
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsEncryptUpdate().
14717
 * wc_AesXtsEncryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
14718
 *
14719
 * xaes  AES keys to use for block encrypt/decrypt
14720
 * out   output buffer to hold cipher text
14721
 * in    input plain text buffer to encrypt
14722
 * sz    size of both out and in buffers -- must be >= WC_AES_BLOCK_SIZE.
14723
 * i     value to use for tweak
14724
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
14725
 *       adds a sanity check on how the user calls the function.
14726
 *
14727
 * returns 0 on success
14728
 */
14729
static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
14730
                           struct XtsAesStreamData *stream)
14731
{
14732
    int ret;
14733
14734
#ifdef WOLFSSL_AESNI
14735
    Aes *aes;
14736
#endif
14737
14738
    if (xaes == NULL || out == NULL || in == NULL) {
14739
        return BAD_FUNC_ARG;
14740
    }
14741
14742
#ifdef WOLFSSL_AESNI
14743
    aes = &xaes->aes;
14744
#endif
14745
14746
    if (sz < WC_AES_BLOCK_SIZE) {
14747
        WOLFSSL_MSG("Plain text input too small for encryption");
14748
        return BAD_FUNC_ARG;
14749
    }
14750
14751
    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
14752
    {
14753
        WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
14754
        return BAD_FUNC_ARG;
14755
    }
14756
14757
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
14758
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
14759
                             stream->bytes_crypted_with_this_tweak))
14760
    {
14761
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
14762
                    "in AesXtsEncryptUpdate().");
14763
    }
14764
#endif
14765
#if FIPS_VERSION3_GE(6,0,0)
14766
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
14767
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
14768
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
14769
     */
14770
    if (stream->bytes_crypted_with_this_tweak >
14771
        FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
14772
    {
14773
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
14774
        return BAD_FUNC_ARG;
14775
    }
14776
#endif
14777
    {
14778
#ifdef WOLFSSL_AESNI
14779
        if (aes->use_aesni) {
14780
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14781
#if defined(HAVE_INTEL_AVX1)
14782
            if (IS_INTEL_AVX1(intel_flags)) {
14783
                AES_XTS_encrypt_update_avx1(in, out, sz,
14784
                                            (const byte*)aes->key,
14785
                                            stream->tweak_block,
14786
                                            (int)aes->rounds);
14787
                ret = 0;
14788
            }
14789
            else
14790
#endif
14791
            {
14792
                AES_XTS_encrypt_update_aesni(in, out, sz,
14793
                                            (const byte*)aes->key,
14794
                                            stream->tweak_block,
14795
                                            (int)aes->rounds);
14796
                ret = 0;
14797
            }
14798
            RESTORE_VECTOR_REGISTERS();
14799
        }
14800
        else
14801
#endif /* WOLFSSL_AESNI */
14802
        {
14803
            ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
14804
        }
14805
    }
14806
14807
    return ret;
14808
}
14809
14810
int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
14811
                           struct XtsAesStreamData *stream)
14812
{
14813
    if (stream == NULL)
14814
        return BAD_FUNC_ARG;
14815
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
14816
        return BAD_FUNC_ARG;
14817
    return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
14818
}
14819
14820
int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
14821
                           struct XtsAesStreamData *stream)
14822
{
14823
    int ret;
14824
    if (stream == NULL)
14825
        return BAD_FUNC_ARG;
14826
    if (sz > 0)
14827
        ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
14828
    else
14829
        ret = 0;
14830
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
14831
     * after finalization.
14832
     */
14833
    stream->bytes_crypted_with_this_tweak |= 1U;
14834
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
14835
#ifdef WOLFSSL_CHECK_MEM_ZERO
14836
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
14837
#endif
14838
    return ret;
14839
}
14840
14841
#endif /* WOLFSSL_AESXTS_STREAM */
14842
14843
#ifdef HAVE_AES_DECRYPT
14844
14845
/* Same process as encryption but use aes_decrypt key.
14846
 *
14847
 * xaes  AES keys to use for block encrypt/decrypt
14848
 * out   output buffer to hold plain text
14849
 * in    input cipher text buffer to decrypt
14850
 * sz    size of both out and in buffers
14851
 * i     value to use for tweak
14852
 *
14853
 * returns 0 on success
14854
 */
14855
/* Software AES - XTS Decrypt */
14856
14857
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM) || \
14858
      defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14859
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
14860
                                  word32 sz, byte *i);
14861
14862
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
14863
        const byte* i)
14864
119
{
14865
119
    int ret;
14866
119
    byte tweak_block[WC_AES_BLOCK_SIZE];
14867
14868
119
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
14869
119
    if (ret != 0)
14870
0
        return ret;
14871
14872
119
    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
14873
119
}
14874
14875
/* Block-streaming AES-XTS.
14876
 *
14877
 * Same process as encryption but use decrypt key.
14878
 *
14879
 * Supply block-aligned input data with successive calls.  Final call need not
14880
 * be block aligned.
14881
 *
14882
 * xaes  AES keys to use for block encrypt/decrypt
14883
 * out   output buffer to hold plain text
14884
 * in    input cipher text buffer to decrypt
14885
 * sz    size of both out and in buffers
14886
 * i     value to use for tweak
14887
 *
14888
 * returns 0 on success
14889
 */
14890
/* Software AES - XTS Decrypt */
14891
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
14892
                                  word32 sz, byte *i)
14893
119
{
14894
119
    int ret = 0;
14895
119
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
14896
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14897
    Aes *aes = &xaes->aes_decrypt;
14898
#else
14899
119
    Aes *aes = &xaes->aes;
14900
119
#endif
14901
119
    word32 j;
14902
119
    byte carry = 0;
14903
119
    byte stl = (sz % WC_AES_BLOCK_SIZE);
14904
14905
    /* if Stealing then break out of loop one block early to handle special
14906
     * case */
14907
119
    if (stl > 0) {
14908
43
        blocks--;
14909
43
    }
14910
14911
119
#ifdef HAVE_AES_ECB
14912
    /* decrypt all of buffer at once when possible */
14913
119
    if (in != out) { /* can not handle inline */
14914
119
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
14915
119
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
14916
0
            return ret;
14917
119
    }
14918
119
#endif
14919
14920
417
    while (blocks > 0) {
14921
298
#ifdef HAVE_AES_ECB
14922
298
        if (in == out)
14923
0
#endif
14924
0
        { /* check for if inline */
14925
0
            byte buf[WC_AES_BLOCK_SIZE];
14926
14927
0
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
14928
0
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
14929
0
            ret = wc_AesDecryptDirect(aes, out, buf);
14930
0
            if (ret != 0)
14931
0
                return ret;
14932
0
        }
14933
298
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
14934
14935
        /* multiply by shift left and propagate carry */
14936
5.06k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
14937
4.76k
            byte tmpC;
14938
14939
4.76k
            tmpC   = (i[j] >> 7) & 0x01;
14940
4.76k
            i[j] = (byte)((i[j] << 1) + carry);
14941
4.76k
            carry  = tmpC;
14942
4.76k
        }
14943
298
        if (carry) {
14944
148
            i[0] ^= GF_XTS;
14945
148
        }
14946
298
        carry = 0;
14947
14948
298
        in  += WC_AES_BLOCK_SIZE;
14949
298
        out += WC_AES_BLOCK_SIZE;
14950
298
        sz  -= WC_AES_BLOCK_SIZE;
14951
298
        blocks--;
14952
298
    }
14953
14954
    /* stealing operation of XTS to handle left overs */
14955
119
    if (sz >= WC_AES_BLOCK_SIZE) {
14956
43
        byte buf[WC_AES_BLOCK_SIZE];
14957
43
        byte tmp2[WC_AES_BLOCK_SIZE];
14958
14959
        /* multiply by shift left and propagate carry */
14960
731
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
14961
688
            byte tmpC;
14962
14963
688
            tmpC   = (i[j] >> 7) & 0x01;
14964
688
            tmp2[j] = (byte)((i[j] << 1) + carry);
14965
688
            carry  = tmpC;
14966
688
        }
14967
43
        if (carry) {
14968
22
            tmp2[0] ^= GF_XTS;
14969
22
        }
14970
14971
43
        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
14972
43
        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
14973
43
        ret = wc_AesDecryptDirect(aes, out, buf);
14974
43
        if (ret != 0)
14975
0
            return ret;
14976
43
        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
14977
14978
        /* tmp2 holds partial | last */
14979
43
        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
14980
43
        in  += WC_AES_BLOCK_SIZE;
14981
43
        out += WC_AES_BLOCK_SIZE;
14982
43
        sz  -= WC_AES_BLOCK_SIZE;
14983
14984
        /* Make buffer with end of cipher text | last */
14985
43
        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
14986
43
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
14987
0
            return BUFFER_E;
14988
0
        }
14989
43
        XMEMCPY(buf, in,   sz);
14990
43
        XMEMCPY(out, tmp2, sz);
14991
14992
43
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
14993
43
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
14994
43
        if (ret != 0)
14995
0
            return ret;
14996
43
        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
14997
43
        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
14998
43
    }
14999
15000
119
    return ret;
15001
119
}
15002
#endif
15003
15004
/* Same process as encryption but Aes key is AES_DECRYPTION type.
15005
 *
15006
 * xaes  AES keys to use for block encrypt/decrypt
15007
 * out   output buffer to hold plain text
15008
 * in    input cipher text buffer to decrypt
15009
 * sz    size of both out and in buffers
15010
 * i     value to use for tweak
15011
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15012
 *       adds a sanity check on how the user calls the function.
15013
 *
15014
 * returns 0 on success
15015
 */
15016
int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15017
        const byte* i, word32 iSz)
15018
122
{
15019
122
    int ret;
15020
122
    Aes *aes;
15021
15022
122
    if (xaes == NULL || out == NULL || in == NULL) {
15023
0
        return BAD_FUNC_ARG;
15024
0
    }
15025
15026
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15027
    aes = &xaes->aes_decrypt;
15028
#else
15029
122
    aes = &xaes->aes;
15030
122
#endif
15031
15032
/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
15033
 * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
15034
 * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes or
15035
 * 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
15036
 * return whenever sz / WC_AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
15037
 * not a sequence of complete blocks.
15038
 */
15039
15040
122
    if (aes->keylen == 0) {
15041
0
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
15042
0
        return BAD_FUNC_ARG;
15043
0
    }
15044
15045
122
    if (iSz < WC_AES_BLOCK_SIZE) {
15046
0
        return BAD_FUNC_ARG;
15047
0
    }
15048
15049
122
    if (sz < WC_AES_BLOCK_SIZE) {
15050
3
        WOLFSSL_MSG("Cipher text input too small for decryption");
15051
3
        return BAD_FUNC_ARG;
15052
3
    }
15053
15054
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
15055
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15056
    AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
15057
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15058
    ret = 0;
15059
#else
15060
#ifdef WOLFSSL_AESNI
15061
    if (aes->use_aesni) {
15062
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
15063
#if defined(HAVE_INTEL_AVX1)
15064
        if (IS_INTEL_AVX1(intel_flags)) {
15065
            AES_XTS_decrypt_avx1(in, out, sz, i,
15066
                                 (const byte*)aes->key,
15067
                                 (const byte*)xaes->tweak.key,
15068
                                 (int)aes->rounds);
15069
            ret = 0;
15070
        }
15071
        else
15072
#endif
15073
        {
15074
            AES_XTS_decrypt_aesni(in, out, sz, i,
15075
                                  (const byte*)aes->key,
15076
                                  (const byte*)xaes->tweak.key,
15077
                                  (int)aes->rounds);
15078
            ret = 0;
15079
        }
15080
        RESTORE_VECTOR_REGISTERS();
15081
    }
15082
    else
15083
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
15084
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15085
    if (aes->use_aes_hw_crypto) {
15086
        AES_XTS_decrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
15087
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15088
        ret = 0;
15089
    }
15090
    else
15091
#endif
15092
119
    {
15093
119
        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
15094
119
    }
15095
119
#endif
15096
15097
119
    return ret;
15098
122
}
15099
15100
#ifdef WOLFSSL_AESXTS_STREAM
15101
15102
/* Same process as encryption but Aes key is AES_DECRYPTION type.
15103
 *
15104
 * xaes  AES keys to use for block encrypt/decrypt
15105
 * i     readwrite value to use for tweak
15106
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15107
 *       adds a sanity check on how the user calls the function.
15108
 *
15109
 * returns 0 on success
15110
 */
15111
int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
15112
                         struct XtsAesStreamData *stream)
15113
{
15114
    int ret;
15115
    Aes *aes;
15116
15117
    if (xaes == NULL) {
15118
        return BAD_FUNC_ARG;
15119
    }
15120
15121
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15122
    aes = &xaes->aes_decrypt;
15123
#else
15124
    aes = &xaes->aes;
15125
#endif
15126
15127
    if (aes->keylen == 0) {
15128
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
15129
        return BAD_FUNC_ARG;
15130
    }
15131
15132
    if (iSz < WC_AES_BLOCK_SIZE) {
15133
        return BAD_FUNC_ARG;
15134
    }
15135
15136
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
15137
    stream->bytes_crypted_with_this_tweak = 0;
15138
15139
    {
15140
#ifdef WOLFSSL_AESNI
15141
        if (aes->use_aesni) {
15142
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15143
#if defined(HAVE_INTEL_AVX1)
15144
            if (IS_INTEL_AVX1(intel_flags)) {
15145
                AES_XTS_init_avx1(stream->tweak_block,
15146
                                  (const byte*)xaes->tweak.key,
15147
                                  (int)xaes->tweak.rounds);
15148
                ret = 0;
15149
            }
15150
            else
15151
#endif
15152
            {
15153
                AES_XTS_init_aesni(stream->tweak_block,
15154
                                   (const byte*)xaes->tweak.key,
15155
                                   (int)xaes->tweak.rounds);
15156
                ret = 0;
15157
            }
15158
            RESTORE_VECTOR_REGISTERS();
15159
        }
15160
        else
15161
#endif /* WOLFSSL_AESNI */
15162
        {
15163
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
15164
        }
15165
15166
    }
15167
15168
    return ret;
15169
}
15170
15171
/* Block-streaming AES-XTS
15172
 *
15173
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
15174
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsDecryptUpdate().
15175
 * wc_AesXtsDecryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
15176
 *
15177
 * xaes  AES keys to use for block encrypt/decrypt
15178
 * out   output buffer to hold plain text
15179
 * in    input cipher text buffer to decrypt
15180
 * sz    size of both out and in buffers
15181
 * i     tweak buffer of size WC_AES_BLOCK_SIZE.
15182
 *
15183
 * returns 0 on success
15184
 */
15185
static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15186
                           struct XtsAesStreamData *stream)
15187
{
15188
    int ret;
15189
#ifdef WOLFSSL_AESNI
15190
    Aes *aes;
15191
#endif
15192
15193
    if (xaes == NULL || out == NULL || in == NULL) {
15194
        return BAD_FUNC_ARG;
15195
    }
15196
15197
#ifdef WOLFSSL_AESNI
15198
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15199
    aes = &xaes->aes_decrypt;
15200
#else
15201
    aes = &xaes->aes;
15202
#endif
15203
#endif
15204
15205
    if (sz < WC_AES_BLOCK_SIZE) {
15206
        WOLFSSL_MSG("Cipher text input too small for decryption");
15207
        return BAD_FUNC_ARG;
15208
    }
15209
15210
    if (stream->bytes_crypted_with_this_tweak &
15211
        ((word32)WC_AES_BLOCK_SIZE - 1U))
15212
    {
15213
        WOLFSSL_MSG("AesXtsDecryptUpdate after previous finalizing call");
15214
        return BAD_FUNC_ARG;
15215
    }
15216
15217
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
15218
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
15219
                             stream->bytes_crypted_with_this_tweak))
15220
    {
15221
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
15222
                    "in AesXtsDecryptUpdate().");
15223
    }
15224
#endif
15225
15226
    {
15227
#ifdef WOLFSSL_AESNI
15228
        if (aes->use_aesni) {
15229
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15230
#if defined(HAVE_INTEL_AVX1)
15231
            if (IS_INTEL_AVX1(intel_flags)) {
15232
                AES_XTS_decrypt_update_avx1(in, out, sz,
15233
                                            (const byte*)aes->key,
15234
                                            stream->tweak_block,
15235
                                            (int)aes->rounds);
15236
                ret = 0;
15237
            }
15238
            else
15239
#endif
15240
            {
15241
                AES_XTS_decrypt_update_aesni(in, out, sz,
15242
                                             (const byte*)aes->key,
15243
                                             stream->tweak_block,
15244
                                             (int)aes->rounds);
15245
                ret = 0;
15246
            }
15247
            RESTORE_VECTOR_REGISTERS();
15248
        }
15249
        else
15250
#endif /* WOLFSSL_AESNI */
15251
        {
15252
            ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
15253
                                         stream->tweak_block);
15254
        }
15255
    }
15256
15257
    return ret;
15258
}
15259
15260
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15261
                           struct XtsAesStreamData *stream)
15262
{
15263
    if (stream == NULL)
15264
        return BAD_FUNC_ARG;
15265
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
15266
        return BAD_FUNC_ARG;
15267
    return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
15268
}
15269
15270
int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15271
                           struct XtsAesStreamData *stream)
15272
{
15273
    int ret;
15274
    if (stream == NULL)
15275
        return BAD_FUNC_ARG;
15276
    if (sz > 0)
15277
        ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
15278
    else
15279
        ret = 0;
15280
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
15281
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
15282
     * after finalization.
15283
     */
15284
    stream->bytes_crypted_with_this_tweak |= 1U;
15285
#ifdef WOLFSSL_CHECK_MEM_ZERO
15286
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
15287
#endif
15288
    return ret;
15289
}
15290
15291
#endif /* WOLFSSL_AESXTS_STREAM */
15292
#endif /* HAVE_AES_DECRYPT */
15293
15294
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
15295
 * sectorSz bytes
15296
 *
15297
 * xaes     AES keys to use for block encrypt
15298
 * out      output buffer to hold cipher text
15299
 * in       input plain text buffer to encrypt
15300
 * sz       size of both out and in buffers
15301
 * sector   value to use for tweak
15302
 * sectorSz size of the sector
15303
 *
15304
 * returns 0 on success
15305
 */
15306
int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
15307
        word32 sz, word64 sector, word32 sectorSz)
15308
0
{
15309
0
    int ret  = 0;
15310
0
    word32 iter = 0;
15311
0
    word32 sectorCount;
15312
0
    word32 remainder;
15313
15314
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
15315
0
        return BAD_FUNC_ARG;
15316
0
    }
15317
15318
0
    if (sz < WC_AES_BLOCK_SIZE) {
15319
0
        WOLFSSL_MSG("Cipher text input too small for encryption");
15320
0
        return BAD_FUNC_ARG;
15321
0
    }
15322
15323
0
    sectorCount  = sz / sectorSz;
15324
0
    remainder = sz % sectorSz;
15325
15326
0
    while (sectorCount) {
15327
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
15328
0
                in + (iter * sectorSz), sectorSz, sector);
15329
0
        if (ret != 0)
15330
0
            break;
15331
15332
0
        sectorCount--;
15333
0
        iter++;
15334
0
        sector++;
15335
0
    }
15336
15337
0
    if (remainder && ret == 0)
15338
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
15339
0
                in + (iter * sectorSz), remainder, sector);
15340
15341
0
    return ret;
15342
0
}
15343
15344
#ifdef HAVE_AES_DECRYPT
15345
15346
/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
15347
 *
15348
 * xaes     AES keys to use for block decrypt
15349
 * out      output buffer to hold cipher text
15350
 * in       input plain text buffer to encrypt
15351
 * sz       size of both out and in buffers
15352
 * sector   value to use for tweak
15353
 * sectorSz size of the sector
15354
 *
15355
 * returns 0 on success
15356
 */
15357
int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
15358
        word32 sz, word64 sector, word32 sectorSz)
15359
0
{
15360
0
    int ret  = 0;
15361
0
    word32 iter = 0;
15362
0
    word32 sectorCount;
15363
0
    word32 remainder;
15364
15365
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
15366
0
        return BAD_FUNC_ARG;
15367
0
    }
15368
15369
0
    if (sz < WC_AES_BLOCK_SIZE) {
15370
0
        WOLFSSL_MSG("Cipher text input too small for decryption");
15371
0
        return BAD_FUNC_ARG;
15372
0
    }
15373
15374
0
    sectorCount  = sz / sectorSz;
15375
0
    remainder = sz % sectorSz;
15376
15377
0
    while (sectorCount) {
15378
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
15379
0
                in + (iter * sectorSz), sectorSz, sector);
15380
0
        if (ret != 0)
15381
0
            break;
15382
15383
0
        sectorCount--;
15384
0
        iter++;
15385
0
        sector++;
15386
0
    }
15387
15388
0
    if (remainder && ret == 0)
15389
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
15390
0
                in + (iter * sectorSz), remainder, sector);
15391
15392
0
    return ret;
15393
0
}
15394
#endif /* HAVE_AES_DECRYPT */
15395
#endif /* WOLFSSL_AES_XTS */
15396
15397
#ifdef WOLFSSL_AES_SIV
15398
15399
/*
15400
 * See RFC 5297 Section 2.4.
15401
 */
15402
static WARN_UNUSED_RESULT int S2V(
15403
    const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc,
15404
    const byte* nonce, word32 nonceSz, const byte* data,
15405
    word32 dataSz, byte* out)
15406
0
{
15407
0
#ifdef WOLFSSL_SMALL_STACK
15408
0
    byte* tmp[3] = {NULL, NULL, NULL};
15409
0
    int i;
15410
0
    Cmac* cmac;
15411
#else
15412
    byte tmp[3][WC_AES_BLOCK_SIZE];
15413
    Cmac cmac[1];
15414
#endif
15415
0
    word32 macSz = WC_AES_BLOCK_SIZE;
15416
0
    int ret = 0;
15417
0
    byte tmpi = 0;
15418
0
    word32 ai;
15419
0
    word32 zeroBytes;
15420
15421
0
#ifdef WOLFSSL_SMALL_STACK
15422
0
    for (i = 0; i < 3; ++i) {
15423
0
        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15424
0
        if (tmp[i] == NULL) {
15425
0
            ret = MEMORY_E;
15426
0
            break;
15427
0
        }
15428
0
    }
15429
0
    if (ret == 0)
15430
0
#endif
15431
15432
0
    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
15433
        /* See RFC 5297 Section 7. */
15434
0
        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
15435
0
                    " 126.");
15436
0
        ret = BAD_FUNC_ARG;
15437
0
    }
15438
15439
0
    if (ret == 0) {
15440
0
        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
15441
0
        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
15442
15443
0
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
15444
0
                                 key, keySz);
15445
0
    }
15446
15447
0
    if (ret == 0) {
15448
        /* Loop over authenticated associated data AD1..ADn */
15449
0
        for (ai = 0; ai < numAssoc; ++ai) {
15450
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
15451
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
15452
0
                                     assoc[ai].assocSz, key, keySz);
15453
0
            if (ret != 0)
15454
0
                break;
15455
0
            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
15456
0
            tmpi = (byte)(1 - tmpi);
15457
0
        }
15458
15459
        /* Add nonce as final AD. See RFC 5297 Section 3. */
15460
0
        if ((ret == 0) && (nonceSz > 0)) {
15461
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
15462
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
15463
0
                                     nonceSz, key, keySz);
15464
0
            if (ret == 0) {
15465
0
                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
15466
0
            }
15467
0
            tmpi = (byte)(1U - tmpi);
15468
0
        }
15469
15470
        /* For simplicity of the remaining code, make sure the "final" result
15471
           is always in tmp[0]. */
15472
0
        if (tmpi == 1) {
15473
0
            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
15474
0
        }
15475
0
    }
15476
15477
0
    if (ret == 0) {
15478
0
        if (dataSz >= WC_AES_BLOCK_SIZE) {
15479
15480
0
            WC_ALLOC_VAR_EX(cmac, Cmac, 1, NULL, DYNAMIC_TYPE_CMAC,
15481
0
                ret=MEMORY_E);
15482
0
            if (WC_VAR_OK(cmac))
15483
0
            {
15484
            #ifdef WOLFSSL_CHECK_MEM_ZERO
15485
                /* Aes part is checked by wc_AesFree. */
15486
                wc_MemZero_Add("wc_AesCmacGenerate cmac",
15487
                    ((unsigned char *)cmac) + sizeof(Aes),
15488
                    sizeof(Cmac) - sizeof(Aes));
15489
            #endif
15490
0
                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
15491
0
                       WC_AES_BLOCK_SIZE);
15492
0
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
15493
0
                if (ret == 0) {
15494
0
                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
15495
0
                }
15496
0
                if (ret == 0) {
15497
0
                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
15498
0
                }
15499
0
                if (ret == 0) {
15500
0
                    ret = wc_CmacFinal(cmac, out, &macSz);
15501
0
                }
15502
0
            }
15503
0
        #ifdef WOLFSSL_SMALL_STACK
15504
0
            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
15505
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
15506
            wc_MemZero_Check(cmac, sizeof(Cmac));
15507
        #endif
15508
0
        }
15509
0
        else {
15510
0
            XMEMCPY(tmp[2], data, dataSz);
15511
0
            tmp[2][dataSz] |= 0x80;
15512
0
            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
15513
0
            if (zeroBytes != 0) {
15514
0
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
15515
0
            }
15516
0
            ShiftAndXorRb(tmp[1], tmp[0]);
15517
0
            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
15518
0
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
15519
0
                                     keySz);
15520
0
        }
15521
0
    }
15522
15523
0
#ifdef WOLFSSL_SMALL_STACK
15524
0
    for (i = 0; i < 3; ++i) {
15525
0
        if (tmp[i] != NULL) {
15526
0
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
15527
0
        }
15528
0
    }
15529
0
#endif
15530
15531
0
    return ret;
15532
0
}
15533
15534
static WARN_UNUSED_RESULT int AesSivCipher(
15535
    const byte* key, word32 keySz, const AesSivAssoc* assoc,
15536
    word32 numAssoc, const byte* nonce, word32 nonceSz,
15537
    const byte* data, word32 dataSz, byte* siv, byte* out,
15538
    int enc)
15539
0
{
15540
0
    int ret = 0;
15541
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
15542
0
    byte sivTmp[WC_AES_BLOCK_SIZE];
15543
15544
0
    if (key == NULL || siv == NULL || out == NULL) {
15545
0
        WOLFSSL_MSG("Bad parameter");
15546
0
        ret = BAD_FUNC_ARG;
15547
0
    }
15548
15549
0
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
15550
0
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
15551
0
        ret = BAD_FUNC_ARG;
15552
0
    }
15553
15554
0
    if (ret == 0) {
15555
0
        if (enc == 1) {
15556
0
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
15557
0
                      dataSz, sivTmp);
15558
0
            if (ret != 0) {
15559
0
                WOLFSSL_MSG("S2V failed.");
15560
0
            }
15561
0
            else {
15562
0
                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
15563
0
            }
15564
0
        }
15565
0
        else {
15566
0
            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
15567
0
        }
15568
0
    }
15569
15570
0
    if (ret == 0) {
15571
0
#ifdef WOLFSSL_SMALL_STACK
15572
0
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
15573
#else
15574
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15575
#endif
15576
0
        if (ret != 0) {
15577
0
            WOLFSSL_MSG("Failed to initialized AES object.");
15578
0
        }
15579
0
    }
15580
15581
0
    if (ret == 0 && dataSz > 0) {
15582
0
        sivTmp[12] &= 0x7f;
15583
0
        sivTmp[8] &= 0x7f;
15584
0
        ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
15585
0
                           AES_ENCRYPTION);
15586
0
        if (ret != 0) {
15587
0
            WOLFSSL_MSG("Failed to set key for AES-CTR.");
15588
0
        }
15589
0
        else {
15590
0
            ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
15591
0
            if (ret != 0) {
15592
0
                WOLFSSL_MSG("AES-CTR encryption failed.");
15593
0
            }
15594
0
        }
15595
0
    }
15596
15597
0
    if (ret == 0 && enc == 0) {
15598
0
        ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out, dataSz,
15599
0
                  sivTmp);
15600
0
        if (ret != 0) {
15601
0
            WOLFSSL_MSG("S2V failed.");
15602
0
        }
15603
15604
0
        if (XMEMCMP(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
15605
0
            WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
15606
0
            ret = AES_SIV_AUTH_E;
15607
0
        }
15608
0
    }
15609
15610
0
#ifdef WOLFSSL_SMALL_STACK
15611
0
    wc_AesDelete(aes, NULL);
15612
#else
15613
    wc_AesFree(aes);
15614
#endif
15615
15616
0
    return ret;
15617
0
}
15618
15619
/*
15620
 * See RFC 5297 Section 2.6.
15621
 */
15622
int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
15623
                     word32 assocSz, const byte* nonce, word32 nonceSz,
15624
                     const byte* in, word32 inSz, byte* siv, byte* out)
15625
0
{
15626
0
    AesSivAssoc ad;
15627
0
    ad.assoc = assoc;
15628
0
    ad.assocSz = assocSz;
15629
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
15630
0
                        siv, out, 1);
15631
0
}
15632
15633
/*
15634
 * See RFC 5297 Section 2.7.
15635
 */
15636
int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
15637
                     word32 assocSz, const byte* nonce, word32 nonceSz,
15638
                     const byte* in, word32 inSz, byte* siv, byte* out)
15639
0
{
15640
0
    AesSivAssoc ad;
15641
0
    ad.assoc = assoc;
15642
0
    ad.assocSz = assocSz;
15643
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
15644
0
                        siv, out, 0);
15645
0
}
15646
15647
/*
15648
 * See RFC 5297 Section 2.6.
15649
 */
15650
int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
15651
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
15652
                        const byte* in, word32 inSz, byte* siv, byte* out)
15653
0
{
15654
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
15655
0
                        siv, out, 1);
15656
0
}
15657
15658
/*
15659
 * See RFC 5297 Section 2.7.
15660
 */
15661
int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
15662
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
15663
                        const byte* in, word32 inSz, byte* siv, byte* out)
15664
0
{
15665
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
15666
0
                        siv, out, 0);
15667
0
}
15668
15669
#endif /* WOLFSSL_AES_SIV */
15670
15671
#if defined(WOLFSSL_AES_EAX)
15672
15673
/*
15674
 * AES EAX one-shot API
15675
 * Encrypts input data and computes an auth tag over the input
15676
 * auth data and ciphertext
15677
 *
15678
 * Returns 0 on success
15679
 * Returns error code on failure
15680
 */
15681
int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
15682
                          const byte* in, word32 inSz,
15683
                          const byte* nonce, word32 nonceSz,
15684
                          /* output computed auth tag */
15685
                          byte* authTag, word32 authTagSz,
15686
                          /* input data to authenticate */
15687
                          const byte* authIn, word32 authInSz)
15688
{
15689
#if defined(WOLFSSL_SMALL_STACK)
15690
    AesEax *eax;
15691
#else
15692
    AesEax eax_mem;
15693
    AesEax *eax = &eax_mem;
15694
#endif
15695
    int ret;
15696
    int eaxInited = 0;
15697
15698
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
15699
                              || authTag == NULL || authIn == NULL) {
15700
        return BAD_FUNC_ARG;
15701
    }
15702
15703
#if defined(WOLFSSL_SMALL_STACK)
15704
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
15705
                                 NULL,
15706
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
15707
        return MEMORY_E;
15708
    }
15709
#endif
15710
15711
    if ((ret = wc_AesEaxInit(eax,
15712
                             key, keySz,
15713
                             nonce, nonceSz,
15714
                             authIn, authInSz)) != 0) {
15715
        goto cleanup;
15716
    }
15717
    eaxInited = 1;
15718
15719
    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
15720
        goto cleanup;
15721
    }
15722
15723
    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
15724
        goto cleanup;
15725
    }
15726
15727
cleanup:
15728
    if (eaxInited)
15729
        wc_AesEaxFree(eax);
15730
#if defined(WOLFSSL_SMALL_STACK)
15731
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
15732
#endif
15733
    return ret;
15734
}
15735
15736
15737
/*
15738
 * AES EAX one-shot API
15739
 * Decrypts and authenticates data against a supplied auth tag
15740
 *
15741
 * Returns 0 on success
15742
 * Returns error code on failure
15743
 */
15744
int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
15745
                          const byte* in, word32 inSz,
15746
                          const byte* nonce, word32 nonceSz,
15747
                          /* auth tag to verify against */
15748
                          const byte* authTag, word32 authTagSz,
15749
                          /* input data to authenticate */
15750
                          const byte* authIn, word32 authInSz)
15751
{
15752
#if defined(WOLFSSL_SMALL_STACK)
15753
    AesEax *eax;
15754
#else
15755
    AesEax eax_mem;
15756
    AesEax *eax = &eax_mem;
15757
#endif
15758
    int ret;
15759
    int eaxInited = 0;
15760
15761
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
15762
                              || authTag == NULL || authIn == NULL) {
15763
        return BAD_FUNC_ARG;
15764
    }
15765
15766
#if defined(WOLFSSL_SMALL_STACK)
15767
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
15768
                                 NULL,
15769
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
15770
        return MEMORY_E;
15771
    }
15772
#endif
15773
15774
    if ((ret = wc_AesEaxInit(eax,
15775
                             key, keySz,
15776
                             nonce, nonceSz,
15777
                             authIn, authInSz)) != 0) {
15778
15779
        goto cleanup;
15780
    }
15781
    eaxInited = 1;
15782
15783
    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
15784
        goto cleanup;
15785
    }
15786
15787
    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
15788
        goto cleanup;
15789
    }
15790
15791
cleanup:
15792
    if (eaxInited)
15793
        wc_AesEaxFree(eax);
15794
#if defined(WOLFSSL_SMALL_STACK)
15795
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
15796
#endif
15797
    return ret;
15798
}
15799
15800
15801
/*
15802
 * AES EAX Incremental API:
15803
 * Initializes an AES EAX encryption or decryption operation. This must be
15804
 * called before any other EAX APIs are used on the AesEax struct
15805
 *
15806
 * Returns 0 on success
15807
 * Returns error code on failure
15808
 */
15809
int  wc_AesEaxInit(AesEax* eax,
15810
                   const byte* key, word32 keySz,
15811
                   const byte* nonce, word32 nonceSz,
15812
                   const byte* authIn, word32 authInSz)
15813
{
15814
    int ret = 0;
15815
    word32 cmacSize;
15816
    int aesInited = 0;
15817
    int nonceCmacInited = 0;
15818
    int aadCmacInited = 0;
15819
15820
    if (eax == NULL || key == NULL ||  nonce == NULL) {
15821
        return BAD_FUNC_ARG;
15822
    }
15823
15824
    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
15825
15826
    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
15827
        goto out;
15828
    }
15829
    aesInited = 1;
15830
15831
    if ((ret = wc_AesSetKey(&eax->aes,
15832
                            key,
15833
                            keySz,
15834
                            NULL,
15835
                            AES_ENCRYPTION)) != 0) {
15836
        goto out;
15837
    }
15838
15839
    /*
15840
    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
15841
    *   N' = OMAC^0_K(N)
15842
    */
15843
    if ((ret = wc_InitCmac(&eax->nonceCmac,
15844
                           key,
15845
                           keySz,
15846
                           WC_CMAC_AES,
15847
                           NULL)) != 0) {
15848
        return ret;
15849
    }
15850
    nonceCmacInited = 1;
15851
15852
    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
15853
                             eax->prefixBuf,
15854
                             sizeof(eax->prefixBuf))) != 0) {
15855
        goto out;
15856
    }
15857
15858
    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
15859
        goto out;
15860
    }
15861
15862
    cmacSize = WC_AES_BLOCK_SIZE;
15863
    if ((ret = wc_CmacFinal(&eax->nonceCmac,
15864
                            eax->nonceCmacFinal,
15865
                            &cmacSize)) != 0) {
15866
        goto out;
15867
    }
15868
15869
    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
15870
        goto out;
15871
    }
15872
15873
    /*
15874
     * start the OMAC used to build the auth tag chunk for the AD .
15875
     * This CMAC is continued in subsequent update calls when more auth data is
15876
     * provided
15877
     *   H' = OMAC^1_K(H)
15878
     */
15879
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 1;
15880
    if ((ret = wc_InitCmac(&eax->aadCmac,
15881
                           key,
15882
                           keySz,
15883
                           WC_CMAC_AES,
15884
                           NULL)) != 0) {
15885
        goto out;
15886
    }
15887
    aadCmacInited = 1;
15888
15889
    if ((ret = wc_CmacUpdate(&eax->aadCmac,
15890
                             eax->prefixBuf,
15891
                             sizeof(eax->prefixBuf))) != 0) {
15892
        goto out;
15893
    }
15894
15895
    if (authIn != NULL) {
15896
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
15897
            goto out;
15898
        }
15899
    }
15900
15901
    /*
15902
     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
15903
     * updated in subsequent calls to encrypt/decrypt
15904
     *  C' = OMAC^2_K(C)
15905
     */
15906
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 2;
15907
    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
15908
                           key,
15909
                           keySz,
15910
                           WC_CMAC_AES,
15911
                           NULL)) != 0) {
15912
        goto out;
15913
    }
15914
15915
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
15916
                             eax->prefixBuf,
15917
                             sizeof(eax->prefixBuf))) != 0) {
15918
        goto out;
15919
    }
15920
15921
out:
15922
15923
    if (ret != 0) {
15924
        if (aesInited)
15925
            wc_AesFree(&eax->aes);
15926
        if (nonceCmacInited)
15927
            wc_CmacFree(&eax->nonceCmac);
15928
        if (aadCmacInited)
15929
            wc_CmacFree(&eax->aadCmac);
15930
    }
15931
15932
    return ret;
15933
}
15934
15935
15936
/*
15937
 * AES EAX Incremental API:
15938
 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
15939
 * the authentication stream
15940
 *
15941
 * Returns 0 on success
15942
 * Returns error code on failure
15943
 */
15944
int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
15945
                            const byte* in, word32 inSz,
15946
                            const byte* authIn, word32 authInSz)
15947
{
15948
    int ret;
15949
15950
    if (eax == NULL || out == NULL ||  in == NULL) {
15951
        return BAD_FUNC_ARG;
15952
    }
15953
15954
    /*
15955
     * Encrypt the plaintext using AES CTR
15956
     *  C = CTR(M)
15957
     */
15958
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
15959
        return ret;
15960
    }
15961
15962
    /*
15963
     * update OMAC with new ciphertext
15964
     *  C' = OMAC^2_K(C)
15965
     */
15966
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
15967
        return ret;
15968
    }
15969
15970
    /* If there exists new auth data, update the OMAC for that as well */
15971
    if (authIn != NULL) {
15972
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
15973
            return ret;
15974
        }
15975
    }
15976
15977
    return 0;
15978
}
15979
15980
15981
/*
15982
 * AES EAX Incremental API:
15983
 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
15984
 * the authentication stream
15985
 *
15986
 * Returns 0 on success
15987
 * Returns error code on failure
15988
 */
15989
int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
15990
                            const byte* in, word32 inSz,
15991
                            const byte* authIn, word32 authInSz)
15992
{
15993
    int ret;
15994
15995
    if (eax == NULL || out == NULL ||  in == NULL) {
15996
        return BAD_FUNC_ARG;
15997
    }
15998
15999
    /*
16000
     * Decrypt the plaintext using AES CTR
16001
     *  C = CTR(M)
16002
     */
16003
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
16004
        return ret;
16005
    }
16006
16007
    /*
16008
     * update OMAC with new ciphertext
16009
     *  C' = OMAC^2_K(C)
16010
     */
16011
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
16012
        return ret;
16013
    }
16014
16015
    /* If there exists new auth data, update the OMAC for that as well */
16016
    if (authIn != NULL) {
16017
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
16018
            return ret;
16019
        }
16020
    }
16021
16022
    return 0;
16023
}
16024
16025
16026
/*
16027
 * AES EAX Incremental API:
16028
 * Provides additional auth data information to the authentication
16029
 * stream for an authenticated encryption or decryption operation
16030
 *
16031
 * Returns 0 on success
16032
 * Returns error code on failure
16033
 */
16034
int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
16035
{
16036
    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
16037
}
16038
16039
16040
/*
16041
 * AES EAX Incremental API:
16042
 * Finalizes the authenticated encryption operation, computing the auth tag
16043
 * over previously supplied auth data and computed ciphertext
16044
 *
16045
 * Returns 0 on success
16046
 * Returns error code on failure
16047
 */
16048
int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
16049
{
16050
    word32 cmacSize;
16051
    int ret;
16052
    word32 i;
16053
16054
    if (eax == NULL || authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE) {
16055
        return BAD_FUNC_ARG;
16056
    }
16057
16058
    /* Complete the OMAC for the ciphertext */
16059
    cmacSize = WC_AES_BLOCK_SIZE;
16060
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
16061
                                  eax->ciphertextCmacFinal,
16062
                                  &cmacSize)) != 0) {
16063
        return ret;
16064
    }
16065
16066
    /* Complete the OMAC for auth data */
16067
    cmacSize = WC_AES_BLOCK_SIZE;
16068
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
16069
                                  eax->aadCmacFinal,
16070
                                  &cmacSize)) != 0) {
16071
        return ret;
16072
    }
16073
16074
    /*
16075
     * Concatenate all three auth tag chunks into the final tag, truncating
16076
     * at the specified tag length
16077
     *   T = Tag [first authTagSz bytes]
16078
     */
16079
    for (i = 0; i < authTagSz; i++) {
16080
        authTag[i] = eax->nonceCmacFinal[i]
16081
                    ^ eax->aadCmacFinal[i]
16082
                    ^ eax->ciphertextCmacFinal[i];
16083
    }
16084
16085
    return 0;
16086
}
16087
16088
16089
/*
16090
 * AES EAX Incremental API:
16091
 * Finalizes the authenticated decryption operation, computing the auth tag
16092
 * for the previously supplied auth data and cipher text and validating it
16093
 * against a provided auth tag
16094
 *
16095
 * Returns 0 on success
16096
 * Return error code for failure
16097
 */
16098
int wc_AesEaxDecryptFinal(AesEax* eax,
16099
                          const byte* authIn, word32 authInSz)
16100
{
16101
    int ret;
16102
    word32 i;
16103
    word32 cmacSize;
16104
16105
#if defined(WOLFSSL_SMALL_STACK)
16106
    byte *authTag;
16107
#else
16108
    byte authTag[WC_AES_BLOCK_SIZE];
16109
#endif
16110
16111
    if (eax == NULL || authIn == NULL || authInSz > WC_AES_BLOCK_SIZE) {
16112
        return BAD_FUNC_ARG;
16113
    }
16114
16115
    /* Complete the OMAC for the ciphertext */
16116
    cmacSize = WC_AES_BLOCK_SIZE;
16117
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
16118
                                  eax->ciphertextCmacFinal,
16119
                                  &cmacSize)) != 0) {
16120
        return ret;
16121
    }
16122
16123
    /* Complete the OMAC for auth data */
16124
    cmacSize = WC_AES_BLOCK_SIZE;
16125
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
16126
                                  eax->aadCmacFinal,
16127
                                  &cmacSize)) != 0) {
16128
        return ret;
16129
    }
16130
16131
#if defined(WOLFSSL_SMALL_STACK)
16132
    authTag = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16133
    if (authTag == NULL) {
16134
        return MEMORY_E;
16135
    }
16136
#endif
16137
16138
    /*
16139
     * Concatenate all three auth tag chunks into the final tag, truncating
16140
     * at the specified tag length
16141
     *   T = Tag [first authInSz bytes]
16142
     */
16143
    for (i = 0; i < authInSz; i++) {
16144
        authTag[i] = eax->nonceCmacFinal[i]
16145
                    ^ eax->aadCmacFinal[i]
16146
                    ^ eax->ciphertextCmacFinal[i];
16147
    }
16148
16149
    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
16150
        ret = AES_EAX_AUTH_E;
16151
    }
16152
    else {
16153
        ret = 0;
16154
    }
16155
16156
#if defined(WOLFSSL_SMALL_STACK)
16157
    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16158
#endif
16159
16160
    return ret;
16161
}
16162
16163
/*
16164
 * Frees the underlying CMAC and AES contexts. Must be called when done using
16165
 * the AES EAX context structure.
16166
 *
16167
 * Returns 0 on success
16168
 * Returns error code on failure
16169
 */
16170
int wc_AesEaxFree(AesEax* eax)
16171
{
16172
    if (eax == NULL) {
16173
        return BAD_FUNC_ARG;
16174
    }
16175
16176
    (void)wc_CmacFree(&eax->ciphertextCmac);
16177
    (void)wc_CmacFree(&eax->aadCmac);
16178
    wc_AesFree(&eax->aes);
16179
16180
    return 0;
16181
}
16182
16183
#endif /* WOLFSSL_AES_EAX */
16184
16185
#ifdef WOLFSSL_AES_CTS
16186
16187
16188
/* One-shot API */
16189
int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out,
16190
                     const byte* in, word32 inSz,
16191
                     const byte* iv)
16192
{
16193
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16194
    int ret = 0;
16195
    word32 outSz = inSz;
16196
16197
    if (key == NULL || out == NULL || in == NULL || iv == NULL)
16198
        return BAD_FUNC_ARG;
16199
16200
#ifdef WOLFSSL_SMALL_STACK
16201
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
16202
#else
16203
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16204
#endif
16205
    if (ret == 0)
16206
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
16207
    if (ret == 0)
16208
        ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz);
16209
    if (ret == 0) {
16210
        out += outSz;
16211
        outSz = inSz - outSz;
16212
        ret = wc_AesCtsEncryptFinal(aes, out, &outSz);
16213
    }
16214
16215
#ifdef WOLFSSL_SMALL_STACK
16216
    wc_AesDelete(aes, NULL);
16217
#else
16218
    wc_AesFree(aes);
16219
#endif
16220
    return ret;
16221
}
16222
16223
int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out,
16224
                     const byte* in, word32 inSz,
16225
                     const byte* iv)
16226
{
16227
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16228
    int ret = 0;
16229
    word32 outSz = inSz;
16230
16231
    if (key == NULL || out == NULL || in == NULL || iv == NULL) {
16232
        return BAD_FUNC_ARG;
16233
    }
16234
16235
#ifdef WOLFSSL_SMALL_STACK
16236
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
16237
#else
16238
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16239
#endif
16240
    if (ret == 0)
16241
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
16242
    if (ret == 0)
16243
        ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz);
16244
    if (ret == 0) {
16245
        out += outSz;
16246
        outSz = inSz - outSz;
16247
        ret = wc_AesCtsDecryptFinal(aes, out, &outSz);
16248
    }
16249
16250
#ifdef WOLFSSL_SMALL_STACK
16251
    wc_AesDelete(aes, NULL);
16252
#else
16253
    wc_AesFree(aes);
16254
#endif
16255
    return ret;
16256
}
16257
16258
static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz,
16259
                        const byte* in, word32 inSz, int enc)
16260
{
16261
    word32 blocks = 0;
16262
    int ret = 0;
16263
    word32 writtenSz = 0;
16264
    word32 tmpOutSz;
16265
16266
    if (aes == NULL || out == NULL || in == NULL || outSz == NULL)
16267
        return BAD_FUNC_ARG;
16268
16269
    /* Error out early for easy sanity check */
16270
    if (*outSz < inSz)
16271
        return BUFFER_E;
16272
    tmpOutSz = *outSz;
16273
16274
    /* We need to store last two blocks of plaintext */
16275
    if (aes->left > 0) {
16276
        word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left);
16277
        XMEMCPY(aes->ctsBlock + aes->left, in, copySz);
16278
        aes->left += copySz;
16279
        in += copySz;
16280
        inSz -= copySz;
16281
16282
        if (aes->left == WC_AES_BLOCK_SIZE * 2) {
16283
            if (inSz > WC_AES_BLOCK_SIZE) {
16284
                if (tmpOutSz < WC_AES_BLOCK_SIZE * 2)
16285
                    return BUFFER_E;
16286
                if (enc) {
16287
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
16288
                                           WC_AES_BLOCK_SIZE * 2);
16289
                }
16290
                else {
16291
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
16292
                                           WC_AES_BLOCK_SIZE * 2);
16293
                }
16294
                if (ret != 0)
16295
                    return ret;
16296
                out += WC_AES_BLOCK_SIZE * 2;
16297
                writtenSz += WC_AES_BLOCK_SIZE * 2;
16298
                tmpOutSz -= WC_AES_BLOCK_SIZE * 2;
16299
                aes->left = 0;
16300
            }
16301
            else if (inSz > 0) {
16302
                if (tmpOutSz < WC_AES_BLOCK_SIZE)
16303
                    return BUFFER_E;
16304
                if (enc) {
16305
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
16306
                                           WC_AES_BLOCK_SIZE);
16307
                }
16308
                else {
16309
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
16310
                                           WC_AES_BLOCK_SIZE);
16311
                }
16312
                if (ret != 0)
16313
                    return ret;
16314
                out += WC_AES_BLOCK_SIZE;
16315
                writtenSz += WC_AES_BLOCK_SIZE;
16316
                tmpOutSz -= WC_AES_BLOCK_SIZE;
16317
                /* Move the last block in ctsBlock to the beginning for
16318
                 * next operation */
16319
                XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE,
16320
                        WC_AES_BLOCK_SIZE);
16321
                XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz);
16322
                aes->left = WC_AES_BLOCK_SIZE + inSz;
16323
                *outSz = writtenSz;
16324
                return ret; /* Return the result of encryption */
16325
            }
16326
            else {
16327
                /* Can't output data as we need > 1 block for Final call */
16328
                *outSz = writtenSz;
16329
                return 0;
16330
            }
16331
        }
16332
        else {
16333
            /* All input has been absorbed into aes->ctsBlock */
16334
            *outSz = 0;
16335
            return 0;
16336
        }
16337
    }
16338
    if (inSz > WC_AES_BLOCK_SIZE) {
16339
        /* We need to store the last two full or partial blocks */
16340
        blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE;
16341
        blocks -= 2;
16342
    }
16343
    if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE)
16344
        return BUFFER_E;
16345
    if (enc)
16346
        ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
16347
    else
16348
        ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
16349
    in += blocks * WC_AES_BLOCK_SIZE;
16350
    inSz -= blocks * WC_AES_BLOCK_SIZE;
16351
    XMEMCPY(aes->ctsBlock, in, inSz);
16352
    aes->left = inSz;
16353
    writtenSz += blocks * WC_AES_BLOCK_SIZE;
16354
    *outSz = writtenSz;
16355
    return ret;
16356
}
16357
16358
/* Incremental API */
16359
int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz,
16360
                           const byte* in, word32 inSz)
16361
{
16362
    return AesCtsUpdate(aes, out, outSz, in, inSz, 1);
16363
}
16364
16365
int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz)
16366
{
16367
    int ret = 0;
16368
16369
    if (aes == NULL || out == NULL || outSz == NULL)
16370
        return BAD_FUNC_ARG;
16371
    if (*outSz < aes->left)
16372
        return BUFFER_E;
16373
16374
    /* Input must be at least two complete or partial blocks */
16375
    if (aes->left <= WC_AES_BLOCK_SIZE)
16376
        return BAD_FUNC_ARG;
16377
16378
    /* Zero padding */
16379
    XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left);
16380
16381
    ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock,
16382
                           WC_AES_BLOCK_SIZE * 2);
16383
    if (ret != 0)
16384
        return ret;
16385
16386
    XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
16387
    XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock,
16388
            aes->left - WC_AES_BLOCK_SIZE);
16389
    *outSz = aes->left;
16390
    return ret;
16391
}
16392
16393
int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz,
16394
                           const byte* in, word32 inSz)
16395
{
16396
    return AesCtsUpdate(aes, out, outSz, in, inSz, 0);
16397
}
16398
16399
int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz)
16400
{
16401
    int ret = 0;
16402
    byte iv[WC_AES_BLOCK_SIZE];
16403
    byte tmp[WC_AES_BLOCK_SIZE];
16404
    word32 partialSz;
16405
    word32 padSz;
16406
16407
    if (aes == NULL || out == NULL || outSz == NULL)
16408
        return BAD_FUNC_ARG;
16409
    if (*outSz < aes->left)
16410
        return BUFFER_E;
16411
16412
    /* Input must be at least two complete or partial blocks */
16413
    if (aes->left <= WC_AES_BLOCK_SIZE)
16414
        return BAD_FUNC_ARG;
16415
16416
    partialSz = aes->left - WC_AES_BLOCK_SIZE;
16417
    padSz = 2 * WC_AES_BLOCK_SIZE - aes->left;
16418
    /* Zero pad */
16419
    XMEMSET(aes->ctsBlock + aes->left, 0, padSz);
16420
16421
    /* Store IV */
16422
    XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE);
16423
    /* Load IV */
16424
    XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
16425
16426
    ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE);
16427
    if (ret != 0)
16428
        return ret;
16429
16430
    /* Write out partial block */
16431
    XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz);
16432
    /* Retrieve the padding */
16433
    XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz);
16434
    /* Restore IV */
16435
    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
16436
16437
    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE,
16438
                           WC_AES_BLOCK_SIZE);
16439
    if (ret != 0)
16440
        return ret;
16441
16442
    *outSz = aes->left;
16443
    return ret;
16444
}
16445
16446
#endif /* WOLFSSL_AES_CTS */
16447
16448
16449
#endif /* !NO_AES */