Coverage Report

Created: 2026-01-06 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-fastmath/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
97
#if defined(WOLFSSL_PSOC6_CRYPTO)
98
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
99
#endif /* WOLFSSL_PSOC6_CRYPTO */
100
101
#ifdef NO_INLINE
102
    #include <wolfssl/wolfcrypt/misc.h>
103
#else
104
    #define WOLFSSL_MISC_INCLUDED
105
    #include <wolfcrypt/src/misc.c>
106
#endif
107
108
#if !defined(WOLFSSL_RISCV_ASM)
109
110
#ifdef WOLFSSL_IMX6_CAAM_BLOB
111
    /* case of possibly not using hardware acceleration for AES but using key
112
       blobs */
113
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
114
#endif
115
116
#ifdef DEBUG_AESNI
117
    #include <stdio.h>
118
#endif
119
120
#ifdef _MSC_VER
121
    /* 4127 warning constant while(1)  */
122
    #pragma warning(disable: 4127)
123
#endif
124
125
#if (!defined(WOLFSSL_ARMASM) && FIPS_VERSION3_GE(6,0,0)) || \
126
    FIPS_VERSION3_GE(7,0,0)
127
    const unsigned int wolfCrypt_FIPS_aes_ro_sanity[2] =
128
                                                     { 0x1a2b3c4d, 0x00000002 };
129
    int wolfCrypt_FIPS_AES_sanity(void)
130
    {
131
        return 0;
132
    }
133
#endif
134
135
/* Define AES implementation includes and functions */
136
#if defined(STM32_CRYPTO)
137
     /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
138
139
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
140
141
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
142
        Aes* aes, const byte* inBlock, byte* outBlock)
143
    {
144
        int ret = 0;
145
    #ifdef WOLFSSL_STM32_CUBEMX
146
        CRYP_HandleTypeDef hcryp;
147
    #else
148
        CRYP_InitTypeDef cryptInit;
149
        CRYP_KeyInitTypeDef keyInit;
150
    #endif
151
152
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
153
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
154
        if (ret < 0)
155
            return ret;
156
#endif
157
158
    #ifdef WOLFSSL_STM32U5_DHUK
159
        ret = wolfSSL_CryptHwMutexLock();
160
        if (ret != 0)
161
            return ret;
162
163
        /* Handle making use of wrapped key */
164
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
165
            CRYP_ConfigTypeDef Config = {0};
166
167
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key,
168
                aes->keylen, aes->dhukIV, aes->dhukIVLen);
169
            if (ret != HAL_OK) {
170
                WOLFSSL_MSG("Error with DHUK key unwrap");
171
                ret = BAD_FUNC_ARG;
172
            }
173
            /* reconfigure for using unwrapped key now */
174
            HAL_CRYP_GetConfig(&hcryp, &Config);
175
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
176
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
177
            Config.Algorithm = CRYP_AES_ECB;
178
            Config.DataType  = CRYP_DATATYPE_8B;
179
            Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
180
            HAL_CRYP_SetConfig(&hcryp, &Config);
181
        }
182
        else {
183
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
184
            if (ret == 0) {
185
                hcryp.Init.Algorithm  = CRYP_AES_ECB;
186
                ret = HAL_CRYP_Init(&hcryp);
187
                if (ret != HAL_OK) {
188
                    ret = BAD_FUNC_ARG;
189
                }
190
            }
191
        }
192
193
        if (ret == HAL_OK) {
194
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
195
                    (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
196
            if (ret != HAL_OK) {
197
                ret = WC_TIMEOUT_E;
198
            }
199
        }
200
        HAL_CRYP_DeInit(&hcryp);
201
    #elif defined(WOLFSSL_STM32_CUBEMX)
202
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
203
        if (ret != 0)
204
            return ret;
205
206
        ret = wolfSSL_CryptHwMutexLock();
207
        if (ret != 0)
208
            return ret;
209
210
    #if defined(STM32_HAL_V2)
211
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
212
    #elif defined(STM32_CRYPTO_AES_ONLY)
213
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
214
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
215
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
216
    #endif
217
        if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
218
            ret = BAD_FUNC_ARG;
219
        }
220
221
        if (ret == 0) {
222
        #if defined(STM32_HAL_V2)
223
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
224
                (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
225
        #elif defined(STM32_CRYPTO_AES_ONLY)
226
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
227
                outBlock, STM32_HAL_TIMEOUT);
228
        #else
229
            ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
230
                outBlock, STM32_HAL_TIMEOUT);
231
        #endif
232
            if (ret != HAL_OK) {
233
                ret = WC_TIMEOUT_E;
234
            }
235
            HAL_CRYP_DeInit(&hcryp);
236
        }
237
238
    #else /* Standard Peripheral Library */
239
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
240
        if (ret != 0)
241
            return ret;
242
243
        ret = wolfSSL_CryptHwMutexLock();
244
        if (ret != 0)
245
            return ret;
246
247
        /* reset registers to their default values */
248
        CRYP_DeInit();
249
250
        /* setup key */
251
        CRYP_KeyInit(&keyInit);
252
253
        /* set direction and mode */
254
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
255
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
256
        CRYP_Init(&cryptInit);
257
258
        /* enable crypto processor */
259
        CRYP_Cmd(ENABLE);
260
261
        /* flush IN/OUT FIFOs */
262
        CRYP_FIFOFlush();
263
264
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
265
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
266
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
267
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
268
269
        /* wait until the complete message has been processed */
270
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
271
272
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
273
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
274
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
275
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
276
277
        /* disable crypto processor */
278
        CRYP_Cmd(DISABLE);
279
    #endif /* WOLFSSL_STM32_CUBEMX */
280
        wolfSSL_CryptHwMutexUnLock();
281
        wc_Stm32_Aes_Cleanup();
282
283
        return ret;
284
    }
285
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
286
287
#ifdef HAVE_AES_DECRYPT
288
    #if defined(WOLFSSL_AES_DIRECT)
289
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
290
        Aes* aes, const byte* inBlock, byte* outBlock)
291
    {
292
        int ret = 0;
293
    #ifdef WOLFSSL_STM32_CUBEMX
294
        CRYP_HandleTypeDef hcryp;
295
    #else
296
        CRYP_InitTypeDef cryptInit;
297
        CRYP_KeyInitTypeDef keyInit;
298
    #endif
299
300
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
301
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
302
        if (ret < 0)
303
            return ret;
304
#endif
305
306
    #ifdef WOLFSSL_STM32U5_DHUK
307
        ret = wolfSSL_CryptHwMutexLock();
308
        if (ret != 0)
309
            return ret;
310
311
        /* Handle making use of wrapped key */
312
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
313
            CRYP_ConfigTypeDef Config;
314
315
            XMEMSET(&Config, 0, sizeof(Config));
316
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key,
317
                aes->keylen, aes->dhukIV, aes->dhukIVLen);
318
            if (ret != HAL_OK) {
319
                WOLFSSL_MSG("Error with DHUK unwrap");
320
                ret = BAD_FUNC_ARG;
321
            }
322
            /* reconfigure for using unwrapped key now */
323
            HAL_CRYP_GetConfig(&hcryp, &Config);
324
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
325
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
326
            Config.Algorithm = CRYP_AES_ECB;
327
            Config.DataType  = CRYP_DATATYPE_8B;
328
            Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
329
            HAL_CRYP_SetConfig(&hcryp, &Config);
330
        }
331
        else {
332
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
333
            if (ret == 0) {
334
                hcryp.Init.Algorithm  = CRYP_AES_ECB;
335
                ret = HAL_CRYP_Init(&hcryp);
336
                if (ret != HAL_OK) {
337
                    ret = BAD_FUNC_ARG;
338
                }
339
            }
340
        }
341
342
        if (ret == HAL_OK) {
343
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
344
                    (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
345
            if (ret != HAL_OK) {
346
                ret = WC_TIMEOUT_E;
347
            }
348
        }
349
        HAL_CRYP_DeInit(&hcryp);
350
    #elif defined(WOLFSSL_STM32_CUBEMX)
351
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
352
        if (ret != 0)
353
            return ret;
354
355
        ret = wolfSSL_CryptHwMutexLock();
356
        if (ret != 0)
357
            return ret;
358
359
    #if defined(STM32_HAL_V2)
360
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
361
    #elif defined(STM32_CRYPTO_AES_ONLY)
362
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
363
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
364
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
365
    #endif
366
        HAL_CRYP_Init(&hcryp);
367
368
    #if defined(STM32_HAL_V2)
369
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
370
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
371
    #elif defined(STM32_CRYPTO_AES_ONLY)
372
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
373
            outBlock, STM32_HAL_TIMEOUT);
374
    #else
375
        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
376
            outBlock, STM32_HAL_TIMEOUT);
377
    #endif
378
        if (ret != HAL_OK) {
379
            ret = WC_TIMEOUT_E;
380
        }
381
        HAL_CRYP_DeInit(&hcryp);
382
383
    #else /* Standard Peripheral Library */
384
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
385
        if (ret != 0)
386
            return ret;
387
388
        ret = wolfSSL_CryptHwMutexLock();
389
        if (ret != 0)
390
            return ret;
391
392
        /* reset registers to their default values */
393
        CRYP_DeInit();
394
395
        /* set direction and key */
396
        CRYP_KeyInit(&keyInit);
397
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
398
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
399
        CRYP_Init(&cryptInit);
400
401
        /* enable crypto processor */
402
        CRYP_Cmd(ENABLE);
403
404
        /* wait until decrypt key has been initialized */
405
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
406
407
        /* set direction and mode */
408
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
409
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
410
        CRYP_Init(&cryptInit);
411
412
        /* enable crypto processor */
413
        CRYP_Cmd(ENABLE);
414
415
        /* flush IN/OUT FIFOs */
416
        CRYP_FIFOFlush();
417
418
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
419
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
420
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
421
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
422
423
        /* wait until the complete message has been processed */
424
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
425
426
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
427
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
428
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
429
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
430
431
        /* disable crypto processor */
432
        CRYP_Cmd(DISABLE);
433
    #endif /* WOLFSSL_STM32_CUBEMX */
434
        wolfSSL_CryptHwMutexUnLock();
435
        wc_Stm32_Aes_Cleanup();
436
437
        return ret;
438
    }
439
    #endif /* WOLFSSL_AES_DIRECT */
440
#endif /* HAVE_AES_DECRYPT */
441
442
#elif defined(HAVE_COLDFIRE_SEC)
443
    /* Freescale Coldfire SEC support for CBC mode.
444
     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
445
    #include "sec.h"
446
    #include "mcf5475_sec.h"
447
    #include "mcf5475_siu.h"
448
#elif defined(FREESCALE_LTC)
449
    #include "fsl_ltc.h"
450
    #if defined(FREESCALE_LTC_AES_GCM)
451
        #undef NEED_AES_TABLES
452
        #undef GCM_TABLE
453
    #endif
454
455
        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
456
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
457
            Aes* aes, const byte* inBlock, byte* outBlock)
458
        {
459
            word32 keySize = 0;
460
            byte* key = (byte*)aes->key;
461
            int ret = wc_AesGetKeySize(aes, &keySize);
462
            if (ret != 0)
463
                return ret;
464
465
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
466
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
467
            if (ret < 0)
468
                return ret;
469
#endif
470
471
            if (wolfSSL_CryptHwMutexLock() == 0) {
472
                LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
473
                    key, keySize);
474
                wolfSSL_CryptHwMutexUnLock();
475
            }
476
            return 0;
477
        }
478
        #ifdef HAVE_AES_DECRYPT
479
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
480
            Aes* aes, const byte* inBlock, byte* outBlock)
481
        {
482
            word32 keySize = 0;
483
            byte* key = (byte*)aes->key;
484
            int ret = wc_AesGetKeySize(aes, &keySize);
485
            if (ret != 0)
486
                return ret;
487
488
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
489
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
490
            if (ret < 0)
491
                return ret;
492
#endif
493
494
            if (wolfSSL_CryptHwMutexLock() == 0) {
495
                LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
496
                    key, keySize, kLTC_EncryptKey);
497
                wolfSSL_CryptHwMutexUnLock();
498
            }
499
            return 0;
500
        }
501
        #endif
502
503
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
504
505
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
506
507
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
508
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
509
        Aes* aes, const byte* inBlock, byte* outBlock)
510
    {
511
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
512
        {
513
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
514
            if (ret < 0)
515
                return ret;
516
        }
517
#endif
518
        /* Thread mutex protection handled in Pic32Crypto */
519
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
520
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
521
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
522
    }
523
    #endif
524
525
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
526
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
527
        Aes* aes, const byte* inBlock, byte* outBlock)
528
    {
529
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
530
        {
531
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
532
            if (ret < 0)
533
                return ret;
534
        }
535
#endif
536
        /* Thread mutex protection handled in Pic32Crypto */
537
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
538
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
539
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
540
    }
541
    #endif
542
543
#elif defined(WOLFSSL_NRF51_AES)
544
    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
545
    #include "wolfssl/wolfcrypt/port/nrf51.h"
546
547
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
548
        Aes* aes, const byte* inBlock, byte* outBlock)
549
    {
550
        int ret;
551
552
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
553
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
554
        if (ret < 0)
555
            return ret;
556
#endif
557
558
        ret = wolfSSL_CryptHwMutexLock();
559
        if (ret == 0) {
560
            ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds,
561
                                    outBlock);
562
            wolfSSL_CryptHwMutexUnLock();
563
        }
564
        return ret;
565
    }
566
567
    #ifdef HAVE_AES_DECRYPT
568
        #error nRF51 AES Hardware does not support decrypt
569
    #endif /* HAVE_AES_DECRYPT */
570
571
#elif defined(WOLFSSL_ESP32_CRYPT) && \
572
     !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
573
    #include <esp_log.h>
574
    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
575
    #define TAG "aes"
576
577
    /* We'll use SW for fallback:
578
     *   unsupported key lengths. (e.g. ESP32-S3)
579
     *   chipsets not implemented.
580
     *   hardware busy. */
581
    #define NEED_AES_TABLES
582
    #define NEED_AES_HW_FALLBACK
583
    #define NEED_SOFTWARE_AES_SETKEY
584
    #undef  WOLFSSL_AES_DIRECT
585
    #define WOLFSSL_AES_DIRECT
586
587
    /* Encrypt: If we choose to never have a fallback to SW: */
588
    #if !defined(NEED_AES_HW_FALLBACK) && \
589
        (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
590
    /* calling this one when NO_AES_192 is defined */
591
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
592
        Aes* aes, const byte* inBlock, byte* outBlock)
593
    {
594
        int ret;
595
596
    #ifdef WC_DEBUG_CIPHER_LIFECYCLE
597
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
598
        if (ret < 0)
599
            return ret;
600
    #endif
601
602
        /* Thread mutex protection handled in esp_aes_hw_InUse */
603
    #ifdef NEED_AES_HW_FALLBACK
604
        if (wc_esp32AesSupportedKeyLen(aes)) {
605
            ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
606
        }
607
    #else
608
        ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
609
    #endif
610
        return ret;
611
    }
612
    #endif
613
614
    /* Decrypt: If we choose to never have a fallback to SW: */
615
    #if !defined(NEED_AES_HW_FALLBACK) && \
616
        (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
617
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
618
        Aes* aes, const byte* inBlock, byte* outBlock)
619
    {
620
        int ret = 0;
621
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
622
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
623
        if (ret < 0)
624
            return ret;
625
#endif
626
        /* Thread mutex protection handled in esp_aes_hw_InUse */
627
    #ifdef NEED_AES_HW_FALLBACK
628
        if (wc_esp32AesSupportedKeyLen(aes)) {
629
            ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
630
        }
631
        else {
632
            ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
633
        }
634
    #else
635
        /* if we don't need fallback, always use HW */
636
        ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
637
    #endif
638
        return ret;
639
    }
640
    #endif
641
642
#elif defined(WOLFSSL_AESNI)
643
644
    #define NEED_AES_TABLES
645
646
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
647
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
648
     */
649
650
    #ifndef AESNI_ALIGN
651
        #define AESNI_ALIGN 16
652
    #endif
653
654
    /* note that all write access to these static variables must be idempotent,
655
     * as arranged by Check_CPU_support_AES(), else they will be susceptible to
656
     * data races.
657
     */
658
    static int checkedAESNI = 0;
659
    static int haveAESNI  = 0;
660
    static cpuid_flags_t intel_flags = WC_CPUID_INITIALIZER;
661
662
    static WARN_UNUSED_RESULT int Check_CPU_support_AES(void)
663
    {
664
        cpuid_get_flags_ex(&intel_flags);
665
666
        return IS_INTEL_AESNI(intel_flags) != 0;
667
    }
668
669
670
    /* tell C compiler these are asm functions in case any mix up of ABI underscore
671
       prefix between clang/gcc/llvm etc */
672
    #ifdef HAVE_AES_CBC
673
        void AES_CBC_encrypt_AESNI(const unsigned char* in, unsigned char* out,
674
                             unsigned char* ivec, unsigned long length,
675
                             const unsigned char* KS, int nr)
676
                             XASM_LINK("AES_CBC_encrypt_AESNI");
677
678
        #ifdef HAVE_AES_DECRYPT
679
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
680
                void AES_CBC_decrypt_AESNI_by4(const unsigned char* in, unsigned char* out,
681
                                         unsigned char* ivec, unsigned long length,
682
                                         const unsigned char* KS, int nr)
683
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by4");
684
            #elif defined(WOLFSSL_AESNI_BY6)
685
                void AES_CBC_decrypt_AESNI_by6(const unsigned char* in, unsigned char* out,
686
                                         unsigned char* ivec, unsigned long length,
687
                                         const unsigned char* KS, int nr)
688
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by6");
689
            #else /* WOLFSSL_AESNI_BYx */
690
                void AES_CBC_decrypt_AESNI_by8(const unsigned char* in, unsigned char* out,
691
                                         unsigned char* ivec, unsigned long length,
692
                                         const unsigned char* KS, int nr)
693
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by8");
694
            #endif /* WOLFSSL_AESNI_BYx */
695
        #endif /* HAVE_AES_DECRYPT */
696
    #endif /* HAVE_AES_CBC */
697
698
    void AES_ECB_encrypt_AESNI(const unsigned char* in, unsigned char* out,
699
                         unsigned long length, const unsigned char* KS, int nr)
700
                         XASM_LINK("AES_ECB_encrypt_AESNI");
701
702
    #ifdef HAVE_AES_DECRYPT
703
        void AES_ECB_decrypt_AESNI(const unsigned char* in, unsigned char* out,
704
                             unsigned long length, const unsigned char* KS, int nr)
705
                             XASM_LINK("AES_ECB_decrypt_AESNI");
706
    #endif
707
708
    void AES_128_Key_Expansion_AESNI(const unsigned char* userkey,
709
                               unsigned char* key_schedule)
710
                               XASM_LINK("AES_128_Key_Expansion_AESNI");
711
712
    void AES_192_Key_Expansion_AESNI(const unsigned char* userkey,
713
                               unsigned char* key_schedule)
714
                               XASM_LINK("AES_192_Key_Expansion_AESNI");
715
716
    void AES_256_Key_Expansion_AESNI(const unsigned char* userkey,
717
                               unsigned char* key_schedule)
718
                               XASM_LINK("AES_256_Key_Expansion_AESNI");
719
720
721
    static WARN_UNUSED_RESULT int AES_set_encrypt_key_AESNI(
722
        const unsigned char *userKey, const int bits, Aes* aes)
723
    {
724
        int ret;
725
726
        ASSERT_SAVED_VECTOR_REGISTERS();
727
728
        if (!userKey || !aes)
729
            return BAD_FUNC_ARG;
730
731
        switch (bits) {
732
            case 128:
733
               AES_128_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 10;
734
               return 0;
735
            case 192:
736
               AES_192_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 12;
737
               return 0;
738
            case 256:
739
               AES_256_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 14;
740
               return 0;
741
            default:
742
                ret = BAD_FUNC_ARG;
743
        }
744
745
        return ret;
746
    }
747
748
    #ifdef HAVE_AES_DECRYPT
749
        static WARN_UNUSED_RESULT int AES_set_decrypt_key_AESNI(
750
            const unsigned char* userKey, const int bits, Aes* aes)
751
        {
752
            word32 nr;
753
            WC_DECLARE_VAR(temp_key, Aes, 1, 0);
754
            __m128i *Key_Schedule;
755
            __m128i *Temp_Key_Schedule;
756
757
            ASSERT_SAVED_VECTOR_REGISTERS();
758
759
            if (!userKey || !aes)
760
                return BAD_FUNC_ARG;
761
762
#ifdef WOLFSSL_SMALL_STACK
763
            if ((temp_key = (Aes *)XMALLOC(sizeof *aes, aes->heap,
764
                                           DYNAMIC_TYPE_AES)) == NULL)
765
                return MEMORY_E;
766
#endif
767
768
            if (AES_set_encrypt_key_AESNI(userKey,bits,temp_key)
769
                == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
770
                WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
771
                return BAD_FUNC_ARG;
772
            }
773
774
            Key_Schedule = (__m128i*)aes->key;
775
            Temp_Key_Schedule = (__m128i*)temp_key->key;
776
777
            nr = temp_key->rounds;
778
            aes->rounds = nr;
779
780
            Key_Schedule[nr] = Temp_Key_Schedule[0];
781
            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
782
            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
783
            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
784
            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
785
            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
786
            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
787
            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
788
            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
789
            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
790
791
            if (nr>10) {
792
                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
793
                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
794
            }
795
796
            if (nr>12) {
797
                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
798
                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
799
            }
800
801
            Key_Schedule[0] = Temp_Key_Schedule[nr];
802
803
            WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
804
805
            return 0;
806
        }
807
    #endif /* HAVE_AES_DECRYPT */
808
809
#elif defined(WOLFSSL_ARMASM)
810
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
811
static cpuid_flags_t cpuid_flags = WC_CPUID_INITIALIZER;
812
813
static void Check_CPU_support_HwCrypto(Aes* aes)
814
{
815
    cpuid_get_flags_ex(&cpuid_flags);
816
    aes->use_aes_hw_crypto = IS_AARCH64_AES(cpuid_flags);
817
#ifdef HAVE_AESGCM
818
    aes->use_pmull_hw_crypto = IS_AARCH64_PMULL(cpuid_flags);
819
    aes->use_sha3_hw_crypto = IS_AARCH64_SHA3(cpuid_flags);
820
#endif
821
}
822
#endif /* __aarch64__ && !WOLFSSL_ARMASM_NO_HW_CRYPTO */
823
824
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
825
    defined(WOLFSSL_AESGCM_STREAM)
826
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
827
    byte* outBlock)
828
{
829
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
830
#if !defined(__aarch64__)
831
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
832
#else
833
    if (aes->use_aes_hw_crypto) {
834
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
835
           (int)aes->rounds);
836
    }
837
    else
838
#endif /* !__aarch64__ */
839
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
840
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
841
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
842
    {
843
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
844
            (const unsigned char*)aes->key, aes->rounds);
845
    }
846
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
847
    {
848
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
849
            (int)aes->rounds);
850
    }
851
#endif
852
853
    return 0;
854
}
855
#endif
856
857
#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
858
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
859
    byte* outBlock)
860
{
861
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
862
#if !defined(__aarch64__)
863
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
864
#else
865
    if (aes->use_aes_hw_crypto) {
866
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
867
            (int)aes->rounds);
868
    }
869
    else
870
#endif /* !__aarch64__ */
871
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
872
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
873
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
874
    {
875
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
876
            (byte*)aes->key, (int)aes->rounds);
877
    }
878
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
879
    {
880
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
881
            (int)aes->rounds);
882
    }
883
#endif
884
    return 0;
885
}
886
#endif /* HAVE_AES_DECRYPT && WOLFSSL_AES_DIRECT */
887
888
#elif defined(FREESCALE_MMCAU)
889
    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
890
     * through the CAU/mmCAU library. Documentation located in
891
     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
892
     * Guide (See note in README). */
893
    #ifdef FREESCALE_MMCAU_CLASSIC
894
        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
895
        #include "cau_api.h"
896
    #else
897
        #include "fsl_mmcau.h"
898
    #endif
899
900
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
901
        Aes* aes, const byte* inBlock, byte* outBlock)
902
    {
903
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
904
        {
905
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
906
            if (ret < 0)
907
                return ret;
908
        }
909
#endif
910
911
        if (wolfSSL_CryptHwMutexLock() == 0) {
912
        #ifdef FREESCALE_MMCAU_CLASSIC
913
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
914
                WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
915
                return BAD_ALIGN_E;
916
            }
917
            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
918
        #else
919
            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
920
                                 outBlock);
921
        #endif
922
            wolfSSL_CryptHwMutexUnLock();
923
        }
924
        return 0;
925
    }
926
    #ifdef HAVE_AES_DECRYPT
927
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
928
        Aes* aes, const byte* inBlock, byte* outBlock)
929
    {
930
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
931
        {
932
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
933
            if (ret < 0)
934
                return ret;
935
        }
936
#endif
937
        if (wolfSSL_CryptHwMutexLock() == 0) {
938
        #ifdef FREESCALE_MMCAU_CLASSIC
939
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
940
                WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
941
                return BAD_ALIGN_E;
942
            }
943
            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
944
        #else
945
            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
946
                                 outBlock);
947
        #endif
948
            wolfSSL_CryptHwMutexUnLock();
949
        }
950
        return 0;
951
    }
952
    #endif /* HAVE_AES_DECRYPT */
953
954
#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
955
        && !defined(WOLFSSL_QNX_CAAM)) || \
956
      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
957
        defined(HAVE_AESCCM))
958
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
959
            Aes* aes, const byte* inBlock, byte* outBlock)
960
        {
961
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
962
            {
963
                int ret =
964
                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
965
                if (ret < 0)
966
                    return ret;
967
            }
968
#endif
969
            return wc_AesEncryptDirect(aes, outBlock, inBlock);
970
        }
971
972
#elif defined(WOLFSSL_AFALG)
973
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
974
975
#elif defined(WOLFSSL_DEVCRYPTO_AES)
976
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
977
978
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
979
    #include "hal_data.h"
980
981
    #ifndef WOLFSSL_SCE_AES256_HANDLE
982
        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
983
    #endif
984
985
    #ifndef WOLFSSL_SCE_AES192_HANDLE
986
        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
987
    #endif
988
989
    #ifndef WOLFSSL_SCE_AES128_HANDLE
990
        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
991
    #endif
992
993
    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
994
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
995
    {
996
        word32 ret;
997
998
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
999
                CRYPTO_WORD_ENDIAN_BIG) {
1000
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1001
        }
1002
1003
        switch (aes->keylen) {
1004
        #ifdef WOLFSSL_AES_128
1005
            case AES_128_KEY_SIZE:
1006
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
1007
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
1008
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1009
                        (word32*)outBlock);
1010
                break;
1011
        #endif
1012
        #ifdef WOLFSSL_AES_192
1013
            case AES_192_KEY_SIZE:
1014
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
1015
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
1016
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1017
                        (word32*)outBlock);
1018
                break;
1019
        #endif
1020
        #ifdef WOLFSSL_AES_256
1021
            case AES_256_KEY_SIZE:
1022
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
1023
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
1024
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1025
                        (word32*)outBlock);
1026
                break;
1027
        #endif
1028
            default:
1029
                WOLFSSL_MSG("Unknown key size");
1030
                return BAD_FUNC_ARG;
1031
        }
1032
1033
        if (ret != SSP_SUCCESS) {
1034
            /* revert input */
1035
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1036
            return WC_HW_E;
1037
        }
1038
1039
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1040
                CRYPTO_WORD_ENDIAN_BIG) {
1041
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1042
            if (inBlock != outBlock) {
1043
                /* revert input */
1044
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1045
            }
1046
        }
1047
        return 0;
1048
    }
1049
1050
    #if defined(HAVE_AES_DECRYPT)
1051
    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
1052
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1053
    {
1054
        word32 ret;
1055
1056
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1057
                CRYPTO_WORD_ENDIAN_BIG) {
1058
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1059
        }
1060
1061
        switch (aes->keylen) {
1062
        #ifdef WOLFSSL_AES_128
1063
            case AES_128_KEY_SIZE:
1064
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
1065
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
1066
                        (sz / sizeof(word32)), (word32*)inBlock,
1067
                        (word32*)outBlock);
1068
                break;
1069
        #endif
1070
        #ifdef WOLFSSL_AES_192
1071
            case AES_192_KEY_SIZE:
1072
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
1073
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
1074
                        (sz / sizeof(word32)), (word32*)inBlock,
1075
                        (word32*)outBlock);
1076
                break;
1077
        #endif
1078
        #ifdef WOLFSSL_AES_256
1079
            case AES_256_KEY_SIZE:
1080
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
1081
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
1082
                        (sz / sizeof(word32)), (word32*)inBlock,
1083
                        (word32*)outBlock);
1084
                break;
1085
        #endif
1086
            default:
1087
                WOLFSSL_MSG("Unknown key size");
1088
                return BAD_FUNC_ARG;
1089
        }
1090
        if (ret != SSP_SUCCESS) {
1091
            return WC_HW_E;
1092
        }
1093
1094
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1095
                CRYPTO_WORD_ENDIAN_BIG) {
1096
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1097
            if (inBlock != outBlock) {
1098
                /* revert input */
1099
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1100
            }
1101
        }
1102
1103
        return 0;
1104
    }
1105
    #endif /* HAVE_AES_DECRYPT */
1106
1107
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
1108
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1109
        Aes* aes, const byte* inBlock, byte* outBlock)
1110
    {
1111
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1112
        {
1113
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1114
            if (ret < 0)
1115
                return ret;
1116
        }
1117
#endif
1118
        return AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1119
    }
1120
    #endif
1121
1122
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1123
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1124
        Aes* aes, const byte* inBlock, byte* outBlock)
1125
    {
1126
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1127
        {
1128
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1129
            if (ret < 0)
1130
                return ret;
1131
        }
1132
#endif
1133
        return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1134
    }
1135
    #endif
1136
1137
#elif defined(WOLFSSL_KCAPI_AES)
1138
    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
1139
    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
1140
        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1141
        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
1142
        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
1143
        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
1144
1145
        #define NEED_AES_TABLES
1146
    #endif
1147
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
1148
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
1149
1150
#elif defined(WOLFSSL_RISCV_ASM)
1151
/* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
1152
1153
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1154
/* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
1155
1156
#elif defined(WOLFSSL_PSOC6_CRYPTO)
1157
1158
    #if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
1159
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1160
            Aes* aes, const byte* inBlock, byte* outBlock)
1161
        {
1162
            return wc_Psoc6_Aes_Encrypt(aes, inBlock, outBlock);
1163
        }
1164
    #endif
1165
1166
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1167
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
1168
            Aes* aes, const byte* inBlock, byte* outBlock)
1169
        {
1170
            return wc_Psoc6_Aes_Decrypt(aes, inBlock, outBlock);
1171
        }
1172
1173
    #endif
1174
#else
1175
1176
    /* using wolfCrypt software implementation */
1177
    #define NEED_AES_TABLES
1178
#endif
1179
1180
1181
1182
#if defined(WC_AES_BITSLICED) && !defined(HAVE_AES_ECB)
1183
    #error "When WC_AES_BITSLICED is defined, HAVE_AES_ECB is needed."
1184
#endif
1185
1186
#ifdef NEED_AES_TABLES
1187
1188
#ifndef WC_AES_BITSLICED
1189
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1190
#if !defined(WOLFSSL_ESP32_CRYPT) || \
1191
    (defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
1192
     defined(NEED_AES_HW_FALLBACK))
1193
static const FLASH_QUALIFIER word32 rcon[] = {
1194
    0x01000000, 0x02000000, 0x04000000, 0x08000000,
1195
    0x10000000, 0x20000000, 0x40000000, 0x80000000,
1196
    0x1B000000, 0x36000000,
1197
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1198
};
1199
#endif /* ESP32 */
1200
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1201
1202
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
1203
      defined(HAVE_AESCCM)
1204
#ifndef WOLFSSL_AES_SMALL_TABLES
1205
static const FLASH_QUALIFIER word32 Te[4][256] = {
1206
{
1207
    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1208
    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1209
    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1210
    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1211
    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1212
    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1213
    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1214
    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1215
    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1216
    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1217
    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1218
    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1219
    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1220
    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1221
    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1222
    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1223
    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1224
    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1225
    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1226
    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1227
    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1228
    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1229
    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1230
    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1231
    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1232
    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1233
    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1234
    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1235
    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1236
    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1237
    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1238
    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1239
    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1240
    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1241
    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1242
    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1243
    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1244
    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1245
    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1246
    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1247
    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1248
    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1249
    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1250
    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1251
    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1252
    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1253
    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1254
    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1255
    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1256
    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1257
    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1258
    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1259
    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1260
    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1261
    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1262
    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1263
    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1264
    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1265
    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1266
    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1267
    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1268
    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1269
    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1270
    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1271
},
1272
{
1273
    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1274
    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1275
    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1276
    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1277
    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1278
    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1279
    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1280
    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1281
    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1282
    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1283
    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1284
    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1285
    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1286
    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1287
    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1288
    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1289
    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1290
    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1291
    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1292
    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1293
    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1294
    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1295
    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1296
    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1297
    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1298
    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1299
    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1300
    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1301
    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1302
    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1303
    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1304
    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1305
    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1306
    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1307
    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1308
    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1309
    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1310
    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1311
    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1312
    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1313
    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1314
    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1315
    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1316
    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1317
    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1318
    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1319
    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1320
    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1321
    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1322
    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1323
    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1324
    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1325
    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1326
    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1327
    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1328
    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1329
    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1330
    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1331
    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1332
    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1333
    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1334
    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1335
    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1336
    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1337
},
1338
{
1339
    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1340
    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1341
    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1342
    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1343
    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1344
    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1345
    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1346
    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1347
    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1348
    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1349
    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1350
    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1351
    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1352
    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1353
    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1354
    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1355
    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1356
    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1357
    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1358
    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1359
    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1360
    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1361
    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1362
    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1363
    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1364
    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1365
    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1366
    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1367
    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1368
    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1369
    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1370
    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1371
    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1372
    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1373
    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1374
    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1375
    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1376
    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1377
    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1378
    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1379
    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1380
    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1381
    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1382
    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1383
    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1384
    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1385
    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1386
    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1387
    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1388
    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1389
    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1390
    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1391
    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1392
    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1393
    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1394
    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1395
    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1396
    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1397
    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1398
    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1399
    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1400
    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1401
    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1402
    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1403
},
1404
{
1405
    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1406
    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1407
    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1408
    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1409
    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1410
    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1411
    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1412
    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1413
    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1414
    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1415
    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1416
    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1417
    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1418
    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1419
    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1420
    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1421
    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1422
    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1423
    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1424
    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1425
    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1426
    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1427
    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1428
    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1429
    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1430
    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1431
    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1432
    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1433
    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1434
    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1435
    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1436
    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1437
    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1438
    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1439
    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1440
    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1441
    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1442
    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1443
    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1444
    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1445
    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1446
    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1447
    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1448
    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1449
    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1450
    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1451
    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1452
    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1453
    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1454
    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1455
    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1456
    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1457
    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1458
    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1459
    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1460
    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1461
    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1462
    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1463
    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1464
    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1465
    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1466
    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1467
    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1468
    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1469
}
1470
};
1471
1472
#ifdef HAVE_AES_DECRYPT
1473
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1474
static const FLASH_QUALIFIER word32 Td[4][256] = {
1475
{
1476
    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1477
    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1478
    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1479
    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1480
    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1481
    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1482
    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1483
    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1484
    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1485
    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1486
    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1487
    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1488
    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1489
    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1490
    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1491
    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1492
    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1493
    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1494
    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1495
    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1496
    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1497
    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1498
    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1499
    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1500
    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1501
    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1502
    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1503
    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1504
    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1505
    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1506
    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1507
    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1508
    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1509
    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1510
    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1511
    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1512
    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1513
    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1514
    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1515
    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1516
    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1517
    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1518
    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1519
    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1520
    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1521
    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1522
    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1523
    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1524
    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1525
    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1526
    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1527
    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1528
    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1529
    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1530
    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1531
    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1532
    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1533
    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1534
    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1535
    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1536
    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1537
    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1538
    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1539
    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1540
},
1541
{
1542
    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
1543
    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
1544
    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
1545
    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
1546
    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
1547
    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
1548
    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
1549
    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
1550
    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
1551
    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
1552
    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
1553
    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
1554
    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
1555
    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
1556
    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
1557
    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
1558
    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
1559
    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
1560
    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
1561
    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
1562
    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
1563
    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
1564
    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
1565
    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
1566
    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
1567
    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
1568
    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
1569
    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
1570
    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
1571
    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
1572
    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
1573
    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
1574
    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
1575
    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
1576
    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
1577
    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
1578
    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
1579
    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
1580
    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
1581
    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
1582
    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
1583
    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
1584
    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
1585
    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
1586
    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
1587
    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
1588
    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
1589
    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
1590
    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
1591
    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
1592
    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
1593
    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
1594
    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
1595
    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
1596
    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
1597
    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
1598
    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
1599
    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
1600
    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
1601
    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
1602
    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
1603
    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
1604
    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
1605
    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
1606
},
1607
{
1608
    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
1609
    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
1610
    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
1611
    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
1612
    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
1613
    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
1614
    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
1615
    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
1616
    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
1617
    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
1618
    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
1619
    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
1620
    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
1621
    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
1622
    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
1623
    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
1624
    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
1625
    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
1626
    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
1627
    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
1628
1629
    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
1630
    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
1631
    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
1632
    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
1633
    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
1634
    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
1635
    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
1636
    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
1637
    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
1638
    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
1639
    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
1640
    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
1641
    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
1642
    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
1643
    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
1644
    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
1645
    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
1646
    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
1647
    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
1648
    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
1649
    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
1650
    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
1651
    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
1652
    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
1653
    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
1654
    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
1655
    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
1656
    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
1657
    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
1658
    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
1659
    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
1660
    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
1661
    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
1662
    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
1663
    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
1664
    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
1665
    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
1666
    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
1667
    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
1668
    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
1669
    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
1670
    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
1671
    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
1672
    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
1673
},
1674
{
1675
    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
1676
    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
1677
    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
1678
    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
1679
    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
1680
    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
1681
    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
1682
    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
1683
    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
1684
    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
1685
    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
1686
    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
1687
    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
1688
    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
1689
    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
1690
    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
1691
    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
1692
    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
1693
    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
1694
    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
1695
    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
1696
    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
1697
    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
1698
    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
1699
    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
1700
    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
1701
    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
1702
    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
1703
    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
1704
    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
1705
    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
1706
    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
1707
    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
1708
    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
1709
    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
1710
    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
1711
    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
1712
    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
1713
    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
1714
    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
1715
    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
1716
    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
1717
    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
1718
    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
1719
    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
1720
    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
1721
    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
1722
    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
1723
    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
1724
    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
1725
    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
1726
    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
1727
    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
1728
    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
1729
    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
1730
    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
1731
    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
1732
    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
1733
    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
1734
    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
1735
    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
1736
    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
1737
    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
1738
    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
1739
}
1740
};
1741
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1742
#endif /* HAVE_AES_DECRYPT */
1743
#endif /* WOLFSSL_AES_SMALL_TABLES */
1744
1745
#ifdef HAVE_AES_DECRYPT
1746
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
1747
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)
1748
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1749
static const FLASH_QUALIFIER byte Td4[256] =
1750
{
1751
    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
1752
    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
1753
    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
1754
    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
1755
    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
1756
    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
1757
    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
1758
    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
1759
    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
1760
    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
1761
    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
1762
    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
1763
    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
1764
    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
1765
    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
1766
    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
1767
    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
1768
    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
1769
    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
1770
    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
1771
    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
1772
    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
1773
    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
1774
    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
1775
    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
1776
    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
1777
    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
1778
    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
1779
    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
1780
    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
1781
    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
1782
    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
1783
};
1784
#endif
1785
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1786
#endif /* HAVE_AES_DECRYPT */
1787
1788
#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
1789
1790
#ifdef WOLFSSL_AES_SMALL_TABLES
1791
static const byte Tsbox[256] = {
1792
    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
1793
    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
1794
    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
1795
    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
1796
    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
1797
    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
1798
    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
1799
    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
1800
    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
1801
    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
1802
    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
1803
    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
1804
    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
1805
    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
1806
    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
1807
    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
1808
    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
1809
    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
1810
    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
1811
    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
1812
    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
1813
    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
1814
    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
1815
    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
1816
    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
1817
    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
1818
    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
1819
    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
1820
    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
1821
    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
1822
    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
1823
    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
1824
};
1825
1826
#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
1827
1828
static WARN_UNUSED_RESULT word32 col_mul(
1829
    word32 t, int i2, int i3, int ia, int ib)
1830
{
1831
    byte t3 = GETBYTE(t, i3);
1832
    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
1833
1834
    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
1835
}
1836
1837
#if defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
1838
    defined(WOLFSSL_AES_DIRECT)
1839
static WARN_UNUSED_RESULT word32 inv_col_mul(
1840
    word32 t, int i9, int ib, int id, int ie)
1841
{
1842
    byte t9 = GETBYTE(t, i9);
1843
    byte tb = GETBYTE(t, ib);
1844
    byte td = GETBYTE(t, id);
1845
    byte te = GETBYTE(t, ie);
1846
    byte t0 = t9 ^ tb ^ td;
1847
    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
1848
}
1849
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1850
#endif /* WOLFSSL_AES_SMALL_TABLES */
1851
#endif
1852
#endif
1853
1854
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
1855
                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
1856
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
1857
      defined(HAVE_AESCCM)
1858
1859
1860
#ifndef WC_AES_BITSLICED
1861
1862
#ifndef WC_CACHE_LINE_SZ
1863
    #if defined(__x86_64__) || defined(_M_X64) || \
1864
       (defined(__ILP32__) && (__ILP32__ >= 1))
1865
15.9M
        #define WC_CACHE_LINE_SZ 64
1866
    #else
1867
        /* default cache line size */
1868
        #define WC_CACHE_LINE_SZ 32
1869
    #endif
1870
#endif
1871
1872
#ifndef WC_NO_CACHE_RESISTANT
1873
1874
#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
1875
    #define WOLFSSL_AES_TOUCH_LINES
1876
#endif
1877
1878
#ifndef WOLFSSL_AES_SMALL_TABLES
1879
/* load 4 Te Tables into cache by cache line stride */
1880
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
1881
237k
{
1882
237k
#ifndef WOLFSSL_AES_TOUCH_LINES
1883
237k
    word32 x = 0;
1884
237k
    int i,j;
1885
1886
1.18M
    for (i = 0; i < 4; i++) {
1887
        /* 256 elements, each one is 4 bytes */
1888
16.1M
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
1889
15.1M
            x &= Te[i][j];
1890
15.1M
        }
1891
949k
    }
1892
237k
    return x;
1893
#else
1894
    return 0;
1895
#endif
1896
237k
}
1897
#else
1898
/* load sbox into cache by cache line stride */
1899
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
1900
{
1901
#ifndef WOLFSSL_AES_TOUCH_LINES
1902
    word32 x = 0;
1903
    int i;
1904
1905
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
1906
        x &= Tsbox[i];
1907
    }
1908
    return x;
1909
#else
1910
    return 0;
1911
#endif
1912
}
1913
#endif
1914
#endif
1915
1916
#ifdef WOLFSSL_AES_TOUCH_LINES
1917
#if WC_CACHE_LINE_SZ == 128
1918
    #define WC_CACHE_LINE_BITS      5
1919
    #define WC_CACHE_LINE_MASK_HI   0xe0
1920
    #define WC_CACHE_LINE_MASK_LO   0x1f
1921
    #define WC_CACHE_LINE_ADD       0x20
1922
#elif WC_CACHE_LINE_SZ == 64
1923
    #define WC_CACHE_LINE_BITS      4
1924
    #define WC_CACHE_LINE_MASK_HI   0xf0
1925
    #define WC_CACHE_LINE_MASK_LO   0x0f
1926
    #define WC_CACHE_LINE_ADD       0x10
1927
#elif WC_CACHE_LINE_SZ == 32
1928
    #define WC_CACHE_LINE_BITS      3
1929
    #define WC_CACHE_LINE_MASK_HI   0xf8
1930
    #define WC_CACHE_LINE_MASK_LO   0x07
1931
    #define WC_CACHE_LINE_ADD       0x08
1932
#elif WC_CACHE_LINE_SZ == 16
1933
    #define WC_CACHE_LINE_BITS      2
1934
    #define WC_CACHE_LINE_MASK_HI   0xfc
1935
    #define WC_CACHE_LINE_MASK_LO   0x03
1936
    #define WC_CACHE_LINE_ADD       0x04
1937
#else
1938
    #error Cache line size not supported
1939
#endif
1940
1941
#ifndef WOLFSSL_AES_SMALL_TABLES
1942
static word32 GetTable(const word32* t, byte o)
1943
{
1944
#if WC_CACHE_LINE_SZ == 64
1945
    word32 e;
1946
    byte hi = o & 0xf0;
1947
    byte lo = o & 0x0f;
1948
1949
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1950
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1951
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1952
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1953
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1954
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1955
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1956
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1957
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1958
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1959
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1960
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1961
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1962
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1963
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1964
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1965
1966
    return e;
1967
#else
1968
    word32 e = 0;
1969
    int i;
1970
    byte hi = o & WC_CACHE_LINE_MASK_HI;
1971
    byte lo = o & WC_CACHE_LINE_MASK_LO;
1972
1973
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1974
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1975
        hi -= WC_CACHE_LINE_ADD;
1976
    }
1977
1978
    return e;
1979
#endif
1980
}
1981
#endif
1982
1983
#ifdef WOLFSSL_AES_SMALL_TABLES
1984
static byte GetTable8(const byte* t, byte o)
1985
{
1986
#if WC_CACHE_LINE_SZ == 64
1987
    byte e;
1988
    byte hi = o & 0xf0;
1989
    byte lo = o & 0x0f;
1990
1991
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1992
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1993
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1994
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1995
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1996
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1997
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1998
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1999
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2000
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2001
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2002
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2003
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2004
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2005
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2006
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2007
2008
    return e;
2009
#else
2010
    byte e = 0;
2011
    int i;
2012
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2013
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2014
2015
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2016
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2017
        hi -= WC_CACHE_LINE_ADD;
2018
    }
2019
2020
    return e;
2021
#endif
2022
}
2023
#endif
2024
2025
#ifndef WOLFSSL_AES_SMALL_TABLES
2026
static void GetTable_Multi(const word32* t, word32* t0, byte o0,
2027
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2028
{
2029
    word32 e0 = 0;
2030
    word32 e1 = 0;
2031
    word32 e2 = 0;
2032
    word32 e3 = 0;
2033
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2034
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2035
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2036
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2037
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2038
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2039
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2040
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2041
    int i;
2042
2043
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2044
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2045
        hi0 -= WC_CACHE_LINE_ADD;
2046
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2047
        hi1 -= WC_CACHE_LINE_ADD;
2048
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2049
        hi2 -= WC_CACHE_LINE_ADD;
2050
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2051
        hi3 -= WC_CACHE_LINE_ADD;
2052
    }
2053
    *t0 = e0;
2054
    *t1 = e1;
2055
    *t2 = e2;
2056
    *t3 = e3;
2057
}
2058
static void XorTable_Multi(const word32* t, word32* t0, byte o0,
2059
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2060
{
2061
    word32 e0 = 0;
2062
    word32 e1 = 0;
2063
    word32 e2 = 0;
2064
    word32 e3 = 0;
2065
    byte hi0 = o0 & 0xf0;
2066
    byte lo0 = o0 & 0x0f;
2067
    byte hi1 = o1 & 0xf0;
2068
    byte lo1 = o1 & 0x0f;
2069
    byte hi2 = o2 & 0xf0;
2070
    byte lo2 = o2 & 0x0f;
2071
    byte hi3 = o3 & 0xf0;
2072
    byte lo3 = o3 & 0x0f;
2073
    int i;
2074
2075
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2076
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2077
        hi0 -= WC_CACHE_LINE_ADD;
2078
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2079
        hi1 -= WC_CACHE_LINE_ADD;
2080
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2081
        hi2 -= WC_CACHE_LINE_ADD;
2082
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2083
        hi3 -= WC_CACHE_LINE_ADD;
2084
    }
2085
    *t0 ^= e0;
2086
    *t1 ^= e1;
2087
    *t2 ^= e2;
2088
    *t3 ^= e3;
2089
}
2090
static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
2091
{
2092
    word32 e = 0;
2093
    int i;
2094
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2095
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2096
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2097
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2098
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2099
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2100
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2101
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2102
2103
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2104
        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
2105
             << 24;
2106
        hi0 -= WC_CACHE_LINE_ADD;
2107
        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
2108
             << 16;
2109
        hi1 -= WC_CACHE_LINE_ADD;
2110
        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
2111
             <<  8;
2112
        hi2 -= WC_CACHE_LINE_ADD;
2113
        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
2114
             <<  0;
2115
        hi3 -= WC_CACHE_LINE_ADD;
2116
    }
2117
2118
    return e;
2119
}
2120
#endif
2121
#else
2122
2123
44.6M
#define GetTable(t, o)  t[o]
2124
#define GetTable8(t, o) t[o]
2125
#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2126
    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
2127
#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2128
    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
2129
#define GetTable8_4(t, o0, o1, o2, o3) \
2130
43.6k
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
2131
43.6k
     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
2132
#endif
2133
2134
#ifndef HAVE_CUDA
2135
/* Encrypt a block using AES.
2136
 *
2137
 * @param [in]  aes       AES object.
2138
 * @param [in]  inBlock   Block to encrypt.
2139
 * @param [out] outBlock  Encrypted block.
2140
 * @param [in]  r         Rounds divided by 2.
2141
 */
2142
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2143
        word32 r)
2144
237k
{
2145
237k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
2146
237k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
2147
237k
    const word32* rk;
2148
2149
#ifdef WC_C_DYNAMIC_FALLBACK
2150
    rk = aes->key_C_fallback;
2151
#else
2152
237k
    rk = aes->key;
2153
237k
#endif
2154
2155
    /*
2156
     * map byte array block to cipher state
2157
     * and add initial round key:
2158
     */
2159
237k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
2160
237k
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
2161
237k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
2162
237k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
2163
2164
237k
#ifdef LITTLE_ENDIAN_ORDER
2165
237k
    s0 = ByteReverseWord32(s0);
2166
237k
    s1 = ByteReverseWord32(s1);
2167
237k
    s2 = ByteReverseWord32(s2);
2168
237k
    s3 = ByteReverseWord32(s3);
2169
237k
#endif
2170
2171
    /* AddRoundKey */
2172
237k
    s0 ^= rk[0];
2173
237k
    s1 ^= rk[1];
2174
237k
    s2 ^= rk[2];
2175
237k
    s3 ^= rk[3];
2176
2177
237k
#ifndef WOLFSSL_AES_SMALL_TABLES
2178
237k
#ifndef WC_NO_CACHE_RESISTANT
2179
237k
    s0 |= PreFetchTe();
2180
237k
#endif
2181
2182
237k
#ifndef WOLFSSL_AES_TOUCH_LINES
2183
237k
#define ENC_ROUND_T_S(o)                                                       \
2184
1.32M
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
2185
1.32M
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
2186
1.32M
         rk[(o)+4];                                                            \
2187
1.32M
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
2188
1.32M
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
2189
1.32M
         rk[(o)+5];                                                            \
2190
1.32M
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
2191
1.32M
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
2192
1.32M
         rk[(o)+6];                                                            \
2193
1.32M
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
2194
1.32M
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
2195
1.32M
         rk[(o)+7]
2196
237k
#define ENC_ROUND_S_T(o)                                                       \
2197
1.08M
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
2198
1.08M
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
2199
1.08M
         rk[(o)+0];                                                            \
2200
1.08M
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
2201
1.08M
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
2202
1.08M
         rk[(o)+1];                                                            \
2203
1.08M
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
2204
1.08M
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
2205
1.08M
         rk[(o)+2];                                                            \
2206
1.08M
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
2207
1.08M
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
2208
1.08M
         rk[(o)+3]
2209
#else
2210
#define ENC_ROUND_T_S(o)                                                       \
2211
    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
2212
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
2213
    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
2214
                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
2215
    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
2216
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
2217
    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
2218
                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
2219
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
2220
2221
#define ENC_ROUND_S_T(o)                                                       \
2222
    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
2223
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
2224
    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
2225
                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
2226
    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
2227
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2228
    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
2229
                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
2230
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2231
#endif
2232
2233
237k
#ifndef WOLFSSL_AES_NO_UNROLL
2234
/* Unroll the loop. */
2235
237k
                       ENC_ROUND_T_S( 0);
2236
237k
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2237
237k
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2238
237k
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2239
237k
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2240
237k
    if (r > 5) {
2241
75.2k
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2242
75.2k
        if (r > 6) {
2243
63.7k
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2244
63.7k
        }
2245
75.2k
    }
2246
237k
    rk += r * 8;
2247
#else
2248
    /*
2249
     * Nr - 1 full rounds:
2250
     */
2251
2252
    for (;;) {
2253
        ENC_ROUND_T_S(0);
2254
2255
        rk += 8;
2256
        if (--r == 0) {
2257
            break;
2258
        }
2259
2260
        ENC_ROUND_S_T(0);
2261
    }
2262
#endif
2263
2264
    /*
2265
     * apply last round and
2266
     * map cipher state to byte array block:
2267
     */
2268
2269
237k
#ifndef WOLFSSL_AES_TOUCH_LINES
2270
237k
    s0 =
2271
237k
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2272
237k
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2273
237k
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2274
237k
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2275
237k
        rk[0];
2276
237k
    s1 =
2277
237k
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2278
237k
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2279
237k
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2280
237k
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2281
237k
        rk[1];
2282
237k
    s2 =
2283
237k
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2284
237k
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2285
237k
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2286
237k
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2287
237k
        rk[2];
2288
237k
    s3 =
2289
237k
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2290
237k
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2291
237k
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2292
237k
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2293
237k
        rk[3];
2294
#else
2295
{
2296
    word32 u0;
2297
    word32 u1;
2298
    word32 u2;
2299
    word32 u3;
2300
2301
    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
2302
    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
2303
                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
2304
    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
2305
    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
2306
    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
2307
                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
2308
    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
2309
    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
2310
    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
2311
                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
2312
    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
2313
    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
2314
    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
2315
                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
2316
    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
2317
    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
2318
}
2319
#endif
2320
#else
2321
#ifndef WC_NO_CACHE_RESISTANT
2322
    s0 |= PreFetchSBox();
2323
#endif
2324
2325
    r *= 2;
2326
    /* Two rounds at a time */
2327
    for (rk += 4; r > 1; r--, rk += 4) {
2328
        t0 =
2329
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2330
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2331
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2332
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2333
        t1 =
2334
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2335
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2336
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2337
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2338
        t2 =
2339
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2340
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2341
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2342
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2343
        t3 =
2344
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2345
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2346
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2347
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2348
2349
        s0 =
2350
            (col_mul(t0, 3, 2, 0, 1) << 24) ^
2351
            (col_mul(t0, 2, 1, 0, 3) << 16) ^
2352
            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
2353
            (col_mul(t0, 0, 3, 2, 1)      ) ^
2354
            rk[0];
2355
        s1 =
2356
            (col_mul(t1, 3, 2, 0, 1) << 24) ^
2357
            (col_mul(t1, 2, 1, 0, 3) << 16) ^
2358
            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
2359
            (col_mul(t1, 0, 3, 2, 1)      ) ^
2360
            rk[1];
2361
        s2 =
2362
            (col_mul(t2, 3, 2, 0, 1) << 24) ^
2363
            (col_mul(t2, 2, 1, 0, 3) << 16) ^
2364
            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
2365
            (col_mul(t2, 0, 3, 2, 1)      ) ^
2366
            rk[2];
2367
        s3 =
2368
            (col_mul(t3, 3, 2, 0, 1) << 24) ^
2369
            (col_mul(t3, 2, 1, 0, 3) << 16) ^
2370
            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
2371
            (col_mul(t3, 0, 3, 2, 1)      ) ^
2372
            rk[3];
2373
    }
2374
2375
    t0 =
2376
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2377
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2378
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2379
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2380
    t1 =
2381
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2382
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2383
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2384
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2385
    t2 =
2386
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2387
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2388
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2389
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2390
    t3 =
2391
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2392
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2393
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2394
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2395
    s0 = t0 ^ rk[0];
2396
    s1 = t1 ^ rk[1];
2397
    s2 = t2 ^ rk[2];
2398
    s3 = t3 ^ rk[3];
2399
#endif
2400
2401
    /* write out */
2402
237k
#ifdef LITTLE_ENDIAN_ORDER
2403
237k
    s0 = ByteReverseWord32(s0);
2404
237k
    s1 = ByteReverseWord32(s1);
2405
237k
    s2 = ByteReverseWord32(s2);
2406
237k
    s3 = ByteReverseWord32(s3);
2407
237k
#endif
2408
2409
237k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2410
237k
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2411
237k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2412
237k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2413
237k
}
2414
2415
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2416
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
2417
    !defined(MAX3266X_AES)
2418
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
2419
/* Encrypt a number of blocks using AES.
2420
 *
2421
 * @param [in]  aes  AES object.
2422
 * @param [in]  in   Block to encrypt.
2423
 * @param [out] out  Encrypted block.
2424
 * @param [in]  sz   Number of blocks to encrypt.
2425
 */
2426
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2427
1.10k
{
2428
1.10k
    word32 i;
2429
2430
12.8k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
2431
11.7k
        AesEncrypt_C(aes, in, out, aes->rounds >> 1);
2432
11.7k
        in += WC_AES_BLOCK_SIZE;
2433
11.7k
        out += WC_AES_BLOCK_SIZE;
2434
11.7k
    }
2435
1.10k
}
2436
#endif
2437
#endif
2438
#else
2439
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2440
        word32 r);
2441
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2442
#endif /* HAVE_CUDA */
2443
2444
#else
2445
2446
/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
2447
 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
2448
 */
2449
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
2450
static void bs_sub_bytes(bs_word u[8])
2451
{
2452
    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
2453
    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
2454
    bs_word y20, y21;
2455
    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
2456
    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
2457
    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
2458
    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
2459
    bs_word t40, t41, t42, t43, t44, t45;
2460
    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
2461
    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
2462
    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
2463
    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
2464
    bs_word tc20, tc21, tc26;
2465
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
2466
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
2467
2468
    U0 = u[7];
2469
    U1 = u[6];
2470
    U2 = u[5];
2471
    U3 = u[4];
2472
    U4 = u[3];
2473
    U5 = u[2];
2474
    U6 = u[1];
2475
    U7 = u[0];
2476
2477
    y14 = U3 ^ U5;
2478
    y13 = U0 ^ U6;
2479
    y9 = U0 ^ U3;
2480
    y8 = U0 ^ U5;
2481
    t0 = U1 ^ U2;
2482
    y1 = t0 ^ U7;
2483
    y4 = y1 ^ U3;
2484
    y12 = y13 ^ y14;
2485
    y2 = y1 ^ U0;
2486
    y5 = y1 ^ U6;
2487
    y3 = y5 ^ y8;
2488
    t1 = U4 ^ y12;
2489
    y15 = t1 ^ U5;
2490
    y20 = t1 ^ U1;
2491
    y6 = y15 ^ U7;
2492
    y10 = y15 ^ t0;
2493
    y11 = y20 ^ y9;
2494
    y7 = U7 ^ y11;
2495
    y17 = y10 ^ y11;
2496
    y19 = y10 ^ y8;
2497
    y16 = t0 ^ y11;
2498
    y21 = y13 ^ y16;
2499
    y18 = U0 ^ y16;
2500
    t2 = y12 & y15;
2501
    t3 = y3 & y6;
2502
    t4 = t3 ^ t2;
2503
    t5 = y4 & U7;
2504
    t6 = t5 ^ t2;
2505
    t7 = y13 & y16;
2506
    t8 = y5 & y1;
2507
    t9 = t8 ^ t7;
2508
    t10 = y2 & y7;
2509
    t11 = t10 ^ t7;
2510
    t12 = y9 & y11;
2511
    t13 = y14 & y17;
2512
    t14 = t13 ^ t12;
2513
    t15 = y8 & y10;
2514
    t16 = t15 ^ t12;
2515
    t17 = t4 ^ y20;
2516
    t18 = t6 ^ t16;
2517
    t19 = t9 ^ t14;
2518
    t20 = t11 ^ t16;
2519
    t21 = t17 ^ t14;
2520
    t22 = t18 ^ y19;
2521
    t23 = t19 ^ y21;
2522
    t24 = t20 ^ y18;
2523
    t25 = t21 ^ t22;
2524
    t26 = t21 & t23;
2525
    t27 = t24 ^ t26;
2526
    t28 = t25 & t27;
2527
    t29 = t28 ^ t22;
2528
    t30 = t23 ^ t24;
2529
    t31 = t22 ^ t26;
2530
    t32 = t31 & t30;
2531
    t33 = t32 ^ t24;
2532
    t34 = t23 ^ t33;
2533
    t35 = t27 ^ t33;
2534
    t36 = t24 & t35;
2535
    t37 = t36 ^ t34;
2536
    t38 = t27 ^ t36;
2537
    t39 = t29 & t38;
2538
    t40 = t25 ^ t39;
2539
    t41 = t40 ^ t37;
2540
    t42 = t29 ^ t33;
2541
    t43 = t29 ^ t40;
2542
    t44 = t33 ^ t37;
2543
    t45 = t42 ^ t41;
2544
    z0 = t44 & y15;
2545
    z1 = t37 & y6;
2546
    z2 = t33 & U7;
2547
    z3 = t43 & y16;
2548
    z4 = t40 & y1;
2549
    z5 = t29 & y7;
2550
    z6 = t42 & y11;
2551
    z7 = t45 & y17;
2552
    z8 = t41 & y10;
2553
    z9 = t44 & y12;
2554
    z10 = t37 & y3;
2555
    z11 = t33 & y4;
2556
    z12 = t43 & y13;
2557
    z13 = t40 & y5;
2558
    z14 = t29 & y2;
2559
    z15 = t42 & y9;
2560
    z16 = t45 & y14;
2561
    z17 = t41 & y8;
2562
    tc1 = z15 ^ z16;
2563
    tc2 = z10 ^ tc1;
2564
    tc3 = z9 ^ tc2;
2565
    tc4 = z0 ^ z2;
2566
    tc5 = z1 ^ z0;
2567
    tc6 = z3 ^ z4;
2568
    tc7 = z12 ^ tc4;
2569
    tc8 = z7 ^ tc6;
2570
    tc9 = z8 ^ tc7;
2571
    tc10 = tc8 ^ tc9;
2572
    tc11 = tc6 ^ tc5;
2573
    tc12 = z3 ^ z5;
2574
    tc13 = z13 ^ tc1;
2575
    tc14 = tc4 ^ tc12;
2576
    S3 = tc3 ^ tc11;
2577
    tc16 = z6 ^ tc8;
2578
    tc17 = z14 ^ tc10;
2579
    tc18 = tc13 ^ tc14;
2580
    S7 = ~(z12 ^ tc18);
2581
    tc20 = z15 ^ tc16;
2582
    tc21 = tc2 ^ z11;
2583
    S0 = tc3 ^ tc16;
2584
    S6 = ~(tc10 ^ tc18);
2585
    S4 = tc14 ^ S3;
2586
    S1 = ~(S3 ^ tc16);
2587
    tc26 = tc17 ^ tc20;
2588
    S2 = ~(tc26 ^ z17);
2589
    S5 = tc21 ^ tc17;
2590
2591
    u[0] = S7;
2592
    u[1] = S6;
2593
    u[2] = S5;
2594
    u[3] = S4;
2595
    u[4] = S3;
2596
    u[5] = S2;
2597
    u[6] = S1;
2598
    u[7] = S0;
2599
}
2600
2601
#define BS_MASK_BIT_SET(w, j, bmask) \
2602
    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
2603
2604
#define BS_TRANS_8(t, o, w, bmask, s)                   \
2605
    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
2606
    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
2607
    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
2608
    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
2609
    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
2610
    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
2611
    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
2612
    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2613
2614
static void bs_transpose(bs_word* t, bs_word* blocks)
2615
{
2616
    bs_word bmask = 1;
2617
    int i;
2618
2619
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2620
2621
    for (i = 0; i < BS_WORD_SIZE; i++) {
2622
        int j;
2623
        int o = 0;
2624
        for (j = 0; j < BS_BLOCK_WORDS; j++) {
2625
        #ifdef LITTLE_ENDIAN_ORDER
2626
            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
2627
        #else
2628
            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
2629
        #endif
2630
    #ifdef WOLFSSL_AES_NO_UNROLL
2631
            int k;
2632
            for (k = 0; k < BS_WORD_SIZE; k++) {
2633
                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
2634
            }
2635
    #else
2636
            BS_TRANS_8(t, o, w, bmask,  0);
2637
        #if BS_WORD_SIZE >= 16
2638
            BS_TRANS_8(t, o, w, bmask,  8);
2639
        #endif
2640
        #if BS_WORD_SIZE >= 32
2641
            BS_TRANS_8(t, o, w, bmask, 16);
2642
            BS_TRANS_8(t, o, w, bmask, 24);
2643
        #endif
2644
        #if BS_WORD_SIZE >= 64
2645
            BS_TRANS_8(t, o, w, bmask, 32);
2646
            BS_TRANS_8(t, o, w, bmask, 40);
2647
            BS_TRANS_8(t, o, w, bmask, 48);
2648
            BS_TRANS_8(t, o, w, bmask, 56);
2649
        #endif
2650
    #endif
2651
            o += BS_WORD_SIZE;
2652
        }
2653
        bmask <<= 1;
2654
    }
2655
}
2656
2657
#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
2658
    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
2659
    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
2660
    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
2661
    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
2662
    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
2663
    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
2664
    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
2665
    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2666
2667
static void bs_inv_transpose(bs_word* t, bs_word* blocks)
2668
{
2669
    int o;
2670
2671
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2672
2673
    for (o = 0; o < BS_BLOCK_WORDS; o++) {
2674
        int i;
2675
        for (i = 0; i < BS_WORD_SIZE; i++) {
2676
        #ifdef LITTLE_ENDIAN_ORDER
2677
            bs_word bmask = (bs_word)1 << i;
2678
        #else
2679
            bs_word bmask = bs_bswap((bs_word)1 << i);
2680
        #endif
2681
            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
2682
    #ifdef WOLFSSL_AES_NO_UNROLL
2683
            int j;
2684
            for (j = 0; j < BS_WORD_SIZE; j++) {
2685
                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
2686
            }
2687
    #else
2688
            BS_INV_TRANS_8(t, o, w, bmask, 0);
2689
        #if BS_WORD_SIZE >= 16
2690
            BS_INV_TRANS_8(t, o, w, bmask, 8);
2691
        #endif
2692
        #if BS_WORD_SIZE >= 32
2693
            BS_INV_TRANS_8(t, o, w, bmask, 16);
2694
            BS_INV_TRANS_8(t, o, w, bmask, 24);
2695
        #endif
2696
        #if BS_WORD_SIZE >= 64
2697
            BS_INV_TRANS_8(t, o, w, bmask, 32);
2698
            BS_INV_TRANS_8(t, o, w, bmask, 40);
2699
            BS_INV_TRANS_8(t, o, w, bmask, 48);
2700
            BS_INV_TRANS_8(t, o, w, bmask, 56);
2701
        #endif
2702
    #endif
2703
        }
2704
    }
2705
}
2706
2707
#define BS_ROW_OFF_0    0
2708
#define BS_ROW_OFF_1    32
2709
#define BS_ROW_OFF_2    64
2710
#define BS_ROW_OFF_3    96
2711
2712
#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
2713
#define BS_IDX_MASK     0x7f
2714
2715
#define BS_ASSIGN_8(d, od, s, os)   \
2716
    d[(od) + 0] = s[(os) + 0];      \
2717
    d[(od) + 1] = s[(os) + 1];      \
2718
    d[(od) + 2] = s[(os) + 2];      \
2719
    d[(od) + 3] = s[(os) + 3];      \
2720
    d[(od) + 4] = s[(os) + 4];      \
2721
    d[(od) + 5] = s[(os) + 5];      \
2722
    d[(od) + 6] = s[(os) + 6];      \
2723
    d[(od) + 7] = s[(os) + 7]
2724
2725
static void bs_shift_rows(bs_word* t, bs_word* b)
2726
{
2727
    int i;
2728
2729
    for (i = 0; i < 128; i += 32) {
2730
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
2731
        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
2732
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
2733
        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
2734
    }
2735
}
2736
2737
#define BS_SHIFT_OFF_0  0
2738
#define BS_SHIFT_OFF_1  8
2739
#define BS_SHIFT_OFF_2  16
2740
#define BS_SHIFT_OFF_3  24
2741
2742
/* Shift rows and mix columns.
2743
 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
2744
 */
2745
2746
#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
2747
        of      = br0[7] ^ br1[7];                                  \
2748
        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
2749
        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
2750
        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
2751
        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
2752
        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
2753
        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
2754
        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
2755
        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
2756
2757
static void bs_shift_mix(bs_word* t, bs_word* b)
2758
{
2759
    int i;
2760
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
2761
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
2762
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
2763
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
2764
2765
    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
2766
        bs_word* br0 = b + or0;
2767
        bs_word* br1 = b + or1;
2768
        bs_word* br2 = b + or2;
2769
        bs_word* br3 = b + or3;
2770
        bs_word of;
2771
2772
        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
2773
        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
2774
        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
2775
        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
2776
2777
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2778
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2779
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2780
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2781
    }
2782
}
2783
2784
static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
2785
{
2786
    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
2787
}
2788
2789
static void bs_sub_bytes_blocks(bs_word* b)
2790
{
2791
    int i;
2792
2793
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
2794
        bs_sub_bytes(b + i);
2795
    }
2796
}
2797
2798
static const FLASH_QUALIFIER byte bs_rcon[] = {
2799
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
2800
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
2801
};
2802
2803
static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
2804
    bs_word block[AES_BLOCK_BITS];
2805
    bs_word trans[AES_BLOCK_BITS];
2806
2807
    XMEMSET(block, 0, sizeof(block));
2808
    XMEMCPY(block, in, 4);
2809
2810
    bs_transpose(trans, block);
2811
    bs_sub_bytes_blocks(trans);
2812
    bs_inv_transpose(block, trans);
2813
2814
    XMEMCPY(out, block, 4);
2815
}
2816
2817
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
2818
    /* Rotate the input 8 bits to the left */
2819
#ifdef LITTLE_ENDIAN_ORDER
2820
    *(word32*)out = rotrFixed(*(word32*)in, 8);
2821
#else
2822
    *(word32*)out = rotlFixed(*(word32*)in, 8);
2823
#endif
2824
    bs_ke_sub_bytes(out, out);
2825
    /* On just the first byte, add 2^i to the byte */
2826
    out[0] ^= bs_rcon[i];
2827
}
2828
2829
static void bs_expand_key(unsigned char *in, word32 sz) {
2830
    unsigned char t[4];
2831
    word32 o;
2832
    word8 i = 0;
2833
2834
    if (sz == 176) {
2835
        /* Total of 11 rounds - AES-128. */
2836
        for (o = 16; o < sz; o += 16) {
2837
            bs_ke_transform(t, in + o - 4, i);
2838
            i++;
2839
            *(word32*)(in + o +  0) = *(word32*)(in + o - 16) ^
2840
                                      *(word32*) t;
2841
            *(word32*)(in + o +  4) = *(word32*)(in + o - 12) ^
2842
                                      *(word32*)(in + o +  0);
2843
            *(word32*)(in + o +  8) = *(word32*)(in + o -  8) ^
2844
                                      *(word32*)(in + o +  4);
2845
            *(word32*)(in + o + 12) = *(word32*)(in + o -  4) ^
2846
                                      *(word32*)(in + o +  8);
2847
        }
2848
    }
2849
    else if (sz == 208) {
2850
        /* Total of 13 rounds - AES-192. */
2851
        for (o = 24; o < sz; o += 24) {
2852
            bs_ke_transform(t, in + o - 4, i);
2853
            i++;
2854
            *(word32*)(in + o +  0) = *(word32*)(in + o - 24) ^
2855
                                      *(word32*) t;
2856
            *(word32*)(in + o +  4) = *(word32*)(in + o - 20) ^
2857
                                      *(word32*)(in + o +  0);
2858
            *(word32*)(in + o +  8) = *(word32*)(in + o - 16) ^
2859
                                      *(word32*)(in + o +  4);
2860
            *(word32*)(in + o + 12) = *(word32*)(in + o - 12) ^
2861
                                      *(word32*)(in + o +  8);
2862
            *(word32*)(in + o + 16) = *(word32*)(in + o -  8) ^
2863
                                      *(word32*)(in + o + 12);
2864
            *(word32*)(in + o + 20) = *(word32*)(in + o -  4) ^
2865
                                      *(word32*)(in + o + 16);
2866
        }
2867
    }
2868
    else if (sz == 240) {
2869
        /* Total of 15 rounds - AES-256. */
2870
        for (o = 32; o < sz; o += 16) {
2871
            if ((o & 0x1f) == 0) {
2872
                bs_ke_transform(t, in + o - 4, i);
2873
                i++;
2874
            }
2875
            else {
2876
                bs_ke_sub_bytes(t, in + o - 4);
2877
            }
2878
            *(word32*)(in + o +  0) = *(word32*)(in + o - 32) ^
2879
                                      *(word32*) t;
2880
            *(word32*)(in + o +  4) = *(word32*)(in + o - 28) ^
2881
                                      *(word32*)(in + o +  0);
2882
            *(word32*)(in + o +  8) = *(word32*)(in + o - 24) ^
2883
                                      *(word32*)(in + o +  4);
2884
            *(word32*)(in + o + 12) = *(word32*)(in + o - 20) ^
2885
                                      *(word32*)(in + o +  8);
2886
        }
2887
    }
2888
}
2889
2890
static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
2891
    word32 rounds)
2892
{
2893
    int i;
2894
    byte bs_key[15 * WC_AES_BLOCK_SIZE];
2895
    int ksSz = (rounds + 1) * WC_AES_BLOCK_SIZE;
2896
    bs_word block[AES_BLOCK_BITS];
2897
2898
    /* Fist round. */
2899
    XMEMCPY(bs_key, key, keyLen);
2900
    bs_expand_key(bs_key, ksSz);
2901
2902
    for (i = 0; i < ksSz; i += WC_AES_BLOCK_SIZE) {
2903
        int k;
2904
2905
        XMEMCPY(block, bs_key + i, WC_AES_BLOCK_SIZE);
2906
        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
2907
            int l;
2908
            for (l = 0; l < BS_BLOCK_WORDS; l++) {
2909
                block[k + l] = block[l];
2910
            }
2911
        }
2912
        bs_transpose(rk, block);
2913
        rk += AES_BLOCK_BITS;
2914
    }
2915
}
2916
2917
static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
2918
{
2919
    word32 i;
2920
    bs_word trans[AES_BLOCK_BITS];
2921
2922
    bs_transpose(trans, state);
2923
2924
    bs_add_round_key(trans, trans, rk);
2925
    for (i = 1; i < r; i++) {
2926
        bs_sub_bytes_blocks(trans);
2927
        bs_shift_mix(state, trans);
2928
        rk += AES_BLOCK_BITS;
2929
        bs_add_round_key(trans, state, rk);
2930
    }
2931
    bs_sub_bytes_blocks(trans);
2932
    bs_shift_rows(state, trans);
2933
    rk += AES_BLOCK_BITS;
2934
    bs_add_round_key(trans, state, rk);
2935
    bs_inv_transpose(state, trans);
2936
}
2937
2938
#ifndef HAVE_CUDA
2939
/* Encrypt a block using AES.
2940
 *
2941
 * @param [in]  aes       AES object.
2942
 * @param [in]  inBlock   Block to encrypt.
2943
 * @param [out] outBlock  Encrypted block.
2944
 * @param [in]  r         Rounds divided by 2.
2945
 */
2946
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2947
        word32 r)
2948
{
2949
    bs_word state[AES_BLOCK_BITS];
2950
2951
    (void)r;
2952
2953
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
2954
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
2955
2956
    bs_encrypt(state, aes->bs_key, aes->rounds);
2957
2958
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
2959
}
2960
2961
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2962
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
2963
/* Encrypt a number of blocks using AES.
2964
 *
2965
 * @param [in]  aes  AES object.
2966
 * @param [in]  in   Block to encrypt.
2967
 * @param [out] out  Encrypted block.
2968
 * @param [in]  sz   Number of blocks to encrypt.
2969
 */
2970
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2971
{
2972
    bs_word state[AES_BLOCK_BITS];
2973
2974
    while (sz >= BS_BLOCK_SIZE) {
2975
        XMEMCPY(state, in, BS_BLOCK_SIZE);
2976
        bs_encrypt(state, aes->bs_key, aes->rounds);
2977
        XMEMCPY(out, state, BS_BLOCK_SIZE);
2978
        sz  -= BS_BLOCK_SIZE;
2979
        in  += BS_BLOCK_SIZE;
2980
        out += BS_BLOCK_SIZE;
2981
    }
2982
    if (sz > 0) {
2983
        XMEMCPY(state, in, sz);
2984
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
2985
        bs_encrypt(state, aes->bs_key, aes->rounds);
2986
        XMEMCPY(out, state, sz);
2987
    }
2988
}
2989
#endif
2990
#else
2991
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2992
        word32 r);
2993
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2994
#endif /* HAVE_CUDA */
2995
2996
#endif /* !WC_AES_BITSLICED */
2997
2998
/* this section disabled with NO_AES_192 */
2999
/* calling this one when missing NO_AES_192  */
3000
static WARN_UNUSED_RESULT int wc_AesEncrypt(
3001
    Aes* aes, const byte* inBlock, byte* outBlock)
3002
225k
{
3003
#if defined(MAX3266X_AES)
3004
    word32 keySize;
3005
#endif
3006
#if defined(MAX3266X_CB)
3007
    int ret_cb;
3008
#endif
3009
225k
    word32 r;
3010
3011
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3012
    {
3013
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3014
        if (ret < 0)
3015
            return ret;
3016
    }
3017
#endif
3018
3019
225k
    r = aes->rounds >> 1;
3020
3021
225k
    if (r > 7 || r == 0) {
3022
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3023
0
        return KEYUSAGE_E;
3024
0
    }
3025
3026
#ifdef WOLFSSL_AESNI
3027
    if (aes->use_aesni) {
3028
        ASSERT_SAVED_VECTOR_REGISTERS();
3029
3030
        #ifdef DEBUG_AESNI
3031
            printf("about to aes encrypt\n");
3032
            printf("in  = %p\n", inBlock);
3033
            printf("out = %p\n", outBlock);
3034
            printf("aes->key = %p\n", aes->key);
3035
            printf("aes->rounds = %d\n", aes->rounds);
3036
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
3037
        #endif
3038
3039
        /* check alignment, decrypt doesn't need alignment */
3040
        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
3041
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
3042
            byte* tmp = (byte*)XMALLOC(WC_AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
3043
                                                      DYNAMIC_TYPE_TMP_BUFFER);
3044
            byte* tmp_align;
3045
            if (tmp == NULL)
3046
                return MEMORY_E;
3047
3048
            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
3049
3050
            XMEMCPY(tmp_align, inBlock, WC_AES_BLOCK_SIZE);
3051
            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, WC_AES_BLOCK_SIZE,
3052
                    (byte*)aes->key, (int)aes->rounds);
3053
            XMEMCPY(outBlock, tmp_align, WC_AES_BLOCK_SIZE);
3054
            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3055
            return 0;
3056
        #else
3057
            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
3058
            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
3059
            return BAD_ALIGN_E;
3060
        #endif
3061
        }
3062
3063
        AES_ECB_encrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3064
                        (int)aes->rounds);
3065
3066
        return 0;
3067
    }
3068
    else {
3069
        #ifdef DEBUG_AESNI
3070
            printf("Skipping AES-NI\n");
3071
        #endif
3072
    }
3073
#elif defined(WOLFSSL_ARMASM)
3074
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
3075
#if !defined(__aarch64__)
3076
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
3077
#else
3078
    if (aes->use_aes_hw_crypto) {
3079
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3080
            (int)aes->rounds);
3081
    }
3082
    else
3083
#endif /* !__aarch64__ */
3084
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
3085
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
3086
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
3087
    {
3088
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3089
            (const unsigned char*)aes->key, aes->rounds);
3090
    }
3091
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
3092
    {
3093
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3094
            (const unsigned char*)aes->key, aes->rounds);
3095
    }
3096
#endif
3097
    return 0;
3098
#endif /* WOLFSSL_AESNI */
3099
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3100
    AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3101
    return 0;
3102
#endif
3103
3104
#if defined(WOLFSSL_IMXRT_DCP)
3105
    if (aes->keylen == 16) {
3106
        DCPAesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3107
        return 0;
3108
    }
3109
#endif
3110
3111
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3112
    if (aes->useSWCrypt == 0) {
3113
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3114
                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
3115
    }
3116
#endif
3117
3118
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3119
    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
3120
    if (wc_esp32AesSupportedKeyLen(aes)) {
3121
        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
3122
    }
3123
    else {
3124
        /* For example, the ESP32-S3 does not support HW for len = 24,
3125
         * so fall back to SW */
3126
    #ifdef DEBUG_WOLFSSL
3127
        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
3128
                      aes->keylen);
3129
    #endif
3130
    }
3131
#endif
3132
3133
#if defined(MAX3266X_AES)
3134
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3135
        return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3136
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3137
                                    outBlock, (unsigned int)keySize);
3138
    }
3139
#endif
3140
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3141
    #ifndef WOLF_CRYPTO_CB_FIND
3142
    if (aes->devId != INVALID_DEVID)
3143
    #endif
3144
    {
3145
        ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock,
3146
                                            WC_AES_BLOCK_SIZE);
3147
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3148
            return ret_cb;
3149
        /* fall-through when unavailable */
3150
    }
3151
#endif
3152
3153
225k
    AesEncrypt_C(aes, inBlock, outBlock, r);
3154
3155
225k
    return 0;
3156
225k
} /* wc_AesEncrypt */
3157
#endif
3158
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
3159
3160
#if defined(HAVE_AES_DECRYPT)
3161
#if ((defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3162
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)) && \
3163
    (defined(__aarch64__) || !defined(WOLFSSL_ARMASM))
3164
3165
#ifndef WC_AES_BITSLICED
3166
#ifndef WC_NO_CACHE_RESISTANT
3167
#ifndef WOLFSSL_AES_SMALL_TABLES
3168
/* load 4 Td Tables into cache by cache line stride */
3169
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
3170
10.9k
{
3171
10.9k
    word32 x = 0;
3172
10.9k
    int i,j;
3173
3174
54.5k
    for (i = 0; i < 4; i++) {
3175
        /* 256 elements, each one is 4 bytes */
3176
741k
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
3177
698k
            x &= Td[i][j];
3178
698k
        }
3179
43.6k
    }
3180
10.9k
    return x;
3181
10.9k
}
3182
#endif /* !WOLFSSL_AES_SMALL_TABLES */
3183
3184
/* load Td Table4 into cache by cache line stride */
3185
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
3186
10.9k
{
3187
10.9k
#ifndef WOLFSSL_AES_TOUCH_LINES
3188
10.9k
    word32 x = 0;
3189
10.9k
    int i;
3190
3191
54.5k
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
3192
43.6k
        x &= (word32)Td4[i];
3193
43.6k
    }
3194
10.9k
    return x;
3195
#else
3196
    return 0;
3197
#endif
3198
10.9k
}
3199
#endif /* !WC_NO_CACHE_RESISTANT */
3200
3201
/* Decrypt a block using AES.
3202
 *
3203
 * @param [in]  aes       AES object.
3204
 * @param [in]  inBlock   Block to encrypt.
3205
 * @param [out] outBlock  Encrypted block.
3206
 * @param [in]  r         Rounds divided by 2.
3207
 */
3208
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3209
    word32 r)
3210
10.9k
{
3211
10.9k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
3212
10.9k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
3213
10.9k
    const word32* rk;
3214
3215
#ifdef WC_C_DYNAMIC_FALLBACK
3216
    rk = aes->key_C_fallback;
3217
#else
3218
10.9k
    rk = aes->key;
3219
10.9k
#endif
3220
3221
    /*
3222
     * map byte array block to cipher state
3223
     * and add initial round key:
3224
     */
3225
10.9k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
3226
10.9k
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
3227
10.9k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
3228
10.9k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
3229
3230
10.9k
#ifdef LITTLE_ENDIAN_ORDER
3231
10.9k
    s0 = ByteReverseWord32(s0);
3232
10.9k
    s1 = ByteReverseWord32(s1);
3233
10.9k
    s2 = ByteReverseWord32(s2);
3234
10.9k
    s3 = ByteReverseWord32(s3);
3235
10.9k
#endif
3236
3237
10.9k
    s0 ^= rk[0];
3238
10.9k
    s1 ^= rk[1];
3239
10.9k
    s2 ^= rk[2];
3240
10.9k
    s3 ^= rk[3];
3241
3242
10.9k
#ifndef WOLFSSL_AES_SMALL_TABLES
3243
10.9k
#ifndef WC_NO_CACHE_RESISTANT
3244
10.9k
    s0 |= PreFetchTd();
3245
10.9k
#endif
3246
3247
10.9k
#ifndef WOLFSSL_AES_TOUCH_LINES
3248
/* Unroll the loop. */
3249
10.9k
#define DEC_ROUND_T_S(o)                                            \
3250
64.8k
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
3251
64.8k
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
3252
64.8k
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
3253
64.8k
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
3254
64.8k
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
3255
64.8k
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
3256
64.8k
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
3257
64.8k
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
3258
10.9k
#define DEC_ROUND_S_T(o)                                            \
3259
53.9k
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
3260
53.9k
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
3261
53.9k
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
3262
53.9k
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
3263
53.9k
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
3264
53.9k
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
3265
53.9k
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
3266
53.9k
         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
3267
#else
3268
#define DEC_ROUND_T_S(o)                                                       \
3269
    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
3270
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
3271
    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
3272
                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
3273
    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
3274
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
3275
    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
3276
                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
3277
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
3278
3279
#define DEC_ROUND_S_T(o)                                                       \
3280
    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
3281
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
3282
    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
3283
                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
3284
    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
3285
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
3286
    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
3287
                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
3288
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
3289
#endif
3290
3291
10.9k
#ifndef WOLFSSL_AES_NO_UNROLL
3292
10.9k
                       DEC_ROUND_T_S( 0);
3293
10.9k
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3294
10.9k
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3295
10.9k
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3296
10.9k
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3297
10.9k
    if (r > 5) {
3298
5.33k
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3299
5.33k
        if (r > 6) {
3300
4.99k
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3301
4.99k
        }
3302
5.33k
    }
3303
10.9k
    rk += r * 8;
3304
#else
3305
3306
    /*
3307
     * Nr - 1 full rounds:
3308
     */
3309
3310
    for (;;) {
3311
        DEC_ROUND_T_S(0);
3312
3313
        rk += 8;
3314
        if (--r == 0) {
3315
            break;
3316
        }
3317
3318
        DEC_ROUND_S_T(0);
3319
    }
3320
#endif
3321
    /*
3322
     * apply last round and
3323
     * map cipher state to byte array block:
3324
     */
3325
3326
10.9k
#ifndef WC_NO_CACHE_RESISTANT
3327
10.9k
    t0 |= PreFetchTd4();
3328
10.9k
#endif
3329
3330
10.9k
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3331
10.9k
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3332
10.9k
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3333
10.9k
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3334
10.9k
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3335
10.9k
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3336
10.9k
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3337
10.9k
                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
3338
#else
3339
#ifndef WC_NO_CACHE_RESISTANT
3340
    s0 |= PreFetchTd4();
3341
#endif
3342
3343
    r *= 2;
3344
    for (rk += 4; r > 1; r--, rk += 4) {
3345
        t0 =
3346
            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3347
            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3348
            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3349
            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
3350
            rk[0];
3351
        t1 =
3352
            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3353
            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3354
            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3355
            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
3356
            rk[1];
3357
        t2 =
3358
            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3359
            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3360
            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3361
            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
3362
            rk[2];
3363
        t3 =
3364
            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3365
            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3366
            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3367
            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
3368
            rk[3];
3369
3370
        s0 =
3371
            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
3372
            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
3373
            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
3374
            (inv_col_mul(t0, 1, 3, 2, 0)      );
3375
        s1 =
3376
            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
3377
            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
3378
            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
3379
            (inv_col_mul(t1, 1, 3, 2, 0)      );
3380
        s2 =
3381
            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
3382
            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
3383
            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
3384
            (inv_col_mul(t2, 1, 3, 2, 0)      );
3385
        s3 =
3386
            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
3387
            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
3388
            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
3389
            (inv_col_mul(t3, 1, 3, 2, 0)      );
3390
    }
3391
3392
    t0 =
3393
        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3394
        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3395
        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3396
        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
3397
    t1 =
3398
        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3399
        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3400
        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3401
        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
3402
    t2 =
3403
        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3404
        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3405
        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3406
        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
3407
    t3 =
3408
        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3409
        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3410
        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3411
        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
3412
    s0 = t0 ^ rk[0];
3413
    s1 = t1 ^ rk[1];
3414
    s2 = t2 ^ rk[2];
3415
    s3 = t3 ^ rk[3];
3416
#endif
3417
3418
    /* write out */
3419
10.9k
#ifdef LITTLE_ENDIAN_ORDER
3420
10.9k
    s0 = ByteReverseWord32(s0);
3421
10.9k
    s1 = ByteReverseWord32(s1);
3422
10.9k
    s2 = ByteReverseWord32(s2);
3423
10.9k
    s3 = ByteReverseWord32(s3);
3424
10.9k
#endif
3425
3426
10.9k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
3427
10.9k
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
3428
10.9k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
3429
10.9k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
3430
3431
10.9k
}
3432
3433
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3434
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
3435
    !defined(MAX3266X_AES)
3436
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
3437
/* Decrypt a number of blocks using AES.
3438
 *
3439
 * @param [in]  aes  AES object.
3440
 * @param [in]  in   Block to encrypt.
3441
 * @param [out] out  Encrypted block.
3442
 * @param [in]  sz   Number of blocks to encrypt.
3443
 */
3444
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3445
175
{
3446
175
    word32 i;
3447
3448
2.30k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
3449
2.13k
        AesDecrypt_C(aes, in, out, aes->rounds >> 1);
3450
2.13k
        in += WC_AES_BLOCK_SIZE;
3451
2.13k
        out += WC_AES_BLOCK_SIZE;
3452
2.13k
    }
3453
175
}
3454
#endif
3455
#endif
3456
3457
#else /* WC_AES_BITSLICED */
3458
3459
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
3460
static void bs_inv_sub_bytes(bs_word u[8])
3461
{
3462
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
3463
    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
3464
    bs_word RTL0, RTL1, RTL2;
3465
    bs_word sa0, sa1;
3466
    bs_word sb0, sb1;
3467
    bs_word ab0, ab1, ab2, ab3;
3468
    bs_word ab20, ab21, ab22, ab23;
3469
    bs_word al, ah, aa, bl, bh, bb;
3470
    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
3471
    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
3472
    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
3473
    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
3474
    bs_word rr1, rr2;
3475
    bs_word r10, r11;
3476
    bs_word cp1, cp2, cp3, cp4;
3477
    bs_word vr1, vr2, vr3;
3478
    bs_word pr1, pr2, pr3;
3479
    bs_word wr1, wr2, wr3;
3480
    bs_word qr1, qr2, qr3;
3481
    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
3482
    bs_word tinv10, tinv11, tinv12, tinv13;
3483
    bs_word t01, t02;
3484
    bs_word d0, d1, d2, d3;
3485
    bs_word dl, dd, dh;
3486
    bs_word sd0, sd1;
3487
    bs_word p0, p1, p2, p3, p4, p6, p7;
3488
    bs_word X11, X13, X14, X16, X18, X19;
3489
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
3490
3491
    U0 = u[7];
3492
    U1 = u[6];
3493
    U2 = u[5];
3494
    U3 = u[4];
3495
    U4 = u[3];
3496
    U5 = u[2];
3497
    U6 = u[1];
3498
    U7 = u[0];
3499
3500
    Y0 = U0 ^ U3;
3501
    Y2 = ~(U1 ^ U3);
3502
    Y4 = U0 ^ Y2;
3503
    RTL0 = U6 ^ U7;
3504
    Y1 = Y2 ^ RTL0;
3505
    Y7 = ~(U2 ^ Y1);
3506
    RTL1 = U3 ^ U4;
3507
    Y6 = ~(U7 ^ RTL1);
3508
    Y3 = Y1 ^ RTL1;
3509
    RTL2 = ~(U0 ^ U2);
3510
    Y5 = U5 ^ RTL2;
3511
    sa1 = Y0 ^ Y2;
3512
    sa0 = Y1 ^ Y3;
3513
    sb1 = Y4 ^ Y6;
3514
    sb0 = Y5 ^ Y7;
3515
    ah = Y0 ^ Y1;
3516
    al = Y2 ^ Y3;
3517
    aa = sa0 ^ sa1;
3518
    bh = Y4 ^ Y5;
3519
    bl = Y6 ^ Y7;
3520
    bb = sb0 ^ sb1;
3521
    ab20 = sa0 ^ sb0;
3522
    ab22 = al ^ bl;
3523
    ab23 = Y3 ^ Y7;
3524
    ab21 = sa1 ^ sb1;
3525
    abcd1 = ah & bh;
3526
    rr1 = Y0 & Y4;
3527
    ph11 = ab20 ^ abcd1;
3528
    t01 = Y1 & Y5;
3529
    ph01 = t01 ^ abcd1;
3530
    abcd2 = al & bl;
3531
    r1 = Y2 & Y6;
3532
    pl11 = ab22 ^ abcd2;
3533
    r2 = Y3 & Y7;
3534
    pl01 = r2 ^ abcd2;
3535
    r3 = sa0 & sb0;
3536
    vr1 = aa & bb;
3537
    pr1 = vr1 ^ r3;
3538
    wr1 = sa1 & sb1;
3539
    qr1 = wr1 ^ r3;
3540
    ab0 = ph11 ^ rr1;
3541
    ab1 = ph01 ^ ab21;
3542
    ab2 = pl11 ^ r1;
3543
    ab3 = pl01 ^ qr1;
3544
    cp1 = ab0 ^ pr1;
3545
    cp2 = ab1 ^ qr1;
3546
    cp3 = ab2 ^ pr1;
3547
    cp4 = ab3 ^ ab23;
3548
    tinv1 = cp3 ^ cp4;
3549
    tinv2 = cp3 & cp1;
3550
    tinv3 = cp2 ^ tinv2;
3551
    tinv4 = cp1 ^ cp2;
3552
    tinv5 = cp4 ^ tinv2;
3553
    tinv6 = tinv5 & tinv4;
3554
    tinv7 = tinv3 & tinv1;
3555
    d2 = cp4 ^ tinv7;
3556
    d0 = cp2 ^ tinv6;
3557
    tinv8 = cp1 & cp4;
3558
    tinv9 = tinv4 & tinv8;
3559
    tinv10 = tinv4 ^ tinv2;
3560
    d1 = tinv9 ^ tinv10;
3561
    tinv11 = cp2 & cp3;
3562
    tinv12 = tinv1 & tinv11;
3563
    tinv13 = tinv1 ^ tinv2;
3564
    d3 = tinv12 ^ tinv13;
3565
    sd1 = d1 ^ d3;
3566
    sd0 = d0 ^ d2;
3567
    dl = d0 ^ d1;
3568
    dh = d2 ^ d3;
3569
    dd = sd0 ^ sd1;
3570
    abcd3 = dh & bh;
3571
    rr2 = d3 & Y4;
3572
    t02 = d2 & Y5;
3573
    abcd4 = dl & bl;
3574
    r4 = d1 & Y6;
3575
    r5 = d0 & Y7;
3576
    r6 = sd0 & sb0;
3577
    vr2 = dd & bb;
3578
    wr2 = sd1 & sb1;
3579
    abcd5 = dh & ah;
3580
    r7 = d3 & Y0;
3581
    r8 = d2 & Y1;
3582
    abcd6 = dl & al;
3583
    r9 = d1 & Y2;
3584
    r10 = d0 & Y3;
3585
    r11 = sd0 & sa0;
3586
    vr3 = dd & aa;
3587
    wr3 = sd1 & sa1;
3588
    ph12 = rr2 ^ abcd3;
3589
    ph02 = t02 ^ abcd3;
3590
    pl12 = r4 ^ abcd4;
3591
    pl02 = r5 ^ abcd4;
3592
    pr2 = vr2 ^ r6;
3593
    qr2 = wr2 ^ r6;
3594
    p0 = ph12 ^ pr2;
3595
    p1 = ph02 ^ qr2;
3596
    p2 = pl12 ^ pr2;
3597
    p3 = pl02 ^ qr2;
3598
    ph13 = r7 ^ abcd5;
3599
    ph03 = r8 ^ abcd5;
3600
    pl13 = r9 ^ abcd6;
3601
    pl03 = r10 ^ abcd6;
3602
    pr3 = vr3 ^ r11;
3603
    qr3 = wr3 ^ r11;
3604
    p4 = ph13 ^ pr3;
3605
    S7 = ph03 ^ qr3;
3606
    p6 = pl13 ^ pr3;
3607
    p7 = pl03 ^ qr3;
3608
    S3 = p1 ^ p6;
3609
    S6 = p2 ^ p6;
3610
    S0 = p3 ^ p6;
3611
    X11 = p0 ^ p2;
3612
    S5 = S0 ^ X11;
3613
    X13 = p4 ^ p7;
3614
    X14 = X11 ^ X13;
3615
    S1 = S3 ^ X14;
3616
    X16 = p1 ^ S7;
3617
    S2 = X14 ^ X16;
3618
    X18 = p0 ^ p4;
3619
    X19 = S5 ^ X16;
3620
    S4 = X18 ^ X19;
3621
3622
    u[0] = S7;
3623
    u[1] = S6;
3624
    u[2] = S5;
3625
    u[3] = S4;
3626
    u[4] = S3;
3627
    u[5] = S2;
3628
    u[6] = S1;
3629
    u[7] = S0;
3630
}
3631
3632
static void bs_inv_shift_rows(bs_word* b)
3633
{
3634
    bs_word t[AES_BLOCK_BITS];
3635
    int i;
3636
3637
    for (i = 0; i < 128; i += 32) {
3638
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
3639
        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
3640
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
3641
        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
3642
    }
3643
3644
    XMEMCPY(b, t, sizeof(t));
3645
}
3646
3647
#define O0  0
3648
#define O1  8
3649
#define O2  16
3650
#define O3  24
3651
3652
#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
3653
    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
3654
          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
3655
    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
3656
          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
3657
    of2 =                     b[O0+7] ^             b[O1+7] ^               \
3658
                    b[O2+7] ^ b[O3+7];                                      \
3659
                                                                            \
3660
    br[0] =                                                   b[O1+0] ^     \
3661
            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
3662
    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
3663
            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
3664
    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
3665
            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
3666
    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
3667
            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
3668
    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
3669
            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
3670
    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
3671
            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
3672
    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
3673
            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
3674
    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
3675
            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
3676
3677
/* Inverse mix columns and shift rows. */
3678
static void bs_inv_mix_shift(bs_word* t, bs_word* b)
3679
{
3680
    bs_word* bp = b;
3681
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
3682
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
3683
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
3684
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
3685
    int i;
3686
3687
    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
3688
        bs_word* br;
3689
        bs_word of0;
3690
        bs_word of1;
3691
        bs_word of2;
3692
3693
        br = t + or0;
3694
        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
3695
        br = t + or1;
3696
        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
3697
        br = t + or2;
3698
        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
3699
        br = t + or3;
3700
        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
3701
3702
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3703
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3704
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3705
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3706
3707
        bp += AES_BLOCK_BITS / 4;
3708
    }
3709
}
3710
3711
static void bs_inv_sub_bytes_blocks(bs_word* b)
3712
{
3713
    int i;
3714
3715
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
3716
        bs_inv_sub_bytes(b + i);
3717
    }
3718
}
3719
3720
static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
3721
{
3722
    int i;
3723
    bs_word trans[AES_BLOCK_BITS];
3724
3725
    bs_transpose(trans, state);
3726
3727
    rk += r * AES_BLOCK_BITS;
3728
    bs_add_round_key(trans, trans, rk);
3729
    bs_inv_shift_rows(trans);
3730
    bs_inv_sub_bytes_blocks(trans);
3731
    rk -= AES_BLOCK_BITS;
3732
    bs_add_round_key(trans, trans, rk);
3733
    for (i = (int)r - 2; i >= 0; i--) {
3734
        bs_inv_mix_shift(state, trans);
3735
        bs_inv_sub_bytes_blocks(state);
3736
        rk -= AES_BLOCK_BITS;
3737
        bs_add_round_key(trans, state, rk);
3738
    }
3739
3740
    bs_inv_transpose(state, trans);
3741
}
3742
3743
#ifdef WOLFSSL_AES_DIRECT
3744
/* Decrypt a block using AES.
3745
 *
3746
 * @param [in]  aes       AES object.
3747
 * @param [in]  inBlock   Block to encrypt.
3748
 * @param [out] outBlock  Encrypted block.
3749
 * @param [in]  r         Rounds divided by 2.
3750
 */
3751
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3752
    word32 r)
3753
{
3754
    bs_word state[AES_BLOCK_BITS];
3755
3756
    (void)r;
3757
3758
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
3759
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
3760
3761
    bs_decrypt(state, aes->bs_key, aes->rounds);
3762
3763
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
3764
}
3765
#endif
3766
3767
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3768
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3769
/* Decrypt a number of blocks using AES.
3770
 *
3771
 * @param [in]  aes  AES object.
3772
 * @param [in]  in   Block to encrypt.
3773
 * @param [out] out  Encrypted block.
3774
 * @param [in]  sz   Number of blocks to encrypt.
3775
 */
3776
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3777
{
3778
    bs_word state[AES_BLOCK_BITS];
3779
3780
    while (sz >= BS_BLOCK_SIZE) {
3781
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3782
        bs_decrypt(state, aes->bs_key, aes->rounds);
3783
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3784
        sz  -= BS_BLOCK_SIZE;
3785
        in  += BS_BLOCK_SIZE;
3786
        out += BS_BLOCK_SIZE;
3787
    }
3788
    if (sz > 0) {
3789
        XMEMCPY(state, in, sz);
3790
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3791
        bs_decrypt(state, aes->bs_key, aes->rounds);
3792
        XMEMCPY(out, state, sz);
3793
    }
3794
}
3795
#endif
3796
3797
#endif /* !WC_AES_BITSLICED */
3798
#endif
3799
3800
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3801
    defined(WOLFSSL_AES_DIRECT)
3802
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
3803
#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
3804
/* Software AES - ECB Decrypt */
3805
static WARN_UNUSED_RESULT int wc_AesDecrypt(
3806
    Aes* aes, const byte* inBlock, byte* outBlock)
3807
8.77k
{
3808
#if defined(MAX3266X_AES)
3809
    word32 keySize;
3810
#endif
3811
#if defined(MAX3266X_CB)
3812
    int ret_cb;
3813
#endif
3814
8.77k
    word32 r;
3815
3816
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3817
    {
3818
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3819
        if (ret < 0)
3820
            return ret;
3821
    }
3822
#endif
3823
3824
8.77k
    r = aes->rounds >> 1;
3825
3826
8.77k
    if (r > 7 || r == 0) {
3827
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3828
0
        return KEYUSAGE_E;
3829
0
    }
3830
3831
#ifdef WOLFSSL_AESNI
3832
    if (aes->use_aesni) {
3833
        ASSERT_SAVED_VECTOR_REGISTERS();
3834
3835
        #ifdef DEBUG_AESNI
3836
            printf("about to aes decrypt\n");
3837
            printf("in  = %p\n", inBlock);
3838
            printf("out = %p\n", outBlock);
3839
            printf("aes->key = %p\n", aes->key);
3840
            printf("aes->rounds = %d\n", aes->rounds);
3841
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
3842
        #endif
3843
3844
        /* if input and output same will overwrite input iv */
3845
        if ((const byte*)aes->tmp != inBlock)
3846
            XMEMCPY(aes->tmp, inBlock, WC_AES_BLOCK_SIZE);
3847
        AES_ECB_decrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3848
                        (int)aes->rounds);
3849
        return 0;
3850
    }
3851
    else {
3852
        #ifdef DEBUG_AESNI
3853
            printf("Skipping AES-NI\n");
3854
        #endif
3855
    }
3856
#elif defined(WOLFSSL_ARMASM)
3857
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
3858
#if !defined(__aarch64__)
3859
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
3860
#else
3861
    if (aes->use_aes_hw_crypto) {
3862
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3863
            (int)aes->rounds);
3864
    }
3865
    else
3866
#endif /* !__aarch64__ */
3867
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
3868
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
3869
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
3870
    {
3871
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3872
            (const unsigned char*)aes->key, aes->rounds);
3873
    }
3874
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
3875
    {
3876
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3877
            (const unsigned char*)aes->key, aes->rounds);
3878
    }
3879
#endif
3880
    return 0;
3881
#endif /* WOLFSSL_AESNI */
3882
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3883
    return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3884
#endif
3885
#if defined(WOLFSSL_IMXRT_DCP)
3886
    if (aes->keylen == 16) {
3887
        DCPAesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3888
        return 0;
3889
    }
3890
#endif
3891
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3892
    if (aes->useSWCrypt == 0) {
3893
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3894
                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
3895
    }
3896
#endif
3897
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3898
    if (wc_esp32AesSupportedKeyLen(aes)) {
3899
        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
3900
    }
3901
    else {
3902
        /* For example, the ESP32-S3 does not support HW for len = 24,
3903
         * so fall back to SW */
3904
    #ifdef DEBUG_WOLFSSL
3905
        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
3906
                        "unsupported keylen = %d", aes->keylen);
3907
    #endif
3908
    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
3909
#endif
3910
3911
#if defined(MAX3266X_AES)
3912
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3913
        return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3914
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3915
                                    outBlock, (unsigned int)keySize);
3916
    }
3917
#endif
3918
3919
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3920
    #ifndef WOLF_CRYPTO_CB_FIND
3921
    if (aes->devId != INVALID_DEVID)
3922
    #endif
3923
    {
3924
        ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock,
3925
                                            WC_AES_BLOCK_SIZE);
3926
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3927
            return ret_cb;
3928
        /* fall-through when unavailable */
3929
    }
3930
#endif
3931
3932
8.77k
    AesDecrypt_C(aes, inBlock, outBlock, r);
3933
3934
8.77k
    return 0;
3935
8.77k
} /* wc_AesDecrypt[_SW]() */
3936
#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
3937
#endif
3938
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
3939
#endif /* HAVE_AES_DECRYPT */
3940
3941
#endif /* NEED_AES_TABLES */
3942
3943
3944
3945
/* wc_AesSetKey */
3946
#if defined(STM32_CRYPTO)
3947
3948
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3949
            const byte* iv, int dir)
3950
    {
3951
        word32 *rk;
3952
3953
        (void)dir;
3954
3955
        if (aes == NULL || (keylen != 16 &&
3956
        #ifdef WOLFSSL_AES_192
3957
            keylen != 24 &&
3958
        #endif
3959
            keylen != 32)) {
3960
            return BAD_FUNC_ARG;
3961
        }
3962
3963
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3964
        {
3965
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3966
            if (ret < 0)
3967
                return ret;
3968
        }
3969
#endif
3970
3971
        rk = aes->key;
3972
        aes->keylen = keylen;
3973
        aes->rounds = keylen/4 + 6;
3974
        XMEMCPY(rk, userKey, keylen);
3975
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
3976
        ByteReverseWords(rk, rk, keylen);
3977
    #endif
3978
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
3979
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
3980
        defined(WOLFSSL_AES_CTS)
3981
        aes->left = 0;
3982
    #endif
3983
        return wc_AesSetIV(aes, iv);
3984
    }
3985
    #if defined(WOLFSSL_AES_DIRECT)
3986
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
3987
                            const byte* iv, int dir)
3988
        {
3989
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
3990
        }
3991
    #endif
3992
3993
#elif defined(HAVE_COLDFIRE_SEC)
3994
    #if defined (HAVE_THREADX)
3995
        #include "memory_pools.h"
3996
        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
3997
    #endif
3998
3999
    #define AES_BUFFER_SIZE (WC_AES_BLOCK_SIZE * 64)
4000
    static unsigned char *AESBuffIn = NULL;
4001
    static unsigned char *AESBuffOut = NULL;
4002
    static byte *secReg;
4003
    static byte *secKey;
4004
    static volatile SECdescriptorType *secDesc;
4005
4006
    static wolfSSL_Mutex Mutex_AesSEC;
4007
4008
    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
4009
    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
4010
4011
    extern volatile unsigned char __MBAR[];
4012
4013
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4014
        const byte* iv, int dir)
4015
    {
4016
        if (AESBuffIn == NULL) {
4017
        #if defined (HAVE_THREADX)
4018
            int s1, s2, s3, s4, s5;
4019
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
4020
                                  sizeof(SECdescriptorType), TX_NO_WAIT);
4021
            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
4022
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4023
            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
4024
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4025
            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
4026
                                  WC_AES_BLOCK_SIZE*2, TX_NO_WAIT);
4027
            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
4028
                                  WC_AES_BLOCK_SIZE, TX_NO_WAIT);
4029
4030
            if (s1 || s2 || s3 || s4 || s5)
4031
                return BAD_FUNC_ARG;
4032
        #else
4033
            #warning "Allocate non-Cache buffers"
4034
        #endif
4035
4036
            wc_InitMutex(&Mutex_AesSEC);
4037
        }
4038
4039
        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4040
            return BAD_FUNC_ARG;
4041
4042
        if (aes == NULL)
4043
            return BAD_FUNC_ARG;
4044
4045
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4046
        {
4047
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4048
            if (ret < 0)
4049
                return ret;
4050
        }
4051
#endif
4052
4053
        aes->keylen = keylen;
4054
        aes->rounds = keylen/4 + 6;
4055
        XMEMCPY(aes->key, userKey, keylen);
4056
4057
        if (iv)
4058
            XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4059
4060
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4061
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4062
        defined(WOLFSSL_AES_CTS)
4063
        aes->left = 0;
4064
    #endif
4065
4066
        return 0;
4067
    }
4068
#elif defined(FREESCALE_LTC)
4069
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
4070
        const byte* iv, int dir, int checkKeyLen)
4071
    {
4072
        if (aes == NULL)
4073
            return BAD_FUNC_ARG;
4074
4075
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4076
        {
4077
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4078
            if (ret < 0)
4079
                return ret;
4080
        }
4081
#endif
4082
4083
        if (checkKeyLen) {
4084
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4085
                return BAD_FUNC_ARG;
4086
        }
4087
        (void)dir;
4088
4089
        aes->rounds = keylen/4 + 6;
4090
        XMEMCPY(aes->key, userKey, keylen);
4091
4092
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4093
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4094
        defined(WOLFSSL_AES_CTS)
4095
        aes->left = 0;
4096
    #endif
4097
4098
        return wc_AesSetIV(aes, iv);
4099
    }
4100
4101
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4102
        const byte* iv, int dir)
4103
    {
4104
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4105
    }
4106
4107
4108
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4109
                        const byte* iv, int dir)
4110
    {
4111
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4112
    }
4113
#elif defined(WOLFSSL_NRF51_AES)
4114
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4115
        const byte* iv, int dir)
4116
    {
4117
        int ret;
4118
4119
        (void)dir;
4120
        (void)iv;
4121
4122
        if (aes == NULL || keylen != 16)
4123
            return BAD_FUNC_ARG;
4124
4125
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4126
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4127
        if (ret < 0)
4128
            return ret;
4129
#endif
4130
4131
        aes->keylen = keylen;
4132
        aes->rounds = keylen/4 + 6;
4133
        XMEMCPY(aes->key, userKey, keylen);
4134
        ret = nrf51_aes_set_key(userKey);
4135
4136
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4137
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4138
        defined(WOLFSSL_AES_CTS)
4139
        aes->left = 0;
4140
    #endif
4141
4142
        return ret;
4143
    }
4144
4145
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4146
                        const byte* iv, int dir)
4147
    {
4148
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4149
    }
4150
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4151
    /* This is the only definition for HW only.
4152
     * but needs to be renamed when fallback needed.
4153
     * See call in wc_AesSetKey() */
4154
    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
4155
        const byte* iv, int dir)
4156
    {
4157
        (void)dir;
4158
        (void)iv;
4159
        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
4160
        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
4161
            return BAD_FUNC_ARG;
4162
        }
4163
4164
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4165
        {
4166
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4167
            if (ret < 0)
4168
                return ret;
4169
        }
4170
#endif
4171
4172
    #if !defined(WOLFSSL_AES_128)
4173
        if (keylen == 16) {
4174
            return BAD_FUNC_ARG;
4175
        }
4176
    #endif
4177
4178
    #if !defined(WOLFSSL_AES_192)
4179
        if (keylen == 24) {
4180
            return BAD_FUNC_ARG;
4181
        }
4182
    #endif
4183
4184
    #if !defined(WOLFSSL_AES_256)
4185
        if (keylen == 32) {
4186
            return BAD_FUNC_ARG;
4187
        }
4188
    #endif
4189
4190
        aes->keylen = keylen;
4191
        aes->rounds = keylen/4 + 6;
4192
4193
        XMEMCPY(aes->key, userKey, keylen);
4194
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4195
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4196
            defined(WOLFSSL_AES_CTS)
4197
            aes->left = 0;
4198
        #endif
4199
        return wc_AesSetIV(aes, iv);
4200
    } /* wc_AesSetKey */
4201
4202
    /* end #elif ESP32 */
4203
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
4204
4205
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
4206
                    int dir)
4207
    {
4208
        SaSiError_t ret = SASI_OK;
4209
        SaSiAesIv_t iv_aes;
4210
4211
        if (aes == NULL ||
4212
           (keylen != AES_128_KEY_SIZE &&
4213
            keylen != AES_192_KEY_SIZE &&
4214
            keylen != AES_256_KEY_SIZE)) {
4215
            return BAD_FUNC_ARG;
4216
        }
4217
4218
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4219
        {
4220
            int ret2 =
4221
                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4222
            if (ret2 < 0)
4223
                return ret2;
4224
        }
4225
#endif
4226
4227
    #if defined(AES_MAX_KEY_SIZE)
4228
        if (keylen > (AES_MAX_KEY_SIZE/8)) {
4229
            return BAD_FUNC_ARG;
4230
        }
4231
    #endif
4232
        if (dir != AES_ENCRYPTION &&
4233
            dir != AES_DECRYPTION) {
4234
            return BAD_FUNC_ARG;
4235
        }
4236
4237
        if (dir == AES_ENCRYPTION) {
4238
            aes->ctx.mode = SASI_AES_ENCRYPT;
4239
            SaSi_AesInit(&aes->ctx.user_ctx,
4240
                         SASI_AES_ENCRYPT,
4241
                         SASI_AES_MODE_CBC,
4242
                         SASI_AES_PADDING_NONE);
4243
        }
4244
        else {
4245
            aes->ctx.mode = SASI_AES_DECRYPT;
4246
            SaSi_AesInit(&aes->ctx.user_ctx,
4247
                         SASI_AES_DECRYPT,
4248
                         SASI_AES_MODE_CBC,
4249
                         SASI_AES_PADDING_NONE);
4250
        }
4251
4252
        aes->keylen = keylen;
4253
        aes->rounds = keylen/4 + 6;
4254
        XMEMCPY(aes->key, userKey, keylen);
4255
4256
        aes->ctx.key.pKey = (byte*)aes->key;
4257
        aes->ctx.key.keySize= keylen;
4258
4259
        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
4260
                             SASI_AES_USER_KEY,
4261
                             &aes->ctx.key,
4262
                             sizeof(aes->ctx.key));
4263
        if (ret != SASI_OK) {
4264
            return BAD_FUNC_ARG;
4265
        }
4266
4267
        ret = wc_AesSetIV(aes, iv);
4268
4269
        if (iv)
4270
            XMEMCPY(iv_aes, iv, WC_AES_BLOCK_SIZE);
4271
        else
4272
            XMEMSET(iv_aes,  0, WC_AES_BLOCK_SIZE);
4273
4274
4275
        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
4276
        if (ret != SASI_OK) {
4277
            return ret;
4278
        }
4279
       return ret;
4280
    }
4281
    #if defined(WOLFSSL_AES_DIRECT)
4282
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4283
                            const byte* iv, int dir)
4284
        {
4285
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4286
        }
4287
    #endif
4288
4289
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
4290
    && !defined(WOLFSSL_QNX_CAAM)
4291
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4292
4293
#elif defined(WOLFSSL_AFALG)
4294
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4295
4296
#elif defined(WOLFSSL_DEVCRYPTO_AES)
4297
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
4298
4299
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4300
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
4301
4302
#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
4303
     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
4304
    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
4305
4306
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
4307
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4308
            const byte* iv, int dir)
4309
    {
4310
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4311
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4312
        defined(WOLFSSL_AES_CTS)
4313
        aes->left = 0;
4314
    #endif
4315
4316
        aes->keylen = (int)keylen;
4317
        aes->rounds = (keylen/4) + 6;
4318
4319
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4320
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
4321
#else
4322
        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
4323
4324
    #ifdef HAVE_AES_DECRYPT
4325
        if (dir == AES_DECRYPTION) {
4326
            AES_invert_key((byte*)aes->key, aes->rounds);
4327
        }
4328
    #else
4329
        (void)dir;
4330
    #endif
4331
#endif
4332
        return wc_AesSetIV(aes, iv);
4333
    }
4334
4335
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4336
            const byte* iv, int dir)
4337
    {
4338
        if ((aes == NULL) || (userKey == NULL)) {
4339
            return BAD_FUNC_ARG;
4340
        }
4341
4342
        switch (keylen) {
4343
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4344
        defined(WOLFSSL_AES_128)
4345
        case 16:
4346
    #endif
4347
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4348
        defined(WOLFSSL_AES_192)
4349
        case 24:
4350
    #endif
4351
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4352
        defined(WOLFSSL_AES_256)
4353
        case 32:
4354
    #endif
4355
            break;
4356
        default:
4357
            return BAD_FUNC_ARG;
4358
        }
4359
4360
    #ifdef WOLF_CRYPTO_CB
4361
        if (aes->devId != INVALID_DEVID) {
4362
            if (keylen > sizeof(aes->devKey)) {
4363
                return BAD_FUNC_ARG;
4364
            }
4365
            XMEMCPY(aes->devKey, userKey, keylen);
4366
        }
4367
    #endif
4368
4369
        return AesSetKey(aes, userKey, keylen, iv, dir);
4370
    }
4371
4372
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
4373
        /* AES-CTR and AES-DIRECT need to use this for key setup */
4374
        /* This function allows key sizes that are not 128/192/256 bits */
4375
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4376
                           const byte* iv, int dir)
4377
    {
4378
        if (aes == NULL) {
4379
            return BAD_FUNC_ARG;
4380
        }
4381
        if (keylen > sizeof(aes->key)) {
4382
            return BAD_FUNC_ARG;
4383
        }
4384
4385
        return AesSetKey(aes, userKey, keylen, iv, dir);
4386
    }
4387
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
4388
#elif defined(FREESCALE_MMCAU)
4389
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
4390
        const byte* iv, int dir, int checkKeyLen)
4391
    {
4392
        int ret;
4393
        byte* rk;
4394
        byte* tmpKey = (byte*)userKey;
4395
        int tmpKeyDynamic = 0;
4396
        word32 alignOffset = 0;
4397
4398
        (void)dir;
4399
4400
        if (aes == NULL)
4401
            return BAD_FUNC_ARG;
4402
4403
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4404
        {
4405
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4406
            if (ret < 0)
4407
                return ret;
4408
        }
4409
#endif
4410
4411
        if (checkKeyLen) {
4412
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4413
                return BAD_FUNC_ARG;
4414
        }
4415
4416
        rk = (byte*)aes->key;
4417
        if (rk == NULL)
4418
            return BAD_FUNC_ARG;
4419
4420
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4421
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4422
        defined(WOLFSSL_AES_CTS)
4423
        aes->left = 0;
4424
    #endif
4425
4426
        aes->rounds = keylen/4 + 6;
4427
4428
    #ifdef FREESCALE_MMCAU_CLASSIC
4429
        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
4430
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
4431
            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
4432
                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
4433
            if (tmp == NULL) {
4434
                return MEMORY_E;
4435
            }
4436
            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
4437
                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
4438
            tmpKey = tmp + alignOffset;
4439
            XMEMCPY(tmpKey, userKey, keylen);
4440
            tmpKeyDynamic = 1;
4441
        #else
4442
            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
4443
            return BAD_ALIGN_E;
4444
        #endif
4445
        }
4446
    #endif
4447
4448
        ret = wolfSSL_CryptHwMutexLock();
4449
        if(ret == 0) {
4450
        #ifdef FREESCALE_MMCAU_CLASSIC
4451
            cau_aes_set_key(tmpKey, keylen*8, rk);
4452
        #else
4453
            MMCAU_AES_SetKey(tmpKey, keylen, rk);
4454
        #endif
4455
            wolfSSL_CryptHwMutexUnLock();
4456
4457
            ret = wc_AesSetIV(aes, iv);
4458
        }
4459
4460
        if (tmpKeyDynamic == 1) {
4461
            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
4462
        }
4463
4464
        return ret;
4465
    }
4466
4467
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4468
        const byte* iv, int dir)
4469
    {
4470
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4471
    }
4472
4473
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4474
                        const byte* iv, int dir)
4475
    {
4476
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4477
    }
4478
4479
#elif defined(WOLFSSL_PSOC6_CRYPTO)
4480
4481
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4482
        const byte* iv, int dir)
4483
    {
4484
        return wc_Psoc6_Aes_SetKey(aes, userKey, keylen, iv, dir);
4485
    }
4486
4487
    #if defined(WOLFSSL_AES_DIRECT)
4488
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4489
                            const byte* iv, int dir)
4490
        {
4491
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4492
        }
4493
    #endif /* WOLFSSL_AES_DIRECT */
4494
#else
4495
    #define NEED_SOFTWARE_AES_SETKEY
4496
#endif
4497
4498
/* Either we fell though with no HW support at all,
4499
 * or perhaps there's HW support for *some* keylengths
4500
 * and we need both HW and SW. */
4501
#ifdef NEED_SOFTWARE_AES_SETKEY
4502
4503
#ifdef NEED_AES_TABLES
4504
4505
#ifndef WC_AES_BITSLICED
4506
#if !defined(WOLFSSL_ARMASM)
4507
/* Set the AES key and expand.
4508
 *
4509
 * @param [in]  aes    AES object.
4510
 * @param [in]  key    Block to encrypt.
4511
 * @param [in]  keySz  Number of bytes in key.
4512
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4513
 */
4514
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4515
5.99k
{
4516
#ifdef WC_C_DYNAMIC_FALLBACK
4517
    word32* rk = aes->key_C_fallback;
4518
#else
4519
5.99k
    word32* rk = aes->key;
4520
5.99k
#endif
4521
5.99k
    word32 temp;
4522
5.99k
    unsigned int i = 0;
4523
4524
5.99k
    XMEMCPY(rk, key, keySz);
4525
5.99k
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
4526
5.99k
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
4527
5.99k
    !defined(MAX3266X_AES)
4528
    /* Always reverse words when using only SW */
4529
5.99k
    {
4530
5.99k
        ByteReverseWords(rk, rk, keySz);
4531
5.99k
    }
4532
#else
4533
    /* Sometimes reverse words when using supported HW */
4534
    #if defined(WOLFSSL_ESPIDF)
4535
        /* Some platforms may need SW fallback (e.g. AES192) */
4536
        #if defined(NEED_AES_HW_FALLBACK)
4537
        {
4538
            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
4539
            if (wc_esp32AesSupportedKeyLen(aes)) {
4540
                /* don't reverse for HW supported key lengths */
4541
            }
4542
            else {
4543
                ByteReverseWords(rk, rk, keySz);
4544
            }
4545
        }
4546
        #else
4547
            /* If we don't need SW fallback, don't need to reverse words. */
4548
        #endif /* NEED_AES_HW_FALLBACK */
4549
    #endif /* WOLFSSL_ESPIDF */
4550
#endif /* LITTLE_ENDIAN_ORDER, etc */
4551
4552
5.99k
    switch (keySz) {
4553
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
4554
0
        defined(WOLFSSL_AES_128)
4555
3.13k
    case 16:
4556
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4557
        temp = (word32)-1;
4558
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4559
    #endif
4560
31.3k
        while (1)
4561
31.3k
        {
4562
31.3k
            temp  = rk[3];
4563
31.3k
            rk[4] = rk[0] ^
4564
31.3k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4565
31.3k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4566
31.3k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4567
31.3k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4568
31.3k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4569
        #else
4570
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4571
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4572
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4573
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4574
        #endif
4575
31.3k
                rcon[i];
4576
31.3k
            rk[5] = rk[1] ^ rk[4];
4577
31.3k
            rk[6] = rk[2] ^ rk[5];
4578
31.3k
            rk[7] = rk[3] ^ rk[6];
4579
31.3k
            if (++i == 10)
4580
3.13k
                break;
4581
28.1k
            rk += 4;
4582
28.1k
        }
4583
3.13k
        break;
4584
0
#endif /* 128 */
4585
4586
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
4587
0
        defined(WOLFSSL_AES_192)
4588
947
    case 24:
4589
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4590
        temp = (word32)-1;
4591
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4592
    #endif
4593
        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
4594
7.57k
        while (1)
4595
7.57k
        {
4596
7.57k
            temp = rk[ 5];
4597
7.57k
            rk[ 6] = rk[ 0] ^
4598
7.57k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4599
7.57k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4600
7.57k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4601
7.57k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4602
7.57k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4603
        #else
4604
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4605
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4606
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4607
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4608
        #endif
4609
7.57k
                rcon[i];
4610
7.57k
            rk[ 7] = rk[ 1] ^ rk[ 6];
4611
7.57k
            rk[ 8] = rk[ 2] ^ rk[ 7];
4612
7.57k
            rk[ 9] = rk[ 3] ^ rk[ 8];
4613
7.57k
            if (++i == 8)
4614
947
                break;
4615
6.62k
            rk[10] = rk[ 4] ^ rk[ 9];
4616
6.62k
            rk[11] = rk[ 5] ^ rk[10];
4617
6.62k
            rk += 6;
4618
6.62k
        }
4619
947
        break;
4620
0
#endif /* 192 */
4621
4622
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
4623
0
        defined(WOLFSSL_AES_256)
4624
1.91k
    case 32:
4625
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4626
        temp = (word32)-1;
4627
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4628
    #endif
4629
13.3k
        while (1)
4630
13.3k
        {
4631
13.3k
            temp = rk[ 7];
4632
13.3k
            rk[ 8] = rk[ 0] ^
4633
13.3k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4634
13.3k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4635
13.3k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4636
13.3k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4637
13.3k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4638
        #else
4639
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4640
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4641
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4642
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4643
        #endif
4644
13.3k
                rcon[i];
4645
13.3k
            rk[ 9] = rk[ 1] ^ rk[ 8];
4646
13.3k
            rk[10] = rk[ 2] ^ rk[ 9];
4647
13.3k
            rk[11] = rk[ 3] ^ rk[10];
4648
13.3k
            if (++i == 7)
4649
1.91k
                break;
4650
11.4k
            temp = rk[11];
4651
11.4k
            rk[12] = rk[ 4] ^
4652
11.4k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4653
11.4k
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
4654
11.4k
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
4655
11.4k
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
4656
11.4k
                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
4657
        #else
4658
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
4659
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
4660
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
4661
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
4662
        #endif
4663
11.4k
            rk[13] = rk[ 5] ^ rk[12];
4664
11.4k
            rk[14] = rk[ 6] ^ rk[13];
4665
11.4k
            rk[15] = rk[ 7] ^ rk[14];
4666
4667
11.4k
            rk += 8;
4668
11.4k
        }
4669
1.91k
        break;
4670
5.99k
#endif /* 256 */
4671
5.99k
    } /* switch */
4672
5.99k
    ForceZero(&temp, sizeof(temp));
4673
4674
5.99k
#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
4675
5.99k
    if (dir == AES_DECRYPTION) {
4676
639
        unsigned int j;
4677
4678
#ifdef WC_C_DYNAMIC_FALLBACK
4679
        rk = aes->key_C_fallback;
4680
#else
4681
639
        rk = aes->key;
4682
639
#endif
4683
4684
        /* invert the order of the round keys: */
4685
4.19k
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
4686
3.55k
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
4687
3.55k
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
4688
3.55k
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
4689
3.55k
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
4690
3.55k
        }
4691
639
        ForceZero(&temp, sizeof(temp));
4692
639
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
4693
        /* apply the inverse MixColumn transform to all round keys but the
4694
           first and the last: */
4695
7.11k
        for (i = 1; i < aes->rounds; i++) {
4696
6.47k
            rk += 4;
4697
6.47k
            rk[0] =
4698
6.47k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
4699
6.47k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
4700
6.47k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
4701
6.47k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
4702
6.47k
            rk[1] =
4703
6.47k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
4704
6.47k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
4705
6.47k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
4706
6.47k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
4707
6.47k
            rk[2] =
4708
6.47k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
4709
6.47k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
4710
6.47k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
4711
6.47k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
4712
6.47k
            rk[3] =
4713
6.47k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
4714
6.47k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
4715
6.47k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
4716
6.47k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
4717
6.47k
        }
4718
639
    #endif
4719
639
    }
4720
#else
4721
    (void)dir;
4722
#endif /* HAVE_AES_DECRYPT */
4723
4724
#ifdef WOLFSSL_CHECK_MEM_ZERO
4725
    wc_MemZero_Check(&temp, sizeof(temp));
4726
#else
4727
5.99k
    (void)temp;
4728
5.99k
#endif
4729
5.99k
}
4730
#endif
4731
#else /* WC_AES_BITSLICED */
4732
/* Set the AES key and expand.
4733
 *
4734
 * @param [in]  aes    AES object.
4735
 * @param [in]  key    Block to encrypt.
4736
 * @param [in]  keySz  Number of bytes in key.
4737
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4738
 */
4739
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4740
{
4741
    /* No need to invert when decrypting. */
4742
    (void)dir;
4743
4744
    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
4745
}
4746
#endif /* WC_AES_BITSLICED */
4747
4748
#endif /* NEED_AES_TABLES */
4749
4750
#ifndef WOLFSSL_RISCV_ASM
4751
    /* Software AES - SetKey */
4752
    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
4753
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
4754
        int checkKeyLen)
4755
5.99k
    {
4756
5.99k
        int ret;
4757
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4758
        byte   local[32];
4759
        word32 localSz = 32;
4760
    #endif
4761
4762
5.99k
        if (aes == NULL)
4763
0
            return BAD_FUNC_ARG;
4764
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4765
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4766
        if (ret < 0)
4767
            return ret;
4768
#endif
4769
4770
5.99k
        switch (keylen) {
4771
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4772
0
        defined(WOLFSSL_AES_128)
4773
3.13k
        case 16:
4774
3.13k
    #endif
4775
3.13k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4776
3.13k
        defined(WOLFSSL_AES_192)
4777
4.07k
        case 24:
4778
4.07k
    #endif
4779
4.07k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4780
4.07k
        defined(WOLFSSL_AES_256)
4781
5.99k
        case 32:
4782
5.99k
    #endif
4783
5.99k
            break;
4784
0
        default:
4785
0
            return BAD_FUNC_ARG;
4786
5.99k
        }
4787
4788
    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
4789
        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
4790
            return WC_HW_E;
4791
        }
4792
    #endif
4793
4794
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4795
        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
4796
            keylen == (24 + WC_CAAM_BLOB_SZ) ||
4797
            keylen == (32 + WC_CAAM_BLOB_SZ)) {
4798
            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
4799
                return BAD_FUNC_ARG;
4800
            }
4801
4802
            /* set local values */
4803
            userKey = local;
4804
            keylen = localSz;
4805
        }
4806
    #endif
4807
4808
    #ifdef WOLFSSL_SECO_CAAM
4809
        /* if set to use hardware than import the key */
4810
        if (aes->devId == WOLFSSL_SECO_DEVID) {
4811
            int keyGroup = 1; /* group one was chosen arbitrarily */
4812
            unsigned int keyIdOut;
4813
            byte importiv[GCM_NONCE_MID_SZ];
4814
            int importivSz = GCM_NONCE_MID_SZ;
4815
            int keyType = 0;
4816
            WC_RNG rng;
4817
4818
            if (wc_InitRng(&rng) != 0) {
4819
                WOLFSSL_MSG("RNG init for IV failed");
4820
                return WC_HW_E;
4821
            }
4822
4823
            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
4824
                WOLFSSL_MSG("Generate IV failed");
4825
                wc_FreeRng(&rng);
4826
                return WC_HW_E;
4827
            }
4828
            wc_FreeRng(&rng);
4829
4830
            if (iv)
4831
                XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4832
            else
4833
                XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
4834
4835
            switch (keylen) {
4836
                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
4837
                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
4838
                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
4839
            }
4840
4841
            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
4842
                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
4843
            if (keyIdOut == 0) {
4844
                return WC_HW_E;
4845
            }
4846
            aes->blackKey = keyIdOut;
4847
            return 0;
4848
        }
4849
    #endif
4850
4851
5.99k
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
4852
5.99k
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
4853
5.99k
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
4854
5.99k
        #ifdef WOLF_CRYPTO_CB
4855
5.99k
        if (aes->devId != INVALID_DEVID)
4856
590
        #endif
4857
590
        {
4858
590
            if (keylen > sizeof(aes->devKey)) {
4859
0
                return BAD_FUNC_ARG;
4860
0
            }
4861
590
            XMEMCPY(aes->devKey, userKey, keylen);
4862
590
        }
4863
5.99k
    #endif
4864
4865
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
4866
        if (checkKeyLen) {
4867
            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
4868
             * all key sizes. Otherwise this condition is never true. */
4869
            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
4870
                return BAD_FUNC_ARG;
4871
            }
4872
        }
4873
    #else
4874
5.99k
        (void) checkKeyLen;
4875
5.99k
    #endif
4876
4877
5.99k
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4878
5.99k
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4879
5.99k
        defined(WOLFSSL_AES_CTS)
4880
5.99k
        aes->left = 0;
4881
5.99k
    #endif
4882
4883
5.99k
        aes->keylen = (int)keylen;
4884
5.99k
        aes->rounds = (keylen/4) + 6;
4885
5.99k
        ret = wc_AesSetIV(aes, iv);
4886
5.99k
        if (ret != 0)
4887
0
            return ret;
4888
4889
#ifdef WC_C_DYNAMIC_FALLBACK
4890
#ifdef NEED_AES_TABLES
4891
        AesSetKey_C(aes, userKey, keylen, dir);
4892
#endif /* NEED_AES_TABLES */
4893
#endif /* WC_C_DYNAMIC_FALLBACK */
4894
4895
    #ifdef WOLFSSL_AESNI
4896
4897
       /* The dynamics for determining whether AES-NI will be used are tricky.
4898
        *
4899
        * First, we check for CPU support and cache the result -- if AES-NI is
4900
        * missing, we always shortcut to the AesSetKey_C() path.
4901
        *
4902
        * Second, if the CPU supports AES-NI, we confirm on a per-call basis
4903
        * that it's safe to use in the caller context, using
4904
        * SAVE_VECTOR_REGISTERS2().  This is an always-true no-op in user-space
4905
        * builds, but has substantive logic behind it in kernel module builds.
4906
        *
4907
        * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on
4908
        * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with
4909
        * success but with AES-NI disabled (the earlier AesSetKey_C() allows
4910
        * future encrypt/decrypt calls to succeed), otherwise we fail.
4911
        *
4912
        * Upon successful return, aes->use_aesni will have a zero value if
4913
        * AES-NI is disabled, and a nonzero value if it's enabled.
4914
        *
4915
        * An additional, optional semantic is available via
4916
        * WC_FLAG_DONT_USE_VECTOR_OPS, and is used in some kernel module builds
4917
        * to let the caller inhibit AES-NI.  When this macro is defined,
4918
        * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of
4919
        * uninitialized data in aes->use_aesni.  That's why support for
4920
        * WC_FLAG_DONT_USE_VECTOR_OPS must remain optional -- wc_AesInit() was
4921
        * only added in release 3.11.0, so legacy applications inevitably call
4922
        * wc_AesSetKey() on uninitialized Aes contexts.  This must continue to
4923
        * function correctly with default build settings.
4924
        */
4925
4926
        if (checkedAESNI == 0) {
4927
            haveAESNI  = Check_CPU_support_AES();
4928
            checkedAESNI = 1;
4929
        }
4930
        if (haveAESNI
4931
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS) && !defined(WC_C_DYNAMIC_FALLBACK)
4932
            && (aes->use_aesni != WC_FLAG_DONT_USE_VECTOR_OPS)
4933
#endif
4934
            )
4935
        {
4936
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS)
4937
            if (aes->use_aesni == WC_FLAG_DONT_USE_VECTOR_OPS) {
4938
                aes->use_aesni = 0;
4939
                return 0;
4940
            }
4941
#endif
4942
            aes->use_aesni = 0;
4943
            #ifdef WOLFSSL_KERNEL_MODE
4944
            /* runtime alignment check */
4945
            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
4946
                ret = BAD_ALIGN_E;
4947
            }
4948
            else
4949
            #endif /* WOLFSSL_KERNEL_MODE */
4950
            {
4951
                ret = SAVE_VECTOR_REGISTERS2();
4952
            }
4953
            if (ret == 0) {
4954
                if (dir == AES_ENCRYPTION)
4955
                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
4956
#ifdef HAVE_AES_DECRYPT
4957
                else
4958
                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
4959
#endif
4960
4961
                RESTORE_VECTOR_REGISTERS();
4962
4963
                if (ret == 0)
4964
                    aes->use_aesni = 1;
4965
                else {
4966
#ifdef WC_C_DYNAMIC_FALLBACK
4967
                    ret = 0;
4968
#endif
4969
                }
4970
                return ret;
4971
            } else {
4972
#ifdef WC_C_DYNAMIC_FALLBACK
4973
                return 0;
4974
#else
4975
                return ret;
4976
#endif
4977
            }
4978
        }
4979
        else {
4980
            aes->use_aesni = 0;
4981
#ifdef WC_C_DYNAMIC_FALLBACK
4982
            /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C()
4983
             * above.
4984
             */
4985
            return 0;
4986
#endif
4987
        }
4988
    #endif /* WOLFSSL_AESNI */
4989
4990
5.99k
#ifndef WC_C_DYNAMIC_FALLBACK
4991
4992
#if defined(WOLFSSL_ARMASM)
4993
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
4994
    #ifndef __aarch64__
4995
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
4996
    #else
4997
        Check_CPU_support_HwCrypto(aes);
4998
        if (aes->use_aes_hw_crypto) {
4999
            AES_set_key_AARCH64(userKey, keylen, (byte*)aes->key, dir);
5000
        }
5001
        else
5002
    #endif /* __aarch64__ */
5003
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
5004
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
5005
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
5006
        {
5007
            AES_set_encrypt_key_NEON(userKey, keylen * 8, (byte*)aes->key);
5008
        #ifdef HAVE_AES_DECRYPT
5009
            if (dir == AES_DECRYPTION) {
5010
                AES_invert_key_NEON((byte*)aes->key, aes->rounds);
5011
            }
5012
        #else
5013
            (void)dir;
5014
        #endif
5015
        }
5016
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5017
        {
5018
            AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5019
        #ifdef HAVE_AES_DECRYPT
5020
            if (dir == AES_DECRYPTION) {
5021
                AES_invert_key((byte*)aes->key, aes->rounds);
5022
            }
5023
        #else
5024
            (void)dir;
5025
        #endif
5026
        }
5027
    #endif
5028
        return 0;
5029
#else
5030
5031
    #ifdef WOLFSSL_KCAPI_AES
5032
        XMEMCPY(aes->devKey, userKey, keylen);
5033
        if (aes->init != 0) {
5034
            kcapi_cipher_destroy(aes->handle);
5035
            aes->handle = NULL;
5036
            aes->init = 0;
5037
        }
5038
        (void)dir;
5039
    #endif
5040
5041
5.99k
        if (keylen > sizeof(aes->key)) {
5042
0
            return BAD_FUNC_ARG;
5043
0
        }
5044
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
5045
        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
5046
                                  ((psa_algorithm_t)0), dir);
5047
#endif
5048
5049
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
5050
        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
5051
         * instead of SE05x crypto by setting useSWCrypt */
5052
        if (aes->useSWCrypt == 0) {
5053
            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
5054
            if (ret == 0) {
5055
                ret = wc_AesSetIV(aes, iv);
5056
            }
5057
            return ret;
5058
        }
5059
#endif
5060
5061
5.99k
        XMEMCPY(aes->key, userKey, keylen);
5062
5063
5.99k
#ifndef WC_AES_BITSLICED
5064
5.99k
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
5065
5.99k
        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
5066
5.99k
        && !defined(MAX3266X_AES)
5067
5068
        /* software */
5069
5.99k
        ByteReverseWords(aes->key, aes->key, keylen);
5070
5071
    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
5072
        if (wc_esp32AesSupportedKeyLen(aes)) {
5073
            /* supported lengths don't get reversed */
5074
            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
5075
        }
5076
        else {
5077
            word32* rk = aes->key;
5078
5079
            /* For example, the ESP32-S3 does not support HW for len = 24,
5080
             * so fall back to SW */
5081
        #ifdef DEBUG_WOLFSSL
5082
            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
5083
        #endif
5084
            XMEMCPY(rk, userKey, keylen);
5085
            /* When not ESP32 HW, we need to reverse endianness */
5086
            ByteReverseWords(rk, rk, keylen);
5087
        }
5088
    #endif
5089
5090
    #ifdef WOLFSSL_IMXRT_DCP
5091
        {
5092
            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
5093
            word32 temp = 0;
5094
            if (keylen == 16)
5095
                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
5096
            if (temp != 0)
5097
                return WC_HW_E;
5098
        }
5099
    #endif
5100
5.99k
#endif /* !WC_AES_BITSLICED */
5101
5102
5.99k
#ifdef NEED_AES_TABLES
5103
5.99k
        AesSetKey_C(aes, userKey, keylen, dir);
5104
5.99k
#endif /* NEED_AES_TABLES */
5105
5106
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
5107
        XMEMCPY((byte*)aes->key, userKey, keylen);
5108
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
5109
            ByteReverseWords(aes->key, aes->key, 32);
5110
        }
5111
#endif
5112
5113
    #if defined(WOLFSSL_DEVCRYPTO) && \
5114
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
5115
        aes->ctx.cfd = -1;
5116
    #endif
5117
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5118
        ForceZero(local, sizeof(local));
5119
    #endif
5120
5.99k
        return ret;
5121
5.99k
#endif
5122
5123
5.99k
#endif /* !WC_C_DYNAMIC_FALLBACK */
5124
5125
5.99k
    } /* wc_AesSetKeyLocal */
5126
5127
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5128
            const byte* iv, int dir)
5129
5.43k
    {
5130
5.43k
        if (aes == NULL) {
5131
0
            return BAD_FUNC_ARG;
5132
0
        }
5133
5.43k
        if (keylen > sizeof(aes->key)) {
5134
0
            return BAD_FUNC_ARG;
5135
0
        }
5136
5137
    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
5138
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
5139
        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
5140
        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
5141
            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
5142
            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
5143
        }
5144
        else {
5145
        #if  defined(WOLFSSL_HW_METRICS)
5146
            /* It is interesting to know how many times we could not complete
5147
             * AES in hardware due to unsupported lengths. */
5148
            wc_esp32AesUnupportedLengthCountAdd();
5149
        #endif
5150
        #ifdef DEBUG_WOLFSSL
5151
            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
5152
                           keylen);
5153
        #endif
5154
        }
5155
    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
5156
5157
5.43k
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
5158
5159
5.43k
    } /* wc_AesSetKey() */
5160
#endif
5161
5162
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5163
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5164
        /* This function allows key sizes that are not 128/192/256 bits */
5165
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5166
                           const byte* iv, int dir)
5167
552
    {
5168
552
        if (aes == NULL) {
5169
0
            return BAD_FUNC_ARG;
5170
0
        }
5171
552
        if (keylen > sizeof(aes->key)) {
5172
0
            return BAD_FUNC_ARG;
5173
0
        }
5174
5175
552
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
5176
552
    }
5177
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5178
#endif /* wc_AesSetKey block */
5179
5180
5181
/* wc_AesSetIV is shared between software and hardware */
5182
int wc_AesSetIV(Aes* aes, const byte* iv)
5183
6.59k
{
5184
6.59k
    if (aes == NULL)
5185
0
        return BAD_FUNC_ARG;
5186
5187
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5188
    {
5189
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5190
        if (ret < 0)
5191
            return ret;
5192
    }
5193
#endif
5194
5195
6.59k
    if (iv)
5196
3.64k
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5197
2.94k
    else
5198
2.94k
        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
5199
5200
6.59k
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5201
6.59k
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5202
6.59k
    defined(WOLFSSL_AES_CTS)
5203
    /* Clear any unused bytes from last cipher op. */
5204
6.59k
    aes->left = 0;
5205
6.59k
#endif
5206
5207
6.59k
    return 0;
5208
6.59k
}
5209
5210
#ifdef WOLFSSL_AESNI
5211
5212
#ifdef WC_C_DYNAMIC_FALLBACK
5213
5214
#define VECTOR_REGISTERS_PUSH {                                      \
5215
        int orig_use_aesni = aes->use_aesni;                         \
5216
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
5217
            aes->use_aesni = 0;                                      \
5218
        }                                                            \
5219
        WC_DO_NOTHING
5220
5221
#define VECTOR_REGISTERS_POP                                         \
5222
        if (aes->use_aesni)                                          \
5223
            RESTORE_VECTOR_REGISTERS();                              \
5224
        else                                                         \
5225
            aes->use_aesni = orig_use_aesni;                         \
5226
    }                                                                \
5227
    WC_DO_NOTHING
5228
5229
#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
5230
5231
#define VECTOR_REGISTERS_PUSH { \
5232
        WC_DO_NOTHING
5233
5234
#define VECTOR_REGISTERS_POP                                         \
5235
    }                                                                \
5236
    WC_DO_NOTHING
5237
5238
#else
5239
5240
#define VECTOR_REGISTERS_PUSH { \
5241
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
5242
            return ret;                                                  \
5243
        }                                                                \
5244
        WC_DO_NOTHING
5245
5246
#define VECTOR_REGISTERS_POP \
5247
        if (aes->use_aesni) {                                            \
5248
            RESTORE_VECTOR_REGISTERS();                                  \
5249
        }                                                                \
5250
    }                                                                    \
5251
    WC_DO_NOTHING
5252
5253
#endif
5254
5255
#else /* !WOLFSSL_AESNI */
5256
5257
20.4k
#define VECTOR_REGISTERS_PUSH WC_DO_NOTHING
5258
20.4k
#define VECTOR_REGISTERS_POP WC_DO_NOTHING
5259
5260
#endif /* !WOLFSSL_AESNI */
5261
5262
5263
/* AES-DIRECT */
5264
#if defined(WOLFSSL_AES_DIRECT)
5265
    #if defined(HAVE_COLDFIRE_SEC)
5266
        #error "Coldfire SEC doesn't yet support AES direct"
5267
5268
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
5269
        !defined(WOLFSSL_QNX_CAAM)
5270
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
5271
5272
    #elif defined(WOLFSSL_AFALG)
5273
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
5274
5275
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
5276
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
5277
5278
    #else
5279
5280
        /* Allow direct access to one block encrypt */
5281
        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
5282
10.0k
        {
5283
10.0k
            int ret;
5284
5285
10.0k
            if (aes == NULL)
5286
0
                return BAD_FUNC_ARG;
5287
10.0k
            VECTOR_REGISTERS_PUSH;
5288
10.0k
            ret = wc_AesEncrypt(aes, in, out);
5289
10.0k
            VECTOR_REGISTERS_POP;
5290
10.0k
            return ret;
5291
10.0k
        }
5292
5293
        /* vector reg save/restore is explicit in all below calls to
5294
         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
5295
         * macro.
5296
         */
5297
40.8k
        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
5298
5299
        #ifdef HAVE_AES_DECRYPT
5300
        /* Allow direct access to one block decrypt */
5301
        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
5302
0
        {
5303
0
            int ret;
5304
5305
0
            if (aes == NULL)
5306
0
                return BAD_FUNC_ARG;
5307
0
            VECTOR_REGISTERS_PUSH;
5308
0
            ret = wc_AesDecrypt(aes, in, out);
5309
0
            VECTOR_REGISTERS_POP;
5310
0
            return ret;
5311
0
        }
5312
5313
104
        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
5314
5315
        #endif /* HAVE_AES_DECRYPT */
5316
    #endif /* AES direct block */
5317
#endif /* WOLFSSL_AES_DIRECT */
5318
5319
5320
/* AES-CBC */
5321
#ifdef HAVE_AES_CBC
5322
#if defined(STM32_CRYPTO)
5323
5324
#ifdef WOLFSSL_STM32U5_DHUK
5325
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5326
    {
5327
        int ret = 0;
5328
        CRYP_HandleTypeDef hcryp;
5329
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5330
5331
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5332
        if (sz % WC_AES_BLOCK_SIZE) {
5333
            return BAD_LENGTH_E;
5334
        }
5335
#endif
5336
        if (blocks == 0)
5337
            return 0;
5338
5339
        ret = wolfSSL_CryptHwMutexLock();
5340
        if (ret != 0) {
5341
            return ret;
5342
        }
5343
5344
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
5345
            CRYP_ConfigTypeDef Config;
5346
5347
            XMEMSET(&Config, 0, sizeof(Config));
5348
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen,
5349
                (const byte*)aes->dhukIV, aes->dhukIVLen);
5350
5351
            /* reconfigure for using unwrapped key now */
5352
            HAL_CRYP_GetConfig(&hcryp, &Config);
5353
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
5354
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
5355
            Config.Algorithm = CRYP_AES_CBC;
5356
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5357
            Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5358
            HAL_CRYP_SetConfig(&hcryp, &Config);
5359
        }
5360
        else {
5361
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
5362
            if (ret != 0) {
5363
                wolfSSL_CryptHwMutexUnLock();
5364
                return ret;
5365
            }
5366
            hcryp.Init.Algorithm  = CRYP_AES_CBC;
5367
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5368
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5369
            ret = HAL_CRYP_Init(&hcryp);
5370
        }
5371
5372
        if (ret == HAL_OK) {
5373
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5374
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5375
            if (ret != HAL_OK) {
5376
                ret = WC_TIMEOUT_E;
5377
            }
5378
5379
            /* store iv for next call */
5380
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5381
        }
5382
5383
        HAL_CRYP_DeInit(&hcryp);
5384
5385
        wolfSSL_CryptHwMutexUnLock();
5386
        wc_Stm32_Aes_Cleanup();
5387
5388
        return ret;
5389
    }
5390
    #ifdef HAVE_AES_DECRYPT
5391
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5392
    {
5393
        int ret = 0;
5394
        CRYP_HandleTypeDef hcryp;
5395
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5396
5397
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5398
        if (sz % WC_AES_BLOCK_SIZE) {
5399
            return BAD_LENGTH_E;
5400
        }
5401
#endif
5402
        if (blocks == 0)
5403
            return 0;
5404
5405
        ret = wolfSSL_CryptHwMutexLock();
5406
        if (ret != 0) {
5407
            return ret;
5408
        }
5409
5410
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
5411
            CRYP_ConfigTypeDef Config;
5412
5413
            XMEMSET(&Config, 0, sizeof(Config));
5414
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen,
5415
                aes->dhukIV, aes->dhukIVLen);
5416
5417
            /* reconfigure for using unwrapped key now */
5418
            HAL_CRYP_GetConfig(&hcryp, &Config);
5419
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
5420
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
5421
            Config.Algorithm = CRYP_AES_CBC;
5422
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5423
            Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5424
            HAL_CRYP_SetConfig(&hcryp, &Config);
5425
        }
5426
        else {
5427
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
5428
            if (ret != 0) {
5429
                wolfSSL_CryptHwMutexUnLock();
5430
                return ret;
5431
            }
5432
            hcryp.Init.Algorithm  = CRYP_AES_CBC;
5433
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5434
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5435
            ret = HAL_CRYP_Init(&hcryp);
5436
        }
5437
5438
        if (ret == HAL_OK) {
5439
            /* if input and output same will overwrite input iv */
5440
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5441
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5442
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5443
            if (ret != HAL_OK) {
5444
                ret = WC_TIMEOUT_E;
5445
            }
5446
5447
            /* store iv for next call */
5448
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5449
        }
5450
5451
        HAL_CRYP_DeInit(&hcryp);
5452
        wolfSSL_CryptHwMutexUnLock();
5453
        wc_Stm32_Aes_Cleanup();
5454
5455
        return ret;
5456
    }
5457
    #endif /* HAVE_AES_DECRYPT */
5458
5459
#elif defined(WOLFSSL_STM32_CUBEMX)
5460
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5461
    {
5462
        int ret = 0;
5463
        CRYP_HandleTypeDef hcryp;
5464
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5465
5466
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5467
        if (sz % WC_AES_BLOCK_SIZE) {
5468
            return BAD_LENGTH_E;
5469
        }
5470
#endif
5471
        if (blocks == 0)
5472
            return 0;
5473
5474
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
5475
        if (ret != 0)
5476
            return ret;
5477
5478
        ret = wolfSSL_CryptHwMutexLock();
5479
        if (ret != 0) {
5480
            return ret;
5481
        }
5482
5483
    #if defined(STM32_HAL_V2)
5484
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
5485
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5486
    #elif defined(STM32_CRYPTO_AES_ONLY)
5487
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
5488
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
5489
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
5490
    #endif
5491
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5492
        ret = HAL_CRYP_Init(&hcryp);
5493
5494
        if (ret == HAL_OK) {
5495
        #if defined(STM32_HAL_V2)
5496
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5497
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5498
        #elif defined(STM32_CRYPTO_AES_ONLY)
5499
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
5500
                out, STM32_HAL_TIMEOUT);
5501
        #else
5502
            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
5503
                                        blocks * WC_AES_BLOCK_SIZE,
5504
                                        out, STM32_HAL_TIMEOUT);
5505
        #endif
5506
        }
5507
        if (ret != HAL_OK) {
5508
            ret = WC_TIMEOUT_E;
5509
        }
5510
5511
        /* store iv for next call */
5512
        XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5513
5514
        HAL_CRYP_DeInit(&hcryp);
5515
5516
        wolfSSL_CryptHwMutexUnLock();
5517
        wc_Stm32_Aes_Cleanup();
5518
5519
        return ret;
5520
    }
5521
    #ifdef HAVE_AES_DECRYPT
5522
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5523
    {
5524
        int ret = 0;
5525
        CRYP_HandleTypeDef hcryp;
5526
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5527
5528
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5529
        if (sz % WC_AES_BLOCK_SIZE) {
5530
            return BAD_LENGTH_E;
5531
        }
5532
#endif
5533
        if (blocks == 0)
5534
            return 0;
5535
5536
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
5537
        if (ret != 0)
5538
            return ret;
5539
5540
        ret = wolfSSL_CryptHwMutexLock();
5541
        if (ret != 0) {
5542
            return ret;
5543
        }
5544
5545
        /* if input and output same will overwrite input iv */
5546
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5547
5548
    #if defined(STM32_HAL_V2)
5549
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
5550
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5551
    #elif defined(STM32_CRYPTO_AES_ONLY)
5552
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
5553
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
5554
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
5555
    #endif
5556
5557
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5558
        ret = HAL_CRYP_Init(&hcryp);
5559
5560
        if (ret == HAL_OK) {
5561
        #if defined(STM32_HAL_V2)
5562
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5563
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5564
        #elif defined(STM32_CRYPTO_AES_ONLY)
5565
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
5566
                out, STM32_HAL_TIMEOUT);
5567
        #else
5568
            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
5569
                                        blocks * WC_AES_BLOCK_SIZE,
5570
                out, STM32_HAL_TIMEOUT);
5571
        #endif
5572
        }
5573
        if (ret != HAL_OK) {
5574
            ret = WC_TIMEOUT_E;
5575
        }
5576
5577
        /* store iv for next call */
5578
        XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5579
5580
        HAL_CRYP_DeInit(&hcryp);
5581
        wolfSSL_CryptHwMutexUnLock();
5582
        wc_Stm32_Aes_Cleanup();
5583
5584
        return ret;
5585
    }
5586
    #endif /* HAVE_AES_DECRYPT */
5587
5588
#else /* Standard Peripheral Library */
5589
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5590
    {
5591
        int ret;
5592
        word32 *iv;
5593
        CRYP_InitTypeDef cryptInit;
5594
        CRYP_KeyInitTypeDef keyInit;
5595
        CRYP_IVInitTypeDef ivInit;
5596
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5597
5598
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5599
        if (sz % WC_AES_BLOCK_SIZE) {
5600
            return BAD_LENGTH_E;
5601
        }
5602
#endif
5603
        if (blocks == 0)
5604
            return 0;
5605
5606
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
5607
        if (ret != 0)
5608
            return ret;
5609
5610
        ret = wolfSSL_CryptHwMutexLock();
5611
        if (ret != 0) {
5612
            return ret;
5613
        }
5614
5615
        /* reset registers to their default values */
5616
        CRYP_DeInit();
5617
5618
        /* set key */
5619
        CRYP_KeyInit(&keyInit);
5620
5621
        /* set iv */
5622
        iv = aes->reg;
5623
        CRYP_IVStructInit(&ivInit);
5624
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
5625
        ivInit.CRYP_IV0Left  = iv[0];
5626
        ivInit.CRYP_IV0Right = iv[1];
5627
        ivInit.CRYP_IV1Left  = iv[2];
5628
        ivInit.CRYP_IV1Right = iv[3];
5629
        CRYP_IVInit(&ivInit);
5630
5631
        /* set direction and mode */
5632
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
5633
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
5634
        CRYP_Init(&cryptInit);
5635
5636
        /* enable crypto processor */
5637
        CRYP_Cmd(ENABLE);
5638
5639
        while (blocks--) {
5640
            /* flush IN/OUT FIFOs */
5641
            CRYP_FIFOFlush();
5642
5643
            CRYP_DataIn(*(uint32_t*)&in[0]);
5644
            CRYP_DataIn(*(uint32_t*)&in[4]);
5645
            CRYP_DataIn(*(uint32_t*)&in[8]);
5646
            CRYP_DataIn(*(uint32_t*)&in[12]);
5647
5648
            /* wait until the complete message has been processed */
5649
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5650
5651
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5652
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5653
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5654
            *(uint32_t*)&out[12] = CRYP_DataOut();
5655
5656
            /* store iv for next call */
5657
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5658
5659
            sz  -= WC_AES_BLOCK_SIZE;
5660
            in  += WC_AES_BLOCK_SIZE;
5661
            out += WC_AES_BLOCK_SIZE;
5662
        }
5663
5664
        /* disable crypto processor */
5665
        CRYP_Cmd(DISABLE);
5666
        wolfSSL_CryptHwMutexUnLock();
5667
        wc_Stm32_Aes_Cleanup();
5668
5669
        return ret;
5670
    }
5671
5672
    #ifdef HAVE_AES_DECRYPT
5673
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5674
    {
5675
        int ret;
5676
        word32 *iv;
5677
        CRYP_InitTypeDef cryptInit;
5678
        CRYP_KeyInitTypeDef keyInit;
5679
        CRYP_IVInitTypeDef ivInit;
5680
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5681
5682
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5683
        if (sz % WC_AES_BLOCK_SIZE) {
5684
            return BAD_LENGTH_E;
5685
        }
5686
#endif
5687
        if (blocks == 0)
5688
            return 0;
5689
5690
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
5691
        if (ret != 0)
5692
            return ret;
5693
5694
        ret = wolfSSL_CryptHwMutexLock();
5695
        if (ret != 0) {
5696
            return ret;
5697
        }
5698
5699
        /* if input and output same will overwrite input iv */
5700
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5701
5702
        /* reset registers to their default values */
5703
        CRYP_DeInit();
5704
5705
        /* set direction and key */
5706
        CRYP_KeyInit(&keyInit);
5707
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5708
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
5709
        CRYP_Init(&cryptInit);
5710
5711
        /* enable crypto processor */
5712
        CRYP_Cmd(ENABLE);
5713
5714
        /* wait until key has been prepared */
5715
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5716
5717
        /* set direction and mode */
5718
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5719
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
5720
        CRYP_Init(&cryptInit);
5721
5722
        /* set iv */
5723
        iv = aes->reg;
5724
        CRYP_IVStructInit(&ivInit);
5725
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
5726
        ivInit.CRYP_IV0Left  = iv[0];
5727
        ivInit.CRYP_IV0Right = iv[1];
5728
        ivInit.CRYP_IV1Left  = iv[2];
5729
        ivInit.CRYP_IV1Right = iv[3];
5730
        CRYP_IVInit(&ivInit);
5731
5732
        /* enable crypto processor */
5733
        CRYP_Cmd(ENABLE);
5734
5735
        while (blocks--) {
5736
            /* flush IN/OUT FIFOs */
5737
            CRYP_FIFOFlush();
5738
5739
            CRYP_DataIn(*(uint32_t*)&in[0]);
5740
            CRYP_DataIn(*(uint32_t*)&in[4]);
5741
            CRYP_DataIn(*(uint32_t*)&in[8]);
5742
            CRYP_DataIn(*(uint32_t*)&in[12]);
5743
5744
            /* wait until the complete message has been processed */
5745
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5746
5747
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5748
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5749
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5750
            *(uint32_t*)&out[12] = CRYP_DataOut();
5751
5752
            /* store iv for next call */
5753
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5754
5755
            in  += WC_AES_BLOCK_SIZE;
5756
            out += WC_AES_BLOCK_SIZE;
5757
        }
5758
5759
        /* disable crypto processor */
5760
        CRYP_Cmd(DISABLE);
5761
        wolfSSL_CryptHwMutexUnLock();
5762
        wc_Stm32_Aes_Cleanup();
5763
5764
        return ret;
5765
    }
5766
    #endif /* HAVE_AES_DECRYPT */
5767
#endif /* WOLFSSL_STM32_CUBEMX */
5768
5769
#elif defined(HAVE_COLDFIRE_SEC)
5770
    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
5771
        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
5772
    {
5773
        #ifdef DEBUG_WOLFSSL
5774
            int i; int stat1, stat2; int ret;
5775
        #endif
5776
5777
        int size;
5778
        volatile int v;
5779
5780
        if ((pi == NULL) || (po == NULL))
5781
            return BAD_FUNC_ARG;    /*wrong pointer*/
5782
5783
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5784
        if (sz % WC_AES_BLOCK_SIZE) {
5785
            return BAD_LENGTH_E;
5786
        }
5787
#endif
5788
5789
        wc_LockMutex(&Mutex_AesSEC);
5790
5791
        /* Set descriptor for SEC */
5792
        secDesc->length1 = 0x0;
5793
        secDesc->pointer1 = NULL;
5794
5795
        secDesc->length2 = WC_AES_BLOCK_SIZE;
5796
        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
5797
5798
        switch(aes->rounds) {
5799
            case 10: secDesc->length3 = 16; break;
5800
            case 12: secDesc->length3 = 24; break;
5801
            case 14: secDesc->length3 = 32; break;
5802
        }
5803
        XMEMCPY(secKey, aes->key, secDesc->length3);
5804
5805
        secDesc->pointer3 = (byte *)secKey;
5806
        secDesc->pointer4 = AESBuffIn;
5807
        secDesc->pointer5 = AESBuffOut;
5808
        secDesc->length6 = 0x0;
5809
        secDesc->pointer6 = NULL;
5810
        secDesc->length7 = 0x0;
5811
        secDesc->pointer7 = NULL;
5812
        secDesc->nextDescriptorPtr = NULL;
5813
5814
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5815
        size = AES_BUFFER_SIZE;
5816
#endif
5817
        while (sz) {
5818
            secDesc->header = descHeader;
5819
            XMEMCPY(secReg, aes->reg, WC_AES_BLOCK_SIZE);
5820
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5821
            sz -= AES_BUFFER_SIZE;
5822
#else
5823
            if (sz < AES_BUFFER_SIZE) {
5824
                size = sz;
5825
                sz = 0;
5826
            } else {
5827
                size = AES_BUFFER_SIZE;
5828
                sz -= AES_BUFFER_SIZE;
5829
            }
5830
#endif
5831
5832
            secDesc->length4 = size;
5833
            secDesc->length5 = size;
5834
5835
            XMEMCPY(AESBuffIn, pi, size);
5836
            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
5837
                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-WC_AES_BLOCK_SIZE]),
5838
                        WC_AES_BLOCK_SIZE);
5839
            }
5840
5841
            /* Point SEC to the location of the descriptor */
5842
            MCF_SEC_FR0 = (uint32)secDesc;
5843
            /* Initialize SEC and wait for encryption to complete */
5844
            MCF_SEC_CCCR0 = 0x0000001a;
5845
            /* poll SISR to determine when channel is complete */
5846
            v=0;
5847
5848
            while ((secDesc->header>> 24) != 0xff) v++;
5849
5850
            #ifdef DEBUG_WOLFSSL
5851
                ret = MCF_SEC_SISRH;
5852
                stat1 = MCF_SEC_AESSR;
5853
                stat2 = MCF_SEC_AESISR;
5854
                if (ret & 0xe0000000) {
5855
                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
5856
                              "AESISR=%08x\n", i, ret, stat1, stat2);
5857
                }
5858
            #endif
5859
5860
            XMEMCPY(po, AESBuffOut, size);
5861
5862
            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
5863
                XMEMCPY((void*)aes->reg, (void*)&(po[size-WC_AES_BLOCK_SIZE]),
5864
                        WC_AES_BLOCK_SIZE);
5865
            } else {
5866
                XMEMCPY((void*)aes->reg, (void*)aes->tmp, WC_AES_BLOCK_SIZE);
5867
            }
5868
5869
            pi += size;
5870
            po += size;
5871
        }
5872
5873
        wc_UnLockMutex(&Mutex_AesSEC);
5874
        return 0;
5875
    }
5876
5877
    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
5878
    {
5879
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
5880
    }
5881
5882
    #ifdef HAVE_AES_DECRYPT
5883
    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
5884
    {
5885
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
5886
    }
5887
    #endif /* HAVE_AES_DECRYPT */
5888
5889
#elif defined(FREESCALE_LTC)
5890
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5891
    {
5892
        word32 keySize;
5893
        status_t status;
5894
        byte *iv, *enc_key;
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
        enc_key = (byte*)aes->key;
5907
5908
        status = wc_AesGetKeySize(aes, &keySize);
5909
        if (status != 0) {
5910
            return status;
5911
        }
5912
5913
        status = wolfSSL_CryptHwMutexLock();
5914
        if (status != 0)
5915
            return status;
5916
        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
5917
            iv, enc_key, keySize);
5918
        wolfSSL_CryptHwMutexUnLock();
5919
5920
        /* store iv for next call */
5921
        if (status == kStatus_Success) {
5922
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5923
        }
5924
5925
        return (status == kStatus_Success) ? 0 : -1;
5926
    }
5927
5928
    #ifdef HAVE_AES_DECRYPT
5929
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5930
    {
5931
        word32 keySize;
5932
        status_t status;
5933
        byte* iv, *dec_key;
5934
        byte temp_block[WC_AES_BLOCK_SIZE];
5935
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5936
5937
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5938
        if (sz % WC_AES_BLOCK_SIZE) {
5939
            return BAD_LENGTH_E;
5940
        }
5941
#endif
5942
        if (blocks == 0)
5943
            return 0;
5944
5945
        iv      = (byte*)aes->reg;
5946
        dec_key = (byte*)aes->key;
5947
5948
        status = wc_AesGetKeySize(aes, &keySize);
5949
        if (status != 0) {
5950
            return status;
5951
        }
5952
5953
        /* get IV for next call */
5954
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5955
5956
        status = wolfSSL_CryptHwMutexLock();
5957
        if (status != 0)
5958
            return status;
5959
        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
5960
            iv, dec_key, keySize, kLTC_EncryptKey);
5961
        wolfSSL_CryptHwMutexUnLock();
5962
5963
        /* store IV for next call */
5964
        if (status == kStatus_Success) {
5965
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
5966
        }
5967
5968
        return (status == kStatus_Success) ? 0 : -1;
5969
    }
5970
    #endif /* HAVE_AES_DECRYPT */
5971
5972
#elif defined(FREESCALE_MMCAU) && !defined(WOLFSSL_ARMASM)
5973
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5974
    {
5975
        int offset = 0;
5976
        byte *iv;
5977
        byte temp_block[WC_AES_BLOCK_SIZE];
5978
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5979
        int ret;
5980
5981
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5982
        if (sz % WC_AES_BLOCK_SIZE) {
5983
            return BAD_LENGTH_E;
5984
        }
5985
#endif
5986
        if (blocks == 0)
5987
            return 0;
5988
5989
        iv = (byte*)aes->reg;
5990
5991
        while (blocks--) {
5992
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
5993
5994
            /* XOR block with IV for CBC */
5995
            xorbuf(temp_block, iv, WC_AES_BLOCK_SIZE);
5996
5997
            ret = wc_AesEncrypt(aes, temp_block, out + offset);
5998
            if (ret != 0)
5999
                return ret;
6000
6001
            offset += WC_AES_BLOCK_SIZE;
6002
6003
            /* store IV for next block */
6004
            XMEMCPY(iv, out + offset - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6005
        }
6006
6007
        return 0;
6008
    }
6009
    #ifdef HAVE_AES_DECRYPT
6010
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6011
    {
6012
        int ret;
6013
        int offset = 0;
6014
        byte* iv;
6015
        byte temp_block[WC_AES_BLOCK_SIZE];
6016
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6017
6018
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6019
        if (sz % WC_AES_BLOCK_SIZE) {
6020
            return BAD_LENGTH_E;
6021
        }
6022
#endif
6023
        if (blocks == 0)
6024
            return 0;
6025
6026
        iv = (byte*)aes->reg;
6027
6028
        while (blocks--) {
6029
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
6030
6031
            ret = wc_AesDecrypt(aes, in + offset, out + offset);
6032
            if (ret != 0)
6033
                return ret;
6034
6035
            /* XOR block with IV for CBC */
6036
            xorbuf(out + offset, iv, WC_AES_BLOCK_SIZE);
6037
6038
            /* store IV for next block */
6039
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6040
6041
            offset += WC_AES_BLOCK_SIZE;
6042
        }
6043
6044
        return 0;
6045
    }
6046
    #endif /* HAVE_AES_DECRYPT */
6047
6048
#elif defined(MAX3266X_AES)
6049
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6050
    {
6051
        word32 keySize;
6052
        int status;
6053
        byte *iv;
6054
6055
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
6056
            return BAD_FUNC_ARG;
6057
        }
6058
6059
        /* Always enforce a length check */
6060
        if (sz % WC_AES_BLOCK_SIZE) {
6061
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6062
            return BAD_LENGTH_E;
6063
        #else
6064
            return BAD_FUNC_ARG;
6065
        #endif
6066
        }
6067
        if (sz == 0) {
6068
            return 0;
6069
        }
6070
6071
        iv = (byte*)aes->reg;
6072
        status = wc_AesGetKeySize(aes, &keySize);
6073
        if (status != 0) {
6074
            return status;
6075
        }
6076
6077
        status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
6078
                                        MXC_TPU_MODE_CBC, sz, out,
6079
                                        (unsigned int)keySize);
6080
        /* store iv for next call */
6081
        if (status == 0) {
6082
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6083
        }
6084
        return (status == 0) ? 0 : -1;
6085
    }
6086
6087
    #ifdef HAVE_AES_DECRYPT
6088
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6089
    {
6090
        word32 keySize;
6091
        int status;
6092
        byte *iv;
6093
        byte temp_block[WC_AES_BLOCK_SIZE];
6094
6095
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
6096
            return BAD_FUNC_ARG;
6097
        }
6098
6099
        /* Always enforce a length check */
6100
        if (sz % WC_AES_BLOCK_SIZE) {
6101
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6102
            return BAD_LENGTH_E;
6103
        #else
6104
            return BAD_FUNC_ARG;
6105
        #endif
6106
        }
6107
        if (sz == 0) {
6108
            return 0;
6109
        }
6110
6111
        iv = (byte*)aes->reg;
6112
        status = wc_AesGetKeySize(aes, &keySize);
6113
        if (status != 0) {
6114
            return status;
6115
        }
6116
6117
        /* get IV for next call */
6118
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6119
        status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
6120
                                        MXC_TPU_MODE_CBC, sz, out,
6121
                                        keySize);
6122
6123
        /* store iv for next call */
6124
        if (status == 0) {
6125
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6126
        }
6127
        return (status == 0) ? 0 : -1;
6128
    }
6129
    #endif /* HAVE_AES_DECRYPT */
6130
6131
6132
6133
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
6134
6135
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6136
    {
6137
        int ret;
6138
6139
        if (sz == 0)
6140
            return 0;
6141
6142
        /* hardware fails on input that is not a multiple of AES block size */
6143
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6144
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6145
            return BAD_LENGTH_E;
6146
#else
6147
            return BAD_FUNC_ARG;
6148
#endif
6149
        }
6150
6151
        ret = wc_Pic32AesCrypt(
6152
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6153
            out, in, sz, PIC32_ENCRYPTION,
6154
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6155
6156
        /* store iv for next call */
6157
        if (ret == 0) {
6158
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6159
        }
6160
6161
        return ret;
6162
    }
6163
    #ifdef HAVE_AES_DECRYPT
6164
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6165
    {
6166
        int ret;
6167
        byte scratch[WC_AES_BLOCK_SIZE];
6168
6169
        if (sz == 0)
6170
            return 0;
6171
6172
        /* hardware fails on input that is not a multiple of AES block size */
6173
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6174
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6175
            return BAD_LENGTH_E;
6176
#else
6177
            return BAD_FUNC_ARG;
6178
#endif
6179
        }
6180
        XMEMCPY(scratch, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6181
6182
        ret = wc_Pic32AesCrypt(
6183
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6184
            out, in, sz, PIC32_DECRYPTION,
6185
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6186
6187
        /* store iv for next call */
6188
        if (ret == 0) {
6189
            XMEMCPY((byte*)aes->reg, scratch, WC_AES_BLOCK_SIZE);
6190
        }
6191
6192
        return ret;
6193
    }
6194
    #endif /* HAVE_AES_DECRYPT */
6195
#elif defined(WOLFSSL_ESP32_CRYPT) && \
6196
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6197
6198
    /* We'll use SW for fall back:
6199
     *   unsupported key lengths
6200
     *   hardware busy */
6201
    #define NEED_SW_AESCBC
6202
    #define NEED_AESCBC_HW_FALLBACK
6203
6204
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
6205
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6206
    {
6207
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6208
    }
6209
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6210
    {
6211
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6212
    }
6213
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6214
        !defined(WOLFSSL_QNX_CAAM)
6215
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6216
6217
#elif defined(WOLFSSL_AFALG)
6218
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6219
6220
#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
6221
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
6222
6223
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
6224
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6225
6226
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
6227
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
6228
6229
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6230
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
6231
6232
#elif defined(WOLFSSL_PSOC6_CRYPTO)
6233
6234
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6235
    {
6236
        return wc_Psoc6_Aes_CbcEncrypt(aes, out, in, sz);
6237
    }
6238
6239
    #if defined(HAVE_AES_DECRYPT)
6240
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6241
    {
6242
        return wc_Psoc6_Aes_CbcDecrypt(aes, out, in, sz);
6243
    }
6244
    #endif /* HAVE_AES_DECRYPT */
6245
6246
#else
6247
    /* Reminder: Some HW implementations may also define this as needed.
6248
     * (e.g. for unsupported key length fallback)  */
6249
    #define NEED_SW_AESCBC
6250
#endif
6251
6252
#ifdef NEED_SW_AESCBC
6253
    /* Software AES - CBC Encrypt */
6254
6255
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6256
528
    {
6257
528
#if !defined(WOLFSSL_ARMASM)
6258
528
        word32 blocks;
6259
528
        int ret;
6260
528
#endif
6261
6262
528
        if (aes == NULL || out == NULL || in == NULL) {
6263
0
            return BAD_FUNC_ARG;
6264
0
        }
6265
6266
528
        if (sz == 0) {
6267
0
            return 0;
6268
0
        }
6269
6270
528
#if !defined(WOLFSSL_ARMASM)
6271
528
        blocks = sz / WC_AES_BLOCK_SIZE;
6272
528
#endif
6273
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6274
        if (sz % WC_AES_BLOCK_SIZE) {
6275
            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
6276
            return BAD_LENGTH_E;
6277
        }
6278
#endif
6279
6280
    #ifdef WOLFSSL_IMXRT_DCP
6281
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
6282
        if (aes->keylen == 16)
6283
            return DCPAesCbcEncrypt(aes, out, in, sz);
6284
    #endif
6285
6286
528
    #ifdef WOLF_CRYPTO_CB
6287
528
        #ifndef WOLF_CRYPTO_CB_FIND
6288
528
        if (aes->devId != INVALID_DEVID)
6289
0
        #endif
6290
0
        {
6291
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6292
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6293
0
                return crypto_cb_ret;
6294
            /* fall-through when unavailable */
6295
0
        }
6296
528
    #endif
6297
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
6298
        /* if async and byte count above threshold */
6299
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
6300
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
6301
        #if defined(HAVE_CAVIUM)
6302
            return NitroxAesCbcEncrypt(aes, out, in, sz);
6303
        #elif defined(HAVE_INTEL_QA)
6304
            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
6305
                (const byte*)aes->devKey, aes->keylen,
6306
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6307
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
6308
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
6309
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
6310
                sw->aes.aes = aes;
6311
                sw->aes.out = out;
6312
                sw->aes.in = in;
6313
                sw->aes.sz = sz;
6314
                return WC_PENDING_E;
6315
            }
6316
        #endif
6317
        }
6318
    #endif /* WOLFSSL_ASYNC_CRYPT */
6319
6320
#if defined(WOLFSSL_ARMASM)
6321
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
6322
    #if !defined(__aarch64__)
6323
        AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
6324
            (int)aes->rounds);
6325
    #else
6326
        if (aes->use_aes_hw_crypto) {
6327
            AES_CBC_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
6328
                (byte*)aes->key, (int)aes->rounds);
6329
        }
6330
        else
6331
    #endif /* __aarch64__ */
6332
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
6333
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
6334
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
6335
        {
6336
            AES_CBC_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
6337
                aes->rounds, (unsigned char*)aes->reg);
6338
        }
6339
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6340
        {
6341
            AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
6342
                aes->rounds, (unsigned char*)aes->reg);
6343
        }
6344
    #endif
6345
        return 0;
6346
#else
6347
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
6348
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
6349
        if (aes->useSWCrypt == 0) {
6350
            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
6351
                                   kAlgorithm_SSS_AES_CBC);
6352
        }
6353
        else
6354
    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
6355
        if (wc_esp32AesSupportedKeyLen(aes)) {
6356
            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
6357
            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
6358
        }
6359
        else {
6360
            /* For example, the ESP32-S3 does not support HW for len = 24,
6361
             * so fall back to SW */
6362
        #ifdef DEBUG_WOLFSSL
6363
            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
6364
                          "unsupported keylen = %d", aes->keylen);
6365
        #endif
6366
        }
6367
    #elif defined(WOLFSSL_AESNI)
6368
        VECTOR_REGISTERS_PUSH;
6369
        if (aes->use_aesni) {
6370
            #ifdef DEBUG_AESNI
6371
                printf("about to aes cbc encrypt\n");
6372
                printf("in  = %p\n", in);
6373
                printf("out = %p\n", out);
6374
                printf("aes->key = %p\n", aes->key);
6375
                printf("aes->reg = %p\n", aes->reg);
6376
                printf("aes->rounds = %d\n", aes->rounds);
6377
                printf("sz = %d\n", sz);
6378
            #endif
6379
6380
            /* check alignment, decrypt doesn't need alignment */
6381
            if ((wc_ptr_t)in % AESNI_ALIGN) {
6382
            #ifndef NO_WOLFSSL_ALLOC_ALIGN
6383
                byte* tmp = (byte*)XMALLOC(sz + WC_AES_BLOCK_SIZE + AESNI_ALIGN,
6384
                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
6385
                byte* tmp_align;
6386
                if (tmp == NULL)
6387
                    ret = MEMORY_E;
6388
                else {
6389
                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
6390
                    XMEMCPY(tmp_align, in, sz);
6391
                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
6392
                                          (byte*)aes->key, (int)aes->rounds);
6393
                    /* store iv for next call */
6394
                    XMEMCPY(aes->reg, tmp_align + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6395
6396
                    XMEMCPY(out, tmp_align, sz);
6397
                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
6398
                    ret = 0;
6399
                }
6400
            #else
6401
                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
6402
                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
6403
                ret = BAD_ALIGN_E;
6404
            #endif
6405
            } else {
6406
                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6407
                                      (int)aes->rounds);
6408
                /* store iv for next call */
6409
                XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6410
6411
                ret = 0;
6412
            }
6413
        }
6414
        else
6415
    #endif
6416
528
        {
6417
528
            ret = 0;
6418
4.18k
            while (blocks--) {
6419
3.65k
                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
6420
3.65k
                ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
6421
3.65k
                if (ret != 0)
6422
0
                    break;
6423
3.65k
                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
6424
6425
3.65k
                out += WC_AES_BLOCK_SIZE;
6426
3.65k
                in  += WC_AES_BLOCK_SIZE;
6427
3.65k
            }
6428
528
        }
6429
6430
    #ifdef WOLFSSL_AESNI
6431
        VECTOR_REGISTERS_POP;
6432
    #endif
6433
6434
528
        return ret;
6435
528
#endif
6436
528
    } /* wc_AesCbcEncrypt */
6437
6438
#ifdef HAVE_AES_DECRYPT
6439
    /* Software AES - CBC Decrypt */
6440
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6441
373
    {
6442
373
#if !defined(WOLFSSL_ARMASM)
6443
373
        word32 blocks;
6444
373
        int ret;
6445
373
#endif
6446
6447
373
        if (aes == NULL || out == NULL || in == NULL) {
6448
0
            return BAD_FUNC_ARG;
6449
0
        }
6450
6451
373
        if (sz == 0) {
6452
0
            return 0;
6453
0
        }
6454
6455
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
6456
        if (wc_esp32AesSupportedKeyLen(aes)) {
6457
            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
6458
            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
6459
        }
6460
        else {
6461
            /* For example, the ESP32-S3 does not support HW for len = 24,
6462
             * so fall back to SW */
6463
        #ifdef DEBUG_WOLFSSL
6464
            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
6465
                          "unsupported keylen = %d", aes->keylen);
6466
        #endif
6467
        }
6468
    #endif
6469
6470
373
#if !defined(WOLFSSL_ARMASM)
6471
373
        blocks = sz / WC_AES_BLOCK_SIZE;
6472
373
#endif
6473
373
        if (sz % WC_AES_BLOCK_SIZE) {
6474
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6475
            return BAD_LENGTH_E;
6476
#else
6477
0
            return BAD_FUNC_ARG;
6478
0
#endif
6479
0
        }
6480
6481
    #ifdef WOLFSSL_IMXRT_DCP
6482
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
6483
        if (aes->keylen == 16)
6484
            return DCPAesCbcDecrypt(aes, out, in, sz);
6485
    #endif
6486
6487
373
    #ifdef WOLF_CRYPTO_CB
6488
373
        #ifndef WOLF_CRYPTO_CB_FIND
6489
373
        if (aes->devId != INVALID_DEVID)
6490
0
        #endif
6491
0
        {
6492
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6493
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6494
0
                return crypto_cb_ret;
6495
            /* fall-through when unavailable */
6496
0
        }
6497
373
    #endif
6498
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
6499
        /* if async and byte count above threshold */
6500
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
6501
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
6502
        #if defined(HAVE_CAVIUM)
6503
            return NitroxAesCbcDecrypt(aes, out, in, sz);
6504
        #elif defined(HAVE_INTEL_QA)
6505
            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
6506
                (const byte*)aes->devKey, aes->keylen,
6507
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6508
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
6509
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
6510
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
6511
                sw->aes.aes = aes;
6512
                sw->aes.out = out;
6513
                sw->aes.in = in;
6514
                sw->aes.sz = sz;
6515
                return WC_PENDING_E;
6516
            }
6517
        #endif
6518
        }
6519
    #endif
6520
6521
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
6522
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
6523
        if (aes->useSWCrypt == 0) {
6524
            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
6525
                                   kAlgorithm_SSS_AES_CBC);
6526
        }
6527
    #endif
6528
6529
#if defined(WOLFSSL_ARMASM)
6530
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
6531
    #if !defined(__aarch64__)
6532
        AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
6533
            (int)aes->rounds);
6534
    #else
6535
        if (aes->use_aes_hw_crypto) {
6536
            AES_CBC_decrypt_AARCH64(in, out, sz, (byte*)aes->reg,
6537
                (byte*)aes->key, (int)aes->rounds);
6538
        }
6539
        else
6540
    #endif /* !__aarch64__ */
6541
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
6542
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
6543
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
6544
        if (sz >= 64)
6545
    #endif
6546
        {
6547
            AES_CBC_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
6548
                aes->rounds, (unsigned char*)aes->reg);
6549
        }
6550
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
6551
        else
6552
    #endif
6553
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
6554
    #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6555
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
6556
        {
6557
            AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
6558
                aes->rounds, (unsigned char*)aes->reg);
6559
        }
6560
    #endif
6561
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
6562
        return 0;
6563
#else
6564
373
        VECTOR_REGISTERS_PUSH;
6565
6566
    #ifdef WOLFSSL_AESNI
6567
        if (aes->use_aesni) {
6568
            #ifdef DEBUG_AESNI
6569
                printf("about to aes cbc decrypt\n");
6570
                printf("in  = %p\n", in);
6571
                printf("out = %p\n", out);
6572
                printf("aes->key = %p\n", aes->key);
6573
                printf("aes->reg = %p\n", aes->reg);
6574
                printf("aes->rounds = %d\n", aes->rounds);
6575
                printf("sz = %d\n", sz);
6576
            #endif
6577
6578
            /* if input and output same will overwrite input iv */
6579
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6580
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
6581
            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6582
                            aes->rounds);
6583
            #elif defined(WOLFSSL_AESNI_BY6)
6584
            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6585
                            aes->rounds);
6586
            #else /* WOLFSSL_AESNI_BYx */
6587
            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6588
                            (int)aes->rounds);
6589
            #endif /* WOLFSSL_AESNI_BYx */
6590
            /* store iv for next call */
6591
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6592
            ret = 0;
6593
        }
6594
        else
6595
    #endif
6596
373
        {
6597
373
            ret = 0;
6598
#ifdef WC_AES_BITSLICED
6599
            if (in != out) {
6600
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
6601
6602
                while (blocks > BS_WORD_SIZE) {
6603
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
6604
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6605
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
6606
                              WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
6607
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
6608
                            WC_AES_BLOCK_SIZE);
6609
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6610
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6611
                    blocks -= BS_WORD_SIZE;
6612
                }
6613
                if (blocks > 0) {
6614
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
6615
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6616
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
6617
                              WC_AES_BLOCK_SIZE * (blocks - 1));
6618
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (blocks - 1)),
6619
                            WC_AES_BLOCK_SIZE);
6620
                    blocks = 0;
6621
                }
6622
            }
6623
            else {
6624
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
6625
                int i;
6626
6627
                while (blocks > BS_WORD_SIZE) {
6628
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
6629
                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * WC_AES_BLOCK_SIZE,
6630
                            WC_AES_BLOCK_SIZE);
6631
                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
6632
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
6633
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
6634
                                  WC_AES_BLOCK_SIZE);
6635
                    }
6636
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6637
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6638
6639
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6640
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6641
                    blocks -= BS_WORD_SIZE;
6642
                }
6643
                if (blocks > 0) {
6644
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
6645
                    XMEMCPY(aes->tmp, in + (blocks - 1) * WC_AES_BLOCK_SIZE,
6646
                            WC_AES_BLOCK_SIZE);
6647
                    for (i = blocks-1; i >= 1; i--) {
6648
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
6649
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
6650
                                  WC_AES_BLOCK_SIZE);
6651
                    }
6652
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6653
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6654
6655
                    blocks = 0;
6656
                }
6657
            }
6658
#else
6659
9.04k
            while (blocks--) {
6660
8.67k
                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
6661
8.67k
                ret = wc_AesDecrypt(aes, in, out);
6662
8.67k
                if (ret != 0)
6663
0
                    return ret;
6664
8.67k
                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6665
                /* store iv for next call */
6666
8.67k
                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6667
6668
8.67k
                out += WC_AES_BLOCK_SIZE;
6669
8.67k
                in  += WC_AES_BLOCK_SIZE;
6670
8.67k
            }
6671
373
#endif
6672
373
        }
6673
6674
373
        VECTOR_REGISTERS_POP;
6675
6676
373
        return ret;
6677
373
#endif
6678
373
    }
6679
#endif /* HAVE_AES_DECRYPT */
6680
6681
#endif /* AES-CBC block */
6682
#endif /* HAVE_AES_CBC */
6683
6684
/* AES-CTR */
6685
#if defined(WOLFSSL_AES_COUNTER)
6686
6687
    #ifdef STM32_CRYPTO
6688
        #define NEED_AES_CTR_SOFT
6689
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
6690
6691
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
6692
        {
6693
            int ret = 0;
6694
        #ifdef WOLFSSL_STM32_CUBEMX
6695
            CRYP_HandleTypeDef hcryp;
6696
            #ifdef STM32_HAL_V2
6697
            word32 iv[WC_AES_BLOCK_SIZE/sizeof(word32)];
6698
            #endif
6699
        #else
6700
            word32 *iv;
6701
            CRYP_InitTypeDef cryptInit;
6702
            CRYP_KeyInitTypeDef keyInit;
6703
            CRYP_IVInitTypeDef ivInit;
6704
        #endif
6705
6706
        #ifdef WOLFSSL_STM32_CUBEMX
6707
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6708
            if (ret != 0) {
6709
                return ret;
6710
            }
6711
6712
            ret = wolfSSL_CryptHwMutexLock();
6713
            if (ret != 0) {
6714
                return ret;
6715
            }
6716
6717
        #if defined(STM32_HAL_V2)
6718
            hcryp.Init.Algorithm  = CRYP_AES_CTR;
6719
            ByteReverseWords(iv, aes->reg, WC_AES_BLOCK_SIZE);
6720
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
6721
        #elif defined(STM32_CRYPTO_AES_ONLY)
6722
            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
6723
            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
6724
            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6725
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6726
        #else
6727
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6728
        #endif
6729
            HAL_CRYP_Init(&hcryp);
6730
6731
        #if defined(STM32_HAL_V2)
6732
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, WC_AES_BLOCK_SIZE,
6733
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6734
        #elif defined(STM32_CRYPTO_AES_ONLY)
6735
            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
6736
                out, STM32_HAL_TIMEOUT);
6737
        #else
6738
            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
6739
                out, STM32_HAL_TIMEOUT);
6740
        #endif
6741
            if (ret != HAL_OK) {
6742
                ret = WC_TIMEOUT_E;
6743
            }
6744
            HAL_CRYP_DeInit(&hcryp);
6745
6746
        #else /* Standard Peripheral Library */
6747
            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6748
            if (ret != 0) {
6749
                return ret;
6750
            }
6751
6752
            ret = wolfSSL_CryptHwMutexLock();
6753
            if (ret != 0) {
6754
                return ret;
6755
            }
6756
6757
            /* reset registers to their default values */
6758
            CRYP_DeInit();
6759
6760
            /* set key */
6761
            CRYP_KeyInit(&keyInit);
6762
6763
            /* set iv */
6764
            iv = aes->reg;
6765
            CRYP_IVStructInit(&ivInit);
6766
            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
6767
            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
6768
            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
6769
            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
6770
            CRYP_IVInit(&ivInit);
6771
6772
            /* set direction and mode */
6773
            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
6774
            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
6775
            CRYP_Init(&cryptInit);
6776
6777
            /* enable crypto processor */
6778
            CRYP_Cmd(ENABLE);
6779
6780
            /* flush IN/OUT FIFOs */
6781
            CRYP_FIFOFlush();
6782
6783
            CRYP_DataIn(*(uint32_t*)&in[0]);
6784
            CRYP_DataIn(*(uint32_t*)&in[4]);
6785
            CRYP_DataIn(*(uint32_t*)&in[8]);
6786
            CRYP_DataIn(*(uint32_t*)&in[12]);
6787
6788
            /* wait until the complete message has been processed */
6789
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6790
6791
            *(uint32_t*)&out[0]  = CRYP_DataOut();
6792
            *(uint32_t*)&out[4]  = CRYP_DataOut();
6793
            *(uint32_t*)&out[8]  = CRYP_DataOut();
6794
            *(uint32_t*)&out[12] = CRYP_DataOut();
6795
6796
            /* disable crypto processor */
6797
            CRYP_Cmd(DISABLE);
6798
        #endif /* WOLFSSL_STM32_CUBEMX */
6799
6800
            wolfSSL_CryptHwMutexUnLock();
6801
            wc_Stm32_Aes_Cleanup();
6802
            return ret;
6803
        }
6804
6805
6806
    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
6807
6808
        #define NEED_AES_CTR_SOFT
6809
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
6810
6811
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
6812
        {
6813
            word32 tmpIv[WC_AES_BLOCK_SIZE / sizeof(word32)];
6814
            XMEMCPY(tmpIv, aes->reg, WC_AES_BLOCK_SIZE);
6815
            return wc_Pic32AesCrypt(
6816
                aes->key, aes->keylen, tmpIv, WC_AES_BLOCK_SIZE,
6817
                out, in, WC_AES_BLOCK_SIZE,
6818
                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
6819
        }
6820
6821
    #elif defined(HAVE_COLDFIRE_SEC)
6822
        #error "Coldfire SEC doesn't currently support AES-CTR mode"
6823
6824
    #elif defined(FREESCALE_LTC)
6825
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6826
        {
6827
            int ret = 0;
6828
            word32 keySize;
6829
            byte *iv, *enc_key;
6830
            byte* tmp;
6831
6832
            if (aes == NULL || out == NULL || in == NULL) {
6833
                return BAD_FUNC_ARG;
6834
            }
6835
6836
            /* consume any unused bytes left in aes->tmp */
6837
            tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
6838
            while (aes->left && sz) {
6839
                *(out++) = *(in++) ^ *(tmp++);
6840
                aes->left--;
6841
                sz--;
6842
            }
6843
6844
            if (sz) {
6845
                iv      = (byte*)aes->reg;
6846
                enc_key = (byte*)aes->key;
6847
6848
                ret = wc_AesGetKeySize(aes, &keySize);
6849
                if (ret != 0)
6850
                    return ret;
6851
6852
                ret = wolfSSL_CryptHwMutexLock();
6853
                if (ret != 0)
6854
                    return ret;
6855
                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
6856
                    iv, enc_key, keySize, (byte*)aes->tmp,
6857
                    (uint32_t*)&aes->left);
6858
                wolfSSL_CryptHwMutexUnLock();
6859
            }
6860
6861
            return ret;
6862
        }
6863
6864
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6865
        !defined(WOLFSSL_QNX_CAAM)
6866
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6867
6868
    #elif defined(WOLFSSL_AFALG)
6869
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6870
6871
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
6872
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6873
6874
    #elif defined(WOLFSSL_ESP32_CRYPT) && \
6875
        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6876
        /* esp32 doesn't support CRT mode by hw.     */
6877
        /* use aes ecnryption plus sw implementation */
6878
        #define NEED_AES_CTR_SOFT
6879
6880
    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6881
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
6882
    #else
6883
6884
        /* Use software based AES counter */
6885
        #define NEED_AES_CTR_SOFT
6886
    #endif
6887
6888
    #ifdef NEED_AES_CTR_SOFT
6889
        #ifndef WOLFSSL_ARMASM
6890
        /* Increment AES counter */
6891
        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
6892
2.19k
        {
6893
            /* in network byte order so start at end and work back */
6894
2.19k
            int i;
6895
2.93k
            for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
6896
2.93k
                if (++inOutCtr[i])  /* we're done unless we overflow */
6897
2.19k
                    return;
6898
2.93k
            }
6899
2.19k
        }
6900
        #endif
6901
6902
        /* Software AES - CTR Encrypt */
6903
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6904
685
        {
6905
685
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6906
685
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
6907
685
            byte scratch[WC_AES_BLOCK_SIZE];
6908
685
    #endif
6909
685
    #if !defined(WOLFSSL_ARMASM)
6910
685
            int ret = 0;
6911
685
    #endif
6912
685
            word32 processed;
6913
6914
685
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6915
685
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
6916
685
            XMEMSET(scratch, 0, sizeof(scratch));
6917
685
    #endif
6918
6919
685
            if (aes == NULL || out == NULL || in == NULL) {
6920
0
                return BAD_FUNC_ARG;
6921
0
            }
6922
6923
685
        #ifdef WOLF_CRYPTO_CB
6924
685
            #ifndef WOLF_CRYPTO_CB_FIND
6925
685
            if (aes->devId != INVALID_DEVID)
6926
0
            #endif
6927
0
            {
6928
0
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
6929
0
                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6930
0
                    return crypto_cb_ret;
6931
                /* fall-through when unavailable */
6932
0
            }
6933
685
        #endif
6934
6935
            /* consume any unused bytes left in aes->tmp */
6936
685
            processed = min(aes->left, sz);
6937
685
            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
6938
685
                      processed);
6939
685
            out += processed;
6940
685
            in += processed;
6941
685
            aes->left -= processed;
6942
685
            sz -= processed;
6943
6944
    #if defined(WOLFSSL_ARMASM)
6945
        #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
6946
            #ifndef __aarch64__
6947
            AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
6948
                (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
6949
            #else
6950
            if (aes->use_aes_hw_crypto) {
6951
                AES_CTR_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
6952
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
6953
                return 0;
6954
            }
6955
            else
6956
            #endif /* !__aarch64__ */
6957
        #endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
6958
        #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6959
            {
6960
                word32 numBlocks;
6961
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
6962
                /* consume any unused bytes left in aes->tmp */
6963
                while ((aes->left != 0) && (sz != 0)) {
6964
                   *(out++) = *(in++) ^ *(tmp++);
6965
                   aes->left--;
6966
                   sz--;
6967
                }
6968
6969
                /* do as many block size ops as possible */
6970
                numBlocks = sz / WC_AES_BLOCK_SIZE;
6971
                if (numBlocks > 0) {
6972
                #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
6973
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
6974
                    if (sz >= 32)
6975
                #endif
6976
                    {
6977
                        AES_CTR_encrypt_NEON(in, out,
6978
                            numBlocks * WC_AES_BLOCK_SIZE, (byte*)aes->key,
6979
                            aes->rounds, (byte*)aes->reg);
6980
                    }
6981
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
6982
                    else
6983
                #endif
6984
                #endif
6985
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
6986
                    {
6987
                        AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
6988
                            (byte*)aes->key, aes->rounds, (byte*)aes->reg);
6989
                    }
6990
                #endif
6991
6992
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
6993
                    out += numBlocks * WC_AES_BLOCK_SIZE;
6994
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
6995
                }
6996
6997
                /* handle non block size remaining */
6998
                if (sz) {
6999
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
7000
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
7001
7002
                #if defined(__aarch64__) && \
7003
                    !defined(WOLFSSL_ARMASM_NO_NEON) && \
7004
                    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7005
                    {
7006
                        AES_CTR_encrypt_NEON(zeros, (byte*)aes->tmp,
7007
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7008
                            (byte*)aes->reg);
7009
                    }
7010
                #else
7011
                    {
7012
                        AES_CTR_encrypt(zeros, (byte*)aes->tmp,
7013
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7014
                            (byte*)aes->reg);
7015
                    }
7016
                #endif
7017
7018
                    aes->left = WC_AES_BLOCK_SIZE;
7019
                    tmp = (byte*)aes->tmp;
7020
7021
                    while (sz--) {
7022
                        *(out++) = *(in++) ^ *(tmp++);
7023
                        aes->left--;
7024
                    }
7025
                }
7026
            }
7027
        #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
7028
            return 0;
7029
    #else
7030
685
            VECTOR_REGISTERS_PUSH;
7031
7032
685
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
7033
685
            !defined(XTRANSFORM_AESCTRBLOCK)
7034
685
            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
7035
304
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
7036
304
                byte* counter = (byte*)aes->reg;
7037
304
                byte* c = out;
7038
1.75k
                while (blocks--) {
7039
1.44k
                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
7040
1.44k
                    c += WC_AES_BLOCK_SIZE;
7041
1.44k
                    IncrementAesCounter(counter);
7042
1.44k
                }
7043
7044
                /* reset number of blocks and then do encryption */
7045
304
                blocks = sz / WC_AES_BLOCK_SIZE;
7046
304
                wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
7047
304
                xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
7048
304
                in += WC_AES_BLOCK_SIZE * blocks;
7049
304
                out += WC_AES_BLOCK_SIZE * blocks;
7050
304
                sz -= blocks * WC_AES_BLOCK_SIZE;
7051
304
            }
7052
381
            else
7053
381
        #endif
7054
381
            {
7055
            #ifdef WOLFSSL_CHECK_MEM_ZERO
7056
                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
7057
                    WC_AES_BLOCK_SIZE);
7058
            #endif
7059
                /* do as many block size ops as possible */
7060
774
                while (sz >= WC_AES_BLOCK_SIZE) {
7061
                #ifdef XTRANSFORM_AESCTRBLOCK
7062
                    XTRANSFORM_AESCTRBLOCK(aes, out, in);
7063
                #else
7064
393
                    ret = wc_AesEncrypt(aes, (byte*)aes->reg, scratch);
7065
393
                    if (ret != 0)
7066
0
                        break;
7067
393
                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
7068
393
                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
7069
393
                #endif
7070
393
                    IncrementAesCounter((byte*)aes->reg);
7071
7072
393
                    out += WC_AES_BLOCK_SIZE;
7073
393
                    in  += WC_AES_BLOCK_SIZE;
7074
393
                    sz  -= WC_AES_BLOCK_SIZE;
7075
393
                    aes->left = 0;
7076
393
                }
7077
381
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
7078
381
            }
7079
7080
            /* handle non block size remaining and store unused byte count in left */
7081
685
            if ((ret == 0) && sz) {
7082
356
                ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
7083
356
                if (ret == 0) {
7084
356
                    IncrementAesCounter((byte*)aes->reg);
7085
356
                    aes->left = WC_AES_BLOCK_SIZE - sz;
7086
356
                    xorbufout(out, in, aes->tmp, sz);
7087
356
                }
7088
356
            }
7089
7090
685
            if (ret < 0)
7091
0
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
7092
7093
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7094
            wc_MemZero_Check(scratch, WC_AES_BLOCK_SIZE);
7095
        #endif
7096
7097
685
            VECTOR_REGISTERS_POP;
7098
7099
685
            return ret;
7100
685
    #endif
7101
685
        }
7102
7103
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
7104
                                        const byte* iv, int dir)
7105
0
        {
7106
0
            if (aes == NULL) {
7107
0
                return BAD_FUNC_ARG;
7108
0
            }
7109
0
            if (len > sizeof(aes->key)) {
7110
0
                return BAD_FUNC_ARG;
7111
0
            }
7112
7113
0
            return wc_AesSetKey(aes, key, len, iv, dir);
7114
0
        }
7115
7116
    #endif /* NEED_AES_CTR_SOFT */
7117
7118
#endif /* WOLFSSL_AES_COUNTER */
7119
#endif /* !WOLFSSL_RISCV_ASM */
7120
7121
7122
/*
7123
 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
7124
 * of two parts in order:
7125
 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
7126
 *      to the implicit IV.
7127
 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
7128
 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
7129
 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
7130
 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
7131
 * block counter during the encryption.
7132
 */
7133
7134
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
7135
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
7136
2.10k
{
7137
2.10k
    int i;
7138
2.51k
    for (i = (int)ctrSz - 1; i >= 0; i--) {
7139
2.51k
        if (++ctr[i])
7140
2.10k
            break;
7141
2.51k
    }
7142
2.10k
}
7143
#endif /* HAVE_AESGCM || HAVE_AESCCM */
7144
7145
7146
#ifdef HAVE_AESGCM
7147
7148
#ifdef WOLFSSL_AESGCM_STREAM
7149
    /* Access initialization counter data. */
7150
3.60k
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
7151
    /* Access counter data. */
7152
8.93k
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
7153
    /* Access tag data. */
7154
22.9k
    #define AES_TAG(aes)            ((aes)->streamData + 2 * WC_AES_BLOCK_SIZE)
7155
    /* Access last GHASH block. */
7156
    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE)
7157
    /* Access last encrypted block. */
7158
9.73k
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
7159
7160
11.4k
    #define GHASH_ONE_BLOCK     GHASH_ONE_BLOCK_SW
7161
#endif
7162
7163
#if defined(HAVE_COLDFIRE_SEC)
7164
    #error "Coldfire SEC doesn't currently support AES-GCM mode"
7165
7166
#endif
7167
7168
#if defined(WOLFSSL_RISCV_ASM)
7169
    /* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
7170
7171
#elif defined(WOLFSSL_AFALG)
7172
    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
7173
7174
#elif defined(WOLFSSL_KCAPI_AES)
7175
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
7176
7177
#elif defined(WOLFSSL_DEVCRYPTO_AES)
7178
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
7179
7180
#else /* software + AESNI implementation */
7181
7182
#if !defined(FREESCALE_LTC_AES_GCM)
7183
#if (!(defined(__aarch64__) && defined(WOLFSSL_ARMASM))) || \
7184
    defined(WOLFSSL_AESGCM_STREAM)
7185
static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
7186
55.2k
{
7187
55.2k
    int i;
7188
7189
    /* in network byte order so start at end and work back */
7190
55.3k
    for (i = WC_AES_BLOCK_SIZE - 1; i >= WC_AES_BLOCK_SIZE - CTR_SZ; i--) {
7191
55.3k
        if (++inOutCtr[i])  /* we're done unless we overflow */
7192
55.2k
            return;
7193
55.3k
    }
7194
55.2k
}
7195
#endif
7196
#endif /* !FREESCALE_LTC_AES_GCM */
7197
7198
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
7199
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7200
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
7201
7202
static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
7203
5.18k
{
7204
    /* Multiply the sz by 8 */
7205
5.18k
    word32 szHi = (sz >> (8*sizeof(sz) - 3));
7206
5.18k
    sz <<= 3;
7207
7208
    /* copy over the words of the sz into the destination buffer */
7209
5.18k
    buf[0] = (byte)(szHi >> 24);
7210
5.18k
    buf[1] = (byte)(szHi >> 16);
7211
5.18k
    buf[2] = (byte)(szHi >>  8);
7212
5.18k
    buf[3] = (byte)szHi;
7213
5.18k
    buf[4] = (byte)(sz >> 24);
7214
5.18k
    buf[5] = (byte)(sz >> 16);
7215
5.18k
    buf[6] = (byte)(sz >>  8);
7216
5.18k
    buf[7] = (byte)sz;
7217
5.18k
}
7218
7219
7220
static WC_INLINE void RIGHTSHIFTX(byte* x)
7221
5.34k
{
7222
5.34k
    int i;
7223
5.34k
    int carryIn = 0;
7224
5.34k
    volatile byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
7225
7226
90.7k
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
7227
85.4k
        int carryOut = (x[i] & 0x01) << 7;
7228
85.4k
        x[i] = (byte) ((x[i] >> 1) | carryIn);
7229
85.4k
        carryIn = carryOut;
7230
85.4k
    }
7231
5.34k
    x[0] ^= borrow;
7232
5.34k
}
7233
7234
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
7235
7236
7237
#ifdef GCM_TABLE
7238
7239
void GenerateM0(Gcm* gcm)
7240
{
7241
    int i, j;
7242
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
7243
7244
    XMEMCPY(m[128], gcm->H, WC_AES_BLOCK_SIZE);
7245
7246
    for (i = 64; i > 0; i /= 2) {
7247
        XMEMCPY(m[i], m[i*2], WC_AES_BLOCK_SIZE);
7248
        RIGHTSHIFTX(m[i]);
7249
    }
7250
7251
    for (i = 2; i < 256; i *= 2) {
7252
        for (j = 1; j < i; j++) {
7253
            XMEMCPY(m[i+j], m[i], WC_AES_BLOCK_SIZE);
7254
            xorbuf(m[i+j], m[j], WC_AES_BLOCK_SIZE);
7255
        }
7256
    }
7257
7258
    XMEMSET(m[0], 0, WC_AES_BLOCK_SIZE);
7259
}
7260
7261
#elif defined(GCM_TABLE_4BIT)
7262
7263
#if !defined(WC_16BIT_CPU)
7264
static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
7265
28.4k
{
7266
28.4k
    int i;
7267
455k
    for (i = 15; i > 0; i--)
7268
427k
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
7269
28.4k
    r8[0] = (byte)(z8[0] >> 4);
7270
28.4k
}
7271
#endif
7272
7273
void GenerateM0(Gcm* gcm)
7274
1.78k
{
7275
1.78k
#if !defined(WC_16BIT_CPU)
7276
1.78k
    int i;
7277
1.78k
#endif
7278
1.78k
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
7279
7280
    /* 0 times -> 0x0 */
7281
1.78k
    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
7282
    /* 1 times -> 0x8 */
7283
1.78k
    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
7284
    /* 2 times -> 0x4 */
7285
1.78k
    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
7286
1.78k
    RIGHTSHIFTX(m[0x4]);
7287
    /* 4 times -> 0x2 */
7288
1.78k
    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
7289
1.78k
    RIGHTSHIFTX(m[0x2]);
7290
    /* 8 times -> 0x1 */
7291
1.78k
    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
7292
1.78k
    RIGHTSHIFTX(m[0x1]);
7293
7294
    /* 0x3 */
7295
1.78k
    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
7296
1.78k
    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
7297
7298
    /* 0x5 -> 0x7 */
7299
1.78k
    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
7300
1.78k
    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
7301
1.78k
    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
7302
1.78k
    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
7303
1.78k
    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
7304
1.78k
    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
7305
7306
    /* 0x9 -> 0xf */
7307
1.78k
    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
7308
1.78k
    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
7309
1.78k
    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
7310
1.78k
    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
7311
1.78k
    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
7312
1.78k
    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
7313
1.78k
    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
7314
1.78k
    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
7315
1.78k
    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
7316
1.78k
    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
7317
1.78k
    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
7318
1.78k
    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
7319
1.78k
    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
7320
1.78k
    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
7321
7322
1.78k
#if !defined(WC_16BIT_CPU)
7323
30.2k
    for (i = 0; i < 16; i++) {
7324
28.4k
        Shift4_M0(m[16+i], m[i]);
7325
28.4k
    }
7326
1.78k
#endif
7327
7328
#if defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7329
    for (i = 0; i < 32; i++) {
7330
    #if !defined(__aarch64__)
7331
        word32* m32 = (word32*)gcm->M0[i];
7332
        m32[0] = ByteReverseWord32(m32[0]);
7333
        m32[1] = ByteReverseWord32(m32[1]);
7334
        m32[2] = ByteReverseWord32(m32[2]);
7335
        m32[3] = ByteReverseWord32(m32[3]);
7336
    #else
7337
        word64* m64 = (word64*)gcm->M0[i];
7338
        m64[0] = ByteReverseWord64(m64[0]);
7339
        m64[1] = ByteReverseWord64(m64[1]);
7340
    #endif
7341
    }
7342
#endif
7343
7344
1.78k
}
7345
7346
#endif /* GCM_TABLE */
7347
#endif
7348
7349
#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
7350
    #define HAVE_INTEL_AVX1
7351
    #define HAVE_INTEL_AVX2
7352
#endif
7353
7354
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \
7355
    defined(WC_C_DYNAMIC_FALLBACK)
7356
void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m)
7357
                           XASM_LINK("GCM_generate_m0_aesni");
7358
#ifdef HAVE_INTEL_AVX1
7359
void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m)
7360
                          XASM_LINK("GCM_generate_m0_avx1");
7361
#endif
7362
#ifdef HAVE_INTEL_AVX2
7363
void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
7364
                          XASM_LINK("GCM_generate_m0_avx2");
7365
#endif
7366
#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */
7367
7368
/* Software AES - GCM SetKey */
7369
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
7370
1.78k
{
7371
1.78k
    int  ret;
7372
1.78k
    byte iv[WC_AES_BLOCK_SIZE];
7373
7374
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
7375
        byte   local[32];
7376
        word32 localSz = 32;
7377
7378
        if (len == (16 + WC_CAAM_BLOB_SZ) ||
7379
          len == (24 + WC_CAAM_BLOB_SZ) ||
7380
          len == (32 + WC_CAAM_BLOB_SZ)) {
7381
            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
7382
                 return BAD_FUNC_ARG;
7383
            }
7384
7385
            /* set local values */
7386
            key = local;
7387
            len = localSz;
7388
        }
7389
    #endif
7390
7391
1.78k
    if (!((len == 16) || (len == 24) || (len == 32)))
7392
0
        return BAD_FUNC_ARG;
7393
7394
1.78k
    if (aes == NULL || key == NULL) {
7395
#ifdef WOLFSSL_IMX6_CAAM_BLOB
7396
        ForceZero(local, sizeof(local));
7397
#endif
7398
0
        return BAD_FUNC_ARG;
7399
0
    }
7400
#ifdef OPENSSL_EXTRA
7401
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
7402
    aes->gcm.aadLen = 0;
7403
#endif
7404
1.78k
    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
7405
1.78k
    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
7406
1.78k
#ifdef WOLFSSL_AESGCM_STREAM
7407
1.78k
    aes->gcmKeySet = 1;
7408
1.78k
#endif
7409
    #if defined(WOLFSSL_SECO_CAAM)
7410
        if (aes->devId == WOLFSSL_SECO_DEVID) {
7411
            return ret;
7412
        }
7413
    #endif /* WOLFSSL_SECO_CAAM */
7414
7415
    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
7416
        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
7417
        return ret;
7418
    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
7419
7420
#if defined(WOLFSSL_ARMASM)
7421
    if (ret == 0) {
7422
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7423
    #if !defined(__aarch64__)
7424
        AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
7425
    #else
7426
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
7427
            AES_GCM_set_key_AARCH64(iv, (byte*)aes->key, aes->gcm.H,
7428
                aes->rounds);
7429
        }
7430
        else
7431
    #endif /* !__aarch64__ */
7432
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7433
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
7434
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7435
        {
7436
            AES_ECB_encrypt_NEON(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
7437
                (const unsigned char*)aes->key, aes->rounds);
7438
        }
7439
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7440
        {
7441
            AES_ECB_encrypt(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
7442
                (const unsigned char*)aes->key, aes->rounds);
7443
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
7444
            GenerateM0(&aes->gcm);
7445
        #endif /* GCM_TABLE */
7446
        }
7447
#endif
7448
    }
7449
#else
7450
1.78k
#if !defined(FREESCALE_LTC_AES_GCM) && !defined(WOLFSSL_PSOC6_CRYPTO)
7451
1.78k
    if (ret == 0) {
7452
1.78k
        VECTOR_REGISTERS_PUSH;
7453
        /* AES-NI code generates its own H value, but generate it here too, to
7454
         * assure pure-C fallback is always usable.
7455
         */
7456
1.78k
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
7457
1.78k
        VECTOR_REGISTERS_POP;
7458
1.78k
    }
7459
1.78k
    if (ret == 0) {
7460
1.78k
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
7461
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT)
7462
        if (aes->use_aesni) {
7463
    #if defined(WC_C_DYNAMIC_FALLBACK)
7464
        #ifdef HAVE_INTEL_AVX2
7465
            if (IS_INTEL_AVX2(intel_flags)) {
7466
                GCM_generate_m0_avx2(aes->gcm.H, (byte*)aes->gcm.M0);
7467
            }
7468
            else
7469
        #endif
7470
        #if defined(HAVE_INTEL_AVX1)
7471
            if (IS_INTEL_AVX1(intel_flags)) {
7472
                GCM_generate_m0_avx1(aes->gcm.H, (byte*)aes->gcm.M0);
7473
            }
7474
            else
7475
        #endif
7476
            {
7477
                GCM_generate_m0_aesni(aes->gcm.H, (byte*)aes->gcm.M0);
7478
            }
7479
    #endif
7480
        }
7481
        else
7482
#endif
7483
1.78k
        {
7484
1.78k
            GenerateM0(&aes->gcm);
7485
1.78k
        }
7486
1.78k
#endif /* GCM_TABLE || GCM_TABLE_4BIT */
7487
1.78k
    }
7488
1.78k
#endif /* !FREESCALE_LTC_AES_GCM && !WOLFSSL_PSOC6_CRYPTO */
7489
1.78k
#endif
7490
7491
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
7492
    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
7493
#endif
7494
7495
1.78k
#ifdef WOLF_CRYPTO_CB
7496
1.78k
    if (aes->devId != INVALID_DEVID) {
7497
0
        XMEMCPY(aes->devKey, key, len);
7498
0
    }
7499
1.78k
#endif
7500
7501
#ifdef WOLFSSL_IMX6_CAAM_BLOB
7502
    ForceZero(local, sizeof(local));
7503
#endif
7504
1.78k
    return ret;
7505
1.78k
}
7506
7507
7508
#ifdef WOLFSSL_AESNI
7509
7510
void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
7511
                     const unsigned char* addt, const unsigned char* ivec,
7512
                     unsigned char *tag, word32 nbytes,
7513
                     word32 abytes, word32 ibytes,
7514
                     word32 tbytes, const unsigned char* key, int nr)
7515
                     XASM_LINK("AES_GCM_encrypt_aesni");
7516
#ifdef HAVE_INTEL_AVX1
7517
void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
7518
                          const unsigned char* addt, const unsigned char* ivec,
7519
                          unsigned char *tag, word32 nbytes,
7520
                          word32 abytes, word32 ibytes,
7521
                          word32 tbytes, const unsigned char* key,
7522
                          int nr)
7523
                          XASM_LINK("AES_GCM_encrypt_avx1");
7524
#ifdef HAVE_INTEL_AVX2
7525
void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
7526
                          const unsigned char* addt, const unsigned char* ivec,
7527
                          unsigned char *tag, word32 nbytes,
7528
                          word32 abytes, word32 ibytes,
7529
                          word32 tbytes, const unsigned char* key,
7530
                          int nr)
7531
                          XASM_LINK("AES_GCM_encrypt_avx2");
7532
#endif /* HAVE_INTEL_AVX2 */
7533
#endif /* HAVE_INTEL_AVX1 */
7534
7535
#ifdef HAVE_AES_DECRYPT
7536
void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
7537
                     const unsigned char* addt, const unsigned char* ivec,
7538
                     const unsigned char *tag, word32 nbytes, word32 abytes,
7539
                     word32 ibytes, word32 tbytes, const unsigned char* key,
7540
                     int nr, int* res)
7541
                     XASM_LINK("AES_GCM_decrypt_aesni");
7542
#ifdef HAVE_INTEL_AVX1
7543
void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
7544
                          const unsigned char* addt, const unsigned char* ivec,
7545
                          const unsigned char *tag, word32 nbytes,
7546
                          word32 abytes, word32 ibytes, word32 tbytes,
7547
                          const unsigned char* key, int nr, int* res)
7548
                          XASM_LINK("AES_GCM_decrypt_avx1");
7549
#ifdef HAVE_INTEL_AVX2
7550
void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
7551
                          const unsigned char* addt, const unsigned char* ivec,
7552
                          const unsigned char *tag, word32 nbytes,
7553
                          word32 abytes, word32 ibytes, word32 tbytes,
7554
                          const unsigned char* key, int nr, int* res)
7555
                          XASM_LINK("AES_GCM_decrypt_avx2");
7556
#endif /* HAVE_INTEL_AVX2 */
7557
#endif /* HAVE_INTEL_AVX1 */
7558
#endif /* HAVE_AES_DECRYPT */
7559
7560
#endif /* WOLFSSL_AESNI */
7561
7562
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
7563
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7564
#if defined(GCM_SMALL)
7565
static void GMULT(byte* X, byte* Y)
7566
{
7567
    byte Z[WC_AES_BLOCK_SIZE];
7568
    byte V[WC_AES_BLOCK_SIZE];
7569
    int i, j;
7570
7571
    XMEMSET(Z, 0, WC_AES_BLOCK_SIZE);
7572
    XMEMCPY(V, X, WC_AES_BLOCK_SIZE);
7573
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++)
7574
    {
7575
        byte y = Y[i];
7576
        for (j = 0; j < 8; j++)
7577
        {
7578
            if (y & 0x80) {
7579
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
7580
            }
7581
7582
            RIGHTSHIFTX(V);
7583
            y = y << 1;
7584
        }
7585
    }
7586
    XMEMCPY(X, Z, WC_AES_BLOCK_SIZE);
7587
}
7588
7589
7590
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7591
    word32 cSz, byte* s, word32 sSz)
7592
{
7593
    byte x[WC_AES_BLOCK_SIZE];
7594
    byte scratch[WC_AES_BLOCK_SIZE];
7595
    word32 blocks, partial;
7596
    byte* h;
7597
7598
    if (gcm == NULL) {
7599
        return;
7600
    }
7601
7602
    h = gcm->H;
7603
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
7604
7605
    /* Hash in A, the Additional Authentication Data */
7606
    if (aSz != 0 && a != NULL) {
7607
        blocks = aSz / WC_AES_BLOCK_SIZE;
7608
        partial = aSz % WC_AES_BLOCK_SIZE;
7609
        while (blocks--) {
7610
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
7611
            GMULT(x, h);
7612
            a += WC_AES_BLOCK_SIZE;
7613
        }
7614
        if (partial != 0) {
7615
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7616
            XMEMCPY(scratch, a, partial);
7617
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7618
            GMULT(x, h);
7619
        }
7620
    }
7621
7622
    /* Hash in C, the Ciphertext */
7623
    if (cSz != 0 && c != NULL) {
7624
        blocks = cSz / WC_AES_BLOCK_SIZE;
7625
        partial = cSz % WC_AES_BLOCK_SIZE;
7626
        while (blocks--) {
7627
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
7628
            GMULT(x, h);
7629
            c += WC_AES_BLOCK_SIZE;
7630
        }
7631
        if (partial != 0) {
7632
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7633
            XMEMCPY(scratch, c, partial);
7634
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7635
            GMULT(x, h);
7636
        }
7637
    }
7638
7639
    /* Hash in the lengths of A and C in bits */
7640
    FlattenSzInBits(&scratch[0], aSz);
7641
    FlattenSzInBits(&scratch[8], cSz);
7642
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7643
    GMULT(x, h);
7644
7645
    /* Copy the result into s. */
7646
    XMEMCPY(s, x, sSz);
7647
}
7648
7649
#ifdef WOLFSSL_AESGCM_STREAM
7650
/* No extra initialization for small implementation.
7651
 *
7652
 * @param [in] aes  AES GCM object.
7653
 */
7654
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7655
7656
/* GHASH one block of data..
7657
 *
7658
 * XOR block into tag and GMULT with H.
7659
 *
7660
 * @param [in, out] aes    AES GCM object.
7661
 * @param [in]      block  Block of AAD or cipher text.
7662
 */
7663
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
7664
    do {                                                \
7665
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
7666
        GMULT(AES_TAG(aes), (aes)->gcm.H);              \
7667
    }                                                   \
7668
    while (0)
7669
#endif /* WOLFSSL_AESGCM_STREAM */
7670
7671
#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) &&  \
7672
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7673
static void GCM_gmult_len_armasm_C(
7674
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
7675
{
7676
    byte Z[AES_BLOCK_SIZE];
7677
    byte V[AES_BLOCK_SIZE];
7678
    int i;
7679
    int j;
7680
7681
    while (len >= AES_BLOCK_SIZE) {
7682
        xorbuf(x, a, AES_BLOCK_SIZE);
7683
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
7684
        XMEMCPY(V, x, AES_BLOCK_SIZE);
7685
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
7686
            byte y = h[i];
7687
            for (j = 0; j < 8; j++) {
7688
                if (y & 0x80) {
7689
                    xorbuf(Z, V, AES_BLOCK_SIZE);
7690
                }
7691
                RIGHTSHIFTX(V);
7692
                y = y << 1;
7693
            }
7694
        }
7695
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
7696
        len -= AES_BLOCK_SIZE;
7697
        a += AES_BLOCK_SIZE;
7698
    }
7699
}
7700
7701
#define GCM_GMULT_LEN(gcm, x, a, len) \
7702
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
7703
#endif /* WOLFSSL_ARMASM && !__aarch64__ && !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7704
7705
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
7706
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7707
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
7708
#define GCM_GMULT_LEN(gcm, x, a, len) \
7709
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
7710
#else
7711
#define GCM_GMULT_LEN(gcm, x, a, len) \
7712
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
7713
#endif
7714
#endif
7715
7716
#elif defined(GCM_TABLE)
7717
7718
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
7719
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7720
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
7721
#define GCM_GMULT_LEN(gcm, x, a, len) \
7722
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
7723
#else
7724
#define GCM_GMULT_LEN(gcm, x, a, len) \
7725
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
7726
#endif
7727
#else
7728
ALIGN16 static const byte R[256][2] = {
7729
    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
7730
    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
7731
    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
7732
    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
7733
    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
7734
    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
7735
    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
7736
    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
7737
    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
7738
    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
7739
    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
7740
    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
7741
    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
7742
    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
7743
    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
7744
    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
7745
    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
7746
    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
7747
    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
7748
    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
7749
    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
7750
    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
7751
    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
7752
    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
7753
    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
7754
    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
7755
    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
7756
    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
7757
    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
7758
    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
7759
    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
7760
    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
7761
    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
7762
    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
7763
    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
7764
    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
7765
    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
7766
    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
7767
    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
7768
    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
7769
    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
7770
    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
7771
    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
7772
    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
7773
    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
7774
    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
7775
    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
7776
    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
7777
    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
7778
    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
7779
    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
7780
    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
7781
    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
7782
    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
7783
    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
7784
    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
7785
    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
7786
    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
7787
    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
7788
    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
7789
    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
7790
    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
7791
    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
7792
    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
7793
7794
7795
static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE])
7796
{
7797
#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
7798
    int i, j;
7799
    byte Z[WC_AES_BLOCK_SIZE];
7800
    byte a;
7801
7802
    XMEMSET(Z, 0, sizeof(Z));
7803
7804
    for (i = 15; i > 0; i--) {
7805
        xorbuf(Z, m[x[i]], WC_AES_BLOCK_SIZE);
7806
        a = Z[15];
7807
7808
        for (j = 15; j > 0; j--) {
7809
            Z[j] = Z[j-1];
7810
        }
7811
7812
        Z[0]  = R[a][0];
7813
        Z[1] ^= R[a][1];
7814
    }
7815
    xorbuf(Z, m[x[0]], WC_AES_BLOCK_SIZE);
7816
7817
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
7818
#elif defined(WC_32BIT_CPU)
7819
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
7820
    byte a;
7821
    word32* pZ;
7822
    word32* pm;
7823
    word32* px = (word32*)(x);
7824
    int i;
7825
7826
    pZ = (word32*)(Z + 15 + 1);
7827
    pm = (word32*)(m[x[15]]);
7828
    pZ[0] = pm[0];
7829
    pZ[1] = pm[1];
7830
    pZ[2] = pm[2];
7831
    pZ[3] = pm[3];
7832
    a = Z[16 + 15];
7833
    Z[15]  = R[a][0];
7834
    Z[16] ^= R[a][1];
7835
    for (i = 14; i > 0; i--) {
7836
        pZ = (word32*)(Z + i + 1);
7837
        pm = (word32*)(m[x[i]]);
7838
        pZ[0] ^= pm[0];
7839
        pZ[1] ^= pm[1];
7840
        pZ[2] ^= pm[2];
7841
        pZ[3] ^= pm[3];
7842
        a = Z[16 + i];
7843
        Z[i]    = R[a][0];
7844
        Z[i+1] ^= R[a][1];
7845
    }
7846
    pZ = (word32*)(Z + 1);
7847
    pm = (word32*)(m[x[0]]);
7848
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
7849
    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
7850
#else
7851
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
7852
    byte a;
7853
    word64* pZ;
7854
    word64* pm;
7855
    word64* px = (word64*)(x);
7856
    int i;
7857
7858
    pZ = (word64*)(Z + 15 + 1);
7859
    pm = (word64*)(m[x[15]]);
7860
    pZ[0] = pm[0];
7861
    pZ[1] = pm[1];
7862
    a = Z[16 + 15];
7863
    Z[15]  = R[a][0];
7864
    Z[16] ^= R[a][1];
7865
    for (i = 14; i > 0; i--) {
7866
        pZ = (word64*)(Z + i + 1);
7867
        pm = (word64*)(m[x[i]]);
7868
        pZ[0] ^= pm[0];
7869
        pZ[1] ^= pm[1];
7870
        a = Z[16 + i];
7871
        Z[i]    = R[a][0];
7872
        Z[i+1] ^= R[a][1];
7873
    }
7874
    pZ = (word64*)(Z + 1);
7875
    pm = (word64*)(m[x[0]]);
7876
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
7877
#endif
7878
}
7879
#endif
7880
7881
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7882
    word32 cSz, byte* s, word32 sSz)
7883
{
7884
    byte x[WC_AES_BLOCK_SIZE];
7885
    byte scratch[WC_AES_BLOCK_SIZE];
7886
    word32 blocks, partial;
7887
7888
    if (gcm == NULL) {
7889
        return;
7890
    }
7891
7892
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
7893
7894
    /* Hash in A, the Additional Authentication Data */
7895
    if (aSz != 0 && a != NULL) {
7896
        blocks = aSz / WC_AES_BLOCK_SIZE;
7897
        partial = aSz % WC_AES_BLOCK_SIZE;
7898
    #ifdef GCM_GMULT_LEN
7899
        if (blocks > 0) {
7900
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
7901
            a += blocks * WC_AES_BLOCK_SIZE;
7902
        }
7903
        if (partial != 0) {
7904
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7905
            XMEMCPY(scratch, a, partial);
7906
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
7907
        }
7908
    #else
7909
        while (blocks--) {
7910
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
7911
            GMULT(x, gcm->M0);
7912
            a += WC_AES_BLOCK_SIZE;
7913
        }
7914
        if (partial != 0) {
7915
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7916
            XMEMCPY(scratch, a, partial);
7917
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7918
            GMULT(x, gcm->M0);
7919
        }
7920
    #endif
7921
    }
7922
7923
    /* Hash in C, the Ciphertext */
7924
    if (cSz != 0 && c != NULL) {
7925
        blocks = cSz / WC_AES_BLOCK_SIZE;
7926
        partial = cSz % WC_AES_BLOCK_SIZE;
7927
    #ifdef GCM_GMULT_LEN
7928
        if (blocks > 0) {
7929
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
7930
            c += blocks * WC_AES_BLOCK_SIZE;
7931
        }
7932
        if (partial != 0) {
7933
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7934
            XMEMCPY(scratch, c, partial);
7935
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
7936
        }
7937
    #else
7938
        while (blocks--) {
7939
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
7940
            GMULT(x, gcm->M0);
7941
            c += WC_AES_BLOCK_SIZE;
7942
        }
7943
        if (partial != 0) {
7944
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7945
            XMEMCPY(scratch, c, partial);
7946
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7947
            GMULT(x, gcm->M0);
7948
        }
7949
    #endif
7950
    }
7951
7952
    /* Hash in the lengths of A and C in bits */
7953
    FlattenSzInBits(&scratch[0], aSz);
7954
    FlattenSzInBits(&scratch[8], cSz);
7955
#ifdef GCM_GMULT_LEN
7956
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
7957
#else
7958
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7959
    GMULT(x, gcm->M0);
7960
#endif
7961
7962
    /* Copy the result into s. */
7963
    XMEMCPY(s, x, sSz);
7964
}
7965
7966
#ifdef WOLFSSL_AESGCM_STREAM
7967
/* No extra initialization for table implementation.
7968
 *
7969
 * @param [in] aes  AES GCM object.
7970
 */
7971
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7972
7973
/* GHASH one block of data..
7974
 *
7975
 * XOR block into tag and GMULT with H using pre-computed table.
7976
 *
7977
 * @param [in, out] aes    AES GCM object.
7978
 * @param [in]      block  Block of AAD or cipher text.
7979
 */
7980
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
7981
    do {                                                \
7982
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
7983
        GMULT(AES_TAG(aes), aes->gcm.M0);               \
7984
    }                                                   \
7985
    while (0)
7986
#endif /* WOLFSSL_AESGCM_STREAM */
7987
/* end GCM_TABLE */
7988
#elif defined(GCM_TABLE_4BIT)
7989
7990
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
7991
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7992
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
7993
#define GCM_GMULT_LEN(gcm, x, a, len) \
7994
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
7995
#define GMULT(x, m)                                                      \
7996
    GCM_gmult_NEON(x, (const byte**)m)
7997
#else
7998
#define GCM_GMULT_LEN(gcm, x, a, len) \
7999
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
8000
#define GMULT(x, m)                                                      \
8001
    GCM_gmult(x, (const byte**)m)
8002
#endif
8003
#else
8004
/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
8005
 *  R shifts right a reverse bit pair of bytes such that:
8006
 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
8007
 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
8008
 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
8009
 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
8010
 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
8011
 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
8012
 *  To calculate te rest, XOR result for each bit.
8013
 *   e.g. 6 = 4 ^ 2 => 48,c0
8014
 *
8015
 * Second half is same values rotated by 4-bits.
8016
 */
8017
#if defined(WC_16BIT_CPU)
8018
static const byte R[16][2] = {
8019
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
8020
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
8021
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
8022
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
8023
};
8024
#elif defined(BIG_ENDIAN_ORDER)
8025
static const word16 R[32] = {
8026
          0x0000,       0x1c20,       0x3840,       0x2460,
8027
          0x7080,       0x6ca0,       0x48c0,       0x54e0,
8028
          0xe100,       0xfd20,       0xd940,       0xc560,
8029
          0x9180,       0x8da0,       0xa9c0,       0xb5e0,
8030
8031
          0x0000,       0x01c2,       0x0384,       0x0246,
8032
          0x0708,       0x06ca,       0x048c,       0x054e,
8033
          0x0e10,       0x0fd2,       0x0d94,       0x0c56,
8034
          0x0918,       0x08da,       0x0a9c,       0x0b5e,
8035
};
8036
#else
8037
static const word16 R[32] = {
8038
          0x0000,       0x201c,       0x4038,       0x6024,
8039
          0x8070,       0xa06c,       0xc048,       0xe054,
8040
          0x00e1,       0x20fd,       0x40d9,       0x60c5,
8041
          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
8042
8043
          0x0000,       0xc201,       0x8403,       0x4602,
8044
          0x0807,       0xca06,       0x8c04,       0x4e05,
8045
          0x100e,       0xd20f,       0x940d,       0x560c,
8046
          0x1809,       0xda08,       0x9c0a,       0x5e0b,
8047
};
8048
#endif
8049
8050
/* Multiply in GF(2^128) defined by polynomial:
8051
 *   x^128 + x^7 + x^2 + x^1 + 1.
8052
 *
8053
 * H: hash key = encrypt(key, 0)
8054
 * x = x * H in field
8055
 *
8056
 * x: cumulative result
8057
 * m: 4-bit table
8058
 *    [0..15] * H
8059
 */
8060
#if defined(WC_16BIT_CPU)
8061
static void GMULT(byte *x, byte m[16][WC_AES_BLOCK_SIZE])
8062
{
8063
    int i, j, n;
8064
    byte Z[WC_AES_BLOCK_SIZE];
8065
    byte a;
8066
8067
    XMEMSET(Z, 0, sizeof(Z));
8068
8069
    for (i = 15; i >= 0; i--) {
8070
        for (n = 0; n < 2; n++) {
8071
            if (n == 0)
8072
                xorbuf(Z, m[x[i] & 0xf], WC_AES_BLOCK_SIZE);
8073
            else {
8074
                xorbuf(Z, m[x[i] >> 4], WC_AES_BLOCK_SIZE);
8075
                if (i == 0)
8076
                    break;
8077
            }
8078
            a = Z[15] & 0xf;
8079
8080
            for (j = 15; j > 0; j--)
8081
                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
8082
            Z[0] >>= 4;
8083
8084
            Z[0] ^= R[a][0];
8085
            Z[1] ^= R[a][1];
8086
        }
8087
    }
8088
8089
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
8090
}
8091
#elif defined(WC_32BIT_CPU) && defined(BIG_ENDIAN_ORDER)
8092
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
8093
{
8094
    int i;
8095
    word32 z8[4] = {0, 0, 0, 0};
8096
    byte a;
8097
    word32* x8 = (word32*)x;
8098
    word32* m8;
8099
    byte xi;
8100
8101
    for (i = 15; i > 0; i--) {
8102
        xi = x[i];
8103
8104
        /* XOR in (msn * H) */
8105
        m8 = (word32*)m[xi & 0xf];
8106
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8107
8108
        /* Cache top byte for remainder calculations - lost in rotate. */
8109
        a = (byte)(z8[3] & 0xff);
8110
8111
        /* Rotate Z by 8-bits */
8112
        z8[3] = (z8[2] << 24) | (z8[3] >> 8);
8113
        z8[2] = (z8[1] << 24) | (z8[2] >> 8);
8114
        z8[1] = (z8[0] << 24) | (z8[1] >> 8);
8115
        z8[0] >>= 8;
8116
8117
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
8118
        z8[0] ^= ((word32)R[16 + (a & 0xf)]) << 16;
8119
8120
        xi >>= 4;
8121
        /* XOR in next significant nibble (XORed with H) * remainder */
8122
        m8 = (word32*)m[xi];
8123
        a ^= (byte)(m8[3] >> 12) & 0xf;
8124
        a ^= (byte)((m8[3] << 4) & 0xf0);
8125
        z8[0] ^= ((word32)R[a >> 4]) << 16;
8126
8127
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
8128
        m8 = (word32*)m[16 + xi];
8129
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
8130
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
8131
    }
8132
8133
    xi = x[0];
8134
8135
    /* XOR in most significant nibble * H */
8136
    m8 = (word32*)m[xi & 0xf];
8137
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8138
8139
    /* Cache top byte for remainder calculations - lost in rotate. */
8140
    a = (byte)(z8[3] & 0x0f);
8141
8142
    z8[3] = (z8[2] << 28) | (z8[3] >> 4);
8143
    z8[2] = (z8[1] << 28) | (z8[2] >> 4);
8144
    z8[1] = (z8[0] << 28) | (z8[1] >> 4);
8145
    z8[0] >>= 4;
8146
8147
    /* XOR in most significant nibble * remainder */
8148
    z8[0] ^= ((word32)R[a]) << 16;
8149
    /* XOR in next significant nibble * H */
8150
    m8 = (word32*)m[xi >> 4];
8151
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8152
8153
    /* Write back result. */
8154
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
8155
}
8156
#elif defined(WC_32BIT_CPU)
8157
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
8158
{
8159
    int i;
8160
    word32 z8[4] = {0, 0, 0, 0};
8161
    byte a;
8162
    word32* x8 = (word32*)x;
8163
    word32* m8;
8164
    byte xi;
8165
    word32 n7, n6, n5, n4, n3, n2, n1, n0;
8166
8167
    for (i = 15; i > 0; i--) {
8168
        xi = x[i];
8169
8170
        /* XOR in (msn * H) */
8171
        m8 = (word32*)m[xi & 0xf];
8172
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8173
8174
        /* Cache top byte for remainder calculations - lost in rotate. */
8175
        a = (byte)(z8[3] >> 24);
8176
8177
        /* Rotate Z by 8-bits */
8178
        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
8179
        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
8180
        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
8181
        z8[0] <<= 8;
8182
8183
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
8184
        z8[0] ^= (word32)R[16 + (a & 0xf)];
8185
8186
        xi >>= 4;
8187
        /* XOR in next significant nibble (XORed with H) * remainder */
8188
        m8 = (word32*)m[xi];
8189
        a ^= (byte)(m8[3] >> 20);
8190
        z8[0] ^= (word32)R[a >> 4];
8191
8192
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
8193
        m8 = (word32*)m[16 + xi];
8194
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
8195
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
8196
    }
8197
8198
    xi = x[0];
8199
8200
    /* XOR in most significant nibble * H */
8201
    m8 = (word32*)m[xi & 0xf];
8202
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8203
8204
    /* Cache top byte for remainder calculations - lost in rotate. */
8205
    a = (z8[3] >> 24) & 0xf;
8206
8207
    /* Rotate z by 4-bits */
8208
    n7 = z8[3] & 0xf0f0f0f0ULL;
8209
    n6 = z8[3] & 0x0f0f0f0fULL;
8210
    n5 = z8[2] & 0xf0f0f0f0ULL;
8211
    n4 = z8[2] & 0x0f0f0f0fULL;
8212
    n3 = z8[1] & 0xf0f0f0f0ULL;
8213
    n2 = z8[1] & 0x0f0f0f0fULL;
8214
    n1 = z8[0] & 0xf0f0f0f0ULL;
8215
    n0 = z8[0] & 0x0f0f0f0fULL;
8216
    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
8217
    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
8218
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
8219
    z8[0] = (n1 >> 4) | (n0 << 12);
8220
8221
    /* XOR in most significant nibble * remainder */
8222
    z8[0] ^= (word32)R[a];
8223
    /* XOR in next significant nibble * H */
8224
    m8 = (word32*)m[xi >> 4];
8225
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8226
8227
    /* Write back result. */
8228
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
8229
}
8230
#elif defined(WC_64BIT_CPU) && defined(BIG_ENDIAN_ORDER)
8231
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
8232
{
8233
    int i;
8234
    word64 z8[2] = {0, 0};
8235
    byte a;
8236
    word64* x8 = (word64*)x;
8237
    word64* m8;
8238
    byte xi;
8239
8240
    for (i = 15; i > 0; i--) {
8241
        xi = x[i];
8242
8243
        /* XOR in (msn * H) */
8244
        m8 = (word64*)m[xi & 0xf];
8245
        z8[0] ^= m8[0];
8246
        z8[1] ^= m8[1];
8247
8248
        /* Cache top byte for remainder calculations - lost in rotate. */
8249
        a = (byte)(z8[1] & 0xff);
8250
8251
        /* Rotate Z by 8-bits */
8252
        z8[1] = (z8[0] << 56) | (z8[1] >> 8);
8253
        z8[0] >>= 8;
8254
8255
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
8256
        m8 = (word64*)m[16 + (xi >> 4)];
8257
        z8[0] ^= m8[0];
8258
        z8[1] ^= m8[1];
8259
8260
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
8261
        z8[0] ^= ((word64)R[16 + (a & 0xf)]) << 48;
8262
        /* XOR in next significant nibble (XORed with H) * remainder */
8263
        m8 = (word64*)m[xi >> 4];
8264
        a ^= (byte)(m8[1] >> 12) & 0xf;
8265
        a ^= (byte)((m8[1] << 4) & 0xf0);
8266
        z8[0] ^= ((word64)R[a >> 4]) << 48;
8267
    }
8268
8269
    xi = x[0];
8270
8271
    /* XOR in most significant nibble * H */
8272
    m8 = (word64*)m[xi & 0xf];
8273
    z8[0] ^= m8[0];
8274
    z8[1] ^= m8[1];
8275
8276
    /* Cache top byte for remainder calculations - lost in rotate. */
8277
    a = (byte)(z8[1] & 0x0f);
8278
8279
    /* Rotate z by 4-bits */
8280
    z8[1] = (z8[0] << 60) | (z8[1] >> 4);
8281
    z8[0] >>= 4;
8282
8283
    /* XOR in next significant nibble * H */
8284
    m8 = (word64*)m[xi >> 4];
8285
    z8[0] ^= m8[0];
8286
    z8[1] ^= m8[1];
8287
    /* XOR in most significant nibble * remainder */
8288
    z8[0] ^= ((word64)R[a]) << 48;
8289
8290
    /* Write back result. */
8291
    x8[0] = z8[0];
8292
    x8[1] = z8[1];
8293
}
8294
#else
8295
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
8296
63.7k
{
8297
63.7k
    int i;
8298
63.7k
    word64 z8[2] = {0, 0};
8299
63.7k
    byte a;
8300
63.7k
    word64* x8 = (word64*)x;
8301
63.7k
    word64* m8;
8302
63.7k
    word64 n0, n1, n2, n3;
8303
63.7k
    byte xi;
8304
8305
1.02M
    for (i = 15; i > 0; i--) {
8306
956k
        xi = x[i];
8307
8308
        /* XOR in (msn * H) */
8309
956k
        m8 = (word64*)m[xi & 0xf];
8310
956k
        z8[0] ^= m8[0];
8311
956k
        z8[1] ^= m8[1];
8312
8313
        /* Cache top byte for remainder calculations - lost in rotate. */
8314
956k
        a = (byte)(z8[1] >> 56);
8315
8316
        /* Rotate Z by 8-bits */
8317
956k
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
8318
956k
        z8[0] <<= 8;
8319
8320
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
8321
956k
        m8 = (word64*)m[16 + (xi >> 4)];
8322
956k
        z8[0] ^= m8[0];
8323
956k
        z8[1] ^= m8[1];
8324
8325
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
8326
956k
        z8[0] ^= (word64)R[16 + (a & 0xf)];
8327
        /* XOR in next significant nibble (XORed with H) * remainder */
8328
956k
        m8 = (word64*)m[xi >> 4];
8329
956k
        a ^= (byte)(m8[1] >> 52);
8330
956k
        z8[0] ^= (word64)R[a >> 4];
8331
956k
    }
8332
8333
63.7k
    xi = x[0];
8334
8335
    /* XOR in most significant nibble * H */
8336
63.7k
    m8 = (word64*)m[xi & 0xf];
8337
63.7k
    z8[0] ^= m8[0];
8338
63.7k
    z8[1] ^= m8[1];
8339
8340
    /* Cache top byte for remainder calculations - lost in rotate. */
8341
63.7k
    a = (z8[1] >> 56) & 0xf;
8342
8343
    /* Rotate z by 4-bits */
8344
63.7k
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
8345
63.7k
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
8346
63.7k
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
8347
63.7k
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
8348
63.7k
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
8349
63.7k
    z8[0] = (n1 >> 4) | (n0 << 12);
8350
8351
    /* XOR in next significant nibble * H */
8352
63.7k
    m8 = (word64*)m[xi >> 4];
8353
63.7k
    z8[0] ^= m8[0];
8354
63.7k
    z8[1] ^= m8[1];
8355
    /* XOR in most significant nibble * remainder */
8356
63.7k
    z8[0] ^= (word64)R[a];
8357
8358
    /* Write back result. */
8359
63.7k
    x8[0] = z8[0];
8360
63.7k
    x8[1] = z8[1];
8361
63.7k
}
8362
#endif
8363
#endif
8364
8365
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8366
    word32 cSz, byte* s, word32 sSz)
8367
1.67k
{
8368
1.67k
    byte x[WC_AES_BLOCK_SIZE];
8369
1.67k
    byte scratch[WC_AES_BLOCK_SIZE];
8370
1.67k
    word32 blocks, partial;
8371
8372
1.67k
    if (gcm == NULL) {
8373
0
        return;
8374
0
    }
8375
8376
1.67k
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
8377
8378
    /* Hash in A, the Additional Authentication Data */
8379
1.67k
    if (aSz != 0 && a != NULL) {
8380
1.67k
        blocks = aSz / WC_AES_BLOCK_SIZE;
8381
1.67k
        partial = aSz % WC_AES_BLOCK_SIZE;
8382
    #ifdef GCM_GMULT_LEN
8383
        if (blocks > 0) {
8384
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
8385
            a += blocks * WC_AES_BLOCK_SIZE;
8386
        }
8387
        if (partial != 0) {
8388
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8389
            XMEMCPY(scratch, a, partial);
8390
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8391
        }
8392
    #else
8393
1.67k
        while (blocks--) {
8394
0
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
8395
0
            GMULT(x, gcm->M0);
8396
0
            a += WC_AES_BLOCK_SIZE;
8397
0
        }
8398
1.67k
        if (partial != 0) {
8399
1.67k
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8400
1.67k
            XMEMCPY(scratch, a, partial);
8401
1.67k
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8402
1.67k
            GMULT(x, gcm->M0);
8403
1.67k
        }
8404
1.67k
    #endif
8405
1.67k
    }
8406
8407
    /* Hash in C, the Ciphertext */
8408
1.67k
    if (cSz != 0 && c != NULL) {
8409
1.66k
        blocks = cSz / WC_AES_BLOCK_SIZE;
8410
1.66k
        partial = cSz % WC_AES_BLOCK_SIZE;
8411
    #ifdef GCM_GMULT_LEN
8412
        if (blocks > 0) {
8413
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
8414
            c += blocks * WC_AES_BLOCK_SIZE;
8415
        }
8416
        if (partial != 0) {
8417
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8418
            XMEMCPY(scratch, c, partial);
8419
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8420
        }
8421
    #else
8422
49.0k
        while (blocks--) {
8423
47.3k
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
8424
47.3k
            GMULT(x, gcm->M0);
8425
47.3k
            c += WC_AES_BLOCK_SIZE;
8426
47.3k
        }
8427
1.66k
        if (partial != 0) {
8428
1.57k
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8429
1.57k
            XMEMCPY(scratch, c, partial);
8430
1.57k
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8431
1.57k
            GMULT(x, gcm->M0);
8432
1.57k
        }
8433
1.66k
    #endif
8434
1.66k
    }
8435
8436
    /* Hash in the lengths of A and C in bits */
8437
1.67k
    FlattenSzInBits(&scratch[0], aSz);
8438
1.67k
    FlattenSzInBits(&scratch[8], cSz);
8439
#ifdef GCM_GMULT_LEN
8440
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8441
#else
8442
1.67k
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8443
1.67k
    GMULT(x, gcm->M0);
8444
1.67k
#endif
8445
8446
    /* Copy the result into s. */
8447
1.67k
    XMEMCPY(s, x, sSz);
8448
1.67k
}
8449
8450
#ifdef WOLFSSL_AESGCM_STREAM
8451
/* No extra initialization for 4-bit table implementation.
8452
 *
8453
 * @param [in] aes  AES GCM object.
8454
 */
8455
3.60k
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8456
8457
#ifdef GCM_GMULT_LEN
8458
/* GHASH one block of data.
8459
 *
8460
 * @param [in, out] aes    AES GCM object.
8461
 * @param [in]      block  Block of AAD or cipher text.
8462
 */
8463
#define GHASH_ONE_BLOCK_SW(aes, block)                                  \
8464
   GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
8465
#else
8466
/* GHASH one block of data.
8467
 *
8468
 * XOR block into tag and GMULT with H using pre-computed table.
8469
 *
8470
 * @param [in, out] aes    AES GCM object.
8471
 * @param [in]      block  Block of AAD or cipher text.
8472
 */
8473
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
8474
11.4k
    do {                                                \
8475
11.4k
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
8476
11.4k
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
8477
11.4k
    }                                                   \
8478
11.4k
    while (0)
8479
#endif
8480
#endif /* WOLFSSL_AESGCM_STREAM */
8481
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
8482
8483
#if !defined(FREESCALE_LTC_AES_GCM)
8484
static void GMULT(word64* X, word64* Y)
8485
{
8486
    word64 Z[2] = {0,0};
8487
    word64 V[2];
8488
    int i, j;
8489
    word64 v1;
8490
    V[0] = X[0];  V[1] = X[1];
8491
8492
    for (i = 0; i < 2; i++)
8493
    {
8494
        word64 y = Y[i];
8495
        for (j = 0; j < 64; j++)
8496
        {
8497
#ifndef AES_GCM_GMULT_NCT
8498
            word64 mask = 0 - (y >> 63);
8499
            Z[0] ^= V[0] & mask;
8500
            Z[1] ^= V[1] & mask;
8501
#else
8502
            if (y & 0x8000000000000000ULL) {
8503
                Z[0] ^= V[0];
8504
                Z[1] ^= V[1];
8505
            }
8506
#endif
8507
8508
            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
8509
            V[1] >>= 1;
8510
            V[1] |= V[0] << 63;
8511
            V[0] >>= 1;
8512
            V[0] ^= v1;
8513
            y <<= 1;
8514
        }
8515
    }
8516
    X[0] = Z[0];
8517
    X[1] = Z[1];
8518
}
8519
8520
8521
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8522
    word32 cSz, byte* s, word32 sSz)
8523
{
8524
    word64 x[2] = {0,0};
8525
    word32 blocks, partial;
8526
    word64 bigH[2];
8527
8528
    if (gcm == NULL) {
8529
        return;
8530
    }
8531
8532
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
8533
    #ifdef LITTLE_ENDIAN_ORDER
8534
        ByteReverseWords64(bigH, bigH, WC_AES_BLOCK_SIZE);
8535
    #endif
8536
8537
    /* Hash in A, the Additional Authentication Data */
8538
    if (aSz != 0 && a != NULL) {
8539
        word64 bigA[2];
8540
        blocks = aSz / WC_AES_BLOCK_SIZE;
8541
        partial = aSz % WC_AES_BLOCK_SIZE;
8542
        while (blocks--) {
8543
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
8544
            #ifdef LITTLE_ENDIAN_ORDER
8545
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
8546
            #endif
8547
            x[0] ^= bigA[0];
8548
            x[1] ^= bigA[1];
8549
            GMULT(x, bigH);
8550
            a += WC_AES_BLOCK_SIZE;
8551
        }
8552
        if (partial != 0) {
8553
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
8554
            XMEMCPY(bigA, a, partial);
8555
            #ifdef LITTLE_ENDIAN_ORDER
8556
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
8557
            #endif
8558
            x[0] ^= bigA[0];
8559
            x[1] ^= bigA[1];
8560
            GMULT(x, bigH);
8561
        }
8562
#ifdef OPENSSL_EXTRA
8563
        /* store AAD partial tag for next call */
8564
        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
8565
        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
8566
        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
8567
        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
8568
#endif
8569
    }
8570
8571
    /* Hash in C, the Ciphertext */
8572
    if (cSz != 0 && c != NULL) {
8573
        word64 bigC[2];
8574
        blocks = cSz / WC_AES_BLOCK_SIZE;
8575
        partial = cSz % WC_AES_BLOCK_SIZE;
8576
#ifdef OPENSSL_EXTRA
8577
        /* Start from last AAD partial tag */
8578
        if(gcm->aadLen) {
8579
            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
8580
            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
8581
         }
8582
#endif
8583
        while (blocks--) {
8584
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
8585
            #ifdef LITTLE_ENDIAN_ORDER
8586
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
8587
            #endif
8588
            x[0] ^= bigC[0];
8589
            x[1] ^= bigC[1];
8590
            GMULT(x, bigH);
8591
            c += WC_AES_BLOCK_SIZE;
8592
        }
8593
        if (partial != 0) {
8594
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
8595
            XMEMCPY(bigC, c, partial);
8596
            #ifdef LITTLE_ENDIAN_ORDER
8597
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
8598
            #endif
8599
            x[0] ^= bigC[0];
8600
            x[1] ^= bigC[1];
8601
            GMULT(x, bigH);
8602
        }
8603
    }
8604
8605
    /* Hash in the lengths in bits of A and C */
8606
    {
8607
        word64 len[2];
8608
        len[0] = aSz; len[1] = cSz;
8609
#ifdef OPENSSL_EXTRA
8610
        if (gcm->aadLen)
8611
            len[0] = (word64)gcm->aadLen;
8612
#endif
8613
        /* Lengths are in bytes. Convert to bits. */
8614
        len[0] *= 8;
8615
        len[1] *= 8;
8616
8617
        x[0] ^= len[0];
8618
        x[1] ^= len[1];
8619
        GMULT(x, bigH);
8620
    }
8621
    #ifdef LITTLE_ENDIAN_ORDER
8622
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
8623
    #endif
8624
    XMEMCPY(s, x, sSz);
8625
}
8626
#endif /* !FREESCALE_LTC_AES_GCM */
8627
8628
#ifdef WOLFSSL_AESGCM_STREAM
8629
8630
#ifdef LITTLE_ENDIAN_ORDER
8631
8632
/* No extra initialization for small implementation.
8633
 *
8634
 * @param [in] aes  AES GCM object.
8635
 */
8636
#define GHASH_INIT_EXTRA(aes)                                               \
8637
    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, WC_AES_BLOCK_SIZE)
8638
8639
/* GHASH one block of data..
8640
 *
8641
 * XOR block into tag and GMULT with H.
8642
 *
8643
 * @param [in, out] aes    AES GCM object.
8644
 * @param [in]      block  Block of AAD or cipher text.
8645
 */
8646
#define GHASH_ONE_BLOCK_SW(aes, block)                              \
8647
    do {                                                            \
8648
        word64* x = (word64*)AES_TAG(aes);                          \
8649
        word64* h = (word64*)aes->gcm.H;                            \
8650
        word64 block64[2];                                          \
8651
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);                 \
8652
        ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE);    \
8653
        x[0] ^= block64[0];                                         \
8654
        x[1] ^= block64[1];                                         \
8655
        GMULT(x, h);                                                \
8656
    }                                                               \
8657
    while (0)
8658
8659
#ifdef OPENSSL_EXTRA
8660
/* GHASH in AAD and cipher text lengths in bits.
8661
 *
8662
 * Convert tag back to little-endian.
8663
 *
8664
 * @param [in, out] aes  AES GCM object.
8665
 */
8666
#define GHASH_LEN_BLOCK(aes)                            \
8667
    do {                                                \
8668
        word64* x = (word64*)AES_TAG(aes);              \
8669
        word64* h = (word64*)aes->gcm.H;                \
8670
        word64 len[2];                                  \
8671
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8672
        if (aes->gcm.aadLen)                            \
8673
            len[0] = (word64)aes->gcm.aadLen;           \
8674
        /* Lengths are in bytes. Convert to bits. */    \
8675
        len[0] *= 8;                                    \
8676
        len[1] *= 8;                                    \
8677
                                                        \
8678
        x[0] ^= len[0];                                 \
8679
        x[1] ^= len[1];                                 \
8680
        GMULT(x, h);                                    \
8681
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
8682
    }                                                   \
8683
    while (0)
8684
#else
8685
/* GHASH in AAD and cipher text lengths in bits.
8686
 *
8687
 * Convert tag back to little-endian.
8688
 *
8689
 * @param [in, out] aes  AES GCM object.
8690
 */
8691
#define GHASH_LEN_BLOCK(aes)                            \
8692
    do {                                                \
8693
        word64* x = (word64*)AES_TAG(aes);              \
8694
        word64* h = (word64*)aes->gcm.H;                \
8695
        word64 len[2];                                  \
8696
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8697
        /* Lengths are in bytes. Convert to bits. */    \
8698
        len[0] *= 8;                                    \
8699
        len[1] *= 8;                                    \
8700
                                                        \
8701
        x[0] ^= len[0];                                 \
8702
        x[1] ^= len[1];                                 \
8703
        GMULT(x, h);                                    \
8704
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
8705
    }                                                   \
8706
    while (0)
8707
#endif
8708
8709
#else
8710
8711
/* No extra initialization for small implementation.
8712
 *
8713
 * @param [in] aes  AES GCM object.
8714
 */
8715
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8716
8717
/* GHASH one block of data..
8718
 *
8719
 * XOR block into tag and GMULT with H.
8720
 *
8721
 * @param [in, out] aes    AES GCM object.
8722
 * @param [in]      block  Block of AAD or cipher text.
8723
 */
8724
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
8725
    do {                                                \
8726
        word64* x = (word64*)AES_TAG(aes);              \
8727
        word64* h = (word64*)aes->gcm.H;                \
8728
        word64 block64[2];                              \
8729
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);        \
8730
        x[0] ^= block64[0];                             \
8731
        x[1] ^= block64[1];                             \
8732
        GMULT(x, h);                                    \
8733
    }                                                   \
8734
    while (0)
8735
8736
#ifdef OPENSSL_EXTRA
8737
/* GHASH in AAD and cipher text lengths in bits.
8738
 *
8739
 * Convert tag back to little-endian.
8740
 *
8741
 * @param [in, out] aes  AES GCM object.
8742
 */
8743
#define GHASH_LEN_BLOCK(aes)                            \
8744
    do {                                                \
8745
        word64* x = (word64*)AES_TAG(aes);              \
8746
        word64* h = (word64*)aes->gcm.H;                \
8747
        word64 len[2];                                  \
8748
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8749
        if (aes->gcm.aadLen)                            \
8750
            len[0] = (word64)aes->gcm.aadLen;           \
8751
        /* Lengths are in bytes. Convert to bits. */    \
8752
        len[0] *= 8;                                    \
8753
        len[1] *= 8;                                    \
8754
                                                        \
8755
        x[0] ^= len[0];                                 \
8756
        x[1] ^= len[1];                                 \
8757
        GMULT(x, h);                                    \
8758
    }                                                   \
8759
    while (0)
8760
#else
8761
/* GHASH in AAD and cipher text lengths in bits.
8762
 *
8763
 * Convert tag back to little-endian.
8764
 *
8765
 * @param [in, out] aes  AES GCM object.
8766
 */
8767
#define GHASH_LEN_BLOCK(aes)                            \
8768
    do {                                                \
8769
        word64* x = (word64*)AES_TAG(aes);              \
8770
        word64* h = (word64*)aes->gcm.H;                \
8771
        word64 len[2];                                  \
8772
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8773
        /* Lengths are in bytes. Convert to bits. */    \
8774
        len[0] *= 8;                                    \
8775
        len[1] *= 8;                                    \
8776
                                                        \
8777
        x[0] ^= len[0];                                 \
8778
        x[1] ^= len[1];                                 \
8779
        GMULT(x, h);                                    \
8780
    }                                                   \
8781
    while (0)
8782
#endif
8783
8784
#endif /* !LITTLE_ENDIAN_ORDER */
8785
8786
#endif /* WOLFSSL_AESGCM_STREAM */
8787
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
8788
#else /* GCM_WORD32 */
8789
8790
static void GMULT(word32* X, word32* Y)
8791
{
8792
    word32 Z[4] = {0,0,0,0};
8793
    word32 V[4];
8794
    int i, j;
8795
8796
    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
8797
8798
    for (i = 0; i < 4; i++)
8799
    {
8800
        word32 y = Y[i];
8801
        for (j = 0; j < 32; j++)
8802
        {
8803
            if (y & 0x80000000) {
8804
                Z[0] ^= V[0];
8805
                Z[1] ^= V[1];
8806
                Z[2] ^= V[2];
8807
                Z[3] ^= V[3];
8808
            }
8809
8810
            if (V[3] & 0x00000001) {
8811
                V[3] >>= 1;
8812
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
8813
                V[2] >>= 1;
8814
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
8815
                V[1] >>= 1;
8816
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
8817
                V[0] >>= 1;
8818
                V[0] ^= 0xE1000000;
8819
            } else {
8820
                V[3] >>= 1;
8821
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
8822
                V[2] >>= 1;
8823
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
8824
                V[1] >>= 1;
8825
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
8826
                V[0] >>= 1;
8827
            }
8828
            y <<= 1;
8829
        }
8830
    }
8831
    X[0] = Z[0];
8832
    X[1] = Z[1];
8833
    X[2] = Z[2];
8834
    X[3] = Z[3];
8835
}
8836
8837
8838
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8839
    word32 cSz, byte* s, word32 sSz)
8840
{
8841
    word32 x[4] = {0,0,0,0};
8842
    word32 blocks, partial;
8843
    word32 bigH[4];
8844
8845
    if (gcm == NULL) {
8846
        return;
8847
    }
8848
8849
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
8850
    #ifdef LITTLE_ENDIAN_ORDER
8851
        ByteReverseWords(bigH, bigH, WC_AES_BLOCK_SIZE);
8852
    #endif
8853
8854
    /* Hash in A, the Additional Authentication Data */
8855
    if (aSz != 0 && a != NULL) {
8856
        word32 bigA[4];
8857
        blocks = aSz / WC_AES_BLOCK_SIZE;
8858
        partial = aSz % WC_AES_BLOCK_SIZE;
8859
        while (blocks--) {
8860
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
8861
            #ifdef LITTLE_ENDIAN_ORDER
8862
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
8863
            #endif
8864
            x[0] ^= bigA[0];
8865
            x[1] ^= bigA[1];
8866
            x[2] ^= bigA[2];
8867
            x[3] ^= bigA[3];
8868
            GMULT(x, bigH);
8869
            a += WC_AES_BLOCK_SIZE;
8870
        }
8871
        if (partial != 0) {
8872
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
8873
            XMEMCPY(bigA, a, partial);
8874
            #ifdef LITTLE_ENDIAN_ORDER
8875
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
8876
            #endif
8877
            x[0] ^= bigA[0];
8878
            x[1] ^= bigA[1];
8879
            x[2] ^= bigA[2];
8880
            x[3] ^= bigA[3];
8881
            GMULT(x, bigH);
8882
        }
8883
    }
8884
8885
    /* Hash in C, the Ciphertext */
8886
    if (cSz != 0 && c != NULL) {
8887
        word32 bigC[4];
8888
        blocks = cSz / WC_AES_BLOCK_SIZE;
8889
        partial = cSz % WC_AES_BLOCK_SIZE;
8890
        while (blocks--) {
8891
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
8892
            #ifdef LITTLE_ENDIAN_ORDER
8893
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
8894
            #endif
8895
            x[0] ^= bigC[0];
8896
            x[1] ^= bigC[1];
8897
            x[2] ^= bigC[2];
8898
            x[3] ^= bigC[3];
8899
            GMULT(x, bigH);
8900
            c += WC_AES_BLOCK_SIZE;
8901
        }
8902
        if (partial != 0) {
8903
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
8904
            XMEMCPY(bigC, c, partial);
8905
            #ifdef LITTLE_ENDIAN_ORDER
8906
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
8907
            #endif
8908
            x[0] ^= bigC[0];
8909
            x[1] ^= bigC[1];
8910
            x[2] ^= bigC[2];
8911
            x[3] ^= bigC[3];
8912
            GMULT(x, bigH);
8913
        }
8914
    }
8915
8916
    /* Hash in the lengths in bits of A and C */
8917
    {
8918
        word32 len[4];
8919
8920
        /* Lengths are in bytes. Convert to bits. */
8921
        len[0] = (aSz >> (8*sizeof(aSz) - 3));
8922
        len[1] = aSz << 3;
8923
        len[2] = (cSz >> (8*sizeof(cSz) - 3));
8924
        len[3] = cSz << 3;
8925
8926
        x[0] ^= len[0];
8927
        x[1] ^= len[1];
8928
        x[2] ^= len[2];
8929
        x[3] ^= len[3];
8930
        GMULT(x, bigH);
8931
    }
8932
    #ifdef LITTLE_ENDIAN_ORDER
8933
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
8934
    #endif
8935
    XMEMCPY(s, x, sSz);
8936
}
8937
8938
#ifdef WOLFSSL_AESGCM_STREAM
8939
#ifdef LITTLE_ENDIAN_ORDER
8940
/* Little-endian 32-bit word implementation requires byte reversal of H.
8941
 *
8942
 * H is all-zeros block encrypted with key.
8943
 *
8944
 * @param [in, out] aes  AES GCM object.
8945
 */
8946
#define GHASH_INIT_EXTRA(aes) \
8947
    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, WC_AES_BLOCK_SIZE)
8948
8949
/* GHASH one block of data..
8950
 *
8951
 * XOR block, in big-endian form, into tag and GMULT with H.
8952
 *
8953
 * @param [in, out] aes    AES GCM object.
8954
 * @param [in]      block  Block of AAD or cipher text.
8955
 */
8956
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
8957
    do {                                                        \
8958
        word32* x = (word32*)AES_TAG(aes);                      \
8959
        word32* h = (word32*)aes->gcm.H;                        \
8960
        word32 bigEnd[4];                                       \
8961
        XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE);              \
8962
        ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE);    \
8963
        x[0] ^= bigEnd[0];                                      \
8964
        x[1] ^= bigEnd[1];                                      \
8965
        x[2] ^= bigEnd[2];                                      \
8966
        x[3] ^= bigEnd[3];                                      \
8967
        GMULT(x, h);                                            \
8968
    }                                                           \
8969
    while (0)
8970
8971
/* GHASH in AAD and cipher text lengths in bits.
8972
 *
8973
 * Convert tag back to little-endian.
8974
 *
8975
 * @param [in, out] aes  AES GCM object.
8976
 */
8977
#define GHASH_LEN_BLOCK(aes)                                \
8978
    do {                                                    \
8979
        word32 len[4];                                      \
8980
        word32* x = (word32*)AES_TAG(aes);                  \
8981
        word32* h = (word32*)aes->gcm.H;                    \
8982
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
8983
        len[1] = aes->aSz << 3;                             \
8984
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
8985
        len[3] = aes->cSz << 3;                             \
8986
        x[0] ^= len[0];                                     \
8987
        x[1] ^= len[1];                                     \
8988
        x[2] ^= len[2];                                     \
8989
        x[3] ^= len[3];                                     \
8990
        GMULT(x, h);                                        \
8991
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);          \
8992
    }                                                       \
8993
    while (0)
8994
#else
8995
/* No extra initialization for 32-bit word implementation.
8996
 *
8997
 * @param [in] aes  AES GCM object.
8998
 */
8999
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9000
9001
/* GHASH one block of data..
9002
 *
9003
 * XOR block into tag and GMULT with H.
9004
 *
9005
 * @param [in, out] aes    AES GCM object.
9006
 * @param [in]      block  Block of AAD or cipher text.
9007
 */
9008
#define GHASH_ONE_BLOCK_SW(aes, block)                      \
9009
    do {                                                    \
9010
        word32* x = (word32*)AES_TAG(aes);                  \
9011
        word32* h = (word32*)aes->gcm.H;                    \
9012
        word32 block32[4];                                  \
9013
        XMEMCPY(block32, block, WC_AES_BLOCK_SIZE);         \
9014
        x[0] ^= block32[0];                                 \
9015
        x[1] ^= block32[1];                                 \
9016
        x[2] ^= block32[2];                                 \
9017
        x[3] ^= block32[3];                                 \
9018
        GMULT(x, h);                                        \
9019
    }                                                       \
9020
    while (0)
9021
9022
/* GHASH in AAD and cipher text lengths in bits.
9023
 *
9024
 * @param [in, out] aes  AES GCM object.
9025
 */
9026
#define GHASH_LEN_BLOCK(aes)                                \
9027
    do {                                                    \
9028
        word32 len[4];                                      \
9029
        word32* x = (word32*)AES_TAG(aes);                  \
9030
        word32* h = (word32*)aes->gcm.H;                    \
9031
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
9032
        len[1] = aes->aSz << 3;                             \
9033
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
9034
        len[3] = aes->cSz << 3;                             \
9035
        x[0] ^= len[0];                                     \
9036
        x[1] ^= len[1];                                     \
9037
        x[2] ^= len[2];                                     \
9038
        x[3] ^= len[3];                                     \
9039
        GMULT(x, h);                                        \
9040
    }                                                       \
9041
    while (0)
9042
#endif /* LITTLE_ENDIAN_ORDER */
9043
#endif /* WOLFSSL_AESGCM_STREAM */
9044
#endif /* end GCM_WORD32 */
9045
#endif
9046
9047
#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
9048
#ifdef WOLFSSL_AESGCM_STREAM
9049
#ifndef GHASH_LEN_BLOCK
9050
/* Hash in the lengths of the AAD and cipher text in bits.
9051
 *
9052
 * Default implementation.
9053
 *
9054
 * @param [in, out] aes  AES GCM object.
9055
 */
9056
#define GHASH_LEN_BLOCK(aes)                      \
9057
921
    do {                                          \
9058
921
        byte scratch[WC_AES_BLOCK_SIZE];          \
9059
921
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
9060
921
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
9061
921
        GHASH_ONE_BLOCK(aes, scratch);            \
9062
921
    }                                             \
9063
921
    while (0)
9064
#endif
9065
9066
/* Initialize a GHASH for streaming operations.
9067
 *
9068
 * @param [in, out] aes  AES GCM object.
9069
 */
9070
2.68k
static void GHASH_INIT(Aes* aes) {
9071
    /* Set tag to all zeros as initial value. */
9072
2.68k
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
9073
    /* Reset counts of AAD and cipher text. */
9074
2.68k
    aes->aOver = 0;
9075
2.68k
    aes->cOver = 0;
9076
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
9077
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
9078
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
9079
        ; /* Don't do extra initialization. */
9080
    }
9081
    else
9082
#endif
9083
2.68k
    {
9084
        /* Extra initialization based on implementation. */
9085
2.68k
        GHASH_INIT_EXTRA(aes);
9086
2.68k
    }
9087
2.68k
}
9088
9089
/* Update the GHASH with AAD and/or cipher text.
9090
 *
9091
 * @param [in,out] aes   AES GCM object.
9092
 * @param [in]     a     Additional authentication data buffer.
9093
 * @param [in]     aSz   Size of data in AAD buffer.
9094
 * @param [in]     c     Cipher text buffer.
9095
 * @param [in]     cSz   Size of data in cipher text buffer.
9096
 */
9097
static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
9098
    word32 cSz)
9099
9.75k
{
9100
9.75k
    word32 blocks;
9101
9.75k
    word32 partial;
9102
9103
    /* Hash in A, the Additional Authentication Data */
9104
9.75k
    if (aSz != 0 && a != NULL) {
9105
        /* Update count of AAD we have hashed. */
9106
401
        aes->aSz += aSz;
9107
        /* Check if we have unprocessed data. */
9108
401
        if (aes->aOver > 0) {
9109
            /* Calculate amount we can use - fill up the block. */
9110
188
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
9111
188
            if (sz > aSz) {
9112
88
                sz = (byte)aSz;
9113
88
            }
9114
            /* Copy extra into last GHASH block array and update count. */
9115
188
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
9116
188
            aes->aOver = (byte)(aes->aOver + sz);
9117
188
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
9118
                /* We have filled up the block and can process. */
9119
100
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
9120
                /* Reset count. */
9121
100
                aes->aOver = 0;
9122
100
            }
9123
            /* Used up some data. */
9124
188
            aSz -= sz;
9125
188
            a += sz;
9126
188
        }
9127
9128
        /* Calculate number of blocks of AAD and the leftover. */
9129
401
        blocks = aSz / WC_AES_BLOCK_SIZE;
9130
401
        partial = aSz % WC_AES_BLOCK_SIZE;
9131
        /* GHASH full blocks now. */
9132
4.41k
        while (blocks--) {
9133
4.01k
            GHASH_ONE_BLOCK(aes, a);
9134
4.01k
            a += WC_AES_BLOCK_SIZE;
9135
4.01k
        }
9136
401
        if (partial != 0) {
9137
            /* Cache the partial block. */
9138
291
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
9139
291
            aes->aOver = (byte)partial;
9140
291
        }
9141
401
    }
9142
9.75k
    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
9143
        /* No more AAD coming and we have a partial block. */
9144
        /* Fill the rest of the block with zeros. */
9145
97
        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
9146
97
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
9147
        /* GHASH last AAD block. */
9148
97
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
9149
        /* Clear partial count for next time through. */
9150
97
        aes->aOver = 0;
9151
97
    }
9152
9153
    /* Hash in C, the Ciphertext */
9154
9.75k
    if (cSz != 0 && c != NULL) {
9155
        /* Update count of cipher text we have hashed. */
9156
1.54k
        aes->cSz += cSz;
9157
1.54k
        if (aes->cOver > 0) {
9158
            /* Calculate amount we can use - fill up the block. */
9159
672
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
9160
672
            if (sz > cSz) {
9161
435
                sz = (byte)cSz;
9162
435
            }
9163
672
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
9164
            /* Update count of unused encrypted counter. */
9165
672
            aes->cOver = (byte)(aes->cOver + sz);
9166
672
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
9167
                /* We have filled up the block and can process. */
9168
237
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
9169
                /* Reset count. */
9170
237
                aes->cOver = 0;
9171
237
            }
9172
            /* Used up some data. */
9173
672
            cSz -= sz;
9174
672
            c += sz;
9175
672
        }
9176
9177
        /* Calculate number of blocks of cipher text and the leftover. */
9178
1.54k
        blocks = cSz / WC_AES_BLOCK_SIZE;
9179
1.54k
        partial = cSz % WC_AES_BLOCK_SIZE;
9180
        /* GHASH full blocks now. */
9181
7.19k
        while (blocks--) {
9182
5.65k
            GHASH_ONE_BLOCK(aes, c);
9183
5.65k
            c += WC_AES_BLOCK_SIZE;
9184
5.65k
        }
9185
1.54k
        if (partial != 0) {
9186
            /* Cache the partial block. */
9187
637
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
9188
637
            aes->cOver = (byte)partial;
9189
637
        }
9190
1.54k
    }
9191
9.75k
}
9192
9193
/* Finalize the GHASH calculation.
9194
 *
9195
 * Complete hashing cipher text and hash the AAD and cipher text lengths.
9196
 *
9197
 * @param [in, out] aes  AES GCM object.
9198
 * @param [out]     s    Authentication tag.
9199
 * @param [in]      sSz  Size of authentication tag required.
9200
 */
9201
static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
9202
921
{
9203
    /* AAD block incomplete when > 0 */
9204
921
    byte over = aes->aOver;
9205
9206
921
    if (aes->cOver > 0) {
9207
        /* Cipher text block incomplete. */
9208
374
        over = aes->cOver;
9209
374
    }
9210
921
    if (over > 0) {
9211
        /* Zeroize the unused part of the block. */
9212
461
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
9213
461
            (size_t)WC_AES_BLOCK_SIZE - over);
9214
        /* Hash the last block of cipher text. */
9215
461
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
9216
461
    }
9217
    /* Hash in the lengths of AAD and cipher text in bits */
9218
921
    GHASH_LEN_BLOCK(aes);
9219
    /* Copy the result into s. */
9220
921
    XMEMCPY(s, AES_TAG(aes), sSz);
9221
    /* reset aes->gcm.H in case of reuse */
9222
921
    GHASH_INIT_EXTRA(aes);
9223
921
}
9224
#endif /* WOLFSSL_AESGCM_STREAM */
9225
9226
9227
#ifdef FREESCALE_LTC_AES_GCM
9228
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
9229
                   const byte* iv, word32 ivSz,
9230
                   byte* authTag, word32 authTagSz,
9231
                   const byte* authIn, word32 authInSz)
9232
{
9233
    status_t status;
9234
    word32 keySize;
9235
9236
    /* argument checks */
9237
    if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE || ivSz == 0) {
9238
        return BAD_FUNC_ARG;
9239
    }
9240
9241
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
9242
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
9243
        return BAD_FUNC_ARG;
9244
    }
9245
9246
    status = wc_AesGetKeySize(aes, &keySize);
9247
    if (status)
9248
        return status;
9249
9250
    status = wolfSSL_CryptHwMutexLock();
9251
    if (status != 0)
9252
        return status;
9253
9254
    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
9255
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
9256
    wolfSSL_CryptHwMutexUnLock();
9257
9258
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
9259
}
9260
9261
#else
9262
9263
#ifdef STM32_CRYPTO_AES_GCM
9264
9265
/* this function supports inline encrypt */
9266
static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
9267
                                  Aes* aes, byte* out, const byte* in, word32 sz,
9268
                                  const byte* iv, word32 ivSz,
9269
                                  byte* authTag, word32 authTagSz,
9270
                                  const byte* authIn, word32 authInSz)
9271
{
9272
    int ret;
9273
#ifdef WOLFSSL_STM32_CUBEMX
9274
    CRYP_HandleTypeDef hcryp;
9275
#else
9276
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
9277
#endif
9278
    word32 keySize;
9279
#ifdef WOLFSSL_STM32_CUBEMX
9280
    int status = HAL_OK;
9281
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
9282
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
9283
#else
9284
    int status = SUCCESS;
9285
#endif
9286
    word32 partial = sz % WC_AES_BLOCK_SIZE;
9287
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
9288
    word32 ctrInit[WC_AES_BLOCK_SIZE/sizeof(word32)];
9289
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
9290
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
9291
    byte* authInPadded = NULL;
9292
    int authPadSz, wasAlloc = 0, useSwGhash = 0;
9293
9294
    ret = wc_AesGetKeySize(aes, &keySize);
9295
    if (ret != 0)
9296
        return ret;
9297
9298
#ifdef WOLFSSL_STM32_CUBEMX
9299
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
9300
    if (ret != 0)
9301
        return ret;
9302
#endif
9303
9304
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
9305
    if (ivSz == GCM_NONCE_MID_SZ) {
9306
        byte* pCtr = (byte*)ctr;
9307
        XMEMCPY(ctr, iv, ivSz);
9308
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
9309
    }
9310
    else {
9311
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
9312
    }
9313
    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
9314
9315
    /* Authentication buffer */
9316
#if STM_CRYPT_HEADER_WIDTH == 1
9317
    authPadSz = 0; /* CubeHAL supports byte mode */
9318
#else
9319
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
9320
#endif
9321
#ifdef WOLFSSL_STM32MP13
9322
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
9323
     * minimum of 16 bytes for the auth */
9324
    if ((authInSz > 0) && (authInSz < 16)) {
9325
        authPadSz = 16 - authInSz;
9326
    }
9327
#endif
9328
    if (authPadSz != 0) {
9329
        if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) {
9330
            authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
9331
        }
9332
        if (authPadSz <= sizeof(authhdr)) {
9333
            authInPadded = (byte*)authhdr;
9334
        }
9335
        else {
9336
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
9337
                DYNAMIC_TYPE_TMP_BUFFER);
9338
            if (authInPadded == NULL) {
9339
                wolfSSL_CryptHwMutexUnLock();
9340
                return MEMORY_E;
9341
            }
9342
            wasAlloc = 1;
9343
        }
9344
        XMEMSET(authInPadded, 0, authPadSz);
9345
        XMEMCPY(authInPadded, authIn, authInSz);
9346
    } else {
9347
        authPadSz = authInSz;
9348
        authInPadded = (byte*)authIn;
9349
    }
9350
9351
    /* for cases where hardware cannot be used for authTag calculate it */
9352
    /* if IV is not 12 calculate GHASH using software */
9353
    if (ivSz != GCM_NONCE_MID_SZ
9354
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
9355
        /* or hardware that does not support partial block */
9356
        || sz == 0 || partial != 0
9357
    #endif
9358
    #if STM_CRYPT_HEADER_WIDTH == 4
9359
        /* or authIn is not a multiple of 4  */
9360
        || authPadSz != authInSz
9361
    #endif
9362
    ) {
9363
        useSwGhash = 1;
9364
    }
9365
9366
    /* Hardware requires counter + 1 */
9367
    IncrementGcmCounter((byte*)ctr);
9368
9369
    ret = wolfSSL_CryptHwMutexLock();
9370
    if (ret != 0) {
9371
        return ret;
9372
    }
9373
9374
#ifdef WOLFSSL_STM32_CUBEMX
9375
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
9376
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
9377
9378
#if defined(STM32_HAL_V2)
9379
    hcryp.Init.Algorithm = CRYP_AES_GCM;
9380
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
9381
    #ifdef CRYP_KEYIVCONFIG_ONCE
9382
    /* allows repeated calls to HAL_CRYP_Encrypt */
9383
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
9384
    #endif
9385
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
9386
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
9387
    HAL_CRYP_Init(&hcryp);
9388
9389
    #ifndef CRYP_KEYIVCONFIG_ONCE
9390
    /* GCM payload phase - can handle partial blocks */
9391
    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
9392
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
9393
    #else
9394
    /* GCM payload phase - blocks */
9395
    if (blocks) {
9396
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
9397
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
9398
    }
9399
    /* GCM payload phase - partial remainder */
9400
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
9401
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9402
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9403
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
9404
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
9405
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9406
    }
9407
    #endif
9408
    if (status == HAL_OK && !useSwGhash) {
9409
        /* Compute the authTag */
9410
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
9411
            STM32_HAL_TIMEOUT);
9412
    }
9413
#elif defined(STM32_CRYPTO_AES_ONLY)
9414
    /* Set the CRYP parameters */
9415
    hcryp.Init.HeaderSize = authPadSz;
9416
    if (authPadSz == 0)
9417
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
9418
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
9419
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
9420
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
9421
    HAL_CRYP_Init(&hcryp);
9422
9423
    /* GCM init phase */
9424
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9425
    if (status == HAL_OK) {
9426
        /* GCM header phase */
9427
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
9428
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9429
    }
9430
    if (status == HAL_OK) {
9431
        /* GCM payload phase - blocks */
9432
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
9433
        if (blocks) {
9434
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
9435
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9436
        }
9437
    }
9438
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
9439
        /* GCM payload phase - partial remainder */
9440
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9441
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9442
        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
9443
                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
9444
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9445
    }
9446
    if (status == HAL_OK && !useSwGhash) {
9447
        /* GCM final phase */
9448
        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
9449
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
9450
    }
9451
#else
9452
    hcryp.Init.HeaderSize = authPadSz;
9453
    HAL_CRYP_Init(&hcryp);
9454
    if (blocks) {
9455
        /* GCM payload phase - blocks */
9456
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
9457
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9458
    }
9459
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
9460
        /* GCM payload phase - partial remainder */
9461
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9462
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9463
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
9464
            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
9465
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9466
    }
9467
    if (status == HAL_OK && !useSwGhash) {
9468
        /* Compute the authTag */
9469
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
9470
    }
9471
#endif
9472
9473
    if (status != HAL_OK)
9474
        ret = AES_GCM_AUTH_E;
9475
    HAL_CRYP_DeInit(&hcryp);
9476
9477
#else /* Standard Peripheral Library */
9478
    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
9479
    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
9480
                         (uint8_t*)keyCopy,      keySize * 8,
9481
                         (uint8_t*)in,           sz,
9482
                         (uint8_t*)authInPadded, authInSz,
9483
                         (uint8_t*)out,          (uint8_t*)tag);
9484
    if (status != SUCCESS)
9485
        ret = AES_GCM_AUTH_E;
9486
#endif /* WOLFSSL_STM32_CUBEMX */
9487
    wolfSSL_CryptHwMutexUnLock();
9488
    wc_Stm32_Aes_Cleanup();
9489
9490
    if (ret == 0) {
9491
        /* return authTag */
9492
        if (authTag) {
9493
            if (useSwGhash) {
9494
                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
9495
                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
9496
                if (ret == 0) {
9497
                    xorbuf(authTag, tag, authTagSz);
9498
                }
9499
            }
9500
            else {
9501
                /* use hardware calculated tag */
9502
                XMEMCPY(authTag, tag, authTagSz);
9503
            }
9504
        }
9505
    }
9506
9507
    /* Free memory */
9508
    if (wasAlloc) {
9509
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
9510
    }
9511
9512
    return ret;
9513
}
9514
9515
#endif /* STM32_CRYPTO_AES_GCM */
9516
9517
#if !defined(WOLFSSL_ARMASM)
9518
#ifdef WOLFSSL_AESNI
9519
/* For performance reasons, this code needs to be not inlined. */
9520
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
9521
                      Aes* aes, byte* out, const byte* in, word32 sz,
9522
                      const byte* iv, word32 ivSz,
9523
                      byte* authTag, word32 authTagSz,
9524
                      const byte* authIn, word32 authInSz);
9525
#else
9526
static
9527
#endif
9528
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
9529
                      Aes* aes, byte* out, const byte* in, word32 sz,
9530
                      const byte* iv, word32 ivSz,
9531
                      byte* authTag, word32 authTagSz,
9532
                      const byte* authIn, word32 authInSz)
9533
{
9534
    int ret = 0;
9535
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
9536
    word32 partial = sz % WC_AES_BLOCK_SIZE;
9537
    const byte* p = in;
9538
    byte* c = out;
9539
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
9540
    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
9541
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
9542
9543
    if (ivSz == GCM_NONCE_MID_SZ) {
9544
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
9545
        XMEMCPY(counter, iv, ivSz);
9546
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
9547
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
9548
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
9549
    }
9550
    else {
9551
        /* Counter is GHASH of IV. */
9552
#ifdef OPENSSL_EXTRA
9553
        word32 aadTemp = aes->gcm.aadLen;
9554
        aes->gcm.aadLen = 0;
9555
#endif
9556
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
9557
#ifdef OPENSSL_EXTRA
9558
        aes->gcm.aadLen = aadTemp;
9559
#endif
9560
    }
9561
    XMEMCPY(initialCounter, counter, WC_AES_BLOCK_SIZE);
9562
9563
#ifdef WOLFSSL_PIC32MZ_CRYPT
9564
    if (blocks) {
9565
        /* use initial IV for HW, but don't use it below */
9566
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
9567
9568
        ret = wc_Pic32AesCrypt(
9569
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
9570
            out, in, (blocks * WC_AES_BLOCK_SIZE),
9571
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
9572
        if (ret != 0)
9573
            return ret;
9574
    }
9575
    /* process remainder using partial handling */
9576
#endif
9577
9578
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
9579
    /* some hardware acceleration can gain performance from doing AES encryption
9580
     * of the whole buffer at once */
9581
    if (c != p && blocks > 0) { /* can not handle inline encryption */
9582
        while (blocks--) {
9583
            IncrementGcmCounter(counter);
9584
            XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
9585
            c += WC_AES_BLOCK_SIZE;
9586
        }
9587
9588
        /* reset number of blocks and then do encryption */
9589
        blocks = sz / WC_AES_BLOCK_SIZE;
9590
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
9591
        xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
9592
        p += WC_AES_BLOCK_SIZE * blocks;
9593
    }
9594
    else
9595
#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
9596
    {
9597
        while (blocks--) {
9598
            IncrementGcmCounter(counter);
9599
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
9600
            ret = wc_AesEncrypt(aes, counter, scratch);
9601
            if (ret != 0)
9602
                return ret;
9603
            xorbufout(c, scratch, p, WC_AES_BLOCK_SIZE);
9604
        #endif
9605
            p += WC_AES_BLOCK_SIZE;
9606
            c += WC_AES_BLOCK_SIZE;
9607
        }
9608
    }
9609
9610
    if (partial != 0) {
9611
        IncrementGcmCounter(counter);
9612
        ret = wc_AesEncrypt(aes, counter, scratch);
9613
        if (ret != 0)
9614
            return ret;
9615
        xorbufout(c, scratch, p, partial);
9616
    }
9617
    if (authTag) {
9618
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
9619
        ret = wc_AesEncrypt(aes, initialCounter, scratch);
9620
        if (ret != 0)
9621
            return ret;
9622
        xorbuf(authTag, scratch, authTagSz);
9623
#ifdef OPENSSL_EXTRA
9624
        if (!in && !sz)
9625
            /* store AAD size for next call */
9626
            aes->gcm.aadLen = authInSz;
9627
#endif
9628
    }
9629
9630
    return ret;
9631
}
9632
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
9633
static int AES_GCM_encrypt_ARM(Aes* aes, byte* out, const byte* in,
9634
    word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
9635
    const byte* authIn, word32 authInSz)
9636
{
9637
    word32 blocks;
9638
    word32 partial;
9639
    byte counter[WC_AES_BLOCK_SIZE];
9640
    byte initialCounter[WC_AES_BLOCK_SIZE];
9641
    byte x[WC_AES_BLOCK_SIZE];
9642
    byte scratch[WC_AES_BLOCK_SIZE];
9643
9644
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
9645
    if (ivSz == GCM_NONCE_MID_SZ) {
9646
        XMEMCPY(initialCounter, iv, ivSz);
9647
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
9648
    }
9649
    else {
9650
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
9651
    }
9652
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
9653
9654
    /* Hash in the Additional Authentication Data */
9655
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9656
    if (authInSz != 0 && authIn != NULL) {
9657
        blocks = authInSz / WC_AES_BLOCK_SIZE;
9658
        partial = authInSz % WC_AES_BLOCK_SIZE;
9659
        if (blocks > 0) {
9660
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
9661
            authIn += blocks * WC_AES_BLOCK_SIZE;
9662
        }
9663
        if (partial != 0) {
9664
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9665
            XMEMCPY(scratch, authIn, partial);
9666
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9667
        }
9668
    }
9669
9670
    /* do as many blocks as possible */
9671
    blocks = sz / WC_AES_BLOCK_SIZE;
9672
    partial = sz % WC_AES_BLOCK_SIZE;
9673
    if (blocks > 0) {
9674
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
9675
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
9676
        if (sz >= 32)
9677
    #endif
9678
        {
9679
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
9680
                (const unsigned char*)aes->key, aes->rounds, counter);
9681
        }
9682
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
9683
        else
9684
    #endif
9685
    #endif
9686
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
9687
        {
9688
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
9689
                (const unsigned char*)aes->key, aes->rounds, counter);
9690
        }
9691
    #endif
9692
        GCM_GMULT_LEN(&aes->gcm, x, out, blocks * WC_AES_BLOCK_SIZE);
9693
        in += blocks * WC_AES_BLOCK_SIZE;
9694
        out += blocks * WC_AES_BLOCK_SIZE;
9695
    }
9696
    /* take care of partial block sizes leftover */
9697
    if (partial != 0) {
9698
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
9699
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
9700
        {
9701
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
9702
                (const unsigned char*)aes->key, aes->rounds, counter);
9703
        }
9704
    #else
9705
        {
9706
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
9707
                (const unsigned char*)aes->key, aes->rounds, counter);
9708
        }
9709
    #endif
9710
        XMEMCPY(out, scratch, partial);
9711
9712
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9713
        XMEMCPY(scratch, out, partial);
9714
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9715
    }
9716
9717
    /* Hash in the lengths of A and C in bits */
9718
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9719
    FlattenSzInBits(&scratch[0], authInSz);
9720
    FlattenSzInBits(&scratch[8], sz);
9721
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9722
    if (authTagSz > WC_AES_BLOCK_SIZE) {
9723
        XMEMCPY(authTag, x, WC_AES_BLOCK_SIZE);
9724
    }
9725
    else {
9726
        /* authTagSz can be smaller than WC_AES_BLOCK_SIZE */
9727
        XMEMCPY(authTag, x, authTagSz);
9728
    }
9729
9730
    /* Auth tag calculation. */
9731
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
9732
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
9733
    {
9734
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
9735
            (const unsigned char*)aes->key, aes->rounds);
9736
    }
9737
#else
9738
    {
9739
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
9740
            (const unsigned char*)aes->key, aes->rounds);
9741
    }
9742
#endif
9743
    xorbuf(authTag, scratch, authTagSz);
9744
9745
    return 0;
9746
}
9747
#endif
9748
9749
/* Software AES - GCM Encrypt */
9750
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
9751
                   const byte* iv, word32 ivSz,
9752
                   byte* authTag, word32 authTagSz,
9753
                   const byte* authIn, word32 authInSz)
9754
843
{
9755
843
    int ret;
9756
9757
    /* argument checks */
9758
843
    if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE || ivSz == 0 ||
9759
843
        ((authTagSz > 0) && (authTag == NULL)) ||
9760
843
        ((authInSz > 0) && (authIn == NULL)))
9761
0
    {
9762
0
        return BAD_FUNC_ARG;
9763
0
    }
9764
9765
843
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
9766
0
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
9767
0
        return BAD_FUNC_ARG;
9768
0
    }
9769
9770
843
#ifdef WOLF_CRYPTO_CB
9771
843
    #ifndef WOLF_CRYPTO_CB_FIND
9772
843
    if (aes->devId != INVALID_DEVID)
9773
0
    #endif
9774
0
    {
9775
0
        int crypto_cb_ret =
9776
0
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
9777
0
                                      authTagSz, authIn, authInSz);
9778
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
9779
0
            return crypto_cb_ret;
9780
        /* fall-through when unavailable */
9781
0
    }
9782
843
#endif
9783
9784
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
9785
    /* if async and byte count above threshold */
9786
    /* only 12-byte IV is supported in HW */
9787
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
9788
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
9789
    #if defined(HAVE_CAVIUM)
9790
        #ifdef HAVE_CAVIUM_V
9791
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
9792
            return NitroxAesGcmEncrypt(aes, out, in, sz,
9793
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
9794
                authTag, authTagSz, authIn, authInSz);
9795
        }
9796
        #endif
9797
    #elif defined(HAVE_INTEL_QA)
9798
        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
9799
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
9800
            authTag, authTagSz, authIn, authInSz);
9801
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
9802
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
9803
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
9804
            sw->aes.aes = aes;
9805
            sw->aes.out = out;
9806
            sw->aes.in = in;
9807
            sw->aes.sz = sz;
9808
            sw->aes.iv = iv;
9809
            sw->aes.ivSz = ivSz;
9810
            sw->aes.authTag = authTag;
9811
            sw->aes.authTagSz = authTagSz;
9812
            sw->aes.authIn = authIn;
9813
            sw->aes.authInSz = authInSz;
9814
            return WC_PENDING_E;
9815
        }
9816
    #endif
9817
    }
9818
#endif /* WOLFSSL_ASYNC_CRYPT */
9819
9820
#ifdef WOLFSSL_SILABS_SE_ACCEL
9821
    return wc_AesGcmEncrypt_silabs(
9822
        aes, out, in, sz,
9823
        iv, ivSz,
9824
        authTag, authTagSz,
9825
        authIn, authInSz);
9826
#endif
9827
9828
#ifdef STM32_CRYPTO_AES_GCM
9829
    return wc_AesGcmEncrypt_STM32(
9830
        aes, out, in, sz, iv, ivSz,
9831
        authTag, authTagSz, authIn, authInSz);
9832
#endif /* STM32_CRYPTO_AES_GCM */
9833
9834
#if defined(WOLFSSL_PSOC6_CRYPTO)
9835
    return wc_Psoc6_Aes_GcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
9836
                                   authTagSz, authIn, authInSz);
9837
#endif /* WOLFSSL_PSOC6_CRYPTO */
9838
9839
843
    VECTOR_REGISTERS_PUSH;
9840
9841
#if defined(WOLFSSL_ARMASM)
9842
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
9843
#if !defined(__aarch64__)
9844
    AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
9845
        authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
9846
        aes->rounds);
9847
    ret = 0;
9848
#else
9849
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
9850
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
9851
        if (aes->use_sha3_hw_crypto) {
9852
            AES_GCM_encrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
9853
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
9854
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
9855
        }
9856
        else
9857
    #endif
9858
        {
9859
            AES_GCM_encrypt_AARCH64(in, out, sz, iv, ivSz, authTag, authTagSz,
9860
                authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
9861
                (byte*)aes->reg, aes->rounds);
9862
        }
9863
        ret = 0;
9864
    }
9865
    else
9866
#endif /* !__aarch64__ */
9867
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
9868
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
9869
    {
9870
        ret = AES_GCM_encrypt_ARM(aes, out, in, sz, iv, ivSz, authTag,
9871
            authTagSz, authIn, authInSz);
9872
    }
9873
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
9874
#else
9875
#ifdef WOLFSSL_AESNI
9876
    if (aes->use_aesni) {
9877
#ifdef HAVE_INTEL_AVX2
9878
        if (IS_INTEL_AVX2(intel_flags)) {
9879
            AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
9880
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
9881
            ret = 0;
9882
        }
9883
        else
9884
#endif
9885
#if defined(HAVE_INTEL_AVX1)
9886
        if (IS_INTEL_AVX1(intel_flags)) {
9887
            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
9888
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
9889
            ret = 0;
9890
        } else
9891
#endif
9892
        {
9893
            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
9894
                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
9895
            ret = 0;
9896
        }
9897
    }
9898
    else
9899
#endif /* WOLFSSL_AESNI */
9900
843
    {
9901
843
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
9902
843
                                authIn, authInSz);
9903
843
    }
9904
843
#endif
9905
9906
843
    VECTOR_REGISTERS_POP;
9907
9908
843
    return ret;
9909
843
}
9910
#endif
9911
9912
9913
/* AES GCM Decrypt */
9914
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
9915
#ifdef FREESCALE_LTC_AES_GCM
9916
int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
9917
                   const byte* iv, word32 ivSz,
9918
                   const byte* authTag, word32 authTagSz,
9919
                   const byte* authIn, word32 authInSz)
9920
{
9921
    int ret;
9922
    word32 keySize;
9923
    status_t status;
9924
9925
    /* argument checks */
9926
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
9927
     * in and out are don't cares, as this is is the GMAC case. */
9928
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
9929
        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE || authTagSz == 0 ||
9930
        ivSz == 0 || ((authInSz > 0) && (authIn == NULL)))
9931
    {
9932
        return BAD_FUNC_ARG;
9933
    }
9934
9935
    ret = wc_AesGetKeySize(aes, &keySize);
9936
    if (ret != 0) {
9937
        return ret;
9938
    }
9939
9940
    status = wolfSSL_CryptHwMutexLock();
9941
    if (status != 0)
9942
        return status;
9943
9944
    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
9945
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
9946
    wolfSSL_CryptHwMutexUnLock();
9947
9948
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
9949
}
9950
9951
#else
9952
9953
#ifdef STM32_CRYPTO_AES_GCM
9954
/* this function supports inline decrypt */
9955
static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
9956
                                  Aes* aes, byte* out,
9957
                                  const byte* in, word32 sz,
9958
                                  const byte* iv, word32 ivSz,
9959
                                  const byte* authTag, word32 authTagSz,
9960
                                  const byte* authIn, word32 authInSz)
9961
{
9962
    int ret;
9963
#ifdef WOLFSSL_STM32_CUBEMX
9964
    int status = HAL_OK;
9965
    CRYP_HandleTypeDef hcryp;
9966
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
9967
#else
9968
    int status = SUCCESS;
9969
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
9970
#endif
9971
    word32 keySize;
9972
    word32 partial = sz % WC_AES_BLOCK_SIZE;
9973
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
9974
    word32 tagExpected[WC_AES_BLOCK_SIZE/sizeof(word32)];
9975
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
9976
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
9977
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
9978
    byte* authInPadded = NULL;
9979
    int authPadSz, wasAlloc = 0, tagComputed = 0;
9980
9981
    ret = wc_AesGetKeySize(aes, &keySize);
9982
    if (ret != 0)
9983
        return ret;
9984
9985
#ifdef WOLFSSL_STM32_CUBEMX
9986
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
9987
    if (ret != 0)
9988
        return ret;
9989
#endif
9990
9991
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
9992
    if (ivSz == GCM_NONCE_MID_SZ) {
9993
        byte* pCtr = (byte*)ctr;
9994
        XMEMCPY(ctr, iv, ivSz);
9995
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
9996
    }
9997
    else {
9998
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
9999
    }
10000
10001
    /* Make copy of expected authTag, which could get corrupted in some
10002
     * Cube HAL versions without proper partial block support.
10003
     * For TLS blocks the authTag is after the output buffer, so save it */
10004
    XMEMCPY(tagExpected, authTag, authTagSz);
10005
10006
    /* Authentication buffer */
10007
#if STM_CRYPT_HEADER_WIDTH == 1
10008
    authPadSz = 0; /* CubeHAL supports byte mode */
10009
#else
10010
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
10011
#endif
10012
#ifdef WOLFSSL_STM32MP13
10013
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
10014
     * minimum of 16 bytes for the auth */
10015
    if ((authInSz > 0) && (authInSz < 16)) {
10016
        authPadSz = 16 - authInSz;
10017
    }
10018
#else
10019
    if (authPadSz != 0) {
10020
        authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
10021
    }
10022
    else {
10023
        authPadSz = authInSz;
10024
    }
10025
#endif
10026
10027
    /* for cases where hardware cannot be used for authTag calculate it */
10028
    /* if IV is not 12 calculate GHASH using software */
10029
    if (ivSz != GCM_NONCE_MID_SZ
10030
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
10031
        /* or hardware that does not support partial block */
10032
        || sz == 0 || partial != 0
10033
    #endif
10034
    #if STM_CRYPT_HEADER_WIDTH == 4
10035
        /* or authIn is not a multiple of 4  */
10036
        || authPadSz != authInSz
10037
    #endif
10038
    ) {
10039
        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
10040
        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
10041
        if (ret != 0)
10042
            return ret;
10043
        xorbuf(tag, partialBlock, sizeof(tag));
10044
        tagComputed = 1;
10045
    }
10046
10047
    /* if using hardware for authentication tag make sure its aligned and zero padded */
10048
    if (authPadSz != authInSz && !tagComputed) {
10049
        if (authPadSz <= sizeof(authhdr)) {
10050
            authInPadded = (byte*)authhdr;
10051
        }
10052
        else {
10053
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
10054
                DYNAMIC_TYPE_TMP_BUFFER);
10055
            if (authInPadded == NULL) {
10056
                wolfSSL_CryptHwMutexUnLock();
10057
                return MEMORY_E;
10058
            }
10059
            wasAlloc = 1;
10060
        }
10061
        XMEMSET(authInPadded, 0, authPadSz);
10062
        XMEMCPY(authInPadded, authIn, authInSz);
10063
    } else {
10064
        authInPadded = (byte*)authIn;
10065
    }
10066
10067
    /* Hardware requires counter + 1 */
10068
    IncrementGcmCounter((byte*)ctr);
10069
10070
    ret = wolfSSL_CryptHwMutexLock();
10071
    if (ret != 0) {
10072
        return ret;
10073
    }
10074
10075
#ifdef WOLFSSL_STM32_CUBEMX
10076
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10077
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
10078
10079
#if defined(STM32_HAL_V2)
10080
    hcryp.Init.Algorithm = CRYP_AES_GCM;
10081
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
10082
    #ifdef CRYP_KEYIVCONFIG_ONCE
10083
    /* allows repeated calls to HAL_CRYP_Decrypt */
10084
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
10085
    #endif
10086
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
10087
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10088
    HAL_CRYP_Init(&hcryp);
10089
10090
    #ifndef CRYP_KEYIVCONFIG_ONCE
10091
    /* GCM payload phase - can handle partial blocks */
10092
    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
10093
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
10094
    #else
10095
    /* GCM payload phase - blocks */
10096
    if (blocks) {
10097
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
10098
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
10099
    }
10100
    /* GCM payload phase - partial remainder */
10101
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10102
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10103
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10104
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
10105
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
10106
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10107
    }
10108
    #endif
10109
    if (status == HAL_OK && !tagComputed) {
10110
        /* Compute the authTag */
10111
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
10112
            STM32_HAL_TIMEOUT);
10113
    }
10114
#elif defined(STM32_CRYPTO_AES_ONLY)
10115
    /* Set the CRYP parameters */
10116
    hcryp.Init.HeaderSize = authPadSz;
10117
    if (authPadSz == 0)
10118
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
10119
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
10120
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
10121
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
10122
    HAL_CRYP_Init(&hcryp);
10123
10124
    /* GCM init phase */
10125
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10126
    if (status == HAL_OK) {
10127
        /* GCM header phase */
10128
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
10129
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10130
    }
10131
    if (status == HAL_OK) {
10132
        /* GCM payload phase - blocks */
10133
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
10134
        if (blocks) {
10135
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
10136
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10137
        }
10138
    }
10139
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
10140
        /* GCM payload phase - partial remainder */
10141
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10142
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10143
        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
10144
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
10145
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10146
    }
10147
    if (status == HAL_OK && tagComputed == 0) {
10148
        /* GCM final phase */
10149
        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
10150
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
10151
    }
10152
#else
10153
    hcryp.Init.HeaderSize = authPadSz;
10154
    HAL_CRYP_Init(&hcryp);
10155
    if (blocks) {
10156
        /* GCM payload phase - blocks */
10157
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
10158
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10159
    }
10160
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10161
        /* GCM payload phase - partial remainder */
10162
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10163
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10164
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
10165
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
10166
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10167
    }
10168
    if (status == HAL_OK && tagComputed == 0) {
10169
        /* Compute the authTag */
10170
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
10171
    }
10172
#endif
10173
10174
    if (status != HAL_OK)
10175
        ret = AES_GCM_AUTH_E;
10176
10177
    HAL_CRYP_DeInit(&hcryp);
10178
10179
#else /* Standard Peripheral Library */
10180
    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
10181
10182
    /* Input size and auth size need to be the actual sizes, even though
10183
     * they are not block aligned, because this length (in bits) is used
10184
     * in the final GHASH. */
10185
    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
10186
    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
10187
                         (uint8_t*)keyCopy,      keySize * 8,
10188
                         (uint8_t*)in,           sz,
10189
                         (uint8_t*)authInPadded, authInSz,
10190
                         (uint8_t*)out,          (uint8_t*)partialBlock);
10191
    if (status != SUCCESS)
10192
        ret = AES_GCM_AUTH_E;
10193
    if (tagComputed == 0)
10194
        XMEMCPY(tag, partialBlock, authTagSz);
10195
#endif /* WOLFSSL_STM32_CUBEMX */
10196
    wolfSSL_CryptHwMutexUnLock();
10197
    wc_Stm32_Aes_Cleanup();
10198
10199
    /* Check authentication tag */
10200
    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
10201
        ret = AES_GCM_AUTH_E;
10202
    }
10203
10204
    /* Free memory */
10205
    if (wasAlloc) {
10206
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
10207
    }
10208
10209
    return ret;
10210
}
10211
10212
#endif /* STM32_CRYPTO_AES_GCM */
10213
10214
#if !defined(WOLFSSL_ARMASM)
10215
#ifdef WOLFSSL_AESNI
10216
/* For performance reasons, this code needs to be not inlined. */
10217
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
10218
                      Aes* aes, byte* out, const byte* in, word32 sz,
10219
                      const byte* iv, word32 ivSz,
10220
                      const byte* authTag, word32 authTagSz,
10221
                      const byte* authIn, word32 authInSz);
10222
#else
10223
static
10224
#endif
10225
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
10226
                      Aes* aes, byte* out, const byte* in, word32 sz,
10227
                      const byte* iv, word32 ivSz,
10228
                      const byte* authTag, word32 authTagSz,
10229
                      const byte* authIn, word32 authInSz)
10230
0
{
10231
0
    int ret;
10232
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10233
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
10234
0
    const byte* c = in;
10235
0
    byte* p = out;
10236
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
10237
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
10238
0
    ALIGN16 byte Tprime[WC_AES_BLOCK_SIZE];
10239
0
    ALIGN16 byte EKY0[WC_AES_BLOCK_SIZE];
10240
0
    volatile sword32 res;
10241
10242
0
    if (ivSz == GCM_NONCE_MID_SZ) {
10243
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
10244
0
        XMEMCPY(counter, iv, ivSz);
10245
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
10246
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
10247
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
10248
0
    }
10249
0
    else {
10250
        /* Counter is GHASH of IV. */
10251
#ifdef OPENSSL_EXTRA
10252
        word32 aadTemp = aes->gcm.aadLen;
10253
        aes->gcm.aadLen = 0;
10254
#endif
10255
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
10256
#ifdef OPENSSL_EXTRA
10257
        aes->gcm.aadLen = aadTemp;
10258
#endif
10259
0
    }
10260
10261
    /* Calc the authTag again using received auth data and the cipher text */
10262
0
    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
10263
0
    ret = wc_AesEncrypt(aes, counter, EKY0);
10264
0
    if (ret != 0)
10265
0
        return ret;
10266
0
    xorbuf(Tprime, EKY0, sizeof(Tprime));
10267
#ifdef WC_AES_GCM_DEC_AUTH_EARLY
10268
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
10269
     * the pairwise bytes in the strings.
10270
     */
10271
    res = ConstantCompare(authTag, Tprime, authTagSz);
10272
    /* convert positive retval from ConstantCompare() to all-1s word, in
10273
     * constant time.
10274
     */
10275
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
10276
    ret = res & AES_GCM_AUTH_E;
10277
    if (ret != 0)
10278
        return ret;
10279
#endif
10280
10281
#ifdef OPENSSL_EXTRA
10282
    if (!out) {
10283
        /* authenticated, non-confidential data */
10284
        /* store AAD size for next call */
10285
        aes->gcm.aadLen = authInSz;
10286
    }
10287
#endif
10288
10289
#if defined(WOLFSSL_PIC32MZ_CRYPT)
10290
    if (blocks) {
10291
        /* use initial IV for HW, but don't use it below */
10292
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
10293
10294
        ret = wc_Pic32AesCrypt(
10295
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
10296
            out, in, (blocks * WC_AES_BLOCK_SIZE),
10297
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
10298
        if (ret != 0)
10299
            return ret;
10300
    }
10301
    /* process remainder using partial handling */
10302
#endif
10303
10304
0
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
10305
    /* some hardware acceleration can gain performance from doing AES encryption
10306
     * of the whole buffer at once */
10307
0
    if (c != p && blocks > 0) { /* can not handle inline decryption */
10308
0
        while (blocks--) {
10309
0
            IncrementGcmCounter(counter);
10310
0
            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
10311
0
            p += WC_AES_BLOCK_SIZE;
10312
0
        }
10313
10314
        /* reset number of blocks and then do encryption */
10315
0
        blocks = sz / WC_AES_BLOCK_SIZE;
10316
10317
0
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
10318
0
        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
10319
0
        c += WC_AES_BLOCK_SIZE * blocks;
10320
0
    }
10321
0
    else
10322
0
#endif /* HAVE_AES_ECB && !PIC32MZ */
10323
0
    {
10324
0
        while (blocks--) {
10325
0
            IncrementGcmCounter(counter);
10326
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
10327
0
            ret = wc_AesEncrypt(aes, counter, scratch);
10328
0
            if (ret != 0)
10329
0
                return ret;
10330
0
            xorbufout(p, scratch, c, WC_AES_BLOCK_SIZE);
10331
0
        #endif
10332
0
            p += WC_AES_BLOCK_SIZE;
10333
0
            c += WC_AES_BLOCK_SIZE;
10334
0
        }
10335
0
    }
10336
10337
0
    if (partial != 0) {
10338
0
        IncrementGcmCounter(counter);
10339
0
        ret = wc_AesEncrypt(aes, counter, scratch);
10340
0
        if (ret != 0)
10341
0
            return ret;
10342
0
        xorbuf(scratch, c, partial);
10343
0
        XMEMCPY(p, scratch, partial);
10344
0
    }
10345
10346
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
10347
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
10348
     * the pairwise bytes in the strings.
10349
     */
10350
0
    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
10351
    /* convert positive retval from ConstantCompare() to all-1s word, in
10352
     * constant time.
10353
     */
10354
0
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
10355
    /* now use res as a mask for constant time return of ret, unless tag
10356
     * mismatch, whereupon AES_GCM_AUTH_E is returned.
10357
     */
10358
0
    ret = (ret & ~res) | (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
10359
0
#endif
10360
0
    return ret;
10361
0
}
10362
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10363
static int AES_GCM_decrypt_ARM(Aes* aes, byte* out, const byte* in,
10364
    word32 sz, const byte* iv, word32 ivSz, const byte* authTag,
10365
    word32 authTagSz, const byte* authIn, word32 authInSz)
10366
{
10367
    word32 blocks;
10368
    word32 partial;
10369
    byte counter[WC_AES_BLOCK_SIZE];
10370
    byte initialCounter[WC_AES_BLOCK_SIZE];
10371
    byte scratch[WC_AES_BLOCK_SIZE];
10372
    byte x[WC_AES_BLOCK_SIZE];
10373
10374
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
10375
    if (ivSz == GCM_NONCE_MID_SZ) {
10376
        XMEMCPY(initialCounter, iv, ivSz);
10377
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
10378
    }
10379
    else {
10380
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
10381
    }
10382
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
10383
10384
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
10385
    /* Hash in the Additional Authentication Data */
10386
    if (authInSz != 0 && authIn != NULL) {
10387
        blocks = authInSz / WC_AES_BLOCK_SIZE;
10388
        partial = authInSz % WC_AES_BLOCK_SIZE;
10389
        if (blocks > 0) {
10390
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
10391
            authIn += blocks * WC_AES_BLOCK_SIZE;
10392
        }
10393
        if (partial != 0) {
10394
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10395
            XMEMCPY(scratch, authIn, partial);
10396
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10397
        }
10398
    }
10399
10400
    blocks = sz / WC_AES_BLOCK_SIZE;
10401
    partial = sz % WC_AES_BLOCK_SIZE;
10402
    /* do as many blocks as possible */
10403
    if (blocks > 0) {
10404
        GCM_GMULT_LEN(&aes->gcm, x, in, blocks * WC_AES_BLOCK_SIZE);
10405
10406
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
10407
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10408
        if (sz >= 32)
10409
    #endif
10410
        {
10411
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
10412
                (const unsigned char*)aes->key, aes->rounds, counter);
10413
        }
10414
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10415
        else
10416
    #endif
10417
    #endif
10418
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10419
        {
10420
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
10421
                (const unsigned char*)aes->key, aes->rounds, counter);
10422
        }
10423
    #endif
10424
        in += blocks * WC_AES_BLOCK_SIZE;
10425
        out += blocks * WC_AES_BLOCK_SIZE;
10426
    }
10427
    if (partial != 0) {
10428
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10429
        XMEMCPY(scratch, in, partial);
10430
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10431
10432
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10433
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10434
        {
10435
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
10436
                (const unsigned char*)aes->key, aes->rounds, counter);
10437
        }
10438
    #else
10439
        {
10440
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
10441
                (const unsigned char*)aes->key, aes->rounds, counter);
10442
        }
10443
    #endif
10444
        XMEMCPY(out, scratch, partial);
10445
    }
10446
10447
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10448
    FlattenSzInBits(&scratch[0], authInSz);
10449
    FlattenSzInBits(&scratch[8], sz);
10450
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10451
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10452
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10453
    {
10454
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10455
            (const unsigned char*)aes->key, aes->rounds);
10456
    }
10457
#else
10458
    {
10459
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10460
            (const unsigned char*)aes->key, aes->rounds);
10461
    }
10462
#endif
10463
    xorbuf(x, scratch, authTagSz);
10464
    if (authTag != NULL) {
10465
        if (ConstantCompare(authTag, x, authTagSz) != 0) {
10466
            return AES_GCM_AUTH_E;
10467
        }
10468
    }
10469
10470
    return 0;
10471
}
10472
#endif
10473
10474
/* Software AES - GCM Decrypt */
10475
int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10476
                     const byte* iv, word32 ivSz,
10477
                     const byte* authTag, word32 authTagSz,
10478
                     const byte* authIn, word32 authInSz)
10479
830
{
10480
830
    int ret;
10481
#ifdef WOLFSSL_AESNI
10482
    int res = WC_NO_ERR_TRACE(AES_GCM_AUTH_E);
10483
#endif
10484
10485
    /* argument checks */
10486
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
10487
     * in and out are don't cares, as this is is the GMAC case. */
10488
830
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
10489
830
        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE || authTagSz == 0 ||
10490
830
        ivSz == 0) {
10491
10492
0
        return BAD_FUNC_ARG;
10493
0
    }
10494
10495
830
#ifdef WOLF_CRYPTO_CB
10496
830
    #ifndef WOLF_CRYPTO_CB_FIND
10497
830
    if (aes->devId != INVALID_DEVID)
10498
0
    #endif
10499
0
    {
10500
0
        int crypto_cb_ret =
10501
0
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
10502
0
                                      authTag, authTagSz, authIn, authInSz);
10503
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
10504
0
            return crypto_cb_ret;
10505
        /* fall-through when unavailable */
10506
0
    }
10507
830
#endif
10508
10509
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
10510
    /* if async and byte count above threshold */
10511
    /* only 12-byte IV is supported in HW */
10512
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
10513
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
10514
    #if defined(HAVE_CAVIUM)
10515
        #ifdef HAVE_CAVIUM_V
10516
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
10517
            return NitroxAesGcmDecrypt(aes, out, in, sz,
10518
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10519
                authTag, authTagSz, authIn, authInSz);
10520
        }
10521
        #endif
10522
    #elif defined(HAVE_INTEL_QA)
10523
        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
10524
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10525
            authTag, authTagSz, authIn, authInSz);
10526
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
10527
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
10528
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
10529
            sw->aes.aes = aes;
10530
            sw->aes.out = out;
10531
            sw->aes.in = in;
10532
            sw->aes.sz = sz;
10533
            sw->aes.iv = iv;
10534
            sw->aes.ivSz = ivSz;
10535
            sw->aes.authTag = (byte*)authTag;
10536
            sw->aes.authTagSz = authTagSz;
10537
            sw->aes.authIn = authIn;
10538
            sw->aes.authInSz = authInSz;
10539
            return WC_PENDING_E;
10540
        }
10541
    #endif
10542
    }
10543
#endif /* WOLFSSL_ASYNC_CRYPT */
10544
10545
#ifdef WOLFSSL_SILABS_SE_ACCEL
10546
    return wc_AesGcmDecrypt_silabs(
10547
        aes, out, in, sz, iv, ivSz,
10548
        authTag, authTagSz, authIn, authInSz);
10549
10550
#endif
10551
10552
#ifdef STM32_CRYPTO_AES_GCM
10553
    /* The STM standard peripheral library API's doesn't support partial blocks */
10554
    return wc_AesGcmDecrypt_STM32(
10555
        aes, out, in, sz, iv, ivSz,
10556
        authTag, authTagSz, authIn, authInSz);
10557
#endif /* STM32_CRYPTO_AES_GCM */
10558
10559
#if defined(WOLFSSL_PSOC6_CRYPTO)
10560
    return wc_Psoc6_Aes_GcmDecrypt(aes, out, in, sz, iv, ivSz, authTag,
10561
                                   authTagSz, authIn, authInSz);
10562
#endif /* WOLFSSL_PSOC6_CRYPTO */
10563
10564
830
    VECTOR_REGISTERS_PUSH;
10565
10566
#if defined(WOLFSSL_ARMASM)
10567
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
10568
#ifndef __aarch64__
10569
    {
10570
    #ifdef OPENSSL_EXTRA
10571
        word32 reg[WC_AES_BLOCK_SIZE / sizeof(word32)];
10572
        XMEMCPY(reg, aes->reg, sizeof(reg));
10573
    #endif
10574
        ret = AES_GCM_decrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
10575
            authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
10576
            (byte*)aes->reg, aes->rounds);
10577
    #ifdef OPENSSL_EXTRA
10578
        XMEMCPY(aes->reg, reg, sizeof(reg));
10579
    #endif
10580
    }
10581
#else
10582
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10583
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
10584
        if (aes->use_sha3_hw_crypto) {
10585
            ret = AES_GCM_decrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
10586
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
10587
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
10588
        }
10589
        else
10590
    #endif
10591
        {
10592
            ret = AES_GCM_decrypt_AARCH64(in, out, sz, iv, ivSz, authTag,
10593
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
10594
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
10595
        }
10596
    }
10597
    else
10598
#endif /* !__aarch64__ */
10599
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
10600
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10601
    {
10602
        ret = AES_GCM_decrypt_ARM(aes, out, in, sz, iv, ivSz, authTag,
10603
            authTagSz, authIn, authInSz);
10604
    }
10605
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
10606
#else
10607
#ifdef WOLFSSL_AESNI
10608
    if (aes->use_aesni) {
10609
#ifdef HAVE_INTEL_AVX2
10610
        if (IS_INTEL_AVX2(intel_flags)) {
10611
            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10612
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
10613
            if (res == 0)
10614
                ret = AES_GCM_AUTH_E;
10615
            else
10616
                ret = 0;
10617
        }
10618
        else
10619
#endif
10620
#if defined(HAVE_INTEL_AVX1)
10621
        if (IS_INTEL_AVX1(intel_flags)) {
10622
            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10623
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
10624
            if (res == 0)
10625
                ret = AES_GCM_AUTH_E;
10626
            else
10627
                ret = 0;
10628
        }
10629
        else
10630
#endif
10631
        {
10632
            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10633
                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
10634
            if (res == 0)
10635
                ret = AES_GCM_AUTH_E;
10636
            else
10637
                ret = 0;
10638
        }
10639
    }
10640
    else
10641
#endif /* WOLFSSL_AESNI */
10642
830
    {
10643
830
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
10644
830
                                                             authIn, authInSz);
10645
830
    }
10646
830
#endif
10647
10648
830
    VECTOR_REGISTERS_POP;
10649
10650
830
    return ret;
10651
830
}
10652
#endif
10653
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
10654
10655
#ifdef WOLFSSL_AESGCM_STREAM
10656
10657
/* Initialize the AES GCM cipher with an IV. C implementation.
10658
 *
10659
 * @param [in, out] aes   AES object.
10660
 * @param [in]      iv    IV/nonce buffer.
10661
 * @param [in]      ivSz  Length of IV/nonce data.
10662
 */
10663
static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
10664
2.68k
{
10665
2.68k
    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
10666
2.68k
    int ret;
10667
10668
2.68k
    if (ivSz == GCM_NONCE_MID_SZ) {
10669
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
10670
2.68k
        XMEMCPY(counter, iv, ivSz);
10671
2.68k
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
10672
2.68k
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
10673
2.68k
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
10674
2.68k
    }
10675
0
    else {
10676
        /* Counter is GHASH of IV. */
10677
    #ifdef OPENSSL_EXTRA
10678
        word32 aadTemp = aes->gcm.aadLen;
10679
        aes->gcm.aadLen = 0;
10680
    #endif
10681
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
10682
    #ifdef OPENSSL_EXTRA
10683
        aes->gcm.aadLen = aadTemp;
10684
    #endif
10685
0
    }
10686
10687
    /* Copy in the counter for use with cipher. */
10688
2.68k
    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
10689
    /* Encrypt initial counter into a buffer for GCM. */
10690
2.68k
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
10691
2.68k
    if (ret != 0)
10692
0
        return ret;
10693
    /* Reset state fields. */
10694
2.68k
    aes->over = 0;
10695
2.68k
    aes->aSz = 0;
10696
2.68k
    aes->cSz = 0;
10697
    /* Initialization for GHASH. */
10698
2.68k
    GHASH_INIT(aes);
10699
10700
2.68k
    return 0;
10701
2.68k
}
10702
10703
/* Update the AES GCM cipher with data. C implementation.
10704
 *
10705
 * Only enciphers data.
10706
 *
10707
 * @param [in, out] aes  AES object.
10708
 * @param [in]      out  Cipher text or plaintext buffer.
10709
 * @param [in]      in   Plaintext or cipher text buffer.
10710
 * @param [in]      sz   Length of data.
10711
 */
10712
static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
10713
    Aes* aes, byte* out, const byte* in, word32 sz)
10714
9.75k
{
10715
9.75k
    word32 blocks;
10716
9.75k
    word32 partial;
10717
9.75k
    int ret;
10718
10719
    /* Check if previous encrypted block was not used up. */
10720
9.75k
    if (aes->over > 0) {
10721
7.54k
        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
10722
7.54k
        if (pSz > sz) pSz = (byte)sz;
10723
10724
        /* Use some/all of last encrypted block. */
10725
7.54k
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
10726
7.54k
        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
10727
10728
        /* Some data used. */
10729
7.54k
        sz  -= pSz;
10730
7.54k
        in  += pSz;
10731
7.54k
        out += pSz;
10732
7.54k
    }
10733
10734
    /* Calculate the number of blocks needing to be encrypted and any leftover.
10735
     */
10736
9.75k
    blocks  = sz / WC_AES_BLOCK_SIZE;
10737
9.75k
    partial = sz & (WC_AES_BLOCK_SIZE - 1);
10738
10739
9.75k
#if defined(HAVE_AES_ECB)
10740
    /* Some hardware acceleration can gain performance from doing AES encryption
10741
     * of the whole buffer at once.
10742
     * Overwrites the cipher text before using plaintext - no inline encryption.
10743
     */
10744
9.75k
    if ((out != in) && blocks > 0) {
10745
476
        word32 b;
10746
        /* Place incrementing counter blocks into cipher text. */
10747
4.11k
        for (b = 0; b < blocks; b++) {
10748
3.64k
            IncrementGcmCounter(AES_COUNTER(aes));
10749
3.64k
            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
10750
3.64k
        }
10751
10752
        /* Encrypt counter blocks. */
10753
476
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
10754
        /* XOR in plaintext. */
10755
476
        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
10756
        /* Skip over processed data. */
10757
476
        in += WC_AES_BLOCK_SIZE * blocks;
10758
476
        out += WC_AES_BLOCK_SIZE * blocks;
10759
476
    }
10760
9.27k
    else
10761
9.27k
#endif /* HAVE_AES_ECB */
10762
9.27k
    {
10763
        /* Encrypt block by block. */
10764
11.2k
        while (blocks--) {
10765
2.00k
            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
10766
2.00k
            IncrementGcmCounter(AES_COUNTER(aes));
10767
            /* Encrypt counter into a buffer. */
10768
2.00k
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
10769
2.00k
            if (ret != 0)
10770
0
                return ret;
10771
            /* XOR plain text into encrypted counter into cipher text buffer. */
10772
2.00k
            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
10773
            /* Data complete. */
10774
2.00k
            in  += WC_AES_BLOCK_SIZE;
10775
2.00k
            out += WC_AES_BLOCK_SIZE;
10776
2.00k
        }
10777
9.27k
    }
10778
10779
9.75k
    if (partial != 0) {
10780
        /* Generate an extra block and use up as much as needed. */
10781
637
        IncrementGcmCounter(AES_COUNTER(aes));
10782
        /* Encrypt counter into cache. */
10783
637
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
10784
637
        if (ret != 0)
10785
0
            return ret;
10786
        /* XOR plain text into encrypted counter into cipher text buffer. */
10787
637
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
10788
        /* Keep amount of encrypted block used. */
10789
637
        aes->over = (byte)partial;
10790
637
    }
10791
10792
9.75k
    return 0;
10793
9.75k
}
10794
10795
/* Calculates authentication tag for AES GCM. C implementation.
10796
 *
10797
 * @param [in, out] aes        AES object.
10798
 * @param [out]     authTag    Buffer to store authentication tag in.
10799
 * @param [in]      authTagSz  Length of tag to create.
10800
 */
10801
static WARN_UNUSED_RESULT int AesGcmFinal_C(
10802
    Aes* aes, byte* authTag, word32 authTagSz)
10803
921
{
10804
    /* Calculate authentication tag. */
10805
921
    GHASH_FINAL(aes, authTag, authTagSz);
10806
    /* XOR in as much of encrypted counter as is required. */
10807
921
    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
10808
#ifdef OPENSSL_EXTRA
10809
    /* store AAD size for next call */
10810
    aes->gcm.aadLen = aes->aSz;
10811
#endif
10812
    /* Zeroize last block to protect sensitive data. */
10813
921
    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
10814
10815
921
    return 0;
10816
921
}
10817
10818
#ifdef WOLFSSL_AESNI
10819
10820
#ifdef __cplusplus
10821
    extern "C" {
10822
#endif
10823
10824
/* Assembly code implementations in: aes_gcm_asm.S */
10825
#ifdef HAVE_INTEL_AVX2
10826
extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
10827
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
10828
    unsigned char* counter, unsigned char* initCtr);
10829
extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
10830
    unsigned int abytes, unsigned char* tag, unsigned char* h);
10831
extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
10832
    unsigned char* out, const unsigned char* in, unsigned char* counter);
10833
extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
10834
    unsigned char* tag, unsigned char* h);
10835
10836
extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
10837
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10838
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10839
extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
10840
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10841
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
10842
#endif
10843
#ifdef HAVE_INTEL_AVX1
10844
extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
10845
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
10846
    unsigned char* counter, unsigned char* initCtr);
10847
extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
10848
    unsigned int abytes, unsigned char* tag, unsigned char* h);
10849
extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
10850
    unsigned char* out, const unsigned char* in, unsigned char* counter);
10851
extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
10852
    unsigned char* tag, unsigned char* h);
10853
10854
extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
10855
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10856
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10857
extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
10858
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10859
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
10860
#endif
10861
extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
10862
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
10863
    unsigned char* counter, unsigned char* initCtr);
10864
extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
10865
    unsigned int abytes, unsigned char* tag, unsigned char* h);
10866
extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
10867
    unsigned char* out, const unsigned char* in, unsigned char* counter);
10868
extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
10869
    unsigned char* tag, unsigned char* h);
10870
10871
extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
10872
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10873
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10874
extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
10875
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10876
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
10877
10878
#ifdef __cplusplus
10879
    } /* extern "C" */
10880
#endif
10881
10882
/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
10883
 *
10884
 * @param [in, out] aes   AES object.
10885
 * @param [in]      iv    IV/nonce buffer.
10886
 * @param [in]      ivSz  Length of IV/nonce data.
10887
 */
10888
static WARN_UNUSED_RESULT int AesGcmInit_aesni(
10889
    Aes* aes, const byte* iv, word32 ivSz)
10890
{
10891
    ASSERT_SAVED_VECTOR_REGISTERS();
10892
10893
    /* Reset state fields. */
10894
    aes->over = 0;
10895
    aes->aSz = 0;
10896
    aes->cSz = 0;
10897
    /* Set tag to all zeros as initial value. */
10898
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
10899
    /* Reset counts of AAD and cipher text. */
10900
    aes->aOver = 0;
10901
    aes->cOver = 0;
10902
10903
#ifdef HAVE_INTEL_AVX2
10904
    if (IS_INTEL_AVX2(intel_flags)) {
10905
        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
10906
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
10907
    }
10908
    else
10909
#endif
10910
#ifdef HAVE_INTEL_AVX1
10911
    if (IS_INTEL_AVX1(intel_flags)) {
10912
        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
10913
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
10914
    }
10915
    else
10916
#endif
10917
    {
10918
        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
10919
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
10920
    }
10921
10922
    return 0;
10923
}
10924
10925
/* Update the AES GCM for encryption with authentication data.
10926
 *
10927
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
10928
 *
10929
 * @param [in, out] aes   AES object.
10930
 * @param [in]      a     Buffer holding authentication data.
10931
 * @param [in]      aSz   Length of authentication data in bytes.
10932
 * @param [in]      endA  Whether no more authentication data is expected.
10933
 */
10934
static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
10935
    Aes* aes, const byte* a, word32 aSz, int endA)
10936
{
10937
    word32 blocks;
10938
    int partial;
10939
10940
    ASSERT_SAVED_VECTOR_REGISTERS();
10941
10942
    if (aSz != 0 && a != NULL) {
10943
        /* Total count of AAD updated. */
10944
        aes->aSz += aSz;
10945
        /* Check if we have unprocessed data. */
10946
        if (aes->aOver > 0) {
10947
            /* Calculate amount we can use - fill up the block. */
10948
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10949
            if (sz > aSz) {
10950
                sz = (byte)aSz;
10951
            }
10952
            /* Copy extra into last GHASH block array and update count. */
10953
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
10954
            aes->aOver = (byte)(aes->aOver + sz);
10955
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
10956
                /* We have filled up the block and can process. */
10957
            #ifdef HAVE_INTEL_AVX2
10958
                if (IS_INTEL_AVX2(intel_flags)) {
10959
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
10960
                                             aes->gcm.H);
10961
                }
10962
                else
10963
            #endif
10964
            #ifdef HAVE_INTEL_AVX1
10965
                if (IS_INTEL_AVX1(intel_flags)) {
10966
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
10967
                                             aes->gcm.H);
10968
                }
10969
                else
10970
            #endif
10971
                {
10972
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
10973
                                              aes->gcm.H);
10974
                }
10975
                /* Reset count. */
10976
                aes->aOver = 0;
10977
            }
10978
            /* Used up some data. */
10979
            aSz -= sz;
10980
            a += sz;
10981
        }
10982
10983
        /* Calculate number of blocks of AAD and the leftover. */
10984
        blocks = aSz / WC_AES_BLOCK_SIZE;
10985
        partial = aSz % WC_AES_BLOCK_SIZE;
10986
        if (blocks > 0) {
10987
            /* GHASH full blocks now. */
10988
        #ifdef HAVE_INTEL_AVX2
10989
            if (IS_INTEL_AVX2(intel_flags)) {
10990
                AES_GCM_aad_update_avx2(a, blocks * WC_AES_BLOCK_SIZE,
10991
                                        AES_TAG(aes), aes->gcm.H);
10992
            }
10993
            else
10994
        #endif
10995
        #ifdef HAVE_INTEL_AVX1
10996
            if (IS_INTEL_AVX1(intel_flags)) {
10997
                AES_GCM_aad_update_avx1(a, blocks * WC_AES_BLOCK_SIZE,
10998
                                        AES_TAG(aes), aes->gcm.H);
10999
            }
11000
            else
11001
        #endif
11002
            {
11003
                AES_GCM_aad_update_aesni(a, blocks * WC_AES_BLOCK_SIZE,
11004
                                         AES_TAG(aes), aes->gcm.H);
11005
            }
11006
            /* Skip over to end of AAD blocks. */
11007
            a += blocks * WC_AES_BLOCK_SIZE;
11008
        }
11009
        if (partial != 0) {
11010
            /* Cache the partial block. */
11011
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
11012
            aes->aOver = (byte)partial;
11013
        }
11014
    }
11015
    if (endA && (aes->aOver > 0)) {
11016
        /* No more AAD coming and we have a partial block. */
11017
        /* Fill the rest of the block with zeros. */
11018
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
11019
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
11020
        /* GHASH last AAD block. */
11021
    #ifdef HAVE_INTEL_AVX2
11022
        if (IS_INTEL_AVX2(intel_flags)) {
11023
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11024
                                     aes->gcm.H);
11025
        }
11026
        else
11027
    #endif
11028
    #ifdef HAVE_INTEL_AVX1
11029
        if (IS_INTEL_AVX1(intel_flags)) {
11030
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11031
                                     aes->gcm.H);
11032
        }
11033
        else
11034
    #endif
11035
        {
11036
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11037
                                      aes->gcm.H);
11038
        }
11039
        /* Clear partial count for next time through. */
11040
        aes->aOver = 0;
11041
    }
11042
11043
    return 0;
11044
}
11045
11046
/* Update the AES GCM for encryption with data and/or authentication data.
11047
 *
11048
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
11049
 *
11050
 * @param [in, out] aes  AES object.
11051
 * @param [out]     c    Buffer to hold cipher text.
11052
 * @param [in]      p    Buffer holding plaintext.
11053
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11054
 * @param [in]      a    Buffer holding authentication data.
11055
 * @param [in]      aSz  Length of authentication data in bytes.
11056
 */
11057
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
11058
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
11059
{
11060
    word32 blocks;
11061
    int partial;
11062
    int ret;
11063
11064
    ASSERT_SAVED_VECTOR_REGISTERS();
11065
11066
    /* Hash in A, the Authentication Data */
11067
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
11068
    if (ret != 0)
11069
        return ret;
11070
11071
    /* Encrypt plaintext and Hash in C, the Cipher text */
11072
    if (cSz != 0 && c != NULL) {
11073
        /* Update count of cipher text we have hashed. */
11074
        aes->cSz += cSz;
11075
        if (aes->cOver > 0) {
11076
            /* Calculate amount we can use - fill up the block. */
11077
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11078
            if (sz > cSz) {
11079
                sz = (byte)cSz;
11080
            }
11081
            /* Encrypt some of the plaintext. */
11082
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
11083
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11084
            /* Update count of unused encrypted counter. */
11085
            aes->cOver = (byte)(aes->cOver + sz);
11086
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11087
                /* We have filled up the block and can process. */
11088
            #ifdef HAVE_INTEL_AVX2
11089
                if (IS_INTEL_AVX2(intel_flags)) {
11090
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11091
                                             aes->gcm.H);
11092
                }
11093
                else
11094
            #endif
11095
            #ifdef HAVE_INTEL_AVX1
11096
                if (IS_INTEL_AVX1(intel_flags)) {
11097
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11098
                                             aes->gcm.H);
11099
                }
11100
                else
11101
            #endif
11102
                {
11103
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11104
                                              aes->gcm.H);
11105
                }
11106
                /* Reset count. */
11107
                aes->cOver = 0;
11108
            }
11109
            /* Used up some data. */
11110
            cSz -= sz;
11111
            p += sz;
11112
            c += sz;
11113
        }
11114
11115
        /* Calculate number of blocks of plaintext and the leftover. */
11116
        blocks = cSz / WC_AES_BLOCK_SIZE;
11117
        partial = cSz % WC_AES_BLOCK_SIZE;
11118
        if (blocks > 0) {
11119
            /* Encrypt and GHASH full blocks now. */
11120
        #ifdef HAVE_INTEL_AVX2
11121
            if (IS_INTEL_AVX2(intel_flags)) {
11122
                AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
11123
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11124
                    AES_COUNTER(aes));
11125
            }
11126
            else
11127
        #endif
11128
        #ifdef HAVE_INTEL_AVX1
11129
            if (IS_INTEL_AVX1(intel_flags)) {
11130
                AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
11131
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11132
                    AES_COUNTER(aes));
11133
            }
11134
            else
11135
        #endif
11136
            {
11137
                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
11138
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11139
                    AES_COUNTER(aes));
11140
            }
11141
            /* Skip over to end of blocks. */
11142
            p += blocks * WC_AES_BLOCK_SIZE;
11143
            c += blocks * WC_AES_BLOCK_SIZE;
11144
        }
11145
        if (partial != 0) {
11146
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
11147
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11148
        #ifdef HAVE_INTEL_AVX2
11149
            if (IS_INTEL_AVX2(intel_flags)) {
11150
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
11151
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11152
            }
11153
            else
11154
        #endif
11155
        #ifdef HAVE_INTEL_AVX1
11156
            if (IS_INTEL_AVX1(intel_flags)) {
11157
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
11158
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11159
            }
11160
            else
11161
        #endif
11162
            {
11163
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
11164
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11165
            }
11166
            /* XOR the remaining plaintext to calculate cipher text.
11167
             * Keep cipher text for GHASH of last partial block.
11168
             */
11169
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
11170
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
11171
            /* Update count of the block used. */
11172
            aes->cOver = (byte)partial;
11173
        }
11174
    }
11175
    return 0;
11176
}
11177
11178
/* Finalize the AES GCM for encryption and calculate the authentication tag.
11179
 *
11180
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
11181
 *
11182
 * @param [in, out] aes        AES object.
11183
 * @param [in]      authTag    Buffer to hold authentication tag.
11184
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11185
 * @return  0 on success.
11186
 */
11187
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
11188
    Aes* aes, byte* authTag, word32 authTagSz)
11189
{
11190
    /* AAD block incomplete when > 0 */
11191
    byte over = aes->aOver;
11192
11193
    ASSERT_SAVED_VECTOR_REGISTERS();
11194
11195
    if (aes->cOver > 0) {
11196
        /* Cipher text block incomplete. */
11197
        over = aes->cOver;
11198
    }
11199
    if (over > 0) {
11200
        /* Fill the rest of the block with zeros. */
11201
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
11202
        /* GHASH last cipher block. */
11203
    #ifdef HAVE_INTEL_AVX2
11204
        if (IS_INTEL_AVX2(intel_flags)) {
11205
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11206
                                     aes->gcm.H);
11207
        }
11208
        else
11209
    #endif
11210
    #ifdef HAVE_INTEL_AVX1
11211
        if (IS_INTEL_AVX1(intel_flags)) {
11212
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11213
                                     aes->gcm.H);
11214
        }
11215
        else
11216
    #endif
11217
        {
11218
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11219
                                      aes->gcm.H);
11220
        }
11221
    }
11222
    /* Calculate the authentication tag. */
11223
#ifdef HAVE_INTEL_AVX2
11224
    if (IS_INTEL_AVX2(intel_flags)) {
11225
        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11226
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11227
    }
11228
    else
11229
#endif
11230
#ifdef HAVE_INTEL_AVX1
11231
    if (IS_INTEL_AVX1(intel_flags)) {
11232
        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11233
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11234
    }
11235
    else
11236
#endif
11237
    {
11238
        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11239
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11240
    }
11241
11242
    return 0;
11243
}
11244
11245
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
11246
11247
#ifdef __cplusplus
11248
    extern "C" {
11249
#endif
11250
11251
/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
11252
#ifdef HAVE_INTEL_AVX2
11253
extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
11254
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11255
    unsigned char* tag, unsigned char* h, unsigned char* counter);
11256
extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
11257
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11258
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
11259
#endif
11260
#ifdef HAVE_INTEL_AVX1
11261
extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
11262
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11263
    unsigned char* tag, unsigned char* h, unsigned char* counter);
11264
extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
11265
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11266
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
11267
#endif
11268
extern void AES_GCM_decrypt_update_aesni(const unsigned char* key, int nr,
11269
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11270
    unsigned char* tag, unsigned char* h, unsigned char* counter);
11271
extern void AES_GCM_decrypt_final_aesni(unsigned char* tag,
11272
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11273
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
11274
11275
#ifdef __cplusplus
11276
    } /* extern "C" */
11277
#endif
11278
11279
/* Update the AES GCM for decryption with data and/or authentication data.
11280
 *
11281
 * @param [in, out] aes  AES object.
11282
 * @param [out]     p    Buffer to hold plaintext.
11283
 * @param [in]      c    Buffer holding cipher text.
11284
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11285
 * @param [in]      a    Buffer holding authentication data.
11286
 * @param [in]      aSz  Length of authentication data in bytes.
11287
 */
11288
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
11289
    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
11290
{
11291
    word32 blocks;
11292
    int partial;
11293
    int ret;
11294
11295
    ASSERT_SAVED_VECTOR_REGISTERS();
11296
11297
    /* Hash in A, the Authentication Data */
11298
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
11299
    if (ret != 0)
11300
        return ret;
11301
11302
    /* Hash in C, the Cipher text, and decrypt. */
11303
    if (cSz != 0 && p != NULL) {
11304
        /* Update count of cipher text we have hashed. */
11305
        aes->cSz += cSz;
11306
        if (aes->cOver > 0) {
11307
            /* Calculate amount we can use - fill up the block. */
11308
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11309
            if (sz > cSz) {
11310
                sz = (byte)cSz;
11311
            }
11312
            /* Keep a copy of the cipher text for GHASH. */
11313
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
11314
            /* Decrypt some of the cipher text. */
11315
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
11316
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11317
            /* Update count of unused encrypted counter. */
11318
            aes->cOver = (byte)(aes->cOver + sz);
11319
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11320
                /* We have filled up the block and can process. */
11321
            #ifdef HAVE_INTEL_AVX2
11322
                if (IS_INTEL_AVX2(intel_flags)) {
11323
                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
11324
                                             aes->gcm.H);
11325
                }
11326
                else
11327
            #endif
11328
            #ifdef HAVE_INTEL_AVX1
11329
                if (IS_INTEL_AVX1(intel_flags)) {
11330
                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
11331
                                             aes->gcm.H);
11332
                }
11333
                else
11334
            #endif
11335
                {
11336
                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
11337
                                              aes->gcm.H);
11338
                }
11339
                /* Reset count. */
11340
                aes->cOver = 0;
11341
            }
11342
            /* Used up some data. */
11343
            cSz -= sz;
11344
            c += sz;
11345
            p += sz;
11346
        }
11347
11348
        /* Calculate number of blocks of plaintext and the leftover. */
11349
        blocks = cSz / WC_AES_BLOCK_SIZE;
11350
        partial = cSz % WC_AES_BLOCK_SIZE;
11351
        if (blocks > 0) {
11352
            /* Decrypt and GHASH full blocks now. */
11353
        #ifdef HAVE_INTEL_AVX2
11354
            if (IS_INTEL_AVX2(intel_flags)) {
11355
                AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
11356
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11357
                    AES_COUNTER(aes));
11358
            }
11359
            else
11360
        #endif
11361
        #ifdef HAVE_INTEL_AVX1
11362
            if (IS_INTEL_AVX1(intel_flags)) {
11363
                AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
11364
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11365
                    AES_COUNTER(aes));
11366
            }
11367
            else
11368
        #endif
11369
            {
11370
                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
11371
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11372
                    AES_COUNTER(aes));
11373
            }
11374
            /* Skip over to end of blocks. */
11375
            c += blocks * WC_AES_BLOCK_SIZE;
11376
            p += blocks * WC_AES_BLOCK_SIZE;
11377
        }
11378
        if (partial != 0) {
11379
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
11380
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11381
        #ifdef HAVE_INTEL_AVX2
11382
            if (IS_INTEL_AVX2(intel_flags)) {
11383
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
11384
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11385
            }
11386
            else
11387
        #endif
11388
        #ifdef HAVE_INTEL_AVX1
11389
            if (IS_INTEL_AVX1(intel_flags)) {
11390
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
11391
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11392
            }
11393
            else
11394
        #endif
11395
            {
11396
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
11397
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11398
            }
11399
            /* Keep cipher text for GHASH of last partial block. */
11400
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
11401
            /* XOR the remaining cipher text to calculate plaintext. */
11402
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
11403
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
11404
            /* Update count of the block used. */
11405
            aes->cOver = (byte)partial;
11406
        }
11407
    }
11408
11409
    return 0;
11410
}
11411
11412
/* Finalize the AES GCM for decryption and check the authentication tag.
11413
 *
11414
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
11415
 *
11416
 * @param [in, out] aes        AES object.
11417
 * @param [in]      authTag    Buffer holding authentication tag.
11418
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11419
 * @return  0 on success.
11420
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
11421
 *          value.
11422
 */
11423
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
11424
    Aes* aes, const byte* authTag, word32 authTagSz)
11425
{
11426
    int ret = 0;
11427
    int res;
11428
    /* AAD block incomplete when > 0 */
11429
    byte over = aes->aOver;
11430
    byte *lastBlock = AES_LASTGBLOCK(aes);
11431
11432
    ASSERT_SAVED_VECTOR_REGISTERS();
11433
11434
    if (aes->cOver > 0) {
11435
        /* Cipher text block incomplete. */
11436
        over = aes->cOver;
11437
        lastBlock = AES_LASTBLOCK(aes);
11438
    }
11439
    if (over > 0) {
11440
        /* Zeroize the unused part of the block. */
11441
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
11442
        /* Hash the last block of cipher text. */
11443
    #ifdef HAVE_INTEL_AVX2
11444
        if (IS_INTEL_AVX2(intel_flags)) {
11445
            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
11446
        }
11447
        else
11448
    #endif
11449
    #ifdef HAVE_INTEL_AVX1
11450
        if (IS_INTEL_AVX1(intel_flags)) {
11451
            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
11452
        }
11453
        else
11454
    #endif
11455
        {
11456
            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
11457
        }
11458
    }
11459
    /* Calculate and compare the authentication tag. */
11460
#ifdef HAVE_INTEL_AVX2
11461
    if (IS_INTEL_AVX2(intel_flags)) {
11462
        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11463
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11464
    }
11465
    else
11466
#endif
11467
#ifdef HAVE_INTEL_AVX1
11468
    if (IS_INTEL_AVX1(intel_flags)) {
11469
        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11470
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11471
    }
11472
    else
11473
#endif
11474
    {
11475
        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11476
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11477
    }
11478
11479
    /* Return error code when calculated doesn't match input. */
11480
    if (res == 0) {
11481
        ret = AES_GCM_AUTH_E;
11482
    }
11483
    return ret;
11484
}
11485
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
11486
#endif /* WOLFSSL_AESNI */
11487
11488
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11489
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11490
/* Initialize the AES GCM cipher with an IV. Aarch64 HW Crypto implementations.
11491
 *
11492
 * @param [in, out] aes   AES object.
11493
 * @param [in]      iv    IV/nonce buffer.
11494
 * @param [in]      ivSz  Length of IV/nonce data.
11495
 */
11496
static WARN_UNUSED_RESULT int AesGcmInit_AARCH64(Aes* aes, const byte* iv,
11497
    word32 ivSz)
11498
{
11499
    /* Reset state fields. */
11500
    aes->over = 0;
11501
    aes->aSz = 0;
11502
    aes->cSz = 0;
11503
    /* Set tag to all zeros as initial value. */
11504
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
11505
    /* Reset counts of AAD and cipher text. */
11506
    aes->aOver = 0;
11507
    aes->cOver = 0;
11508
11509
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11510
    if (aes->use_sha3_hw_crypto) {
11511
        AES_GCM_init_AARCH64_EOR3((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11512
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11513
    }
11514
    else
11515
#endif
11516
    {
11517
        AES_GCM_init_AARCH64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11518
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11519
    }
11520
11521
    return 0;
11522
}
11523
11524
/* Update the AES GCM for encryption with authentication data.
11525
 *
11526
 * Implementation uses AARCH64 optimized assembly code.
11527
 *
11528
 * @param [in, out] aes   AES object.
11529
 * @param [in]      a     Buffer holding authentication data.
11530
 * @param [in]      aSz   Length of authentication data in bytes.
11531
 * @param [in]      endA  Whether no more authentication data is expected.
11532
 */
11533
static WARN_UNUSED_RESULT int AesGcmAadUpdate_AARCH64(
11534
    Aes* aes, const byte* a, word32 aSz, int endA)
11535
{
11536
    word32 blocks;
11537
    int partial;
11538
11539
    if (aSz != 0 && a != NULL) {
11540
        /* Total count of AAD updated. */
11541
        aes->aSz += aSz;
11542
        /* Check if we have unprocessed data. */
11543
        if (aes->aOver > 0) {
11544
            /* Calculate amount we can use - fill up the block. */
11545
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
11546
            if (sz > aSz) {
11547
                sz = (byte)aSz;
11548
            }
11549
            /* Copy extra into last GHASH block array and update count. */
11550
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
11551
            aes->aOver = (byte)(aes->aOver + sz);
11552
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
11553
                /* We have filled up the block and can process. */
11554
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11555
                if (aes->use_sha3_hw_crypto) {
11556
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
11557
                        AES_TAG(aes), aes->gcm.H);
11558
                }
11559
                else
11560
            #endif
11561
                {
11562
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
11563
                        AES_TAG(aes), aes->gcm.H);
11564
                }
11565
                /* Reset count. */
11566
                aes->aOver = 0;
11567
            }
11568
            /* Used up some data. */
11569
            aSz -= sz;
11570
            a += sz;
11571
        }
11572
11573
        /* Calculate number of blocks of AAD and the leftover. */
11574
        blocks = aSz / WC_AES_BLOCK_SIZE;
11575
        partial = aSz % WC_AES_BLOCK_SIZE;
11576
        if (blocks > 0) {
11577
            /* GHASH full blocks now. */
11578
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11579
            if (aes->use_sha3_hw_crypto) {
11580
                AES_GCM_aad_update_AARCH64_EOR3(a, blocks * WC_AES_BLOCK_SIZE,
11581
                    AES_TAG(aes), aes->gcm.H);
11582
            }
11583
            else
11584
        #endif
11585
            {
11586
                AES_GCM_aad_update_AARCH64(a, blocks * WC_AES_BLOCK_SIZE,
11587
                    AES_TAG(aes), aes->gcm.H);
11588
            }
11589
            /* Skip over to end of AAD blocks. */
11590
            a += blocks * WC_AES_BLOCK_SIZE;
11591
        }
11592
        if (partial != 0) {
11593
            /* Cache the partial block. */
11594
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
11595
            aes->aOver = (byte)partial;
11596
        }
11597
    }
11598
    if (endA && (aes->aOver > 0)) {
11599
        /* No more AAD coming and we have a partial block. */
11600
        /* Fill the rest of the block with zeros. */
11601
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
11602
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
11603
        /* GHASH last AAD block. */
11604
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11605
        if (aes->use_sha3_hw_crypto) {
11606
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
11607
                AES_TAG(aes), aes->gcm.H);
11608
        }
11609
        else
11610
    #endif
11611
        {
11612
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
11613
                AES_TAG(aes), aes->gcm.H);
11614
        }
11615
        /* Clear partial count for next time through. */
11616
        aes->aOver = 0;
11617
    }
11618
11619
    return 0;
11620
}
11621
11622
/* Update the AES GCM for encryption with data and/or authentication data.
11623
 *
11624
 * Implementation uses AARCH64 optimized assembly code.
11625
 *
11626
 * @param [in, out] aes  AES object.
11627
 * @param [out]     c    Buffer to hold cipher text.
11628
 * @param [in]      p    Buffer holding plaintext.
11629
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11630
 * @param [in]      a    Buffer holding authentication data.
11631
 * @param [in]      aSz  Length of authentication data in bytes.
11632
 */
11633
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_AARCH64(
11634
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
11635
{
11636
    word32 blocks;
11637
    int partial;
11638
    int ret;
11639
11640
    /* Hash in A, the Authentication Data */
11641
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, (cSz > 0) && (c != NULL));
11642
    if (ret != 0)
11643
        return ret;
11644
11645
    /* Encrypt plaintext and Hash in C, the Cipher text */
11646
    if (cSz != 0 && c != NULL) {
11647
        /* Update count of cipher text we have hashed. */
11648
        aes->cSz += cSz;
11649
        if (aes->cOver > 0) {
11650
            /* Calculate amount we can use - fill up the block. */
11651
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11652
            if (sz > cSz) {
11653
                sz = (byte)cSz;
11654
            }
11655
            /* Encrypt some of the plaintext. */
11656
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
11657
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11658
            /* Update count of unused encrypted counter. */
11659
            aes->cOver = (byte)(aes->cOver + sz);
11660
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11661
                /* We have filled up the block and can process. */
11662
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11663
                if (aes->use_sha3_hw_crypto) {
11664
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
11665
                        AES_TAG(aes), aes->gcm.H);
11666
                }
11667
                else
11668
            #endif
11669
                {
11670
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
11671
                        AES_TAG(aes), aes->gcm.H);
11672
                }
11673
                /* Reset count. */
11674
                aes->cOver = 0;
11675
            }
11676
            /* Used up some data. */
11677
            cSz -= sz;
11678
            p += sz;
11679
            c += sz;
11680
        }
11681
11682
        /* Calculate number of blocks of plaintext and the leftover. */
11683
        blocks = cSz / WC_AES_BLOCK_SIZE;
11684
        partial = cSz % WC_AES_BLOCK_SIZE;
11685
        if (blocks > 0) {
11686
            /* Encrypt and GHASH full blocks now. */
11687
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11688
            if (aes->use_sha3_hw_crypto) {
11689
                AES_GCM_encrypt_update_AARCH64_EOR3((byte*)aes->key,
11690
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
11691
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11692
            }
11693
            else
11694
        #endif
11695
            {
11696
                AES_GCM_encrypt_update_AARCH64((byte*)aes->key,
11697
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
11698
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11699
            }
11700
            /* Skip over to end of blocks. */
11701
            p += blocks * WC_AES_BLOCK_SIZE;
11702
            c += blocks * WC_AES_BLOCK_SIZE;
11703
        }
11704
        if (partial != 0) {
11705
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
11706
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11707
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11708
            if (aes->use_sha3_hw_crypto) {
11709
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
11710
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
11711
                    AES_COUNTER(aes));
11712
            }
11713
            else
11714
        #endif
11715
            {
11716
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
11717
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11718
            }
11719
            /* XOR the remaining plaintext to calculate cipher text.
11720
             * Keep cipher text for GHASH of last partial block.
11721
             */
11722
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
11723
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
11724
            /* Update count of the block used. */
11725
            aes->cOver = (byte)partial;
11726
        }
11727
    }
11728
    return 0;
11729
}
11730
11731
/* Finalize the AES GCM for encryption and calculate the authentication tag.
11732
 *
11733
 * Calls ARCH64 optimized assembly code.
11734
 *
11735
 * @param [in, out] aes        AES object.
11736
 * @param [in]      authTag    Buffer to hold authentication tag.
11737
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11738
 * @return  0 on success.
11739
 */
11740
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_AARCH64(Aes* aes,
11741
    byte* authTag, word32 authTagSz)
11742
{
11743
    /* AAD block incomplete when > 0 */
11744
    byte over = aes->aOver;
11745
11746
    ASSERT_SAVED_VECTOR_REGISTERS();
11747
11748
    if (aes->cOver > 0) {
11749
        /* Cipher text block incomplete. */
11750
        over = aes->cOver;
11751
    }
11752
    if (over > 0) {
11753
        /* Fill the rest of the block with zeros. */
11754
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
11755
            (size_t)WC_AES_BLOCK_SIZE - over);
11756
        /* GHASH last cipher block. */
11757
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11758
        if (aes->use_sha3_hw_crypto) {
11759
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes), AES_TAG(aes),
11760
                aes->gcm.H);
11761
        }
11762
        else
11763
    #endif
11764
        {
11765
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes), AES_TAG(aes),
11766
                aes->gcm.H);
11767
        }
11768
    }
11769
    /* Calculate the authentication tag. */
11770
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11771
    if (aes->use_sha3_hw_crypto) {
11772
        AES_GCM_encrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
11773
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11774
    }
11775
    else
11776
#endif
11777
    {
11778
        AES_GCM_encrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
11779
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11780
    }
11781
11782
    return 0;
11783
}
11784
11785
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
11786
/* Update the AES GCM for decryption with data and/or authentication data.
11787
 *
11788
 * @param [in, out] aes  AES object.
11789
 * @param [out]     p    Buffer to hold plaintext.
11790
 * @param [in]      c    Buffer holding cipher text.
11791
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11792
 * @param [in]      a    Buffer holding authentication data.
11793
 * @param [in]      aSz  Length of authentication data in bytes.
11794
 */
11795
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_AARCH64(Aes* aes, byte* p,
11796
    const byte* c, word32 cSz, const byte* a, word32 aSz)
11797
{
11798
    word32 blocks;
11799
    int partial;
11800
    int ret;
11801
11802
    /* Hash in A, the Authentication Data */
11803
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, cSz > 0);
11804
    if (ret != 0)
11805
        return ret;
11806
11807
    /* Hash in C, the Cipher text, and decrypt. */
11808
    if (cSz != 0 && p != NULL) {
11809
        /* Update count of cipher text we have hashed. */
11810
        aes->cSz += cSz;
11811
        if (aes->cOver > 0) {
11812
            /* Calculate amount we can use - fill up the block. */
11813
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11814
            if (sz > cSz) {
11815
                sz = (byte)cSz;
11816
            }
11817
            /* Keep a copy of the cipher text for GHASH. */
11818
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
11819
            /* Decrypt some of the cipher text. */
11820
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
11821
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11822
            /* Update count of unused encrypted counter. */
11823
            aes->cOver = (byte)(aes->cOver + sz);
11824
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11825
                /* We have filled up the block and can process. */
11826
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11827
                if (aes->use_sha3_hw_crypto) {
11828
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTBLOCK(aes),
11829
                        AES_TAG(aes), aes->gcm.H);
11830
                }
11831
                else
11832
            #endif
11833
                {
11834
                    AES_GCM_ghash_block_AARCH64(AES_LASTBLOCK(aes),
11835
                        AES_TAG(aes), aes->gcm.H);
11836
                }
11837
                /* Reset count. */
11838
                aes->cOver = 0;
11839
            }
11840
            /* Used up some data. */
11841
            cSz -= sz;
11842
            c += sz;
11843
            p += sz;
11844
        }
11845
11846
        /* Calculate number of blocks of plaintext and the leftover. */
11847
        blocks = cSz / WC_AES_BLOCK_SIZE;
11848
        partial = cSz % WC_AES_BLOCK_SIZE;
11849
        if (blocks > 0) {
11850
            /* Decrypt and GHASH full blocks now. */
11851
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11852
            if (aes->use_sha3_hw_crypto) {
11853
                AES_GCM_decrypt_update_AARCH64_EOR3((byte*)aes->key,
11854
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
11855
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11856
            }
11857
            else
11858
        #endif
11859
            {
11860
                AES_GCM_decrypt_update_AARCH64((byte*)aes->key,
11861
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
11862
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11863
            }
11864
            /* Skip over to end of blocks. */
11865
            c += blocks * WC_AES_BLOCK_SIZE;
11866
            p += blocks * WC_AES_BLOCK_SIZE;
11867
        }
11868
        if (partial != 0) {
11869
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
11870
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11871
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11872
            if (aes->use_sha3_hw_crypto) {
11873
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
11874
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
11875
                    AES_COUNTER(aes));
11876
            }
11877
            else
11878
        #endif
11879
            {
11880
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
11881
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11882
            }
11883
            /* Keep cipher text for GHASH of last partial block. */
11884
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
11885
            /* XOR the remaining cipher text to calculate plaintext. */
11886
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
11887
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
11888
            /* Update count of the block used. */
11889
            aes->cOver = (byte)partial;
11890
        }
11891
    }
11892
11893
    return 0;
11894
}
11895
11896
/* Finalize the AES GCM for decryption and check the authentication tag.
11897
 *
11898
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
11899
 *
11900
 * @param [in, out] aes        AES object.
11901
 * @param [in]      authTag    Buffer holding authentication tag.
11902
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11903
 * @return  0 on success.
11904
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
11905
 *          value.
11906
 */
11907
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_AARCH64(
11908
    Aes* aes, const byte* authTag, word32 authTagSz)
11909
{
11910
    int ret = 0;
11911
    int res;
11912
    /* AAD block incomplete when > 0 */
11913
    byte over = aes->aOver;
11914
    byte *lastBlock = AES_LASTGBLOCK(aes);
11915
11916
    ASSERT_SAVED_VECTOR_REGISTERS();
11917
11918
    if (aes->cOver > 0) {
11919
        /* Cipher text block incomplete. */
11920
        over = aes->cOver;
11921
        lastBlock = AES_LASTBLOCK(aes);
11922
    }
11923
    if (over > 0) {
11924
        /* Zeroize the unused part of the block. */
11925
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
11926
        /* Hash the last block of cipher text. */
11927
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11928
        if (aes->use_sha3_hw_crypto) {
11929
            AES_GCM_ghash_block_AARCH64_EOR3(lastBlock, AES_TAG(aes),
11930
                aes->gcm.H);
11931
        }
11932
        else
11933
    #endif
11934
        {
11935
            AES_GCM_ghash_block_AARCH64(lastBlock, AES_TAG(aes), aes->gcm.H);
11936
        }
11937
    }
11938
    /* Calculate and compare the authentication tag. */
11939
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11940
    if (aes->use_sha3_hw_crypto) {
11941
        AES_GCM_decrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
11942
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11943
    }
11944
    else
11945
#endif
11946
    {
11947
        AES_GCM_decrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
11948
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11949
    }
11950
11951
    /* Return error code when calculated doesn't match input. */
11952
    if (res == 0) {
11953
        ret = AES_GCM_AUTH_E;
11954
    }
11955
    return ret;
11956
}
11957
#endif
11958
#endif
11959
11960
/* Initialize an AES GCM cipher for encryption or decryption.
11961
 *
11962
 * Must call wc_AesInit() before calling this function.
11963
 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
11964
 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
11965
 *
11966
 * @param [in, out] aes   AES object.
11967
 * @param [in]      key   Buffer holding key.
11968
 * @param [in]      len   Length of key in bytes.
11969
 * @param [in]      iv    Buffer holding IV/nonce.
11970
 * @param [in]      ivSz  Length of IV/nonce in bytes.
11971
 * @return  0 on success.
11972
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
11973
 *          is NULL, or the IV is NULL and no previous IV has been set.
11974
 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
11975
 */
11976
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
11977
    word32 ivSz)
11978
2.68k
{
11979
2.68k
    int ret = 0;
11980
11981
    /* Check validity of parameters. */
11982
2.68k
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
11983
2.68k
            ((ivSz == 0) && (iv != NULL)) ||
11984
2.68k
            ((ivSz > 0) && (iv == NULL))) {
11985
0
        ret = BAD_FUNC_ARG;
11986
0
    }
11987
11988
2.68k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
11989
2.68k
    if ((ret == 0) && (aes->streamData == NULL)) {
11990
        /* Allocate buffers for streaming. */
11991
1.00k
        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
11992
1.00k
        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
11993
1.00k
                                                              DYNAMIC_TYPE_AES);
11994
1.00k
        if (aes->streamData == NULL) {
11995
0
            ret = MEMORY_E;
11996
0
        }
11997
1.00k
    }
11998
2.68k
#endif
11999
12000
    /* Set the key if passed in. */
12001
2.68k
    if ((ret == 0) && (key != NULL)) {
12002
1.00k
        ret = wc_AesGcmSetKey(aes, key, len);
12003
1.00k
    }
12004
12005
2.68k
    if (ret == 0) {
12006
        /* Set the IV passed in if it is smaller than a block. */
12007
2.68k
        if ((iv != NULL) && (ivSz <= WC_AES_BLOCK_SIZE)) {
12008
2.68k
            XMEMMOVE((byte*)aes->reg, iv, ivSz);
12009
2.68k
            aes->nonceSz = ivSz;
12010
2.68k
        }
12011
        /* No IV passed in, check for cached IV. */
12012
2.68k
        if ((iv == NULL) && (aes->nonceSz != 0)) {
12013
            /* Use the cached copy. */
12014
0
            iv = (byte*)aes->reg;
12015
0
            ivSz = aes->nonceSz;
12016
0
        }
12017
12018
2.68k
        if (iv != NULL) {
12019
            /* Initialize with the IV. */
12020
12021
        #ifdef WOLFSSL_AESNI
12022
            if (aes->use_aesni) {
12023
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
12024
                ret = AesGcmInit_aesni(aes, iv, ivSz);
12025
                RESTORE_VECTOR_REGISTERS();
12026
            }
12027
            else
12028
        #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12029
              !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12030
            if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12031
                ret = AesGcmInit_AARCH64(aes, iv, ivSz);
12032
            }
12033
            else
12034
        #endif /* WOLFSSL_AESNI */
12035
2.68k
            {
12036
2.68k
                ret = AesGcmInit_C(aes, iv, ivSz);
12037
2.68k
            }
12038
12039
2.68k
            if (ret == 0)
12040
2.68k
                aes->nonceSet = 1;
12041
2.68k
        }
12042
2.68k
    }
12043
12044
2.68k
    return ret;
12045
2.68k
}
12046
12047
/* Initialize an AES GCM cipher for encryption.
12048
 *
12049
 * Must call wc_AesInit() before calling this function.
12050
 *
12051
 * @param [in, out] aes   AES object.
12052
 * @param [in]      key   Buffer holding key.
12053
 * @param [in]      len   Length of key in bytes.
12054
 * @param [in]      iv    Buffer holding IV/nonce.
12055
 * @param [in]      ivSz  Length of IV/nonce in bytes.
12056
 * @return  0 on success.
12057
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
12058
 *          is NULL, or the IV is NULL and no previous IV has been set.
12059
 */
12060
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
12061
    word32 ivSz)
12062
0
{
12063
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
12064
0
}
12065
12066
/* Initialize an AES GCM cipher for encryption. Get IV.
12067
 *
12068
 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
12069
 * function.
12070
 * Must call wc_AesInit() before calling this function.
12071
 *
12072
 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
12073
 *
12074
 * @param [in, out] aes   AES object.
12075
 * @param [in]      key   Buffer holding key.
12076
 * @param [in]      len   Length of key in bytes.
12077
 * @param [in]      iv    Buffer holding IV/nonce.
12078
 * @param [in]      ivSz  Length of IV/nonce in bytes.
12079
 * @return  0 on success.
12080
 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
12081
 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
12082
 *          nonce size.
12083
 */
12084
int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
12085
    word32 ivOutSz)
12086
0
{
12087
0
    int ret;
12088
12089
    /* Check validity of parameters. */
12090
0
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
12091
0
        ret = BAD_FUNC_ARG;
12092
0
    }
12093
0
    else {
12094
        /* Copy out the IV including generated part for decryption. */
12095
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
12096
        /* Initialize AES GCM cipher with key and cached Iv. */
12097
0
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
12098
0
    }
12099
12100
0
    return ret;
12101
0
}
12102
12103
/* Update the AES GCM for encryption with data and/or authentication data. */
12104
int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
12105
    const byte* authIn, word32 authInSz)
12106
8.28k
{
12107
8.28k
    int ret = 0;
12108
12109
    /* Check validity of parameters. */
12110
8.28k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
12111
1.23k
            ((out == NULL) || (in == NULL)))) {
12112
0
        ret = BAD_FUNC_ARG;
12113
0
    }
12114
12115
    /* Check key has been set. */
12116
8.28k
    if ((ret == 0) && (!aes->gcmKeySet)) {
12117
0
        ret = MISSING_KEY;
12118
0
    }
12119
    /* Check IV has been set. */
12120
8.28k
    if ((ret == 0) && (!aes->nonceSet)) {
12121
0
        ret = MISSING_IV;
12122
0
    }
12123
12124
8.28k
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
12125
622
        aes->invokeCtr[0]++;
12126
622
        if (aes->invokeCtr[0] == 0) {
12127
0
            aes->invokeCtr[1]++;
12128
0
            if (aes->invokeCtr[1] == 0)
12129
0
                ret = AES_GCM_OVERFLOW_E;
12130
0
        }
12131
622
    }
12132
12133
8.28k
    if (ret == 0) {
12134
        /* Encrypt with AAD and/or plaintext. */
12135
12136
    #ifdef WOLFSSL_AESNI
12137
        if (aes->use_aesni) {
12138
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12139
            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
12140
            RESTORE_VECTOR_REGISTERS();
12141
        }
12142
        else
12143
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12144
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12145
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12146
            ret = AesGcmEncryptUpdate_AARCH64(aes, out, in, sz, authIn,
12147
                authInSz);
12148
        }
12149
        else
12150
    #endif
12151
8.28k
        {
12152
            /* Encrypt the plaintext. */
12153
8.28k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
12154
8.28k
            if (ret == 0) {
12155
                /* Update the authentication tag with any authentication data and the
12156
                 * new cipher text. */
12157
8.28k
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
12158
8.28k
            }
12159
8.28k
        }
12160
8.28k
    }
12161
12162
8.28k
    return ret;
12163
8.28k
}
12164
12165
/* Finalize the AES GCM for encryption and return the authentication tag.
12166
 *
12167
 * Must set key and IV before calling this function.
12168
 * Must call wc_AesGcmInit() before calling this function.
12169
 *
12170
 * @param [in, out] aes        AES object.
12171
 * @param [out]     authTag    Buffer to hold authentication tag.
12172
 * @param [in]      authTagSz  Length of authentication tag in bytes.
12173
 * @return  0 on success.
12174
 */
12175
int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
12176
527
{
12177
527
    int ret = 0;
12178
12179
    /* Check validity of parameters. */
12180
527
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
12181
527
            (authTagSz == 0)) {
12182
0
        ret = BAD_FUNC_ARG;
12183
0
    }
12184
12185
    /* Check key has been set. */
12186
527
    if ((ret == 0) && (!aes->gcmKeySet)) {
12187
0
        ret = MISSING_KEY;
12188
0
    }
12189
    /* Check IV has been set. */
12190
527
    if ((ret == 0) && (!aes->nonceSet)) {
12191
0
        ret = MISSING_IV;
12192
0
    }
12193
12194
527
    if (ret == 0) {
12195
        /* Calculate authentication tag. */
12196
    #ifdef WOLFSSL_AESNI
12197
        if (aes->use_aesni) {
12198
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12199
            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
12200
            RESTORE_VECTOR_REGISTERS();
12201
        }
12202
        else
12203
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12204
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12205
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12206
            ret = AesGcmEncryptFinal_AARCH64(aes, authTag, authTagSz);
12207
        }
12208
        else
12209
    #endif
12210
527
        {
12211
527
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
12212
527
        }
12213
527
    }
12214
12215
527
    if ((ret == 0) && aes->ctrSet) {
12216
527
        IncCtr((byte*)aes->reg, aes->nonceSz);
12217
527
    }
12218
12219
527
    return ret;
12220
527
}
12221
12222
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
12223
/* Initialize an AES GCM cipher for decryption.
12224
 *
12225
 * Must call wc_AesInit() before calling this function.
12226
 *
12227
 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
12228
 * instead.
12229
 *
12230
 * @param [in, out] aes   AES object.
12231
 * @param [in]      key   Buffer holding key.
12232
 * @param [in]      len   Length of key in bytes.
12233
 * @param [in]      iv    Buffer holding IV/nonce.
12234
 * @param [in]      ivSz  Length of IV/nonce in bytes.
12235
 * @return  0 on success.
12236
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
12237
 *          is NULL, or the IV is NULL and no previous IV has been set.
12238
 */
12239
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
12240
    word32 ivSz)
12241
0
{
12242
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
12243
0
}
12244
12245
/* Update the AES GCM for decryption with data and/or authentication data. */
12246
int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
12247
    const byte* authIn, word32 authInSz)
12248
1.47k
{
12249
1.47k
    int ret = 0;
12250
12251
    /* Check validity of parameters. */
12252
1.47k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
12253
316
            ((out == NULL) || (in == NULL)))) {
12254
0
        ret = BAD_FUNC_ARG;
12255
0
    }
12256
12257
    /* Check key has been set. */
12258
1.47k
    if ((ret == 0) && (!aes->gcmKeySet)) {
12259
0
        ret = MISSING_KEY;
12260
0
    }
12261
    /* Check IV has been set. */
12262
1.47k
    if ((ret == 0) && (!aes->nonceSet)) {
12263
0
        ret = MISSING_IV;
12264
0
    }
12265
12266
1.47k
    if (ret == 0) {
12267
        /* Decrypt with AAD and/or cipher text. */
12268
    #ifdef WOLFSSL_AESNI
12269
        if (aes->use_aesni) {
12270
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12271
            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
12272
            RESTORE_VECTOR_REGISTERS();
12273
        }
12274
        else
12275
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12276
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12277
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12278
            ret = AesGcmDecryptUpdate_AARCH64(aes, out, in, sz, authIn,
12279
                authInSz);
12280
        }
12281
        else
12282
    #endif
12283
1.47k
        {
12284
            /* Update the authentication tag with any authentication data and
12285
             * cipher text. */
12286
1.47k
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
12287
            /* Decrypt the cipher text. */
12288
1.47k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
12289
1.47k
        }
12290
1.47k
    }
12291
12292
1.47k
    return ret;
12293
1.47k
}
12294
12295
/* Finalize the AES GCM for decryption and check the authentication tag.
12296
 *
12297
 * Must set key and IV before calling this function.
12298
 * Must call wc_AesGcmInit() before calling this function.
12299
 *
12300
 * @param [in, out] aes        AES object.
12301
 * @param [in]      authTag    Buffer holding authentication tag.
12302
 * @param [in]      authTagSz  Length of authentication tag in bytes.
12303
 * @return  0 on success.
12304
 */
12305
int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
12306
394
{
12307
394
    int ret = 0;
12308
12309
    /* Check validity of parameters. */
12310
394
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
12311
394
            (authTagSz == 0)) {
12312
0
        ret = BAD_FUNC_ARG;
12313
0
    }
12314
12315
    /* Check key has been set. */
12316
394
    if ((ret == 0) && (!aes->gcmKeySet)) {
12317
0
        ret = MISSING_KEY;
12318
0
    }
12319
    /* Check IV has been set. */
12320
394
    if ((ret == 0) && (!aes->nonceSet)) {
12321
0
        ret = MISSING_IV;
12322
0
    }
12323
12324
394
    if (ret == 0) {
12325
        /* Calculate authentication tag and compare with one passed in.. */
12326
    #ifdef WOLFSSL_AESNI
12327
        if (aes->use_aesni) {
12328
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12329
            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
12330
            RESTORE_VECTOR_REGISTERS();
12331
        }
12332
        else
12333
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12334
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12335
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12336
            ret = AesGcmDecryptFinal_AARCH64(aes, authTag, authTagSz);
12337
        }
12338
        else
12339
    #endif
12340
394
        {
12341
394
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
12342
            /* Calculate authentication tag. */
12343
394
            ret = AesGcmFinal_C(aes, calcTag, authTagSz);
12344
394
            if (ret == 0) {
12345
                /* Check calculated tag matches the one passed in. */
12346
394
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
12347
164
                    ret = AES_GCM_AUTH_E;
12348
164
                }
12349
394
            }
12350
394
        }
12351
394
    }
12352
12353
394
    return ret;
12354
394
}
12355
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
12356
#endif /* WOLFSSL_AESGCM_STREAM */
12357
#endif /* WOLFSSL_XILINX_CRYPT */
12358
#endif /* end of block for AESGCM implementation selection */
12359
12360
12361
/* Common to all, abstract functions that build off of lower level AESGCM
12362
 * functions */
12363
#ifndef WC_NO_RNG
12364
12365
2.59k
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
12366
2.59k
    return (ivSz == GCM_NONCE_MIN_SZ ||
12367
2.59k
            ivSz == GCM_NONCE_MID_SZ ||
12368
0
            ivSz == GCM_NONCE_MAX_SZ);
12369
2.59k
}
12370
12371
12372
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
12373
2.53k
{
12374
2.53k
    int ret = 0;
12375
12376
2.53k
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
12377
0
        ret = BAD_FUNC_ARG;
12378
0
    }
12379
12380
2.53k
    if (ret == 0) {
12381
2.53k
        XMEMCPY((byte*)aes->reg, iv, ivSz);
12382
12383
        /* If the IV is 96, allow for a 2^64 invocation counter.
12384
         * For any other size for the nonce, limit the invocation
12385
         * counter to 32-bits. (SP 800-38D 8.3) */
12386
2.53k
        aes->invokeCtr[0] = 0;
12387
2.53k
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
12388
2.53k
    #ifdef WOLFSSL_AESGCM_STREAM
12389
2.53k
        aes->ctrSet = 1;
12390
2.53k
    #endif
12391
2.53k
        aes->nonceSz = ivSz;
12392
2.53k
    }
12393
12394
2.53k
    return ret;
12395
2.53k
}
12396
12397
12398
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
12399
                   const byte* ivFixed, word32 ivFixedSz,
12400
                   WC_RNG* rng)
12401
65
{
12402
65
    int ret = 0;
12403
12404
65
    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
12405
65
        (ivFixed == NULL && ivFixedSz != 0) ||
12406
65
        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
12407
12408
0
        ret = BAD_FUNC_ARG;
12409
0
    }
12410
12411
65
    if (ret == 0) {
12412
65
        byte* iv = (byte*)aes->reg;
12413
12414
65
        if (ivFixedSz)
12415
65
            XMEMCPY(iv, ivFixed, ivFixedSz);
12416
12417
65
        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
12418
65
    }
12419
12420
65
    if (ret == 0) {
12421
        /* If the IV is 96, allow for a 2^64 invocation counter.
12422
         * For any other size for the nonce, limit the invocation
12423
         * counter to 32-bits. (SP 800-38D 8.3) */
12424
63
        aes->invokeCtr[0] = 0;
12425
63
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
12426
63
    #ifdef WOLFSSL_AESGCM_STREAM
12427
63
        aes->ctrSet = 1;
12428
63
    #endif
12429
63
        aes->nonceSz = ivSz;
12430
63
    }
12431
12432
65
    return ret;
12433
65
}
12434
12435
12436
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
12437
                        byte* ivOut, word32 ivOutSz,
12438
                        byte* authTag, word32 authTagSz,
12439
                        const byte* authIn, word32 authInSz)
12440
843
{
12441
843
    int ret = 0;
12442
12443
843
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
12444
843
        ivOut == NULL || ivOutSz != aes->nonceSz ||
12445
843
        (authIn == NULL && authInSz != 0)) {
12446
12447
0
        ret = BAD_FUNC_ARG;
12448
0
    }
12449
12450
843
    if (ret == 0) {
12451
843
        aes->invokeCtr[0]++;
12452
843
        if (aes->invokeCtr[0] == 0) {
12453
0
            aes->invokeCtr[1]++;
12454
0
            if (aes->invokeCtr[1] == 0)
12455
0
                ret = AES_GCM_OVERFLOW_E;
12456
0
        }
12457
843
    }
12458
12459
843
    if (ret == 0) {
12460
843
        XMEMCPY(ivOut, aes->reg, ivOutSz);
12461
843
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
12462
843
                               (byte*)aes->reg, ivOutSz,
12463
843
                               authTag, authTagSz,
12464
843
                               authIn, authInSz);
12465
843
        if (ret == 0)
12466
843
            IncCtr((byte*)aes->reg, ivOutSz);
12467
843
    }
12468
12469
843
    return ret;
12470
843
}
12471
12472
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
12473
            const byte* authIn, word32 authInSz,
12474
            byte* authTag, word32 authTagSz, WC_RNG* rng)
12475
0
{
12476
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
12477
0
    int ret;
12478
12479
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
12480
0
        authTag == NULL || authTagSz == 0 || rng == NULL) {
12481
12482
0
        return BAD_FUNC_ARG;
12483
0
    }
12484
12485
0
#ifdef WOLFSSL_SMALL_STACK
12486
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
12487
#else
12488
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12489
#endif
12490
0
    if (ret != 0)
12491
0
        return ret;
12492
12493
0
    ret = wc_AesGcmSetKey(aes, key, keySz);
12494
0
    if (ret == 0)
12495
0
        ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
12496
0
    if (ret == 0)
12497
0
        ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
12498
0
                                  authTag, authTagSz, authIn, authInSz);
12499
12500
0
#ifdef WOLFSSL_SMALL_STACK
12501
0
    wc_AesDelete(aes, NULL);
12502
#else
12503
    wc_AesFree(aes);
12504
#endif
12505
12506
0
    return ret;
12507
0
}
12508
12509
int wc_GmacVerify(const byte* key, word32 keySz,
12510
                  const byte* iv, word32 ivSz,
12511
                  const byte* authIn, word32 authInSz,
12512
                  const byte* authTag, word32 authTagSz)
12513
0
{
12514
0
    int ret;
12515
0
#ifdef HAVE_AES_DECRYPT
12516
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
12517
12518
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
12519
0
        authTag == NULL || authTagSz == 0 || authTagSz > WC_AES_BLOCK_SIZE) {
12520
12521
0
        return BAD_FUNC_ARG;
12522
0
    }
12523
12524
0
#ifdef WOLFSSL_SMALL_STACK
12525
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
12526
#else
12527
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12528
#endif
12529
0
    if (ret == 0) {
12530
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
12531
0
        if (ret == 0)
12532
0
            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
12533
0
                                  authTag, authTagSz, authIn, authInSz);
12534
12535
0
    }
12536
0
#ifdef WOLFSSL_SMALL_STACK
12537
0
    wc_AesDelete(aes, NULL);
12538
#else
12539
    wc_AesFree(aes);
12540
#endif
12541
#else
12542
    (void)key;
12543
    (void)keySz;
12544
    (void)iv;
12545
    (void)ivSz;
12546
    (void)authIn;
12547
    (void)authInSz;
12548
    (void)authTag;
12549
    (void)authTagSz;
12550
    ret = NOT_COMPILED_IN;
12551
#endif
12552
0
    return ret;
12553
0
}
12554
12555
#endif /* WC_NO_RNG */
12556
12557
12558
int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
12559
0
{
12560
0
    if (gmac == NULL || key == NULL) {
12561
0
        return BAD_FUNC_ARG;
12562
0
    }
12563
0
    return wc_AesGcmSetKey(&gmac->aes, key, len);
12564
0
}
12565
12566
12567
int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
12568
                              const byte* authIn, word32 authInSz,
12569
                              byte* authTag, word32 authTagSz)
12570
0
{
12571
0
    if (gmac == NULL) {
12572
0
        return BAD_FUNC_ARG;
12573
0
    }
12574
12575
0
    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
12576
0
                                         authTag, authTagSz, authIn, authInSz);
12577
0
}
12578
12579
#endif /* HAVE_AESGCM */
12580
12581
#ifdef HAVE_AESCCM
12582
12583
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
12584
573
{
12585
573
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
12586
0
        return BAD_FUNC_ARG;
12587
12588
573
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
12589
573
}
12590
12591
12592
/* Checks if the tag size is an accepted value based on RFC 3610 section 2
12593
 * returns 0 if tag size is ok
12594
 */
12595
int wc_AesCcmCheckTagSize(int sz)
12596
3.07k
{
12597
    /* values here are from RFC 3610 section 2 */
12598
3.07k
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
12599
2.55k
            && sz != 16) {
12600
0
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
12601
0
        return BAD_FUNC_ARG;
12602
0
    }
12603
3.07k
    return 0;
12604
3.07k
}
12605
12606
#if defined(WOLFSSL_RISCV_ASM)
12607
    /* implementation located in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
12608
12609
#elif defined(HAVE_COLDFIRE_SEC)
12610
    #error "Coldfire SEC doesn't currently support AES-CCM mode"
12611
12612
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
12613
        !defined(WOLFSSL_QNX_CAAM)
12614
    /* implemented in wolfcrypt/src/port/caam_aes.c */
12615
12616
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
12617
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
12618
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12619
                   const byte* nonce, word32 nonceSz,
12620
                   byte* authTag, word32 authTagSz,
12621
                   const byte* authIn, word32 authInSz)
12622
{
12623
    return wc_AesCcmEncrypt_silabs(
12624
        aes, out, in, inSz,
12625
        nonce, nonceSz,
12626
        authTag, authTagSz,
12627
        authIn, authInSz);
12628
}
12629
12630
#ifdef HAVE_AES_DECRYPT
12631
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12632
                   const byte* nonce, word32 nonceSz,
12633
                   const byte* authTag, word32 authTagSz,
12634
                   const byte* authIn, word32 authInSz)
12635
{
12636
    return wc_AesCcmDecrypt_silabs(
12637
        aes, out, in, inSz,
12638
        nonce, nonceSz,
12639
        authTag, authTagSz,
12640
        authIn, authInSz);
12641
}
12642
#endif
12643
#elif defined(FREESCALE_LTC)
12644
12645
/* return 0 on success */
12646
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12647
                   const byte* nonce, word32 nonceSz,
12648
                   byte* authTag, word32 authTagSz,
12649
                   const byte* authIn, word32 authInSz)
12650
{
12651
    byte *key;
12652
    word32 keySize;
12653
    status_t status;
12654
12655
    /* sanity check on arguments */
12656
    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
12657
     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
12658
     * don't allow it here either.
12659
     */
12660
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
12661
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
12662
        return BAD_FUNC_ARG;
12663
    }
12664
12665
    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
12666
        return BAD_FUNC_ARG;
12667
    }
12668
12669
    key = (byte*)aes->key;
12670
12671
    status = wc_AesGetKeySize(aes, &keySize);
12672
    if (status != 0) {
12673
        return status;
12674
    }
12675
12676
    status = wolfSSL_CryptHwMutexLock();
12677
    if (status != 0)
12678
        return status;
12679
12680
    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
12681
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
12682
    wolfSSL_CryptHwMutexUnLock();
12683
12684
    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
12685
}
12686
12687
#ifdef HAVE_AES_DECRYPT
12688
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12689
                   const byte* nonce, word32 nonceSz,
12690
                   const byte* authTag, word32 authTagSz,
12691
                   const byte* authIn, word32 authInSz)
12692
{
12693
    byte *key;
12694
    word32 keySize;
12695
    status_t status;
12696
12697
    /* sanity check on arguments */
12698
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
12699
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
12700
        return BAD_FUNC_ARG;
12701
    }
12702
12703
    key = (byte*)aes->key;
12704
12705
    status = wc_AesGetKeySize(aes, &keySize);
12706
    if (status != 0) {
12707
        return status;
12708
    }
12709
12710
    status = wolfSSL_CryptHwMutexLock();
12711
    if (status != 0)
12712
        return status;
12713
    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
12714
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
12715
    wolfSSL_CryptHwMutexUnLock();
12716
12717
    if (status != kStatus_Success) {
12718
        XMEMSET(out, 0, inSz);
12719
        return AES_CCM_AUTH_E;
12720
    }
12721
    return 0;
12722
}
12723
#endif /* HAVE_AES_DECRYPT */
12724
12725
#else
12726
12727
/* Software CCM */
12728
static WARN_UNUSED_RESULT int roll_x(
12729
    Aes* aes, const byte* in, word32 inSz, byte* out)
12730
3.06k
{
12731
3.06k
    int ret;
12732
12733
    /* process the bulk of the data */
12734
50.5k
    while (inSz >= WC_AES_BLOCK_SIZE) {
12735
47.5k
        xorbuf(out, in, WC_AES_BLOCK_SIZE);
12736
47.5k
        in += WC_AES_BLOCK_SIZE;
12737
47.5k
        inSz -= WC_AES_BLOCK_SIZE;
12738
12739
47.5k
        ret = wc_AesEncrypt(aes, out, out);
12740
47.5k
        if (ret != 0)
12741
0
            return ret;
12742
47.5k
    }
12743
12744
    /* process remainder of the data */
12745
3.06k
    if (inSz > 0) {
12746
2.96k
        xorbuf(out, in, inSz);
12747
2.96k
        ret = wc_AesEncrypt(aes, out, out);
12748
2.96k
        if (ret != 0)
12749
0
            return ret;
12750
2.96k
    }
12751
12752
3.06k
    return 0;
12753
3.06k
}
12754
12755
static WARN_UNUSED_RESULT int roll_auth(
12756
    Aes* aes, const byte* in, word32 inSz, byte* out)
12757
3.07k
{
12758
3.07k
    word32 authLenSz;
12759
3.07k
    word32 remainder;
12760
3.07k
    int ret;
12761
12762
    /* encode the length in */
12763
3.07k
    if (inSz <= 0xFEFF) {
12764
3.07k
        authLenSz = 2;
12765
3.07k
        out[0] ^= (byte)(inSz >> 8);
12766
3.07k
        out[1] ^= (byte)inSz;
12767
3.07k
    }
12768
0
    else {
12769
0
        authLenSz = 6;
12770
0
        out[0] ^= 0xFF;
12771
0
        out[1] ^= 0xFE;
12772
0
        out[2] ^= (byte)(inSz >> 24);
12773
0
        out[3] ^= (byte)(inSz >> 16);
12774
0
        out[4] ^= (byte)(inSz >>  8);
12775
0
        out[5] ^= (byte)inSz;
12776
0
    }
12777
    /* Note, the protocol handles auth data up to 2^64, but we are
12778
     * using 32-bit sizes right now, so the bigger data isn't handled
12779
     * else {}
12780
     */
12781
12782
    /* start fill out the rest of the first block */
12783
3.07k
    remainder = WC_AES_BLOCK_SIZE - authLenSz;
12784
3.07k
    if (inSz >= remainder) {
12785
        /* plenty of bulk data to fill the remainder of this block */
12786
0
        xorbuf(out + authLenSz, in, remainder);
12787
0
        inSz -= remainder;
12788
0
        in += remainder;
12789
0
    }
12790
3.07k
    else {
12791
        /* not enough bulk data, copy what is available, and pad zero */
12792
3.07k
        xorbuf(out + authLenSz, in, inSz);
12793
3.07k
        inSz = 0;
12794
3.07k
    }
12795
3.07k
    ret = wc_AesEncrypt(aes, out, out);
12796
12797
3.07k
    if ((ret == 0) && (inSz > 0)) {
12798
0
        ret = roll_x(aes, in, inSz, out);
12799
0
    }
12800
12801
3.07k
    return ret;
12802
3.07k
}
12803
12804
12805
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
12806
47.5k
{
12807
47.5k
    word32 i;
12808
12809
47.6k
    for (i = 0; i < lenSz; i++) {
12810
47.6k
        if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
12811
47.6k
    }
12812
47.5k
}
12813
12814
#ifdef WOLFSSL_AESNI
12815
static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
12816
{
12817
    word32 i;
12818
12819
    /* B+1 = B */
12820
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 1, B, WC_AES_BLOCK_SIZE);
12821
    /* B+2,B+3 = B,B+1 */
12822
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 2, B, WC_AES_BLOCK_SIZE * 2);
12823
12824
    for (i = 0; i < lenSz; i++) {
12825
        if (++B[WC_AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
12826
    }
12827
    B[WC_AES_BLOCK_SIZE * 3 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 3 - 1] + 2U);
12828
    if (B[WC_AES_BLOCK_SIZE * 3 - 1] < 2U) {
12829
        for (i = 1; i < lenSz; i++) {
12830
            if (++B[WC_AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
12831
        }
12832
    }
12833
    B[WC_AES_BLOCK_SIZE * 4 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 4 - 1] + 3U);
12834
    if (B[WC_AES_BLOCK_SIZE * 4 - 1] < 3U) {
12835
        for (i = 1; i < lenSz; i++) {
12836
            if (++B[WC_AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
12837
        }
12838
    }
12839
}
12840
12841
static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
12842
{
12843
    word32 i;
12844
12845
    B[WC_AES_BLOCK_SIZE - 1] = (byte)(B[WC_AES_BLOCK_SIZE - 1] + 4U);
12846
    if (B[WC_AES_BLOCK_SIZE - 1] < 4U) {
12847
        for (i = 1; i < lenSz; i++) {
12848
            if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) break;
12849
        }
12850
    }
12851
}
12852
#endif
12853
12854
/* Software AES - CCM Encrypt */
12855
/* return 0 on success */
12856
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12857
                   const byte* nonce, word32 nonceSz,
12858
                   byte* authTag, word32 authTagSz,
12859
                   const byte* authIn, word32 authInSz)
12860
731
{
12861
#ifdef WOLFSSL_AESNI
12862
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
12863
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
12864
#else
12865
731
    byte A[WC_AES_BLOCK_SIZE];
12866
731
    byte B[WC_AES_BLOCK_SIZE];
12867
731
#endif
12868
731
    byte lenSz;
12869
731
    word32 i;
12870
731
    byte mask = 0xFF;
12871
731
    const word32 wordSz = (word32)sizeof(word32);
12872
731
    int ret;
12873
12874
    /* sanity check on arguments */
12875
731
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
12876
731
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
12877
731
            authTagSz > WC_AES_BLOCK_SIZE)
12878
0
        return BAD_FUNC_ARG;
12879
12880
    /* Sanity check on authIn to prevent segfault in xorbuf() where
12881
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
12882
731
    if (authIn == NULL && authInSz > 0)
12883
0
        return BAD_FUNC_ARG;
12884
12885
    /* sanity check on tag size */
12886
731
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
12887
0
        return BAD_FUNC_ARG;
12888
0
    }
12889
12890
731
#ifdef WOLF_CRYPTO_CB
12891
731
    #ifndef WOLF_CRYPTO_CB_FIND
12892
731
    if (aes->devId != INVALID_DEVID)
12893
0
    #endif
12894
0
    {
12895
0
        int crypto_cb_ret =
12896
0
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
12897
0
                                      authTag, authTagSz, authIn, authInSz);
12898
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
12899
0
            return crypto_cb_ret;
12900
        /* fall-through when unavailable */
12901
0
    }
12902
731
#endif
12903
12904
731
    XMEMSET(A, 0, sizeof(A));
12905
731
    XMEMCPY(B+1, nonce, nonceSz);
12906
731
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
12907
731
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
12908
731
                  + (8 * (((byte)authTagSz - 2) / 2))
12909
731
                  + (lenSz - 1));
12910
2.92k
    for (i = 0; i < lenSz; i++) {
12911
2.19k
        if (mask && i >= wordSz)
12912
0
            mask = 0x00;
12913
2.19k
        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
12914
2.19k
    }
12915
12916
#ifdef WOLFSSL_CHECK_MEM_ZERO
12917
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
12918
#endif
12919
12920
731
    VECTOR_REGISTERS_PUSH;
12921
731
    ret = wc_AesEncrypt(aes, B, A);
12922
#ifdef WOLFSSL_CHECK_MEM_ZERO
12923
    if (ret == 0)
12924
        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
12925
#endif
12926
12927
731
    if ((ret == 0) && (authInSz > 0))
12928
731
        ret = roll_auth(aes, authIn, authInSz, A);
12929
12930
731
    if ((ret == 0) && (inSz > 0))
12931
731
        ret = roll_x(aes, in, inSz, A);
12932
12933
731
    if (ret == 0) {
12934
731
        XMEMCPY(authTag, A, authTagSz);
12935
12936
731
        B[0] = (byte)(lenSz - 1U);
12937
2.92k
        for (i = 0; i < lenSz; i++)
12938
2.19k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
12939
731
        ret = wc_AesEncrypt(aes, B, A);
12940
731
    }
12941
12942
731
    if (ret == 0) {
12943
731
        xorbuf(authTag, A, authTagSz);
12944
731
        B[15] = 1;
12945
731
    }
12946
#ifdef WOLFSSL_AESNI
12947
    if ((ret == 0) && aes->use_aesni) {
12948
        while (inSz >= WC_AES_BLOCK_SIZE * 4) {
12949
            AesCcmCtrIncSet4(B, lenSz);
12950
12951
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
12952
                            (int)aes->rounds);
12953
12954
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
12955
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE * 4);
12956
12957
            inSz -= WC_AES_BLOCK_SIZE * 4;
12958
            in += WC_AES_BLOCK_SIZE * 4;
12959
            out += WC_AES_BLOCK_SIZE * 4;
12960
12961
            AesCcmCtrInc4(B, lenSz);
12962
        }
12963
    }
12964
#endif
12965
731
    if (ret == 0) {
12966
36.6k
        while (inSz >= WC_AES_BLOCK_SIZE) {
12967
35.9k
            ret = wc_AesEncrypt(aes, B, A);
12968
35.9k
            if (ret != 0)
12969
0
                break;
12970
35.9k
            xorbuf(A, in, WC_AES_BLOCK_SIZE);
12971
35.9k
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
12972
12973
35.9k
            AesCcmCtrInc(B, lenSz);
12974
35.9k
            inSz -= WC_AES_BLOCK_SIZE;
12975
35.9k
            in += WC_AES_BLOCK_SIZE;
12976
35.9k
            out += WC_AES_BLOCK_SIZE;
12977
35.9k
        }
12978
731
    }
12979
731
    if ((ret == 0) && (inSz > 0)) {
12980
662
        ret = wc_AesEncrypt(aes, B, A);
12981
662
    }
12982
731
    if ((ret == 0) && (inSz > 0)) {
12983
662
        xorbuf(A, in, inSz);
12984
662
        XMEMCPY(out, A, inSz);
12985
662
    }
12986
12987
731
    ForceZero(A, sizeof(A));
12988
731
    ForceZero(B, sizeof(B));
12989
12990
#ifdef WOLFSSL_CHECK_MEM_ZERO
12991
    wc_MemZero_Check(A, sizeof(A));
12992
    wc_MemZero_Check(B, sizeof(B));
12993
#endif
12994
12995
731
    VECTOR_REGISTERS_POP;
12996
12997
731
    return ret;
12998
731
}
12999
13000
#ifdef HAVE_AES_DECRYPT
13001
/* Software AES - CCM Decrypt */
13002
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
13003
                   const byte* nonce, word32 nonceSz,
13004
                   const byte* authTag, word32 authTagSz,
13005
                   const byte* authIn, word32 authInSz)
13006
2.33k
{
13007
#ifdef WOLFSSL_AESNI
13008
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
13009
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
13010
#else
13011
2.33k
    byte A[WC_AES_BLOCK_SIZE];
13012
2.33k
    byte B[WC_AES_BLOCK_SIZE];
13013
2.33k
#endif
13014
2.33k
    byte* o;
13015
2.33k
    byte lenSz;
13016
2.33k
    word32 i, oSz;
13017
2.33k
    byte mask = 0xFF;
13018
2.33k
    const word32 wordSz = (word32)sizeof(word32);
13019
2.33k
    int ret = 0;
13020
13021
    /* sanity check on arguments */
13022
2.33k
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
13023
2.33k
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
13024
2.33k
        authTagSz > WC_AES_BLOCK_SIZE)
13025
0
        return BAD_FUNC_ARG;
13026
13027
    /* Sanity check on authIn to prevent segfault in xorbuf() where
13028
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
13029
2.33k
    if (authIn == NULL && authInSz > 0)
13030
0
        return BAD_FUNC_ARG;
13031
13032
    /* sanity check on tag size */
13033
2.33k
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
13034
0
        return BAD_FUNC_ARG;
13035
0
    }
13036
13037
2.33k
#ifdef WOLF_CRYPTO_CB
13038
2.33k
    #ifndef WOLF_CRYPTO_CB_FIND
13039
2.33k
    if (aes->devId != INVALID_DEVID)
13040
0
    #endif
13041
0
    {
13042
0
        int crypto_cb_ret =
13043
0
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
13044
0
            authTag, authTagSz, authIn, authInSz);
13045
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13046
0
            return crypto_cb_ret;
13047
        /* fall-through when unavailable */
13048
0
    }
13049
2.33k
#endif
13050
13051
2.33k
    o = out;
13052
2.33k
    oSz = inSz;
13053
2.33k
    XMEMSET(A, 0, sizeof A);
13054
2.33k
    XMEMCPY(B+1, nonce, nonceSz);
13055
2.33k
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
13056
13057
2.33k
    B[0] = (byte)(lenSz - 1U);
13058
9.35k
    for (i = 0; i < lenSz; i++)
13059
7.01k
        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13060
2.33k
    B[15] = 1;
13061
13062
#ifdef WOLFSSL_CHECK_MEM_ZERO
13063
    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
13064
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
13065
#endif
13066
13067
2.33k
    VECTOR_REGISTERS_PUSH;
13068
13069
#ifdef WOLFSSL_AESNI
13070
    if (aes->use_aesni) {
13071
        while (oSz >= WC_AES_BLOCK_SIZE * 4) {
13072
            AesCcmCtrIncSet4(B, lenSz);
13073
13074
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
13075
                            (int)aes->rounds);
13076
13077
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
13078
            XMEMCPY(o, A, WC_AES_BLOCK_SIZE * 4);
13079
13080
            oSz -= WC_AES_BLOCK_SIZE * 4;
13081
            in += WC_AES_BLOCK_SIZE * 4;
13082
            o += WC_AES_BLOCK_SIZE * 4;
13083
13084
            AesCcmCtrInc4(B, lenSz);
13085
        }
13086
    }
13087
#endif
13088
13089
13.9k
    while (oSz >= WC_AES_BLOCK_SIZE) {
13090
11.5k
        ret = wc_AesEncrypt(aes, B, A);
13091
11.5k
        if (ret != 0)
13092
0
            break;
13093
11.5k
        xorbuf(A, in, WC_AES_BLOCK_SIZE);
13094
11.5k
        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
13095
11.5k
        AesCcmCtrInc(B, lenSz);
13096
11.5k
        oSz -= WC_AES_BLOCK_SIZE;
13097
11.5k
        in += WC_AES_BLOCK_SIZE;
13098
11.5k
        o += WC_AES_BLOCK_SIZE;
13099
11.5k
    }
13100
13101
2.33k
    if ((ret == 0) && (inSz > 0))
13102
2.33k
        ret = wc_AesEncrypt(aes, B, A);
13103
13104
2.33k
    if ((ret == 0) && (inSz > 0)) {
13105
2.33k
        xorbuf(A, in, oSz);
13106
2.33k
        XMEMCPY(o, A, oSz);
13107
9.32k
        for (i = 0; i < lenSz; i++)
13108
6.99k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13109
2.33k
        ret = wc_AesEncrypt(aes, B, A);
13110
2.33k
    }
13111
13112
2.33k
    if (ret == 0) {
13113
2.33k
        o = out;
13114
2.33k
        oSz = inSz;
13115
13116
2.33k
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
13117
2.33k
                      + (8 * (((byte)authTagSz - 2) / 2))
13118
2.33k
                      + (lenSz - 1));
13119
9.35k
        for (i = 0; i < lenSz; i++) {
13120
7.01k
            if (mask && i >= wordSz)
13121
0
                mask = 0x00;
13122
7.01k
            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
13123
7.01k
        }
13124
13125
2.33k
        ret = wc_AesEncrypt(aes, B, A);
13126
2.33k
    }
13127
13128
2.33k
    if (ret == 0) {
13129
2.33k
        if (authInSz > 0)
13130
2.33k
            ret = roll_auth(aes, authIn, authInSz, A);
13131
2.33k
    }
13132
2.33k
    if ((ret == 0) && (inSz > 0))
13133
2.33k
        ret = roll_x(aes, o, oSz, A);
13134
13135
2.33k
    if (ret == 0) {
13136
2.33k
        B[0] = (byte)(lenSz - 1U);
13137
9.35k
        for (i = 0; i < lenSz; i++)
13138
7.01k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13139
2.33k
        ret = wc_AesEncrypt(aes, B, B);
13140
2.33k
    }
13141
13142
2.33k
    if (ret == 0)
13143
2.33k
        xorbuf(A, B, authTagSz);
13144
13145
2.33k
    if (ret == 0) {
13146
2.33k
        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
13147
            /* If the authTag check fails, don't keep the decrypted data.
13148
             * Unfortunately, you need the decrypted data to calculate the
13149
             * check value. */
13150
            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
13151
                        defined(ACVP_VECTOR_TESTING)
13152
            WOLFSSL_MSG("Preserve output for vector responses");
13153
            #else
13154
2.33k
            if (inSz > 0)
13155
2.33k
                XMEMSET(out, 0, inSz);
13156
2.33k
            #endif
13157
2.33k
            ret = AES_CCM_AUTH_E;
13158
2.33k
        }
13159
2.33k
    }
13160
13161
2.33k
    ForceZero(A, sizeof(A));
13162
2.33k
    ForceZero(B, sizeof(B));
13163
2.33k
    o = NULL;
13164
13165
#ifdef WOLFSSL_CHECK_MEM_ZERO
13166
    wc_MemZero_Check(A, sizeof(A));
13167
    wc_MemZero_Check(B, sizeof(B));
13168
#endif
13169
13170
2.33k
    VECTOR_REGISTERS_POP;
13171
13172
2.33k
    return ret;
13173
2.33k
}
13174
13175
#endif /* HAVE_AES_DECRYPT */
13176
#endif /* software CCM */
13177
13178
/* abstract functions that call lower level AESCCM functions */
13179
#ifndef WC_NO_RNG
13180
13181
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
13182
719
{
13183
719
    int ret = 0;
13184
13185
719
    if (aes == NULL || nonce == NULL ||
13186
719
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
13187
13188
0
        ret = BAD_FUNC_ARG;
13189
0
    }
13190
13191
719
    if (ret == 0) {
13192
719
        XMEMCPY(aes->reg, nonce, nonceSz);
13193
719
        aes->nonceSz = nonceSz;
13194
13195
        /* Invocation counter should be 2^61 */
13196
719
        aes->invokeCtr[0] = 0;
13197
719
        aes->invokeCtr[1] = 0xE0000000;
13198
719
    }
13199
13200
719
    return ret;
13201
719
}
13202
13203
13204
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
13205
                        byte* ivOut, word32 ivOutSz,
13206
                        byte* authTag, word32 authTagSz,
13207
                        const byte* authIn, word32 authInSz)
13208
731
{
13209
731
    int ret = 0;
13210
13211
731
    if (aes == NULL || out == NULL ||
13212
731
        (in == NULL && sz != 0) ||
13213
731
        ivOut == NULL ||
13214
731
        (authIn == NULL && authInSz != 0) ||
13215
731
        (ivOutSz != aes->nonceSz)) {
13216
13217
0
        ret = BAD_FUNC_ARG;
13218
0
    }
13219
13220
731
    if (ret == 0) {
13221
731
        aes->invokeCtr[0]++;
13222
731
        if (aes->invokeCtr[0] == 0) {
13223
0
            aes->invokeCtr[1]++;
13224
0
            if (aes->invokeCtr[1] == 0)
13225
0
                ret = AES_CCM_OVERFLOW_E;
13226
0
        }
13227
731
    }
13228
13229
731
    if (ret == 0) {
13230
731
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
13231
731
                               (byte*)aes->reg, aes->nonceSz,
13232
731
                               authTag, authTagSz,
13233
731
                               authIn, authInSz);
13234
731
        if (ret == 0) {
13235
731
            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
13236
731
            IncCtr((byte*)aes->reg, aes->nonceSz);
13237
731
        }
13238
731
    }
13239
13240
731
    return ret;
13241
731
}
13242
13243
#endif /* WC_NO_RNG */
13244
13245
#endif /* HAVE_AESCCM */
13246
13247
#ifndef WC_NO_CONSTRUCTORS
13248
Aes* wc_AesNew(void* heap, int devId, int *result_code)
13249
0
{
13250
0
    int ret;
13251
0
    Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
13252
0
    if (aes == NULL) {
13253
0
        ret = MEMORY_E;
13254
0
    }
13255
0
    else {
13256
0
        ret = wc_AesInit(aes, heap, devId);
13257
0
        if (ret != 0) {
13258
0
            XFREE(aes, heap, DYNAMIC_TYPE_AES);
13259
0
            aes = NULL;
13260
0
        }
13261
0
    }
13262
13263
0
    if (result_code != NULL)
13264
0
        *result_code = ret;
13265
13266
0
    return aes;
13267
0
}
13268
13269
int wc_AesDelete(Aes *aes, Aes** aes_p)
13270
0
{
13271
0
    if (aes == NULL)
13272
0
        return BAD_FUNC_ARG;
13273
0
    wc_AesFree(aes);
13274
0
    XFREE(aes, aes->heap, DYNAMIC_TYPE_AES);
13275
0
    if (aes_p != NULL)
13276
0
        *aes_p = NULL;
13277
0
    return 0;
13278
0
}
13279
#endif /* !WC_NO_CONSTRUCTORS */
13280
13281
/* Initialize Aes */
13282
int wc_AesInit(Aes* aes, void* heap, int devId)
13283
6.72k
{
13284
6.72k
    int ret = 0;
13285
13286
6.72k
    if (aes == NULL)
13287
0
        return BAD_FUNC_ARG;
13288
13289
6.72k
    XMEMSET(aes, 0, sizeof(*aes));
13290
13291
6.72k
    aes->heap = heap;
13292
13293
6.72k
#if defined(WOLF_CRYPTO_CB) || defined(WOLFSSL_STM32U5_DHUK)
13294
6.72k
    aes->devId = devId;
13295
#else
13296
    (void)devId;
13297
#endif
13298
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
13299
    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
13300
                                                        aes->heap, devId);
13301
#endif /* WOLFSSL_ASYNC_CRYPT */
13302
13303
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
13304
    aes->alFd = WC_SOCK_NOTSET;
13305
    aes->rdFd = WC_SOCK_NOTSET;
13306
#endif
13307
#if defined(WOLFSSL_DEVCRYPTO) && \
13308
   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
13309
    aes->ctx.cfd = -1;
13310
#endif
13311
#if defined(WOLFSSL_IMXRT_DCP)
13312
    DCPAesInit(aes);
13313
#endif
13314
13315
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
13316
    ret = wc_psa_aes_init(aes);
13317
#endif
13318
13319
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
13320
    if (ret == 0)
13321
        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
13322
#endif
13323
13324
6.72k
    return ret;
13325
6.72k
}
13326
13327
#ifdef WOLF_PRIVATE_KEY_ID
13328
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
13329
0
{
13330
0
    int ret = 0;
13331
13332
0
    if (aes == NULL)
13333
0
        ret = BAD_FUNC_ARG;
13334
0
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
13335
0
        ret = BUFFER_E;
13336
13337
0
    if (ret == 0)
13338
0
        ret = wc_AesInit(aes, heap, devId);
13339
0
    if (ret == 0) {
13340
0
        XMEMCPY(aes->id, id, (size_t)len);
13341
0
        aes->idLen = len;
13342
0
        aes->labelLen = 0;
13343
0
    }
13344
13345
0
    return ret;
13346
0
}
13347
13348
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
13349
0
{
13350
0
    int ret = 0;
13351
0
    size_t labelLen = 0;
13352
13353
0
    if (aes == NULL || label == NULL)
13354
0
        ret = BAD_FUNC_ARG;
13355
0
    if (ret == 0) {
13356
0
        labelLen = XSTRLEN(label);
13357
0
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
13358
0
            ret = BUFFER_E;
13359
0
    }
13360
13361
0
    if (ret == 0)
13362
0
        ret = wc_AesInit(aes, heap, devId);
13363
0
    if (ret == 0) {
13364
0
        XMEMCPY(aes->label, label, labelLen);
13365
0
        aes->labelLen = (int)labelLen;
13366
0
        aes->idLen = 0;
13367
0
    }
13368
13369
0
    return ret;
13370
0
}
13371
#endif
13372
13373
/* Free Aes resources */
13374
void wc_AesFree(Aes* aes)
13375
338k
{
13376
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
13377
    int ret = 0;
13378
#endif
13379
13380
338k
    if (aes == NULL) {
13381
331k
        return;
13382
331k
    }
13383
13384
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
13385
    #ifndef WOLF_CRYPTO_CB_FIND
13386
    if (aes->devId != INVALID_DEVID)
13387
    #endif
13388
    {
13389
        ret = wc_CryptoCb_Free(aes->devId, WC_ALGO_TYPE_CIPHER,
13390
                         WC_CIPHER_AES, (void*)aes);
13391
        /* If they want the standard free, they can call it themselves */
13392
        /* via their callback setting devId to INVALID_DEVID */
13393
        /* otherwise assume the callback handled it */
13394
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13395
            return;
13396
        /* fall-through when unavailable */
13397
    }
13398
13399
    /* silence compiler warning */
13400
    (void)ret;
13401
13402
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
13403
13404
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
13405
    (void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
13406
#endif
13407
13408
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
13409
    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
13410
#endif /* WOLFSSL_ASYNC_CRYPT */
13411
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
13412
    if (aes->rdFd > 0) { /* negative is error case */
13413
        close(aes->rdFd);
13414
        aes->rdFd = WC_SOCK_NOTSET;
13415
    }
13416
    if (aes->alFd > 0) {
13417
        close(aes->alFd);
13418
        aes->alFd = WC_SOCK_NOTSET;
13419
    }
13420
#endif /* WOLFSSL_AFALG */
13421
#ifdef WOLFSSL_KCAPI_AES
13422
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
13423
    if (aes->init == 1) {
13424
        kcapi_cipher_destroy(aes->handle);
13425
    }
13426
    aes->init = 0;
13427
    aes->handle = NULL;
13428
#endif
13429
#if defined(WOLFSSL_DEVCRYPTO) && \
13430
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
13431
    wc_DevCryptoFree(&aes->ctx);
13432
#endif
13433
6.72k
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
13434
6.72k
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
13435
6.72k
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
13436
6.72k
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
13437
6.72k
#endif
13438
#if defined(WOLFSSL_IMXRT_DCP)
13439
    DCPAesFree(aes);
13440
#endif
13441
6.72k
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
13442
6.72k
    !defined(WOLFSSL_AESNI)
13443
6.72k
    if (aes->streamData != NULL) {
13444
1.00k
        ForceZero(aes->streamData, aes->streamData_sz);
13445
1.00k
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
13446
1.00k
        aes->streamData = NULL;
13447
1.00k
    }
13448
6.72k
#endif
13449
13450
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
13451
    if (aes->useSWCrypt == 0) {
13452
        se050_aes_free(aes);
13453
    }
13454
#endif
13455
13456
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
13457
    wc_psa_aes_free(aes);
13458
#endif
13459
13460
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
13461
    wc_MAXQ10XX_AesFree(aes);
13462
#endif
13463
13464
#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
13465
    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
13466
    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
13467
    wc_fspsm_Aesfree(aes);
13468
#endif
13469
13470
6.72k
    ForceZero(aes, sizeof(Aes));
13471
13472
#ifdef WOLFSSL_CHECK_MEM_ZERO
13473
    wc_MemZero_Check(aes, sizeof(Aes));
13474
#endif
13475
6.72k
}
13476
13477
int wc_AesGetKeySize(Aes* aes, word32* keySize)
13478
0
{
13479
0
    int ret = 0;
13480
13481
0
    if (aes == NULL || keySize == NULL) {
13482
0
        return BAD_FUNC_ARG;
13483
0
    }
13484
13485
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
13486
    return wc_psa_aes_get_key_size(aes, keySize);
13487
#endif
13488
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
13489
    *keySize = aes->ctx.key.keySize;
13490
    return ret;
13491
#endif
13492
0
    switch (aes->rounds) {
13493
0
#ifdef WOLFSSL_AES_128
13494
0
    case 10:
13495
0
        *keySize = 16;
13496
0
        break;
13497
0
#endif
13498
0
#ifdef WOLFSSL_AES_192
13499
0
    case 12:
13500
0
        *keySize = 24;
13501
0
        break;
13502
0
#endif
13503
0
#ifdef WOLFSSL_AES_256
13504
0
    case 14:
13505
0
        *keySize = 32;
13506
0
        break;
13507
0
#endif
13508
0
    default:
13509
0
        *keySize = 0;
13510
0
        ret = BAD_FUNC_ARG;
13511
0
    }
13512
13513
0
    return ret;
13514
0
}
13515
13516
#endif /* !WOLFSSL_TI_CRYPT */
13517
13518
/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
13519
 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
13520
 */
13521
#ifndef VECTOR_REGISTERS_PUSH
13522
    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
13523
#endif
13524
#ifndef VECTOR_REGISTERS_POP
13525
    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
13526
#endif
13527
13528
#ifdef HAVE_AES_ECB
13529
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
13530
        !defined(WOLFSSL_QNX_CAAM)
13531
    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
13532
13533
#elif defined(WOLFSSL_AFALG)
13534
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
13535
13536
#elif defined(WOLFSSL_DEVCRYPTO_AES)
13537
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
13538
13539
#elif defined(WOLFSSL_RISCV_ASM)
13540
    /* implemented in wolfcrypt/src/port/riscv/riscv-64-aes.c */
13541
13542
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
13543
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
13544
13545
#elif defined(MAX3266X_AES)
13546
13547
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13548
{
13549
    int status;
13550
    word32 keySize;
13551
13552
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13553
        return BAD_FUNC_ARG;
13554
13555
    status = wc_AesGetKeySize(aes, &keySize);
13556
    if (status != 0) {
13557
        return status;
13558
    }
13559
13560
    status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key,
13561
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
13562
13563
    return status;
13564
}
13565
13566
#ifdef HAVE_AES_DECRYPT
13567
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13568
{
13569
    int status;
13570
    word32 keySize;
13571
13572
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13573
        return BAD_FUNC_ARG;
13574
13575
    status = wc_AesGetKeySize(aes, &keySize);
13576
    if (status != 0) {
13577
        return status;
13578
    }
13579
13580
    status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key,
13581
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
13582
13583
    return status;
13584
}
13585
#endif /* HAVE_AES_DECRYPT */
13586
13587
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
13588
13589
/* Software AES - ECB */
13590
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13591
{
13592
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13593
        return BAD_FUNC_ARG;
13594
13595
    return AES_ECB_encrypt(aes, in, out, sz);
13596
}
13597
13598
13599
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13600
{
13601
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13602
        return BAD_FUNC_ARG;
13603
13604
    return AES_ECB_decrypt(aes, in, out, sz);
13605
}
13606
13607
#elif defined(WOLFSSL_PSOC6_CRYPTO)
13608
13609
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13610
{
13611
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13612
        return BAD_FUNC_ARG;
13613
13614
    return wc_Psoc6_Aes_EcbEncrypt(aes, out, in, sz);
13615
}
13616
13617
#define _AesEcbEncrypt(aes, out, in, sz) wc_AesEcbEncrypt(aes, out, in, sz)
13618
13619
#ifdef HAVE_AES_DECRYPT
13620
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13621
{
13622
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13623
        return BAD_FUNC_ARG;
13624
13625
    return wc_Psoc6_Aes_EcbDecrypt(aes, out, in, sz);
13626
}
13627
13628
#define _AesEcbDecrypt(aes, out, in, sz) wc_AesEcbDecrypt(aes, out, in, sz)
13629
#endif /* HAVE_AES_DECRYPT */
13630
13631
#else
13632
13633
/* Software AES - ECB */
13634
static WARN_UNUSED_RESULT int _AesEcbEncrypt(
13635
    Aes* aes, byte* out, const byte* in, word32 sz)
13636
1.10k
{
13637
1.10k
    int ret = 0;
13638
13639
1.10k
#ifdef WOLF_CRYPTO_CB
13640
1.10k
    #ifndef WOLF_CRYPTO_CB_FIND
13641
1.10k
    if (aes->devId != INVALID_DEVID)
13642
89
    #endif
13643
89
    {
13644
89
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
13645
89
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13646
0
            return ret;
13647
89
        ret = 0;
13648
        /* fall-through when unavailable */
13649
89
    }
13650
1.10k
#endif
13651
#ifdef WOLFSSL_IMXRT_DCP
13652
    if (aes->keylen == 16)
13653
        return DCPAesEcbEncrypt(aes, out, in, sz);
13654
#endif
13655
13656
1.10k
    VECTOR_REGISTERS_PUSH;
13657
13658
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
13659
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
13660
    AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
13661
#else
13662
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
13663
#endif
13664
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
13665
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13666
    if (aes->use_aes_hw_crypto) {
13667
        AES_encrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
13668
            (int)aes->rounds);
13669
    }
13670
    else
13671
#endif
13672
#if !defined(WOLFSSL_ARMASM_NO_NEON)
13673
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
13674
    if (sz >= 32)
13675
#endif
13676
    {
13677
        AES_ECB_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
13678
            aes->rounds);
13679
    }
13680
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
13681
    else
13682
#endif
13683
#endif
13684
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
13685
    {
13686
        AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key,
13687
            aes->rounds);
13688
    }
13689
#endif
13690
#else
13691
#ifdef WOLFSSL_AESNI
13692
    if (aes->use_aesni) {
13693
        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
13694
    }
13695
    else
13696
#endif
13697
1.10k
    {
13698
1.10k
#if defined(NEED_AES_TABLES)
13699
1.10k
        AesEncryptBlocks_C(aes, in, out, sz);
13700
#else
13701
        word32 i;
13702
13703
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
13704
            ret = wc_AesEncryptDirect(aes, out, in);
13705
            if (ret != 0)
13706
                break;
13707
            in += WC_AES_BLOCK_SIZE;
13708
            out += WC_AES_BLOCK_SIZE;
13709
        }
13710
#endif
13711
1.10k
    }
13712
1.10k
#endif
13713
13714
1.10k
    VECTOR_REGISTERS_POP;
13715
13716
1.10k
    return ret;
13717
1.10k
}
13718
13719
#ifdef HAVE_AES_DECRYPT
13720
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
13721
    Aes* aes, byte* out, const byte* in, word32 sz)
13722
175
{
13723
175
    int ret = 0;
13724
13725
175
#ifdef WOLF_CRYPTO_CB
13726
175
    #ifndef WOLF_CRYPTO_CB_FIND
13727
175
    if (aes->devId != INVALID_DEVID)
13728
137
    #endif
13729
137
    {
13730
137
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
13731
137
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13732
0
            return ret;
13733
137
        ret = 0;
13734
        /* fall-through when unavailable */
13735
137
    }
13736
175
#endif
13737
#ifdef WOLFSSL_IMXRT_DCP
13738
    if (aes->keylen == 16)
13739
        return DCPAesEcbDecrypt(aes, out, in, sz);
13740
#endif
13741
13742
175
    VECTOR_REGISTERS_PUSH;
13743
13744
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
13745
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
13746
    AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
13747
#else
13748
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
13749
#endif
13750
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
13751
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13752
    if (aes->use_aes_hw_crypto) {
13753
        AES_decrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
13754
            (int)aes->rounds);
13755
    }
13756
    else
13757
#endif
13758
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
13759
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
13760
    if (sz >= 64)
13761
#endif
13762
    {
13763
        AES_ECB_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
13764
            aes->rounds);
13765
    }
13766
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
13767
    else
13768
#endif
13769
#endif
13770
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
13771
    {
13772
        AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key,
13773
            aes->rounds);
13774
    }
13775
#endif
13776
#else
13777
#ifdef WOLFSSL_AESNI
13778
    if (aes->use_aesni) {
13779
        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
13780
    }
13781
    else
13782
#endif
13783
175
    {
13784
175
#if defined(NEED_AES_TABLES)
13785
175
        AesDecryptBlocks_C(aes, in, out, sz);
13786
#else
13787
        word32 i;
13788
13789
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
13790
            ret = wc_AesDecryptDirect(aes, out, in);
13791
            if (ret != 0)
13792
                break;
13793
            in += WC_AES_BLOCK_SIZE;
13794
            out += WC_AES_BLOCK_SIZE;
13795
        }
13796
#endif
13797
175
    }
13798
175
#endif
13799
13800
175
    VECTOR_REGISTERS_POP;
13801
13802
175
    return ret;
13803
175
}
13804
#endif
13805
13806
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13807
1.01k
{
13808
1.01k
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13809
0
      return BAD_FUNC_ARG;
13810
1.01k
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
13811
0
        return BAD_LENGTH_E;
13812
0
    }
13813
13814
1.01k
    return _AesEcbEncrypt(aes, out, in, sz);
13815
1.01k
}
13816
13817
#ifdef HAVE_AES_DECRYPT
13818
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13819
38
{
13820
38
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13821
0
      return BAD_FUNC_ARG;
13822
38
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
13823
0
        return BAD_LENGTH_E;
13824
0
    }
13825
13826
38
    return _AesEcbDecrypt(aes, out, in, sz);
13827
38
}
13828
#endif /* HAVE_AES_DECRYPT */
13829
#endif
13830
#endif /* HAVE_AES_ECB */
13831
13832
#if defined(WOLFSSL_AES_CFB)
13833
13834
#if defined(WOLFSSL_PSOC6_CRYPTO)
13835
13836
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13837
{
13838
    return wc_Psoc6_Aes_CfbEncrypt(aes, out, in, sz);
13839
}
13840
13841
#ifdef HAVE_AES_DECRYPT
13842
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13843
{
13844
    return wc_Psoc6_Aes_CfbDecrypt(aes, out, in, sz);
13845
}
13846
#endif /* HAVE_AES_DECRYPT */
13847
13848
#else
13849
/* Feedback AES mode
13850
 *
13851
 * aes structure holding key to use for encryption
13852
 * out buffer to hold result of encryption (must be at least as large as input
13853
 *     buffer)
13854
 * in  buffer to encrypt
13855
 * sz  size of input buffer
13856
 * mode flag to specify AES mode
13857
 *
13858
 * returns 0 on success and negative error values on failure
13859
 */
13860
/* Software AES - CFB Encrypt */
13861
static WARN_UNUSED_RESULT int AesCfbEncrypt_C(Aes* aes, byte* out,
13862
    const byte* in, word32 sz)
13863
0
{
13864
0
    int ret = 0;
13865
0
    word32 processed;
13866
13867
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
13868
0
        return BAD_FUNC_ARG;
13869
0
    }
13870
0
    if (sz == 0) {
13871
0
        return 0;
13872
0
    }
13873
13874
0
    if (aes->left > 0) {
13875
        /* consume any unused bytes left in aes->tmp */
13876
0
        processed = min(aes->left, sz);
13877
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
13878
0
            processed);
13879
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out,
13880
0
            processed);
13881
0
        aes->left -= processed;
13882
0
        out += processed;
13883
0
        in += processed;
13884
0
        sz -= processed;
13885
0
    }
13886
13887
0
    VECTOR_REGISTERS_PUSH;
13888
13889
0
    while (sz >= WC_AES_BLOCK_SIZE) {
13890
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->reg, (byte*)aes->reg);
13891
0
        if (ret != 0) {
13892
0
            break;
13893
0
        }
13894
0
        xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
13895
0
        XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
13896
0
        out += WC_AES_BLOCK_SIZE;
13897
0
        in  += WC_AES_BLOCK_SIZE;
13898
0
        sz  -= WC_AES_BLOCK_SIZE;
13899
0
    }
13900
13901
    /* encrypt left over data */
13902
0
    if ((ret == 0) && sz) {
13903
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
13904
0
        if (ret == 0) {
13905
0
            xorbufout(out, in, aes->tmp, sz);
13906
0
            XMEMCPY(aes->reg, out, sz);
13907
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
13908
0
        }
13909
0
    }
13910
13911
0
    VECTOR_REGISTERS_POP;
13912
13913
0
    return ret;
13914
0
}
13915
13916
13917
#if defined(HAVE_AES_DECRYPT)
13918
/* CFB 128
13919
 *
13920
 * aes structure holding key to use for decryption
13921
 * out buffer to hold result of decryption (must be at least as large as input
13922
 *     buffer)
13923
 * in  buffer to decrypt
13924
 * sz  size of input buffer
13925
 *
13926
 * returns 0 on success and negative error values on failure
13927
 */
13928
/* Software AES - CFB Decrypt */
13929
static WARN_UNUSED_RESULT int AesCfbDecrypt_C(Aes* aes, byte* out,
13930
    const byte* in, word32 sz, byte mode)
13931
0
{
13932
0
    int ret = 0;
13933
0
    word32 processed;
13934
13935
0
    (void)mode;
13936
13937
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
13938
0
        return BAD_FUNC_ARG;
13939
0
    }
13940
0
    if (sz == 0) {
13941
0
        return 0;
13942
0
    }
13943
13944
0
    if (aes->left > 0) {
13945
        /* consume any unused bytes left in aes->tmp */
13946
0
        processed = min(aes->left, sz);
13947
        /* copy input over to aes->reg */
13948
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, processed);
13949
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
13950
0
            processed);
13951
0
        aes->left -= processed;
13952
0
        out += processed;
13953
0
        in += processed;
13954
0
        sz -= processed;
13955
0
    }
13956
13957
0
    VECTOR_REGISTERS_PUSH;
13958
13959
    #if !defined(WOLFSSL_SMALL_STACK) && defined(HAVE_AES_ECB) && \
13960
        !defined(WOLFSSL_PIC32MZ_CRYPT) && \
13961
        (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
13962
    {
13963
        ALIGN16 byte tmp[4 * WC_AES_BLOCK_SIZE];
13964
        while (sz >= 4 * WC_AES_BLOCK_SIZE) {
13965
            XMEMCPY(tmp, aes->reg, WC_AES_BLOCK_SIZE);
13966
            XMEMCPY(tmp + WC_AES_BLOCK_SIZE, in, 3 * WC_AES_BLOCK_SIZE);
13967
            XMEMCPY(aes->reg, in + 3 * WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
13968
            ret = wc_AesEcbEncrypt(aes, tmp, tmp, 4 * WC_AES_BLOCK_SIZE);
13969
            if (ret != 0) {
13970
                break;
13971
            }
13972
            xorbufout(out, in, tmp, 4 * WC_AES_BLOCK_SIZE);
13973
            out += 4 * WC_AES_BLOCK_SIZE;
13974
            in  += 4 * WC_AES_BLOCK_SIZE;
13975
            sz  -= 4 * WC_AES_BLOCK_SIZE;
13976
        }
13977
    }
13978
    #endif
13979
0
    while (sz >= WC_AES_BLOCK_SIZE) {
13980
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
13981
0
        if (ret != 0) {
13982
0
            break;
13983
0
        }
13984
0
        XMEMCPY((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
13985
0
        xorbufout(out, in, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
13986
0
        out += WC_AES_BLOCK_SIZE;
13987
0
        in  += WC_AES_BLOCK_SIZE;
13988
0
        sz  -= WC_AES_BLOCK_SIZE;
13989
0
    }
13990
13991
    /* decrypt left over data */
13992
0
    if ((ret == 0) && sz) {
13993
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
13994
0
        if (ret == 0) {
13995
0
            XMEMCPY(aes->reg, in, sz);
13996
0
            xorbufout(out, in, aes->tmp, sz);
13997
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
13998
0
        }
13999
0
    }
14000
14001
0
    VECTOR_REGISTERS_POP;
14002
14003
0
    return ret;
14004
0
}
14005
#endif /* HAVE_AES_DECRYPT */
14006
14007
/* CFB 128
14008
 *
14009
 * aes structure holding key to use for encryption
14010
 * out buffer to hold result of encryption (must be at least as large as input
14011
 *     buffer)
14012
 * in  buffer to encrypt
14013
 * sz  size of input buffer
14014
 *
14015
 * returns 0 on success and negative error values on failure
14016
 */
14017
/* Software AES - CFB Encrypt */
14018
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14019
0
{
14020
0
    return AesCfbEncrypt_C(aes, out, in, sz);
14021
0
}
14022
14023
14024
#ifdef HAVE_AES_DECRYPT
14025
/* CFB 128
14026
 *
14027
 * aes structure holding key to use for decryption
14028
 * out buffer to hold result of decryption (must be at least as large as input
14029
 *     buffer)
14030
 * in  buffer to decrypt
14031
 * sz  size of input buffer
14032
 *
14033
 * returns 0 on success and negative error values on failure
14034
 */
14035
/* Software AES - CFB Decrypt */
14036
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14037
0
{
14038
0
    return AesCfbDecrypt_C(aes, out, in, sz, AES_CFB_MODE);
14039
0
}
14040
#endif /* HAVE_AES_DECRYPT */
14041
#endif /* WOLFSSL_PSOC6_CRYPTO */
14042
14043
#ifndef WOLFSSL_NO_AES_CFB_1_8
14044
/* shift the whole WC_AES_BLOCK_SIZE array left by 8 or 1 bits */
14045
static void shiftLeftArray(byte* ary, byte shift)
14046
39.1k
{
14047
39.1k
    int i;
14048
14049
39.1k
    if (shift == WOLFSSL_BIT_SIZE) {
14050
        /* shifting over by 8 bits */
14051
47.7k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
14052
44.8k
            ary[i] = ary[i+1];
14053
44.8k
        }
14054
2.98k
        ary[i] = 0;
14055
2.98k
    }
14056
36.1k
    else {
14057
        /* shifting over by 7 or less bits */
14058
578k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
14059
542k
            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
14060
542k
            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
14061
542k
            ary[i] = (byte)((ary[i] << shift) + carry);
14062
542k
        }
14063
36.1k
        ary[i] = (byte)(ary[i] << shift);
14064
36.1k
    }
14065
39.1k
}
14066
14067
14068
/* returns 0 on success and negative values on failure */
14069
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
14070
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
14071
238
{
14072
238
    byte *pt;
14073
238
    int ret = 0;
14074
14075
238
    if (aes == NULL || out == NULL || in == NULL) {
14076
0
        return BAD_FUNC_ARG;
14077
0
    }
14078
14079
238
    if (sz == 0) {
14080
0
        return 0;
14081
0
    }
14082
14083
238
    VECTOR_REGISTERS_PUSH;
14084
14085
3.22k
    while (sz > 0) {
14086
2.98k
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
14087
2.98k
        if (ret != 0)
14088
0
            break;
14089
2.98k
        if (dir == AES_DECRYPTION) {
14090
1.55k
            pt = (byte*)aes->reg;
14091
14092
            /* LSB + CAT */
14093
1.55k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
14094
1.55k
            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
14095
1.55k
        }
14096
14097
        /* MSB + XOR */
14098
    #ifdef BIG_ENDIAN_ORDER
14099
        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
14100
    #endif
14101
2.98k
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
14102
2.98k
        if (dir == AES_ENCRYPTION) {
14103
1.43k
            pt = (byte*)aes->reg;
14104
14105
            /* LSB + CAT */
14106
1.43k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
14107
1.43k
            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
14108
1.43k
        }
14109
14110
2.98k
        out += 1;
14111
2.98k
        in  += 1;
14112
2.98k
        sz  -= 1;
14113
2.98k
    }
14114
14115
238
    VECTOR_REGISTERS_POP;
14116
14117
238
    return ret;
14118
238
}
14119
14120
14121
/* returns 0 on success and negative values on failure */
14122
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
14123
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
14124
409
{
14125
409
    byte tmp;
14126
409
    byte cur = 0; /* hold current work in order to handle inline in=out */
14127
409
    byte* pt;
14128
409
    int bit = 7;
14129
409
    int ret = 0;
14130
14131
409
    if (aes == NULL || out == NULL || in == NULL) {
14132
0
        return BAD_FUNC_ARG;
14133
0
    }
14134
14135
409
    if (sz == 0) {
14136
0
        return 0;
14137
0
    }
14138
14139
409
    VECTOR_REGISTERS_PUSH;
14140
14141
36.5k
    while (sz > 0) {
14142
36.1k
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
14143
36.1k
        if (ret != 0)
14144
0
            break;
14145
36.1k
        if (dir == AES_DECRYPTION) {
14146
17.4k
            pt = (byte*)aes->reg;
14147
14148
            /* LSB + CAT */
14149
17.4k
            tmp = (byte)((0X01U << bit) & in[0]);
14150
17.4k
            tmp = (byte)(tmp >> bit);
14151
17.4k
            tmp &= 0x01;
14152
17.4k
            shiftLeftArray((byte*)aes->reg, 1);
14153
17.4k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
14154
17.4k
        }
14155
14156
        /* MSB  + XOR */
14157
36.1k
        tmp = (byte)((0X01U << bit) & in[0]);
14158
36.1k
        pt = (byte*)aes->tmp;
14159
36.1k
        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
14160
36.1k
        tmp &= 0x01;
14161
36.1k
        cur = (byte)(cur | (tmp << bit));
14162
14163
14164
36.1k
        if (dir == AES_ENCRYPTION) {
14165
18.7k
            pt = (byte*)aes->reg;
14166
14167
            /* LSB + CAT */
14168
18.7k
            shiftLeftArray((byte*)aes->reg, 1);
14169
18.7k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
14170
18.7k
        }
14171
14172
36.1k
        bit--;
14173
36.1k
        if (bit < 0) {
14174
4.51k
            out[0] = cur;
14175
4.51k
            out += 1;
14176
4.51k
            in  += 1;
14177
4.51k
            sz  -= 1;
14178
4.51k
            bit = 7U;
14179
4.51k
            cur = 0;
14180
4.51k
        }
14181
31.6k
        else {
14182
31.6k
            sz -= 1;
14183
31.6k
        }
14184
36.1k
    }
14185
14186
409
    if (ret == 0) {
14187
409
        if (bit >= 0 && bit < 7) {
14188
0
            out[0] = cur;
14189
0
        }
14190
409
    }
14191
14192
409
    VECTOR_REGISTERS_POP;
14193
14194
409
    return ret;
14195
409
}
14196
14197
14198
/* CFB 1
14199
 *
14200
 * aes structure holding key to use for encryption
14201
 * out buffer to hold result of encryption (must be at least as large as input
14202
 *     buffer)
14203
 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
14204
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
14205
 *
14206
 * returns 0 on success and negative values on failure
14207
 */
14208
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14209
272
{
14210
272
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
14211
272
}
14212
14213
14214
/* CFB 8
14215
 *
14216
 * aes structure holding key to use for encryption
14217
 * out buffer to hold result of encryption (must be at least as large as input
14218
 *     buffer)
14219
 * in  buffer to encrypt
14220
 * sz  size of input buffer
14221
 *
14222
 * returns 0 on success and negative values on failure
14223
 */
14224
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14225
134
{
14226
134
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
14227
134
}
14228
#ifdef HAVE_AES_DECRYPT
14229
14230
/* CFB 1
14231
 *
14232
 * aes structure holding key to use for encryption
14233
 * out buffer to hold result of encryption (must be at least as large as input
14234
 *     buffer)
14235
 * in  buffer to encrypt
14236
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
14237
 *
14238
 * returns 0 on success and negative values on failure
14239
 */
14240
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14241
137
{
14242
137
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
14243
137
}
14244
14245
14246
/* CFB 8
14247
 *
14248
 * aes structure holding key to use for encryption
14249
 * out buffer to hold result of encryption (must be at least as large as input
14250
 *     buffer)
14251
 * in  buffer to encrypt
14252
 * sz  size of input buffer
14253
 *
14254
 * returns 0 on success and negative values on failure
14255
 */
14256
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14257
104
{
14258
104
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
14259
104
}
14260
#endif /* HAVE_AES_DECRYPT */
14261
#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
14262
#endif /* WOLFSSL_AES_CFB */
14263
14264
#ifdef WOLFSSL_AES_OFB
14265
/* OFB AES mode
14266
 *
14267
 * aes structure holding key to use for encryption
14268
 * out buffer to hold result of encryption (must be at least as large as input
14269
 *     buffer)
14270
 * in  buffer to encrypt
14271
 * sz  size of input buffer
14272
 *
14273
 * returns 0 on success and negative error values on failure
14274
 */
14275
/* Software AES - OFB Encrypt/Decrypt */
14276
static WARN_UNUSED_RESULT int AesOfbCrypt_C(Aes* aes, byte* out, const byte* in,
14277
    word32 sz)
14278
897
{
14279
897
    int ret = 0;
14280
897
    word32 processed;
14281
14282
897
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
14283
0
        return BAD_FUNC_ARG;
14284
0
    }
14285
897
    if (sz == 0) {
14286
0
        return 0;
14287
0
    }
14288
14289
897
    if (aes->left > 0) {
14290
        /* consume any unused bytes left in aes->tmp */
14291
356
        processed = min(aes->left, sz);
14292
356
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
14293
356
            processed);
14294
356
        aes->left -= processed;
14295
356
        out += processed;
14296
356
        in += processed;
14297
356
        sz -= processed;
14298
356
    }
14299
14300
897
    VECTOR_REGISTERS_PUSH;
14301
14302
1.79k
    while (sz >= WC_AES_BLOCK_SIZE) {
14303
902
        ret = wc_AesEncryptDirect(aes, (byte*)aes->reg, (byte*)aes->reg);
14304
902
        if (ret != 0) {
14305
0
            break;
14306
0
        }
14307
902
        xorbufout(out, in, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
14308
902
        out += WC_AES_BLOCK_SIZE;
14309
902
        in  += WC_AES_BLOCK_SIZE;
14310
902
        sz  -= WC_AES_BLOCK_SIZE;
14311
902
    }
14312
14313
    /* encrypt left over data */
14314
897
    if ((ret == 0) && sz) {
14315
279
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
14316
279
        if (ret == 0) {
14317
279
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
14318
279
            xorbufout(out, in, aes->tmp, sz);
14319
279
            aes->left = WC_AES_BLOCK_SIZE - sz;
14320
279
        }
14321
279
    }
14322
14323
897
    VECTOR_REGISTERS_POP;
14324
14325
897
    return ret;
14326
897
}
14327
14328
/* OFB
14329
 *
14330
 * aes structure holding key to use for encryption
14331
 * out buffer to hold result of encryption (must be at least as large as input
14332
 *     buffer)
14333
 * in  buffer to encrypt
14334
 * sz  size of input buffer
14335
 *
14336
 * returns 0 on success and negative error values on failure
14337
 */
14338
/* Software AES - OFB Encrypt */
14339
int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14340
628
{
14341
628
    return AesOfbCrypt_C(aes, out, in, sz);
14342
628
}
14343
14344
14345
#ifdef HAVE_AES_DECRYPT
14346
/* OFB
14347
 *
14348
 * aes structure holding key to use for decryption
14349
 * out buffer to hold result of decryption (must be at least as large as input
14350
 *     buffer)
14351
 * in  buffer to decrypt
14352
 * sz  size of input buffer
14353
 *
14354
 * returns 0 on success and negative error values on failure
14355
 */
14356
/* Software AES - OFB Decrypt */
14357
int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14358
269
{
14359
269
    return AesOfbCrypt_C(aes, out, in, sz);
14360
269
}
14361
#endif /* HAVE_AES_DECRYPT */
14362
#endif /* WOLFSSL_AES_OFB */
14363
14364
14365
#ifdef HAVE_AES_KEYWRAP
14366
14367
/* Initialize key wrap counter with value */
14368
static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
14369
0
{
14370
0
    word32 i;
14371
0
    word32 bytes;
14372
14373
0
    bytes = sizeof(word32);
14374
0
    for (i = 0; i < sizeof(word32); i++) {
14375
0
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
14376
0
        bytes--;
14377
0
    }
14378
0
}
14379
14380
/* Increment key wrap counter */
14381
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
14382
0
{
14383
0
    int i;
14384
14385
    /* in network byte order so start at end and work back */
14386
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
14387
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
14388
0
            return;
14389
0
    }
14390
0
}
14391
14392
/* Decrement key wrap counter */
14393
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
14394
0
{
14395
0
    int i;
14396
14397
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
14398
0
        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
14399
0
            return;
14400
0
    }
14401
0
}
14402
14403
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
14404
        word32 outSz, const byte* iv)
14405
0
{
14406
0
    word32 i;
14407
0
    byte* r;
14408
0
    int j;
14409
0
    int ret = 0;
14410
14411
0
    byte t[KEYWRAP_BLOCK_SIZE];
14412
0
    byte tmp[WC_AES_BLOCK_SIZE];
14413
14414
    /* n must be at least 2 64-bit blocks, output size is (n + 1) 8 bytes (64-bit) */
14415
0
    if (aes == NULL || in  == NULL || inSz < 2*KEYWRAP_BLOCK_SIZE ||
14416
0
        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
14417
0
        return BAD_FUNC_ARG;
14418
14419
    /* input must be multiple of 64-bits */
14420
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
14421
0
        return BAD_FUNC_ARG;
14422
14423
0
    r = out + 8;
14424
0
    XMEMCPY(r, in, inSz);
14425
0
    XMEMSET(t, 0, sizeof(t));
14426
14427
    /* user IV is optional */
14428
0
    if (iv == NULL) {
14429
0
        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
14430
0
    } else {
14431
0
        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
14432
0
    }
14433
14434
0
    VECTOR_REGISTERS_PUSH;
14435
14436
0
    for (j = 0; j <= 5; j++) {
14437
0
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
14438
            /* load R[i] */
14439
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
14440
14441
0
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
14442
0
            if (ret != 0)
14443
0
                break;
14444
14445
            /* calculate new A */
14446
0
            IncrementKeyWrapCounter(t);
14447
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
14448
14449
            /* save R[i] */
14450
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
14451
0
            r += KEYWRAP_BLOCK_SIZE;
14452
0
        }
14453
0
        if (ret != 0)
14454
0
            break;
14455
0
        r = out + KEYWRAP_BLOCK_SIZE;
14456
0
    }
14457
14458
0
    VECTOR_REGISTERS_POP;
14459
14460
0
    if (ret != 0)
14461
0
        return ret;
14462
14463
    /* C[0] = A */
14464
0
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
14465
14466
0
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
14467
0
}
14468
14469
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
14470
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
14471
                  byte* out, word32 outSz, const byte* iv)
14472
0
{
14473
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
14474
0
    int ret;
14475
14476
0
    if (key == NULL)
14477
0
        return BAD_FUNC_ARG;
14478
14479
0
#ifdef WOLFSSL_SMALL_STACK
14480
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
14481
0
                              DYNAMIC_TYPE_AES)) == NULL)
14482
0
        return MEMORY_E;
14483
0
#endif
14484
14485
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14486
0
    if (ret != 0)
14487
0
        goto out;
14488
14489
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
14490
0
    if (ret != 0) {
14491
0
        wc_AesFree(aes);
14492
0
        goto out;
14493
0
    }
14494
14495
0
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
14496
14497
0
    wc_AesFree(aes);
14498
14499
0
  out:
14500
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
14501
14502
0
    return ret;
14503
0
}
14504
14505
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
14506
        word32 outSz, const byte* iv)
14507
0
{
14508
0
    byte* r;
14509
0
    word32 i, n;
14510
0
    int j;
14511
0
    int ret = 0;
14512
14513
0
    byte t[KEYWRAP_BLOCK_SIZE];
14514
0
    byte tmp[WC_AES_BLOCK_SIZE];
14515
14516
0
    const byte* expIv;
14517
0
    const byte defaultIV[] = {
14518
0
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
14519
0
    };
14520
14521
0
    if (aes == NULL || in == NULL || inSz < 3 * KEYWRAP_BLOCK_SIZE ||
14522
0
        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
14523
0
        return BAD_FUNC_ARG;
14524
14525
    /* input must be multiple of 64-bits */
14526
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
14527
0
        return BAD_FUNC_ARG;
14528
14529
    /* user IV optional */
14530
0
    if (iv != NULL)
14531
0
        expIv = iv;
14532
0
    else
14533
0
        expIv = defaultIV;
14534
14535
    /* A = C[0], R[i] = C[i] */
14536
0
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
14537
0
    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
14538
0
    XMEMSET(t, 0, sizeof(t));
14539
14540
0
    VECTOR_REGISTERS_PUSH;
14541
14542
    /* initialize counter to 6n */
14543
0
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
14544
0
    InitKeyWrapCounter(t, 6 * n);
14545
14546
0
    for (j = 5; j >= 0; j--) {
14547
0
        for (i = n; i >= 1; i--) {
14548
14549
            /* calculate A */
14550
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
14551
0
            DecrementKeyWrapCounter(t);
14552
14553
            /* load R[i], starting at end of R */
14554
0
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
14555
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
14556
0
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
14557
0
            if (ret != 0)
14558
0
                break;
14559
14560
            /* save R[i] */
14561
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
14562
0
        }
14563
0
        if (ret != 0)
14564
0
            break;
14565
0
    }
14566
14567
0
    VECTOR_REGISTERS_POP;
14568
14569
0
    if (ret != 0)
14570
0
        return ret;
14571
14572
    /* verify IV */
14573
0
    if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
14574
0
        return BAD_KEYWRAP_IV_E;
14575
14576
0
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
14577
0
}
14578
14579
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
14580
                    byte* out, word32 outSz, const byte* iv)
14581
0
{
14582
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
14583
0
    int ret;
14584
14585
0
    (void)iv;
14586
14587
0
    if (key == NULL)
14588
0
        return BAD_FUNC_ARG;
14589
14590
0
#ifdef WOLFSSL_SMALL_STACK
14591
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
14592
0
                              DYNAMIC_TYPE_AES)) == NULL)
14593
0
        return MEMORY_E;
14594
0
#endif
14595
14596
14597
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14598
0
    if (ret != 0)
14599
0
        goto out;
14600
14601
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
14602
0
    if (ret != 0) {
14603
0
        wc_AesFree(aes);
14604
0
        goto out;
14605
0
    }
14606
14607
0
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
14608
14609
0
    wc_AesFree(aes);
14610
14611
0
  out:
14612
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
14613
14614
0
    return ret;
14615
0
}
14616
14617
#endif /* HAVE_AES_KEYWRAP */
14618
14619
#ifdef WOLFSSL_AES_XTS
14620
14621
/* Galois Field to use */
14622
736
#define GF_XTS 0x87
14623
14624
/* Set up keys for encryption and/or decryption.
14625
 *
14626
 * aes   buffer holding aes subkeys
14627
 * heap  heap hint to use for memory. Can be NULL
14628
 * devId id to use with async crypto. Can be 0
14629
 *
14630
 * return 0 on success
14631
 */
14632
int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
14633
372
{
14634
372
    int    ret = 0;
14635
14636
372
    if (aes == NULL) {
14637
0
        return BAD_FUNC_ARG;
14638
0
    }
14639
14640
372
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
14641
0
        return ret;
14642
0
    }
14643
372
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
14644
0
        (void)wc_AesFree(&aes->tweak);
14645
0
        return ret;
14646
0
    }
14647
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14648
    if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) {
14649
        (void)wc_AesFree(&aes->tweak);
14650
        (void)wc_AesFree(&aes->aes);
14651
        return ret;
14652
    }
14653
#endif
14654
14655
372
    return 0;
14656
372
}
14657
14658
/* Set up keys for encryption and/or decryption.
14659
 *
14660
 * aes   buffer holding aes subkeys
14661
 * key   AES key for encrypt/decrypt and tweak process (concatenated)
14662
 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
14663
 *       32 for a 16 byte key.
14664
 * dir   direction: AES_ENCRYPTION, AES_DECRYPTION, or
14665
 *       AES_ENCRYPTION_AND_DECRYPTION
14666
 *
14667
 * return 0 on success
14668
 */
14669
int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
14670
295
{
14671
295
    word32 keySz;
14672
295
    int    ret = 0;
14673
14674
295
    if (aes == NULL || key == NULL) {
14675
0
        return BAD_FUNC_ARG;
14676
0
    }
14677
14678
295
    if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION)
14679
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14680
        && (dir != AES_ENCRYPTION_AND_DECRYPTION)
14681
#endif
14682
295
        )
14683
0
    {
14684
0
        return BAD_FUNC_ARG;
14685
0
    }
14686
14687
295
    if ((len != (AES_128_KEY_SIZE*2)) &&
14688
64
#ifndef HAVE_FIPS
14689
        /* XTS-384 not allowed by FIPS and can not be treated like
14690
         * RSA-4096 bit keys back in the day, can not vendor affirm
14691
         * the use of 2 concatenated 192-bit keys (XTS-384) */
14692
64
        (len != (AES_192_KEY_SIZE*2)) &&
14693
64
#endif
14694
64
        (len != (AES_256_KEY_SIZE*2)))
14695
0
    {
14696
0
        WOLFSSL_MSG("Unsupported key size");
14697
0
        return WC_KEY_SIZE_E;
14698
0
    }
14699
14700
295
    keySz = len/2;
14701
14702
#ifdef HAVE_FIPS
14703
    if (XMEMCMP(key, key + keySz, keySz) == 0) {
14704
        WOLFSSL_MSG("FIPS AES-XTS main and tweak keys must differ");
14705
        return BAD_FUNC_ARG;
14706
    }
14707
#endif
14708
14709
295
    if (dir == AES_ENCRYPTION
14710
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14711
        || dir == AES_ENCRYPTION_AND_DECRYPTION
14712
#endif
14713
295
        )
14714
155
    {
14715
155
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
14716
155
    }
14717
14718
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14719
    if ((ret == 0) && ((dir == AES_DECRYPTION)
14720
                       || (dir == AES_ENCRYPTION_AND_DECRYPTION)))
14721
        ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION);
14722
#else
14723
295
    if (dir == AES_DECRYPTION)
14724
140
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
14725
295
#endif
14726
14727
295
    if (ret == 0)
14728
295
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
14729
295
                AES_ENCRYPTION);
14730
14731
#ifdef WOLFSSL_AESNI
14732
    if (ret == 0) {
14733
        /* With WC_C_DYNAMIC_FALLBACK, the main and tweak keys could have
14734
         * conflicting _aesni status, but the AES-XTS asm implementations need
14735
         * them to all be AESNI.  If any aren't, disable AESNI on all.
14736
         */
14737
    #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14738
        if ((((dir == AES_ENCRYPTION) ||
14739
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
14740
             && (aes->aes.use_aesni != aes->tweak.use_aesni))
14741
            ||
14742
            (((dir == AES_DECRYPTION) ||
14743
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
14744
             && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)))
14745
        {
14746
        #ifdef WC_C_DYNAMIC_FALLBACK
14747
            aes->aes.use_aesni = 0;
14748
            aes->aes_decrypt.use_aesni = 0;
14749
            aes->tweak.use_aesni = 0;
14750
        #else
14751
            ret = SYSLIB_FAILED_E;
14752
        #endif
14753
        }
14754
    #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
14755
        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
14756
        #ifdef WC_C_DYNAMIC_FALLBACK
14757
            aes->aes.use_aesni = 0;
14758
            aes->tweak.use_aesni = 0;
14759
        #else
14760
            ret = SYSLIB_FAILED_E;
14761
        #endif
14762
        }
14763
    #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
14764
    }
14765
#endif /* WOLFSSL_AESNI */
14766
14767
295
    return ret;
14768
295
}
14769
14770
/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
14771
 *
14772
 * Note: is up to user to call wc_AesXtsFree when done.
14773
 *
14774
 * return 0 on success
14775
 */
14776
int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
14777
        void* heap, int devId)
14778
0
{
14779
0
    int    ret = 0;
14780
14781
0
    if (aes == NULL || key == NULL) {
14782
0
        return BAD_FUNC_ARG;
14783
0
    }
14784
14785
0
    ret = wc_AesXtsInit(aes, heap, devId);
14786
0
    if (ret != 0)
14787
0
        return ret;
14788
14789
0
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
14790
14791
0
    if (ret != 0)
14792
0
        wc_AesXtsFree(aes);
14793
14794
0
    return ret;
14795
0
}
14796
14797
14798
/* This is used to free up resources used by Aes structs
14799
 *
14800
 * aes AES keys to free
14801
 *
14802
 * return 0 on success
14803
 */
14804
int wc_AesXtsFree(XtsAes* aes)
14805
372
{
14806
372
    if (aes != NULL) {
14807
372
        wc_AesFree(&aes->aes);
14808
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14809
        wc_AesFree(&aes->aes_decrypt);
14810
#endif
14811
372
        wc_AesFree(&aes->tweak);
14812
372
    }
14813
14814
372
    return 0;
14815
372
}
14816
14817
14818
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
14819
 * instead of a byte array. This just converts the word64 to a byte array and
14820
 * calls wc_AesXtsEncrypt.
14821
 *
14822
 * aes    AES keys to use for block encrypt/decrypt
14823
 * out    output buffer to hold cipher text
14824
 * in     input plain text buffer to encrypt
14825
 * sz     size of both out and in buffers
14826
 * sector value to use for tweak
14827
 *
14828
 * returns 0 on success
14829
 */
14830
int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
14831
        word32 sz, word64 sector)
14832
0
{
14833
0
    byte* pt;
14834
0
    byte  i[WC_AES_BLOCK_SIZE];
14835
14836
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
14837
#ifdef BIG_ENDIAN_ORDER
14838
    sector = ByteReverseWord64(sector);
14839
#endif
14840
0
    pt = (byte*)&sector;
14841
0
    XMEMCPY(i, pt, sizeof(word64));
14842
14843
0
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
14844
0
}
14845
14846
#ifdef HAVE_AES_DECRYPT
14847
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
14848
 * instead of a byte array. This just converts the word64 to a byte array.
14849
 *
14850
 * aes    AES keys to use for block encrypt/decrypt
14851
 * out    output buffer to hold plain text
14852
 * in     input cipher text buffer to encrypt
14853
 * sz     size of both out and in buffers
14854
 * sector value to use for tweak
14855
 *
14856
 * returns 0 on success
14857
 */
14858
int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
14859
        word64 sector)
14860
0
{
14861
0
    byte* pt;
14862
0
    byte  i[WC_AES_BLOCK_SIZE];
14863
14864
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
14865
#ifdef BIG_ENDIAN_ORDER
14866
    sector = ByteReverseWord64(sector);
14867
#endif
14868
0
    pt = (byte*)&sector;
14869
0
    XMEMCPY(i, pt, sizeof(word64));
14870
14871
0
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
14872
0
}
14873
#endif
14874
14875
#ifdef WOLFSSL_AESNI
14876
14877
#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
14878
    #define USE_INTEL_SPEEDUP
14879
#endif
14880
14881
#if defined(USE_INTEL_SPEEDUP)
14882
    #define HAVE_INTEL_AVX1
14883
    #define HAVE_INTEL_AVX2
14884
#endif /* USE_INTEL_SPEEDUP */
14885
14886
void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
14887
                     const unsigned char* i, const unsigned char* key,
14888
                     const unsigned char* key2, int nr)
14889
                     XASM_LINK("AES_XTS_encrypt_aesni");
14890
#ifdef WOLFSSL_AESXTS_STREAM
14891
void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
14892
                     int tweak_nr)
14893
                     XASM_LINK("AES_XTS_init_aesni");
14894
void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
14895
                     const unsigned char* key, unsigned char *i, int nr)
14896
                     XASM_LINK("AES_XTS_encrypt_update_aesni");
14897
#endif
14898
#ifdef HAVE_INTEL_AVX1
14899
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
14900
                     word32 sz, const unsigned char* i,
14901
                     const unsigned char* key, const unsigned char* key2,
14902
                     int nr)
14903
                     XASM_LINK("AES_XTS_encrypt_avx1");
14904
#ifdef WOLFSSL_AESXTS_STREAM
14905
void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
14906
                     int tweak_nr)
14907
                     XASM_LINK("AES_XTS_init_avx1");
14908
void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
14909
                     const unsigned char* key, unsigned char *i, int nr)
14910
                     XASM_LINK("AES_XTS_encrypt_update_avx1");
14911
#endif
14912
#endif /* HAVE_INTEL_AVX1 */
14913
14914
#ifdef HAVE_AES_DECRYPT
14915
void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
14916
                     const unsigned char* i, const unsigned char* key,
14917
                     const unsigned char* key2, int nr)
14918
                     XASM_LINK("AES_XTS_decrypt_aesni");
14919
#ifdef WOLFSSL_AESXTS_STREAM
14920
void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
14921
                     const unsigned char* key, unsigned char *i, int nr)
14922
                     XASM_LINK("AES_XTS_decrypt_update_aesni");
14923
#endif
14924
#ifdef HAVE_INTEL_AVX1
14925
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
14926
                     word32 sz, const unsigned char* i,
14927
                     const unsigned char* key, const unsigned char* key2,
14928
                     int nr)
14929
                     XASM_LINK("AES_XTS_decrypt_avx1");
14930
#ifdef WOLFSSL_AESXTS_STREAM
14931
void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
14932
                     const unsigned char* key, unsigned char *i, int nr)
14933
                     XASM_LINK("AES_XTS_decrypt_update_avx1");
14934
#endif
14935
#endif /* HAVE_INTEL_AVX1 */
14936
#endif /* HAVE_AES_DECRYPT */
14937
14938
#endif /* WOLFSSL_AESNI */
14939
14940
#ifdef HAVE_AES_ECB
14941
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
14942
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
14943
/* helper function for encrypting / decrypting full buffer at once */
14944
static WARN_UNUSED_RESULT int _AesXtsHelper(
14945
    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
14946
226
{
14947
226
    word32 outSz   = sz;
14948
226
    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
14949
226
    byte*  pt      = out;
14950
14951
226
    outSz -= WC_AES_BLOCK_SIZE;
14952
14953
788
    while (outSz > 0) {
14954
562
        word32 j;
14955
562
        byte carry = 0;
14956
14957
        /* multiply by shift left and propagate carry */
14958
9.14k
        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
14959
8.57k
            byte tmpC;
14960
14961
8.57k
            tmpC   = (pt[j] >> 7) & 0x01;
14962
8.57k
            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
14963
8.57k
            carry  = tmpC;
14964
8.57k
        }
14965
562
        if (carry) {
14966
271
            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
14967
271
        }
14968
14969
562
        pt += WC_AES_BLOCK_SIZE;
14970
562
    }
14971
14972
226
    xorbuf(out, in, totalSz);
14973
226
#ifndef WOLFSSL_RISCV_ASM
14974
226
    if (dir == AES_ENCRYPTION) {
14975
89
        return _AesEcbEncrypt(aes, out, out, totalSz);
14976
89
    }
14977
137
    else {
14978
137
        return _AesEcbDecrypt(aes, out, out, totalSz);
14979
137
    }
14980
#else
14981
    if (dir == AES_ENCRYPTION) {
14982
        return wc_AesEcbEncrypt(aes, out, out, totalSz);
14983
    }
14984
    else {
14985
        return wc_AesEcbDecrypt(aes, out, out, totalSz);
14986
    }
14987
#endif
14988
226
}
14989
#endif
14990
#endif /* HAVE_AES_ECB */
14991
14992
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
14993
 *
14994
 * xaes  AES keys to use for block encrypt/decrypt
14995
 * out   output buffer to hold cipher text
14996
 * in    input plain text buffer to encrypt
14997
 * sz    size of both out and in buffers
14998
 * i     value to use for tweak
14999
 *
15000
 * returns 0 on success
15001
 */
15002
/* Software AES - XTS Encrypt  */
15003
15004
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15005
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
15006
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15007
                                  word32 sz,
15008
                                  byte *i);
15009
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15010
        const byte* i)
15011
121
{
15012
121
    int ret;
15013
121
    byte tweak_block[WC_AES_BLOCK_SIZE];
15014
15015
121
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
15016
121
    if (ret != 0)
15017
0
        return ret;
15018
15019
121
    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
15020
121
}
15021
#endif
15022
15023
#ifdef WOLFSSL_AESXTS_STREAM
15024
15025
/* Block-streaming AES-XTS tweak setup.
15026
 *
15027
 * xaes  AES keys to use for block encrypt/decrypt
15028
 * i     readwrite value to use for tweak
15029
 *
15030
 * returns 0 on success
15031
 */
15032
static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
15033
    return wc_AesEncryptDirect(&xaes->tweak, i, i);
15034
}
15035
15036
#endif /* WOLFSSL_AESXTS_STREAM */
15037
15038
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15039
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || defined(WOLFSSL_AESXTS_STREAM)
15040
/* Block-streaming AES-XTS.
15041
 *
15042
 * Supply block-aligned input data with successive calls.  Final call need not
15043
 * be block aligned.
15044
 *
15045
 * xaes  AES keys to use for block encrypt/decrypt
15046
 * out   output buffer to hold cipher text
15047
 * in    input plain text buffer to encrypt
15048
 * sz    size of both out and in buffers
15049
 *
15050
 * returns 0 on success
15051
 */
15052
/* Software AES - XTS Encrypt  */
15053
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15054
                                  word32 sz,
15055
                                  byte *i)
15056
121
{
15057
121
    int ret = 0;
15058
121
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
15059
121
    Aes *aes = &xaes->aes;
15060
15061
121
#ifdef HAVE_AES_ECB
15062
    /* encrypt all of buffer at once when possible */
15063
121
    if (in != out) { /* can not handle inline */
15064
89
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
15065
89
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
15066
0
            return ret;
15067
89
    }
15068
121
#endif
15069
15070
559
    while (blocks > 0) {
15071
438
        word32 j;
15072
438
        byte carry = 0;
15073
15074
438
#ifdef HAVE_AES_ECB
15075
438
        if (in == out)
15076
185
#endif
15077
185
        { /* check for if inline */
15078
185
            byte buf[WC_AES_BLOCK_SIZE];
15079
15080
185
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
15081
185
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15082
185
            ret = wc_AesEncryptDirect(aes, out, buf);
15083
185
            if (ret != 0)
15084
0
                return ret;
15085
185
        }
15086
438
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
15087
15088
        /* multiply by shift left and propagate carry */
15089
7.44k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
15090
7.00k
            byte tmpC;
15091
15092
7.00k
            tmpC   = (i[j] >> 7) & 0x01;
15093
7.00k
            i[j] = (byte)((i[j] << 1) + carry);
15094
7.00k
            carry  = tmpC;
15095
7.00k
        }
15096
438
        if (carry) {
15097
225
            i[0] ^= GF_XTS;
15098
225
        }
15099
15100
438
        in  += WC_AES_BLOCK_SIZE;
15101
438
        out += WC_AES_BLOCK_SIZE;
15102
438
        sz  -= WC_AES_BLOCK_SIZE;
15103
438
        blocks--;
15104
438
    }
15105
15106
    /* stealing operation of XTS to handle left overs */
15107
121
    if (sz > 0) {
15108
37
        byte buf[WC_AES_BLOCK_SIZE];
15109
15110
37
        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
15111
37
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
15112
0
            return BUFFER_E;
15113
0
        }
15114
37
        if (in != out) {
15115
23
            XMEMCPY(out, buf, sz);
15116
23
            XMEMCPY(buf, in, sz);
15117
23
        }
15118
14
        else {
15119
14
            byte buf2[WC_AES_BLOCK_SIZE];
15120
15121
14
            XMEMCPY(buf2, buf, sz);
15122
14
            XMEMCPY(buf, in, sz);
15123
14
            XMEMCPY(out, buf2, sz);
15124
14
        }
15125
15126
37
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15127
37
        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
15128
37
        if (ret == 0)
15129
37
            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
15130
37
    }
15131
15132
121
    return ret;
15133
121
}
15134
#endif
15135
15136
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
15137
 *
15138
 * xaes  AES keys to use for block encrypt/decrypt
15139
 * out   output buffer to hold cipher text
15140
 * in    input plain text buffer to encrypt
15141
 * sz    size of both out and in buffers
15142
 * i     value to use for tweak
15143
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15144
 *       adds a sanity check on how the user calls the function.
15145
 *
15146
 * returns 0 on success
15147
 */
15148
int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15149
        const byte* i, word32 iSz)
15150
131
{
15151
131
    int ret;
15152
15153
131
    Aes *aes;
15154
15155
131
    if (xaes == NULL || out == NULL || in == NULL) {
15156
0
        return BAD_FUNC_ARG;
15157
0
    }
15158
15159
#if FIPS_VERSION3_GE(6,0,0)
15160
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
15161
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
15162
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
15163
     */
15164
    if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
15165
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
15166
        return BAD_FUNC_ARG;
15167
    }
15168
#endif
15169
15170
131
    aes = &xaes->aes;
15171
15172
131
    if (aes->keylen == 0) {
15173
0
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
15174
0
        return BAD_FUNC_ARG;
15175
0
    }
15176
15177
131
    if (iSz < WC_AES_BLOCK_SIZE) {
15178
0
        return BAD_FUNC_ARG;
15179
0
    }
15180
15181
131
    if (sz < WC_AES_BLOCK_SIZE) {
15182
10
        WOLFSSL_MSG("Plain text input too small for encryption");
15183
10
        return BAD_FUNC_ARG;
15184
10
    }
15185
15186
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
15187
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15188
    AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
15189
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15190
    ret = 0;
15191
#elif defined(WOLFSSL_AESNI)
15192
    if (aes->use_aesni) {
15193
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
15194
#if defined(HAVE_INTEL_AVX1)
15195
        if (IS_INTEL_AVX1(intel_flags)) {
15196
            AES_XTS_encrypt_avx1(in, out, sz, i,
15197
                                 (const byte*)aes->key,
15198
                                 (const byte*)xaes->tweak.key,
15199
                                 (int)aes->rounds);
15200
            ret = 0;
15201
        }
15202
        else
15203
#endif
15204
        {
15205
            AES_XTS_encrypt_aesni(in, out, sz, i,
15206
                                  (const byte*)aes->key,
15207
                                  (const byte*)xaes->tweak.key,
15208
                                  (int)aes->rounds);
15209
            ret = 0;
15210
        }
15211
        RESTORE_VECTOR_REGISTERS();
15212
    }
15213
    else {
15214
        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
15215
    }
15216
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15217
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15218
    if (aes->use_aes_hw_crypto) {
15219
        AES_XTS_encrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
15220
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15221
        ret = 0;
15222
    }
15223
    else
15224
#endif
15225
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
15226
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15227
    if (sz >= 32)
15228
#endif
15229
    {
15230
        AES_XTS_encrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
15231
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15232
        ret = 0;
15233
    }
15234
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15235
    else
15236
#endif
15237
#endif
15238
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15239
    {
15240
        AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
15241
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15242
        ret = 0;
15243
    }
15244
#endif
15245
#else
15246
121
    ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
15247
121
#endif
15248
15249
121
    return ret;
15250
131
}
15251
15252
#ifdef WOLFSSL_AESXTS_STREAM
15253
15254
/* Block-streaming AES-XTS.
15255
 *
15256
 * xaes  AES keys to use for block encrypt/decrypt
15257
 * i     readwrite value to use for tweak
15258
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15259
 *       adds a sanity check on how the user calls the function.
15260
 *
15261
 * returns 0 on success
15262
 */
15263
int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
15264
                         struct XtsAesStreamData *stream)
15265
{
15266
    int ret;
15267
15268
    Aes *aes;
15269
15270
    if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
15271
        return BAD_FUNC_ARG;
15272
    }
15273
15274
    if (iSz < WC_AES_BLOCK_SIZE) {
15275
        return BAD_FUNC_ARG;
15276
    }
15277
15278
    aes = &xaes->aes;
15279
15280
    if (aes->keylen == 0) {
15281
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
15282
        return BAD_FUNC_ARG;
15283
    }
15284
15285
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
15286
    stream->bytes_crypted_with_this_tweak = 0;
15287
15288
    {
15289
#ifdef WOLFSSL_AESNI
15290
        if (aes->use_aesni) {
15291
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15292
#if defined(HAVE_INTEL_AVX1)
15293
            if (IS_INTEL_AVX1(intel_flags)) {
15294
                AES_XTS_init_avx1(stream->tweak_block,
15295
                                  (const byte*)xaes->tweak.key,
15296
                                  (int)xaes->tweak.rounds);
15297
                ret = 0;
15298
            }
15299
            else
15300
#endif
15301
            {
15302
                AES_XTS_init_aesni(stream->tweak_block,
15303
                                   (const byte*)xaes->tweak.key,
15304
                                   (int)xaes->tweak.rounds);
15305
                ret = 0;
15306
            }
15307
            RESTORE_VECTOR_REGISTERS();
15308
        }
15309
        else
15310
#endif /* WOLFSSL_AESNI */
15311
        {
15312
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
15313
        }
15314
    }
15315
15316
    return ret;
15317
}
15318
15319
/* Block-streaming AES-XTS
15320
 *
15321
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
15322
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsEncryptUpdate().
15323
 * wc_AesXtsEncryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
15324
 *
15325
 * xaes  AES keys to use for block encrypt/decrypt
15326
 * out   output buffer to hold cipher text
15327
 * in    input plain text buffer to encrypt
15328
 * sz    size of both out and in buffers -- must be >= WC_AES_BLOCK_SIZE.
15329
 * i     value to use for tweak
15330
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15331
 *       adds a sanity check on how the user calls the function.
15332
 *
15333
 * returns 0 on success
15334
 */
15335
static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15336
                           struct XtsAesStreamData *stream)
15337
{
15338
    int ret;
15339
15340
#ifdef WOLFSSL_AESNI
15341
    Aes *aes;
15342
#endif
15343
15344
    if (xaes == NULL || out == NULL || in == NULL) {
15345
        return BAD_FUNC_ARG;
15346
    }
15347
15348
#ifdef WOLFSSL_AESNI
15349
    aes = &xaes->aes;
15350
#endif
15351
15352
    if (sz < WC_AES_BLOCK_SIZE) {
15353
        WOLFSSL_MSG("Plain text input too small for encryption");
15354
        return BAD_FUNC_ARG;
15355
    }
15356
15357
    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
15358
    {
15359
        WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
15360
        return BAD_FUNC_ARG;
15361
    }
15362
15363
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
15364
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
15365
                             stream->bytes_crypted_with_this_tweak))
15366
    {
15367
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
15368
                    "in AesXtsEncryptUpdate().");
15369
    }
15370
#endif
15371
#if FIPS_VERSION3_GE(6,0,0)
15372
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
15373
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
15374
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
15375
     */
15376
    if (stream->bytes_crypted_with_this_tweak >
15377
        FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
15378
    {
15379
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
15380
        return BAD_FUNC_ARG;
15381
    }
15382
#endif
15383
    {
15384
#ifdef WOLFSSL_AESNI
15385
        if (aes->use_aesni) {
15386
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15387
#if defined(HAVE_INTEL_AVX1)
15388
            if (IS_INTEL_AVX1(intel_flags)) {
15389
                AES_XTS_encrypt_update_avx1(in, out, sz,
15390
                                            (const byte*)aes->key,
15391
                                            stream->tweak_block,
15392
                                            (int)aes->rounds);
15393
                ret = 0;
15394
            }
15395
            else
15396
#endif
15397
            {
15398
                AES_XTS_encrypt_update_aesni(in, out, sz,
15399
                                            (const byte*)aes->key,
15400
                                            stream->tweak_block,
15401
                                            (int)aes->rounds);
15402
                ret = 0;
15403
            }
15404
            RESTORE_VECTOR_REGISTERS();
15405
        }
15406
        else
15407
#endif /* WOLFSSL_AESNI */
15408
        {
15409
            ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
15410
        }
15411
    }
15412
15413
    return ret;
15414
}
15415
15416
int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15417
                           struct XtsAesStreamData *stream)
15418
{
15419
    if (stream == NULL)
15420
        return BAD_FUNC_ARG;
15421
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
15422
        return BAD_FUNC_ARG;
15423
    return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
15424
}
15425
15426
int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15427
                           struct XtsAesStreamData *stream)
15428
{
15429
    int ret;
15430
    if (stream == NULL)
15431
        return BAD_FUNC_ARG;
15432
    if (sz > 0)
15433
        ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
15434
    else
15435
        ret = 0;
15436
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
15437
     * after finalization.
15438
     */
15439
    stream->bytes_crypted_with_this_tweak |= 1U;
15440
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
15441
#ifdef WOLFSSL_CHECK_MEM_ZERO
15442
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
15443
#endif
15444
    return ret;
15445
}
15446
15447
#endif /* WOLFSSL_AESXTS_STREAM */
15448
15449
#ifdef HAVE_AES_DECRYPT
15450
15451
/* Same process as encryption but use aes_decrypt key.
15452
 *
15453
 * xaes  AES keys to use for block encrypt/decrypt
15454
 * out   output buffer to hold plain text
15455
 * in    input cipher text buffer to decrypt
15456
 * sz    size of both out and in buffers
15457
 * i     value to use for tweak
15458
 *
15459
 * returns 0 on success
15460
 */
15461
/* Software AES - XTS Decrypt */
15462
15463
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15464
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
15465
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15466
                                  word32 sz, byte *i);
15467
15468
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15469
        const byte* i)
15470
137
{
15471
137
    int ret;
15472
137
    byte tweak_block[WC_AES_BLOCK_SIZE];
15473
15474
137
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
15475
137
    if (ret != 0)
15476
0
        return ret;
15477
15478
137
    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
15479
137
}
15480
#endif
15481
15482
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15483
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
15484
/* Block-streaming AES-XTS.
15485
 *
15486
 * Same process as encryption but use decrypt key.
15487
 *
15488
 * Supply block-aligned input data with successive calls.  Final call need not
15489
 * be block aligned.
15490
 *
15491
 * xaes  AES keys to use for block encrypt/decrypt
15492
 * out   output buffer to hold plain text
15493
 * in    input cipher text buffer to decrypt
15494
 * sz    size of both out and in buffers
15495
 * i     value to use for tweak
15496
 *
15497
 * returns 0 on success
15498
 */
15499
/* Software AES - XTS Decrypt */
15500
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15501
                                  word32 sz, byte *i)
15502
137
{
15503
137
    int ret = 0;
15504
137
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
15505
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15506
    Aes *aes = &xaes->aes_decrypt;
15507
#else
15508
137
    Aes *aes = &xaes->aes;
15509
137
#endif
15510
137
    word32 j;
15511
137
    byte carry = 0;
15512
137
    byte stl = (sz % WC_AES_BLOCK_SIZE);
15513
15514
    /* if Stealing then break out of loop one block early to handle special
15515
     * case */
15516
137
    if (stl > 0) {
15517
52
        blocks--;
15518
52
    }
15519
15520
137
#ifdef HAVE_AES_ECB
15521
    /* decrypt all of buffer at once when possible */
15522
137
    if (in != out) { /* can not handle inline */
15523
137
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
15524
137
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
15525
0
            return ret;
15526
137
    }
15527
137
#endif
15528
15529
545
    while (blocks > 0) {
15530
408
#ifdef HAVE_AES_ECB
15531
408
        if (in == out)
15532
0
#endif
15533
0
        { /* check for if inline */
15534
0
            byte buf[WC_AES_BLOCK_SIZE];
15535
15536
0
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
15537
0
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15538
0
            ret = wc_AesDecryptDirect(aes, out, buf);
15539
0
            if (ret != 0)
15540
0
                return ret;
15541
0
        }
15542
408
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
15543
15544
        /* multiply by shift left and propagate carry */
15545
6.93k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
15546
6.52k
            byte tmpC;
15547
15548
6.52k
            tmpC   = (i[j] >> 7) & 0x01;
15549
6.52k
            i[j] = (byte)((i[j] << 1) + carry);
15550
6.52k
            carry  = tmpC;
15551
6.52k
        }
15552
408
        if (carry) {
15553
208
            i[0] ^= GF_XTS;
15554
208
        }
15555
408
        carry = 0;
15556
15557
408
        in  += WC_AES_BLOCK_SIZE;
15558
408
        out += WC_AES_BLOCK_SIZE;
15559
408
        sz  -= WC_AES_BLOCK_SIZE;
15560
408
        blocks--;
15561
408
    }
15562
15563
    /* stealing operation of XTS to handle left overs */
15564
137
    if (sz >= WC_AES_BLOCK_SIZE) {
15565
52
        byte buf[WC_AES_BLOCK_SIZE];
15566
52
        byte tmp2[WC_AES_BLOCK_SIZE];
15567
15568
        /* multiply by shift left and propagate carry */
15569
884
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
15570
832
            byte tmpC;
15571
15572
832
            tmpC   = (i[j] >> 7) & 0x01;
15573
832
            tmp2[j] = (byte)((i[j] << 1) + carry);
15574
832
            carry  = tmpC;
15575
832
        }
15576
52
        if (carry) {
15577
32
            tmp2[0] ^= GF_XTS;
15578
32
        }
15579
15580
52
        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
15581
52
        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
15582
52
        ret = wc_AesDecryptDirect(aes, out, buf);
15583
52
        if (ret != 0)
15584
0
            return ret;
15585
52
        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
15586
15587
        /* tmp2 holds partial | last */
15588
52
        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
15589
52
        in  += WC_AES_BLOCK_SIZE;
15590
52
        out += WC_AES_BLOCK_SIZE;
15591
52
        sz  -= WC_AES_BLOCK_SIZE;
15592
15593
        /* Make buffer with end of cipher text | last */
15594
52
        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
15595
52
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
15596
0
            return BUFFER_E;
15597
0
        }
15598
52
        XMEMCPY(buf, in,   sz);
15599
52
        XMEMCPY(out, tmp2, sz);
15600
15601
52
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15602
52
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
15603
52
        if (ret != 0)
15604
0
            return ret;
15605
52
        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
15606
52
        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
15607
52
    }
15608
15609
137
    return ret;
15610
137
}
15611
#endif
15612
15613
/* Same process as encryption but Aes key is AES_DECRYPTION type.
15614
 *
15615
 * xaes  AES keys to use for block encrypt/decrypt
15616
 * out   output buffer to hold plain text
15617
 * in    input cipher text buffer to decrypt
15618
 * sz    size of both out and in buffers
15619
 * i     value to use for tweak
15620
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15621
 *       adds a sanity check on how the user calls the function.
15622
 *
15623
 * returns 0 on success
15624
 */
15625
int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15626
        const byte* i, word32 iSz)
15627
140
{
15628
140
    int ret;
15629
140
    Aes *aes;
15630
15631
140
    if (xaes == NULL || out == NULL || in == NULL) {
15632
0
        return BAD_FUNC_ARG;
15633
0
    }
15634
15635
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15636
    aes = &xaes->aes_decrypt;
15637
#else
15638
140
    aes = &xaes->aes;
15639
140
#endif
15640
15641
/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
15642
 * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
15643
 * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes or
15644
 * 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
15645
 * return whenever sz / WC_AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
15646
 * not a sequence of complete blocks.
15647
 */
15648
15649
140
    if (aes->keylen == 0) {
15650
0
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
15651
0
        return BAD_FUNC_ARG;
15652
0
    }
15653
15654
140
    if (iSz < WC_AES_BLOCK_SIZE) {
15655
0
        return BAD_FUNC_ARG;
15656
0
    }
15657
15658
140
    if (sz < WC_AES_BLOCK_SIZE) {
15659
3
        WOLFSSL_MSG("Cipher text input too small for decryption");
15660
3
        return BAD_FUNC_ARG;
15661
3
    }
15662
15663
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
15664
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15665
    AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
15666
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15667
    ret = 0;
15668
#elif defined(WOLFSSL_AESNI)
15669
    if (aes->use_aesni) {
15670
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
15671
#if defined(HAVE_INTEL_AVX1)
15672
        if (IS_INTEL_AVX1(intel_flags)) {
15673
            AES_XTS_decrypt_avx1(in, out, sz, i,
15674
                                 (const byte*)aes->key,
15675
                                 (const byte*)xaes->tweak.key,
15676
                                 (int)aes->rounds);
15677
            ret = 0;
15678
        }
15679
        else
15680
#endif
15681
        {
15682
            AES_XTS_decrypt_aesni(in, out, sz, i,
15683
                                  (const byte*)aes->key,
15684
                                  (const byte*)xaes->tweak.key,
15685
                                  (int)aes->rounds);
15686
            ret = 0;
15687
        }
15688
        RESTORE_VECTOR_REGISTERS();
15689
    }
15690
    else {
15691
        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
15692
    }
15693
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15694
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15695
    if (aes->use_aes_hw_crypto) {
15696
        AES_XTS_decrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
15697
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15698
        ret = 0;
15699
    }
15700
    else
15701
#endif
15702
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
15703
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15704
    if (sz >= 64)
15705
#endif
15706
    {
15707
        AES_XTS_decrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
15708
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15709
        ret = 0;
15710
    }
15711
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15712
    else
15713
#endif
15714
#endif
15715
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15716
    {
15717
        AES_XTS_decrypt(in, out, sz, i, (byte*)xaes->aes.key,
15718
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15719
        ret = 0;
15720
    }
15721
#endif
15722
#else
15723
137
    ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
15724
137
#endif
15725
15726
137
    return ret;
15727
140
}
15728
15729
#ifdef WOLFSSL_AESXTS_STREAM
15730
15731
/* Same process as encryption but Aes key is AES_DECRYPTION type.
15732
 *
15733
 * xaes  AES keys to use for block encrypt/decrypt
15734
 * i     readwrite value to use for tweak
15735
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15736
 *       adds a sanity check on how the user calls the function.
15737
 *
15738
 * returns 0 on success
15739
 */
15740
int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
15741
                         struct XtsAesStreamData *stream)
15742
{
15743
    int ret;
15744
    Aes *aes;
15745
15746
    if (xaes == NULL) {
15747
        return BAD_FUNC_ARG;
15748
    }
15749
15750
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15751
    aes = &xaes->aes_decrypt;
15752
#else
15753
    aes = &xaes->aes;
15754
#endif
15755
15756
    if (aes->keylen == 0) {
15757
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
15758
        return BAD_FUNC_ARG;
15759
    }
15760
15761
    if (iSz < WC_AES_BLOCK_SIZE) {
15762
        return BAD_FUNC_ARG;
15763
    }
15764
15765
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
15766
    stream->bytes_crypted_with_this_tweak = 0;
15767
15768
    {
15769
#ifdef WOLFSSL_AESNI
15770
        if (aes->use_aesni) {
15771
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15772
#if defined(HAVE_INTEL_AVX1)
15773
            if (IS_INTEL_AVX1(intel_flags)) {
15774
                AES_XTS_init_avx1(stream->tweak_block,
15775
                                  (const byte*)xaes->tweak.key,
15776
                                  (int)xaes->tweak.rounds);
15777
                ret = 0;
15778
            }
15779
            else
15780
#endif
15781
            {
15782
                AES_XTS_init_aesni(stream->tweak_block,
15783
                                   (const byte*)xaes->tweak.key,
15784
                                   (int)xaes->tweak.rounds);
15785
                ret = 0;
15786
            }
15787
            RESTORE_VECTOR_REGISTERS();
15788
        }
15789
        else
15790
#endif /* WOLFSSL_AESNI */
15791
        {
15792
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
15793
        }
15794
15795
    }
15796
15797
    return ret;
15798
}
15799
15800
/* Block-streaming AES-XTS
15801
 *
15802
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
15803
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsDecryptUpdate().
15804
 * wc_AesXtsDecryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
15805
 *
15806
 * xaes  AES keys to use for block encrypt/decrypt
15807
 * out   output buffer to hold plain text
15808
 * in    input cipher text buffer to decrypt
15809
 * sz    size of both out and in buffers
15810
 * i     tweak buffer of size WC_AES_BLOCK_SIZE.
15811
 *
15812
 * returns 0 on success
15813
 */
15814
static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15815
                           struct XtsAesStreamData *stream)
15816
{
15817
    int ret;
15818
#ifdef WOLFSSL_AESNI
15819
    Aes *aes;
15820
#endif
15821
15822
    if (xaes == NULL || out == NULL || in == NULL) {
15823
        return BAD_FUNC_ARG;
15824
    }
15825
15826
#ifdef WOLFSSL_AESNI
15827
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15828
    aes = &xaes->aes_decrypt;
15829
#else
15830
    aes = &xaes->aes;
15831
#endif
15832
#endif
15833
15834
    if (sz < WC_AES_BLOCK_SIZE) {
15835
        WOLFSSL_MSG("Cipher text input too small for decryption");
15836
        return BAD_FUNC_ARG;
15837
    }
15838
15839
    if (stream->bytes_crypted_with_this_tweak &
15840
        ((word32)WC_AES_BLOCK_SIZE - 1U))
15841
    {
15842
        WOLFSSL_MSG("AesXtsDecryptUpdate after previous finalizing call");
15843
        return BAD_FUNC_ARG;
15844
    }
15845
15846
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
15847
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
15848
                             stream->bytes_crypted_with_this_tweak))
15849
    {
15850
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
15851
                    "in AesXtsDecryptUpdate().");
15852
    }
15853
#endif
15854
15855
    {
15856
#ifdef WOLFSSL_AESNI
15857
        if (aes->use_aesni) {
15858
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15859
#if defined(HAVE_INTEL_AVX1)
15860
            if (IS_INTEL_AVX1(intel_flags)) {
15861
                AES_XTS_decrypt_update_avx1(in, out, sz,
15862
                                            (const byte*)aes->key,
15863
                                            stream->tweak_block,
15864
                                            (int)aes->rounds);
15865
                ret = 0;
15866
            }
15867
            else
15868
#endif
15869
            {
15870
                AES_XTS_decrypt_update_aesni(in, out, sz,
15871
                                             (const byte*)aes->key,
15872
                                             stream->tweak_block,
15873
                                             (int)aes->rounds);
15874
                ret = 0;
15875
            }
15876
            RESTORE_VECTOR_REGISTERS();
15877
        }
15878
        else
15879
#endif /* WOLFSSL_AESNI */
15880
        {
15881
            ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
15882
                                         stream->tweak_block);
15883
        }
15884
    }
15885
15886
    return ret;
15887
}
15888
15889
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15890
                           struct XtsAesStreamData *stream)
15891
{
15892
    if (stream == NULL)
15893
        return BAD_FUNC_ARG;
15894
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
15895
        return BAD_FUNC_ARG;
15896
    return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
15897
}
15898
15899
int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15900
                           struct XtsAesStreamData *stream)
15901
{
15902
    int ret;
15903
    if (stream == NULL)
15904
        return BAD_FUNC_ARG;
15905
    if (sz > 0)
15906
        ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
15907
    else
15908
        ret = 0;
15909
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
15910
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
15911
     * after finalization.
15912
     */
15913
    stream->bytes_crypted_with_this_tweak |= 1U;
15914
#ifdef WOLFSSL_CHECK_MEM_ZERO
15915
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
15916
#endif
15917
    return ret;
15918
}
15919
15920
#endif /* WOLFSSL_AESXTS_STREAM */
15921
#endif /* HAVE_AES_DECRYPT */
15922
15923
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
15924
 * sectorSz bytes
15925
 *
15926
 * xaes     AES keys to use for block encrypt
15927
 * out      output buffer to hold cipher text
15928
 * in       input plain text buffer to encrypt
15929
 * sz       size of both out and in buffers
15930
 * sector   value to use for tweak
15931
 * sectorSz size of the sector
15932
 *
15933
 * returns 0 on success
15934
 */
15935
int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
15936
        word32 sz, word64 sector, word32 sectorSz)
15937
0
{
15938
0
    int ret  = 0;
15939
0
    word32 iter = 0;
15940
0
    word32 sectorCount;
15941
0
    word32 remainder;
15942
15943
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
15944
0
        return BAD_FUNC_ARG;
15945
0
    }
15946
15947
0
    if (sz < WC_AES_BLOCK_SIZE) {
15948
0
        WOLFSSL_MSG("Cipher text input too small for encryption");
15949
0
        return BAD_FUNC_ARG;
15950
0
    }
15951
15952
0
    sectorCount  = sz / sectorSz;
15953
0
    remainder = sz % sectorSz;
15954
15955
0
    while (sectorCount) {
15956
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
15957
0
                in + (iter * sectorSz), sectorSz, sector);
15958
0
        if (ret != 0)
15959
0
            break;
15960
15961
0
        sectorCount--;
15962
0
        iter++;
15963
0
        sector++;
15964
0
    }
15965
15966
0
    if (remainder && ret == 0)
15967
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
15968
0
                in + (iter * sectorSz), remainder, sector);
15969
15970
0
    return ret;
15971
0
}
15972
15973
#ifdef HAVE_AES_DECRYPT
15974
15975
/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
15976
 *
15977
 * xaes     AES keys to use for block decrypt
15978
 * out      output buffer to hold cipher text
15979
 * in       input plain text buffer to encrypt
15980
 * sz       size of both out and in buffers
15981
 * sector   value to use for tweak
15982
 * sectorSz size of the sector
15983
 *
15984
 * returns 0 on success
15985
 */
15986
int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
15987
        word32 sz, word64 sector, word32 sectorSz)
15988
0
{
15989
0
    int ret  = 0;
15990
0
    word32 iter = 0;
15991
0
    word32 sectorCount;
15992
0
    word32 remainder;
15993
15994
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
15995
0
        return BAD_FUNC_ARG;
15996
0
    }
15997
15998
0
    if (sz < WC_AES_BLOCK_SIZE) {
15999
0
        WOLFSSL_MSG("Cipher text input too small for decryption");
16000
0
        return BAD_FUNC_ARG;
16001
0
    }
16002
16003
0
    sectorCount  = sz / sectorSz;
16004
0
    remainder = sz % sectorSz;
16005
16006
0
    while (sectorCount) {
16007
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
16008
0
                in + (iter * sectorSz), sectorSz, sector);
16009
0
        if (ret != 0)
16010
0
            break;
16011
16012
0
        sectorCount--;
16013
0
        iter++;
16014
0
        sector++;
16015
0
    }
16016
16017
0
    if (remainder && ret == 0)
16018
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
16019
0
                in + (iter * sectorSz), remainder, sector);
16020
16021
0
    return ret;
16022
0
}
16023
#endif /* HAVE_AES_DECRYPT */
16024
#endif /* WOLFSSL_AES_XTS */
16025
16026
#ifdef WOLFSSL_AES_SIV
16027
16028
/*
16029
 * See RFC 5297 Section 2.4.
16030
 */
16031
static WARN_UNUSED_RESULT int S2V(
16032
    const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc,
16033
    const byte* nonce, word32 nonceSz, const byte* data,
16034
    word32 dataSz, byte* out)
16035
0
{
16036
0
#ifdef WOLFSSL_SMALL_STACK
16037
0
    byte* tmp[3] = {NULL, NULL, NULL};
16038
0
    int i;
16039
0
    Cmac* cmac;
16040
#else
16041
    byte tmp[3][WC_AES_BLOCK_SIZE];
16042
    Cmac cmac[1];
16043
#endif
16044
0
    word32 macSz = WC_AES_BLOCK_SIZE;
16045
0
    int ret = 0;
16046
0
    byte tmpi = 0;
16047
0
    word32 ai;
16048
0
    word32 zeroBytes;
16049
16050
0
#ifdef WOLFSSL_SMALL_STACK
16051
0
    for (i = 0; i < 3; ++i) {
16052
0
        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16053
0
        if (tmp[i] == NULL) {
16054
0
            ret = MEMORY_E;
16055
0
            break;
16056
0
        }
16057
0
    }
16058
0
    if (ret == 0)
16059
0
#endif
16060
16061
0
    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
16062
        /* See RFC 5297 Section 7. */
16063
0
        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
16064
0
                    " 126.");
16065
0
        ret = BAD_FUNC_ARG;
16066
0
    }
16067
16068
0
    if (ret == 0) {
16069
0
        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
16070
0
        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
16071
16072
0
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
16073
0
                                 key, keySz);
16074
0
    }
16075
16076
0
    if (ret == 0) {
16077
        /* Loop over authenticated associated data AD1..ADn */
16078
0
        for (ai = 0; ai < numAssoc; ++ai) {
16079
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
16080
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
16081
0
                                     assoc[ai].assocSz, key, keySz);
16082
0
            if (ret != 0)
16083
0
                break;
16084
0
            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
16085
0
            tmpi = (byte)(1 - tmpi);
16086
0
        }
16087
16088
        /* Add nonce as final AD. See RFC 5297 Section 3. */
16089
0
        if ((ret == 0) && (nonceSz > 0)) {
16090
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
16091
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
16092
0
                                     nonceSz, key, keySz);
16093
0
            if (ret == 0) {
16094
0
                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
16095
0
            }
16096
0
            tmpi = (byte)(1U - tmpi);
16097
0
        }
16098
16099
        /* For simplicity of the remaining code, make sure the "final" result
16100
           is always in tmp[0]. */
16101
0
        if (tmpi == 1) {
16102
0
            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
16103
0
        }
16104
0
    }
16105
16106
0
    if (ret == 0) {
16107
0
        if (dataSz >= WC_AES_BLOCK_SIZE) {
16108
16109
0
            WC_ALLOC_VAR_EX(cmac, Cmac, 1, NULL, DYNAMIC_TYPE_CMAC,
16110
0
                ret=MEMORY_E);
16111
0
            if (WC_VAR_OK(cmac))
16112
0
            {
16113
            #ifdef WOLFSSL_CHECK_MEM_ZERO
16114
                /* Aes part is checked by wc_AesFree. */
16115
                wc_MemZero_Add("wc_AesCmacGenerate cmac",
16116
                    ((unsigned char *)cmac) + sizeof(Aes),
16117
                    sizeof(Cmac) - sizeof(Aes));
16118
            #endif
16119
0
                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
16120
0
                       WC_AES_BLOCK_SIZE);
16121
0
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
16122
0
                if (ret == 0) {
16123
0
                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
16124
0
                }
16125
0
                if (ret == 0) {
16126
0
                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
16127
0
                }
16128
0
                if (ret == 0) {
16129
0
                    ret = wc_CmacFinal(cmac, out, &macSz);
16130
0
                }
16131
0
            }
16132
0
        #ifdef WOLFSSL_SMALL_STACK
16133
0
            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
16134
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
16135
            wc_MemZero_Check(cmac, sizeof(Cmac));
16136
        #endif
16137
0
        }
16138
0
        else {
16139
0
            XMEMCPY(tmp[2], data, dataSz);
16140
0
            tmp[2][dataSz] |= 0x80;
16141
0
            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
16142
0
            if (zeroBytes != 0) {
16143
0
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
16144
0
            }
16145
0
            ShiftAndXorRb(tmp[1], tmp[0]);
16146
0
            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
16147
0
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
16148
0
                                     keySz);
16149
0
        }
16150
0
    }
16151
16152
0
#ifdef WOLFSSL_SMALL_STACK
16153
0
    for (i = 0; i < 3; ++i) {
16154
0
        if (tmp[i] != NULL) {
16155
0
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
16156
0
        }
16157
0
    }
16158
0
#endif
16159
16160
0
    return ret;
16161
0
}
16162
16163
static WARN_UNUSED_RESULT int AesSivCipher(
16164
    const byte* key, word32 keySz, const AesSivAssoc* assoc,
16165
    word32 numAssoc, const byte* nonce, word32 nonceSz,
16166
    const byte* data, word32 dataSz, byte* siv, byte* out,
16167
    int enc)
16168
0
{
16169
0
    int ret = 0;
16170
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16171
0
    byte sivTmp[WC_AES_BLOCK_SIZE];
16172
16173
0
    if (key == NULL || siv == NULL || out == NULL) {
16174
0
        WOLFSSL_MSG("Bad parameter");
16175
0
        ret = BAD_FUNC_ARG;
16176
0
    }
16177
16178
0
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
16179
0
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
16180
0
        ret = BAD_FUNC_ARG;
16181
0
    }
16182
16183
0
    if (ret == 0) {
16184
0
        if (enc == 1) {
16185
0
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
16186
0
                      dataSz, sivTmp);
16187
0
            if (ret != 0) {
16188
0
                WOLFSSL_MSG("S2V failed.");
16189
0
            }
16190
0
            else {
16191
0
                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
16192
0
            }
16193
0
        }
16194
0
        else {
16195
0
            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
16196
0
        }
16197
0
    }
16198
16199
0
    if (ret == 0) {
16200
0
#ifdef WOLFSSL_SMALL_STACK
16201
0
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
16202
#else
16203
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16204
#endif
16205
0
        if (ret != 0) {
16206
0
            WOLFSSL_MSG("Failed to initialized AES object.");
16207
0
        }
16208
0
    }
16209
16210
0
    if (ret == 0 && dataSz > 0) {
16211
0
        sivTmp[12] &= 0x7f;
16212
0
        sivTmp[8] &= 0x7f;
16213
0
        ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
16214
0
                           AES_ENCRYPTION);
16215
0
        if (ret != 0) {
16216
0
            WOLFSSL_MSG("Failed to set key for AES-CTR.");
16217
0
        }
16218
0
        else {
16219
0
            ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
16220
0
            if (ret != 0) {
16221
0
                WOLFSSL_MSG("AES-CTR encryption failed.");
16222
0
            }
16223
0
        }
16224
0
    }
16225
16226
0
    if (ret == 0 && enc == 0) {
16227
0
        ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out, dataSz,
16228
0
                  sivTmp);
16229
0
        if (ret != 0) {
16230
0
            WOLFSSL_MSG("S2V failed.");
16231
0
        }
16232
16233
0
        if (XMEMCMP(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
16234
0
            WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
16235
0
            ret = AES_SIV_AUTH_E;
16236
0
        }
16237
0
    }
16238
16239
0
#ifdef WOLFSSL_SMALL_STACK
16240
0
    wc_AesDelete(aes, NULL);
16241
#else
16242
    wc_AesFree(aes);
16243
#endif
16244
16245
0
    return ret;
16246
0
}
16247
16248
/*
16249
 * See RFC 5297 Section 2.6.
16250
 */
16251
int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
16252
                     word32 assocSz, const byte* nonce, word32 nonceSz,
16253
                     const byte* in, word32 inSz, byte* siv, byte* out)
16254
0
{
16255
0
    AesSivAssoc ad;
16256
0
    ad.assoc = assoc;
16257
0
    ad.assocSz = assocSz;
16258
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
16259
0
                        siv, out, 1);
16260
0
}
16261
16262
/*
16263
 * See RFC 5297 Section 2.7.
16264
 */
16265
int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
16266
                     word32 assocSz, const byte* nonce, word32 nonceSz,
16267
                     const byte* in, word32 inSz, byte* siv, byte* out)
16268
0
{
16269
0
    AesSivAssoc ad;
16270
0
    ad.assoc = assoc;
16271
0
    ad.assocSz = assocSz;
16272
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
16273
0
                        siv, out, 0);
16274
0
}
16275
16276
/*
16277
 * See RFC 5297 Section 2.6.
16278
 */
16279
int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
16280
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
16281
                        const byte* in, word32 inSz, byte* siv, byte* out)
16282
0
{
16283
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
16284
0
                        siv, out, 1);
16285
0
}
16286
16287
/*
16288
 * See RFC 5297 Section 2.7.
16289
 */
16290
int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
16291
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
16292
                        const byte* in, word32 inSz, byte* siv, byte* out)
16293
0
{
16294
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
16295
0
                        siv, out, 0);
16296
0
}
16297
16298
#endif /* WOLFSSL_AES_SIV */
16299
16300
#if defined(WOLFSSL_AES_EAX)
16301
16302
/*
16303
 * AES EAX one-shot API
16304
 * Encrypts input data and computes an auth tag over the input
16305
 * auth data and ciphertext
16306
 *
16307
 * Returns 0 on success
16308
 * Returns error code on failure
16309
 */
16310
int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
16311
                          const byte* in, word32 inSz,
16312
                          const byte* nonce, word32 nonceSz,
16313
                          /* output computed auth tag */
16314
                          byte* authTag, word32 authTagSz,
16315
                          /* input data to authenticate */
16316
                          const byte* authIn, word32 authInSz)
16317
{
16318
#if defined(WOLFSSL_SMALL_STACK)
16319
    AesEax *eax;
16320
#else
16321
    AesEax eax_mem;
16322
    AesEax *eax = &eax_mem;
16323
#endif
16324
    int ret;
16325
    int eaxInited = 0;
16326
16327
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
16328
                              || authTag == NULL || authIn == NULL) {
16329
        return BAD_FUNC_ARG;
16330
    }
16331
16332
#if defined(WOLFSSL_SMALL_STACK)
16333
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
16334
                                 NULL,
16335
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
16336
        return MEMORY_E;
16337
    }
16338
#endif
16339
16340
    if ((ret = wc_AesEaxInit(eax,
16341
                             key, keySz,
16342
                             nonce, nonceSz,
16343
                             authIn, authInSz)) != 0) {
16344
        goto cleanup;
16345
    }
16346
    eaxInited = 1;
16347
16348
    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
16349
        goto cleanup;
16350
    }
16351
16352
    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
16353
        goto cleanup;
16354
    }
16355
16356
cleanup:
16357
    if (eaxInited)
16358
        wc_AesEaxFree(eax);
16359
#if defined(WOLFSSL_SMALL_STACK)
16360
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
16361
#endif
16362
    return ret;
16363
}
16364
16365
16366
/*
16367
 * AES EAX one-shot API
16368
 * Decrypts and authenticates data against a supplied auth tag
16369
 *
16370
 * Returns 0 on success
16371
 * Returns error code on failure
16372
 */
16373
int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
16374
                          const byte* in, word32 inSz,
16375
                          const byte* nonce, word32 nonceSz,
16376
                          /* auth tag to verify against */
16377
                          const byte* authTag, word32 authTagSz,
16378
                          /* input data to authenticate */
16379
                          const byte* authIn, word32 authInSz)
16380
{
16381
#if defined(WOLFSSL_SMALL_STACK)
16382
    AesEax *eax;
16383
#else
16384
    AesEax eax_mem;
16385
    AesEax *eax = &eax_mem;
16386
#endif
16387
    int ret;
16388
    int eaxInited = 0;
16389
16390
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
16391
                              || authTag == NULL || authIn == NULL) {
16392
        return BAD_FUNC_ARG;
16393
    }
16394
16395
#if defined(WOLFSSL_SMALL_STACK)
16396
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
16397
                                 NULL,
16398
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
16399
        return MEMORY_E;
16400
    }
16401
#endif
16402
16403
    if ((ret = wc_AesEaxInit(eax,
16404
                             key, keySz,
16405
                             nonce, nonceSz,
16406
                             authIn, authInSz)) != 0) {
16407
16408
        goto cleanup;
16409
    }
16410
    eaxInited = 1;
16411
16412
    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
16413
        goto cleanup;
16414
    }
16415
16416
    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
16417
        goto cleanup;
16418
    }
16419
16420
cleanup:
16421
    if (eaxInited)
16422
        wc_AesEaxFree(eax);
16423
#if defined(WOLFSSL_SMALL_STACK)
16424
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
16425
#endif
16426
    return ret;
16427
}
16428
16429
16430
/*
16431
 * AES EAX Incremental API:
16432
 * Initializes an AES EAX encryption or decryption operation. This must be
16433
 * called before any other EAX APIs are used on the AesEax struct
16434
 *
16435
 * Returns 0 on success
16436
 * Returns error code on failure
16437
 */
16438
int  wc_AesEaxInit(AesEax* eax,
16439
                   const byte* key, word32 keySz,
16440
                   const byte* nonce, word32 nonceSz,
16441
                   const byte* authIn, word32 authInSz)
16442
{
16443
    int ret = 0;
16444
    word32 cmacSize;
16445
    int aesInited = 0;
16446
    int nonceCmacInited = 0;
16447
    int aadCmacInited = 0;
16448
16449
    if (eax == NULL || key == NULL ||  nonce == NULL) {
16450
        return BAD_FUNC_ARG;
16451
    }
16452
16453
    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
16454
16455
    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
16456
        goto out;
16457
    }
16458
    aesInited = 1;
16459
16460
    if ((ret = wc_AesSetKey(&eax->aes,
16461
                            key,
16462
                            keySz,
16463
                            NULL,
16464
                            AES_ENCRYPTION)) != 0) {
16465
        goto out;
16466
    }
16467
16468
    /*
16469
    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
16470
    *   N' = OMAC^0_K(N)
16471
    */
16472
    if ((ret = wc_InitCmac(&eax->nonceCmac,
16473
                           key,
16474
                           keySz,
16475
                           WC_CMAC_AES,
16476
                           NULL)) != 0) {
16477
        return ret;
16478
    }
16479
    nonceCmacInited = 1;
16480
16481
    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
16482
                             eax->prefixBuf,
16483
                             sizeof(eax->prefixBuf))) != 0) {
16484
        goto out;
16485
    }
16486
16487
    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
16488
        goto out;
16489
    }
16490
16491
    cmacSize = WC_AES_BLOCK_SIZE;
16492
    if ((ret = wc_CmacFinal(&eax->nonceCmac,
16493
                            eax->nonceCmacFinal,
16494
                            &cmacSize)) != 0) {
16495
        goto out;
16496
    }
16497
16498
    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
16499
        goto out;
16500
    }
16501
16502
    /*
16503
     * start the OMAC used to build the auth tag chunk for the AD .
16504
     * This CMAC is continued in subsequent update calls when more auth data is
16505
     * provided
16506
     *   H' = OMAC^1_K(H)
16507
     */
16508
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 1;
16509
    if ((ret = wc_InitCmac(&eax->aadCmac,
16510
                           key,
16511
                           keySz,
16512
                           WC_CMAC_AES,
16513
                           NULL)) != 0) {
16514
        goto out;
16515
    }
16516
    aadCmacInited = 1;
16517
16518
    if ((ret = wc_CmacUpdate(&eax->aadCmac,
16519
                             eax->prefixBuf,
16520
                             sizeof(eax->prefixBuf))) != 0) {
16521
        goto out;
16522
    }
16523
16524
    if (authIn != NULL) {
16525
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
16526
            goto out;
16527
        }
16528
    }
16529
16530
    /*
16531
     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
16532
     * updated in subsequent calls to encrypt/decrypt
16533
     *  C' = OMAC^2_K(C)
16534
     */
16535
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 2;
16536
    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
16537
                           key,
16538
                           keySz,
16539
                           WC_CMAC_AES,
16540
                           NULL)) != 0) {
16541
        goto out;
16542
    }
16543
16544
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
16545
                             eax->prefixBuf,
16546
                             sizeof(eax->prefixBuf))) != 0) {
16547
        goto out;
16548
    }
16549
16550
out:
16551
16552
    if (ret != 0) {
16553
        if (aesInited)
16554
            wc_AesFree(&eax->aes);
16555
        if (nonceCmacInited)
16556
            wc_CmacFree(&eax->nonceCmac);
16557
        if (aadCmacInited)
16558
            wc_CmacFree(&eax->aadCmac);
16559
    }
16560
16561
    return ret;
16562
}
16563
16564
16565
/*
16566
 * AES EAX Incremental API:
16567
 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
16568
 * the authentication stream
16569
 *
16570
 * Returns 0 on success
16571
 * Returns error code on failure
16572
 */
16573
int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
16574
                            const byte* in, word32 inSz,
16575
                            const byte* authIn, word32 authInSz)
16576
{
16577
    int ret;
16578
16579
    if (eax == NULL || out == NULL ||  in == NULL) {
16580
        return BAD_FUNC_ARG;
16581
    }
16582
16583
    /*
16584
     * Encrypt the plaintext using AES CTR
16585
     *  C = CTR(M)
16586
     */
16587
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
16588
        return ret;
16589
    }
16590
16591
    /*
16592
     * update OMAC with new ciphertext
16593
     *  C' = OMAC^2_K(C)
16594
     */
16595
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
16596
        return ret;
16597
    }
16598
16599
    /* If there exists new auth data, update the OMAC for that as well */
16600
    if (authIn != NULL) {
16601
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
16602
            return ret;
16603
        }
16604
    }
16605
16606
    return 0;
16607
}
16608
16609
16610
/*
16611
 * AES EAX Incremental API:
16612
 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
16613
 * the authentication stream
16614
 *
16615
 * Returns 0 on success
16616
 * Returns error code on failure
16617
 */
16618
int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
16619
                            const byte* in, word32 inSz,
16620
                            const byte* authIn, word32 authInSz)
16621
{
16622
    int ret;
16623
16624
    if (eax == NULL || out == NULL ||  in == NULL) {
16625
        return BAD_FUNC_ARG;
16626
    }
16627
16628
    /*
16629
     * Decrypt the plaintext using AES CTR
16630
     *  C = CTR(M)
16631
     */
16632
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
16633
        return ret;
16634
    }
16635
16636
    /*
16637
     * update OMAC with new ciphertext
16638
     *  C' = OMAC^2_K(C)
16639
     */
16640
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
16641
        return ret;
16642
    }
16643
16644
    /* If there exists new auth data, update the OMAC for that as well */
16645
    if (authIn != NULL) {
16646
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
16647
            return ret;
16648
        }
16649
    }
16650
16651
    return 0;
16652
}
16653
16654
16655
/*
16656
 * AES EAX Incremental API:
16657
 * Provides additional auth data information to the authentication
16658
 * stream for an authenticated encryption or decryption operation
16659
 *
16660
 * Returns 0 on success
16661
 * Returns error code on failure
16662
 */
16663
int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
16664
{
16665
    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
16666
}
16667
16668
16669
/*
16670
 * AES EAX Incremental API:
16671
 * Finalizes the authenticated encryption operation, computing the auth tag
16672
 * over previously supplied auth data and computed ciphertext
16673
 *
16674
 * Returns 0 on success
16675
 * Returns error code on failure
16676
 */
16677
int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
16678
{
16679
    word32 cmacSize;
16680
    int ret;
16681
    word32 i;
16682
16683
    if (eax == NULL || authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE) {
16684
        return BAD_FUNC_ARG;
16685
    }
16686
16687
    /* Complete the OMAC for the ciphertext */
16688
    cmacSize = WC_AES_BLOCK_SIZE;
16689
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
16690
                                  eax->ciphertextCmacFinal,
16691
                                  &cmacSize)) != 0) {
16692
        return ret;
16693
    }
16694
16695
    /* Complete the OMAC for auth data */
16696
    cmacSize = WC_AES_BLOCK_SIZE;
16697
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
16698
                                  eax->aadCmacFinal,
16699
                                  &cmacSize)) != 0) {
16700
        return ret;
16701
    }
16702
16703
    /*
16704
     * Concatenate all three auth tag chunks into the final tag, truncating
16705
     * at the specified tag length
16706
     *   T = Tag [first authTagSz bytes]
16707
     */
16708
    for (i = 0; i < authTagSz; i++) {
16709
        authTag[i] = eax->nonceCmacFinal[i]
16710
                    ^ eax->aadCmacFinal[i]
16711
                    ^ eax->ciphertextCmacFinal[i];
16712
    }
16713
16714
    return 0;
16715
}
16716
16717
16718
/*
16719
 * AES EAX Incremental API:
16720
 * Finalizes the authenticated decryption operation, computing the auth tag
16721
 * for the previously supplied auth data and cipher text and validating it
16722
 * against a provided auth tag
16723
 *
16724
 * Returns 0 on success
16725
 * Return error code for failure
16726
 */
16727
int wc_AesEaxDecryptFinal(AesEax* eax,
16728
                          const byte* authIn, word32 authInSz)
16729
{
16730
    int ret;
16731
    word32 i;
16732
    word32 cmacSize;
16733
16734
#if defined(WOLFSSL_SMALL_STACK)
16735
    byte *authTag;
16736
#else
16737
    byte authTag[WC_AES_BLOCK_SIZE];
16738
#endif
16739
16740
    if (eax == NULL || authIn == NULL || authInSz > WC_AES_BLOCK_SIZE) {
16741
        return BAD_FUNC_ARG;
16742
    }
16743
16744
    /* Complete the OMAC for the ciphertext */
16745
    cmacSize = WC_AES_BLOCK_SIZE;
16746
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
16747
                                  eax->ciphertextCmacFinal,
16748
                                  &cmacSize)) != 0) {
16749
        return ret;
16750
    }
16751
16752
    /* Complete the OMAC for auth data */
16753
    cmacSize = WC_AES_BLOCK_SIZE;
16754
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
16755
                                  eax->aadCmacFinal,
16756
                                  &cmacSize)) != 0) {
16757
        return ret;
16758
    }
16759
16760
#if defined(WOLFSSL_SMALL_STACK)
16761
    authTag = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16762
    if (authTag == NULL) {
16763
        return MEMORY_E;
16764
    }
16765
#endif
16766
16767
    /*
16768
     * Concatenate all three auth tag chunks into the final tag, truncating
16769
     * at the specified tag length
16770
     *   T = Tag [first authInSz bytes]
16771
     */
16772
    for (i = 0; i < authInSz; i++) {
16773
        authTag[i] = eax->nonceCmacFinal[i]
16774
                    ^ eax->aadCmacFinal[i]
16775
                    ^ eax->ciphertextCmacFinal[i];
16776
    }
16777
16778
    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
16779
        ret = AES_EAX_AUTH_E;
16780
    }
16781
    else {
16782
        ret = 0;
16783
    }
16784
16785
#if defined(WOLFSSL_SMALL_STACK)
16786
    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16787
#endif
16788
16789
    return ret;
16790
}
16791
16792
/*
16793
 * Frees the underlying CMAC and AES contexts. Must be called when done using
16794
 * the AES EAX context structure.
16795
 *
16796
 * Returns 0 on success
16797
 * Returns error code on failure
16798
 */
16799
int wc_AesEaxFree(AesEax* eax)
16800
{
16801
    if (eax == NULL) {
16802
        return BAD_FUNC_ARG;
16803
    }
16804
16805
    (void)wc_CmacFree(&eax->ciphertextCmac);
16806
    (void)wc_CmacFree(&eax->aadCmac);
16807
    wc_AesFree(&eax->aes);
16808
16809
    return 0;
16810
}
16811
16812
#endif /* WOLFSSL_AES_EAX */
16813
16814
#ifdef WOLFSSL_AES_CTS
16815
16816
16817
/* One-shot API */
16818
int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out,
16819
                     const byte* in, word32 inSz,
16820
                     const byte* iv)
16821
{
16822
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16823
    int ret = 0;
16824
    word32 outSz = inSz;
16825
16826
    if (key == NULL || out == NULL || in == NULL || iv == NULL)
16827
        return BAD_FUNC_ARG;
16828
16829
#ifdef WOLFSSL_SMALL_STACK
16830
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
16831
#else
16832
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16833
#endif
16834
    if (ret == 0)
16835
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
16836
    if (ret == 0)
16837
        ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz);
16838
    if (ret == 0) {
16839
        out += outSz;
16840
        outSz = inSz - outSz;
16841
        ret = wc_AesCtsEncryptFinal(aes, out, &outSz);
16842
    }
16843
16844
#ifdef WOLFSSL_SMALL_STACK
16845
    wc_AesDelete(aes, NULL);
16846
#else
16847
    wc_AesFree(aes);
16848
#endif
16849
    return ret;
16850
}
16851
16852
int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out,
16853
                     const byte* in, word32 inSz,
16854
                     const byte* iv)
16855
{
16856
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16857
    int ret = 0;
16858
    word32 outSz = inSz;
16859
16860
    if (key == NULL || out == NULL || in == NULL || iv == NULL) {
16861
        return BAD_FUNC_ARG;
16862
    }
16863
16864
#ifdef WOLFSSL_SMALL_STACK
16865
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
16866
#else
16867
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16868
#endif
16869
    if (ret == 0)
16870
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
16871
    if (ret == 0)
16872
        ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz);
16873
    if (ret == 0) {
16874
        out += outSz;
16875
        outSz = inSz - outSz;
16876
        ret = wc_AesCtsDecryptFinal(aes, out, &outSz);
16877
    }
16878
16879
#ifdef WOLFSSL_SMALL_STACK
16880
    wc_AesDelete(aes, NULL);
16881
#else
16882
    wc_AesFree(aes);
16883
#endif
16884
    return ret;
16885
}
16886
16887
static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz,
16888
                        const byte* in, word32 inSz, int enc)
16889
{
16890
    word32 blocks = 0;
16891
    int ret = 0;
16892
    word32 writtenSz = 0;
16893
    word32 tmpOutSz;
16894
16895
    if (aes == NULL || out == NULL || in == NULL || outSz == NULL)
16896
        return BAD_FUNC_ARG;
16897
16898
    /* Error out early for easy sanity check */
16899
    if (*outSz < inSz)
16900
        return BUFFER_E;
16901
    tmpOutSz = *outSz;
16902
16903
    /* We need to store last two blocks of plaintext */
16904
    if (aes->left > 0) {
16905
        word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left);
16906
        XMEMCPY(aes->ctsBlock + aes->left, in, copySz);
16907
        aes->left += copySz;
16908
        in += copySz;
16909
        inSz -= copySz;
16910
16911
        if (aes->left == WC_AES_BLOCK_SIZE * 2) {
16912
            if (inSz > WC_AES_BLOCK_SIZE) {
16913
                if (tmpOutSz < WC_AES_BLOCK_SIZE * 2)
16914
                    return BUFFER_E;
16915
                if (enc) {
16916
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
16917
                                           WC_AES_BLOCK_SIZE * 2);
16918
                }
16919
                else {
16920
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
16921
                                           WC_AES_BLOCK_SIZE * 2);
16922
                }
16923
                if (ret != 0)
16924
                    return ret;
16925
                out += WC_AES_BLOCK_SIZE * 2;
16926
                writtenSz += WC_AES_BLOCK_SIZE * 2;
16927
                tmpOutSz -= WC_AES_BLOCK_SIZE * 2;
16928
                aes->left = 0;
16929
            }
16930
            else if (inSz > 0) {
16931
                if (tmpOutSz < WC_AES_BLOCK_SIZE)
16932
                    return BUFFER_E;
16933
                if (enc) {
16934
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
16935
                                           WC_AES_BLOCK_SIZE);
16936
                }
16937
                else {
16938
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
16939
                                           WC_AES_BLOCK_SIZE);
16940
                }
16941
                if (ret != 0)
16942
                    return ret;
16943
                out += WC_AES_BLOCK_SIZE;
16944
                writtenSz += WC_AES_BLOCK_SIZE;
16945
                tmpOutSz -= WC_AES_BLOCK_SIZE;
16946
                /* Move the last block in ctsBlock to the beginning for
16947
                 * next operation */
16948
                XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE,
16949
                        WC_AES_BLOCK_SIZE);
16950
                XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz);
16951
                aes->left = WC_AES_BLOCK_SIZE + inSz;
16952
                *outSz = writtenSz;
16953
                return ret; /* Return the result of encryption */
16954
            }
16955
            else {
16956
                /* Can't output data as we need > 1 block for Final call */
16957
                *outSz = writtenSz;
16958
                return 0;
16959
            }
16960
        }
16961
        else {
16962
            /* All input has been absorbed into aes->ctsBlock */
16963
            *outSz = 0;
16964
            return 0;
16965
        }
16966
    }
16967
    if (inSz > WC_AES_BLOCK_SIZE) {
16968
        /* We need to store the last two full or partial blocks */
16969
        blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE;
16970
        blocks -= 2;
16971
    }
16972
    if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE)
16973
        return BUFFER_E;
16974
    if (enc)
16975
        ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
16976
    else
16977
        ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
16978
    in += blocks * WC_AES_BLOCK_SIZE;
16979
    inSz -= blocks * WC_AES_BLOCK_SIZE;
16980
    XMEMCPY(aes->ctsBlock, in, inSz);
16981
    aes->left = inSz;
16982
    writtenSz += blocks * WC_AES_BLOCK_SIZE;
16983
    *outSz = writtenSz;
16984
    return ret;
16985
}
16986
16987
/* Incremental API */
16988
int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz,
16989
                           const byte* in, word32 inSz)
16990
{
16991
    return AesCtsUpdate(aes, out, outSz, in, inSz, 1);
16992
}
16993
16994
int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz)
16995
{
16996
    int ret = 0;
16997
16998
    if (aes == NULL || out == NULL || outSz == NULL)
16999
        return BAD_FUNC_ARG;
17000
    if (*outSz < aes->left)
17001
        return BUFFER_E;
17002
17003
    /* Input must be at least two complete or partial blocks */
17004
    if (aes->left <= WC_AES_BLOCK_SIZE)
17005
        return BAD_FUNC_ARG;
17006
17007
    /* Zero padding */
17008
    XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left);
17009
17010
    ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock,
17011
                           WC_AES_BLOCK_SIZE * 2);
17012
    if (ret != 0)
17013
        return ret;
17014
17015
    XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
17016
    XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock,
17017
            aes->left - WC_AES_BLOCK_SIZE);
17018
    *outSz = aes->left;
17019
    return ret;
17020
}
17021
17022
int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz,
17023
                           const byte* in, word32 inSz)
17024
{
17025
    return AesCtsUpdate(aes, out, outSz, in, inSz, 0);
17026
}
17027
17028
int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz)
17029
{
17030
    int ret = 0;
17031
    byte iv[WC_AES_BLOCK_SIZE];
17032
    byte tmp[WC_AES_BLOCK_SIZE];
17033
    word32 partialSz;
17034
    word32 padSz;
17035
17036
    if (aes == NULL || out == NULL || outSz == NULL)
17037
        return BAD_FUNC_ARG;
17038
    if (*outSz < aes->left)
17039
        return BUFFER_E;
17040
17041
    /* Input must be at least two complete or partial blocks */
17042
    if (aes->left <= WC_AES_BLOCK_SIZE)
17043
        return BAD_FUNC_ARG;
17044
17045
    partialSz = aes->left - WC_AES_BLOCK_SIZE;
17046
    padSz = 2 * WC_AES_BLOCK_SIZE - aes->left;
17047
    /* Zero pad */
17048
    XMEMSET(aes->ctsBlock + aes->left, 0, padSz);
17049
17050
    /* Store IV */
17051
    XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE);
17052
    /* Load IV */
17053
    XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
17054
17055
    ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE);
17056
    if (ret != 0)
17057
        return ret;
17058
17059
    /* Write out partial block */
17060
    XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz);
17061
    /* Retrieve the padding */
17062
    XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz);
17063
    /* Restore IV */
17064
    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
17065
17066
    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE,
17067
                           WC_AES_BLOCK_SIZE);
17068
    if (ret != 0)
17069
        return ret;
17070
17071
    *outSz = aes->left;
17072
    return ret;
17073
}
17074
17075
#endif /* WOLFSSL_AES_CTS */
17076
17077
17078
#endif /* !NO_AES */