Coverage Report

Created: 2026-04-05 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math/wolfcrypt/src/aes.c
Line
Count
Source
1
/* aes.c
2
 *
3
 * Copyright (C) 2006-2026 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
/*
33
 * AES Build Options:
34
 *
35
 * Core:
36
 * NO_AES:                  Disable AES support entirely          default: off
37
 * WOLFSSL_AES_128:         Enable AES-128 key size               default: on
38
 * WOLFSSL_AES_192:         Enable AES-192 key size               default: on
39
 * WOLFSSL_AES_256:         Enable AES-256 key size               default: on
40
 * AES_MAX_KEY_SIZE:        Maximum AES key size in bits           default: 256
41
 *
42
 * Cipher Modes:
43
 * HAVE_AES_CBC:            Enable AES-CBC mode                   default: on
44
 * HAVE_AES_ECB:            Enable AES-ECB mode                   default: off
45
 * HAVE_AES_DECRYPT:        Enable AES decryption                 default: on
46
 * WOLFSSL_AES_COUNTER:     Enable AES-CTR mode                   default: off
47
 * WOLFSSL_AES_CFB:         Enable AES-CFB mode                   default: off
48
 * WOLFSSL_NO_AES_CFB_1_8:  Disable AES-CFB-1 and AES-CFB-8      default: off
49
 * WOLFSSL_AES_OFB:         Enable AES-OFB mode                   default: off
50
 * WOLFSSL_AES_DIRECT:      Enable direct AES encrypt/decrypt API default: off
51
 * WOLFSSL_AES_XTS:         Enable AES-XTS mode                   default: off
52
 * WOLFSSL_AES_CTS:         Enable AES-CTS (ciphertext stealing)  default: off
53
 * WOLFSSL_AES_SIV:         Enable AES-SIV (synthetic IV) mode    default: off
54
 * WOLFSSL_AES_EAX:         Enable AES-EAX AEAD mode              default: off
55
 * WOLFSSL_CMAC:            Enable AES-CMAC (RFC 4493)            default: off
56
 * HAVE_AESCCM:             Enable AES-CCM mode                   default: off
57
 * HAVE_AES_KEYWRAP:        Enable AES key wrap (RFC 3394)        default: off
58
 * WOLFSSL_AES_CBC_LENGTH_CHECKS: Validate CBC input length       default: off
59
 *
60
 * AES-GCM:
61
 * HAVE_AESGCM:             Enable AES-GCM mode                   default: off
62
 * HAVE_AESGCM_DECRYPT:     Enable AES-GCM decryption             default: on
63
 *                           (when HAVE_AESGCM is enabled)
64
 * WOLFSSL_AESGCM_STREAM:   Enable streaming AES-GCM API          default: off
65
 * WC_AES_GCM_DEC_AUTH_EARLY: Authenticate tag before decryption  default: off
66
 * GCM_SMALL:               Small GCM table, saves memory         default: off
67
 * GCM_TABLE:               Full 4-bit GCM lookup table, faster   default: off
68
 * GCM_TABLE_4BIT:          Explicit 4-bit GCM table mode         default: off
69
 * GCM_WORD32:              Use 32-bit word GCM implementation    default: off
70
 * GCM_GMULT_LEN:           GCM GMULT length optimization         default: off
71
 *
72
 * AES-XTS Stream:
73
 * WOLFSSL_AESXTS_STREAM:   Enable streaming AES-XTS API          default: off
74
 * WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING:
75
 *                           Disable XTS stream request accounting default: off
76
 * WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS:
77
 *                           Support both encrypt and decrypt keys default: off
78
 *                           simultaneously in XTS context
79
 *
80
 * Performance / Side-Channel:
81
 * WOLFSSL_AESNI:           Enable Intel AES-NI instructions      default: off
82
 * WOLFSSL_AESNI_BY4:       AES-NI 4-block parallel processing    default: off
83
 * WOLFSSL_AESNI_BY6:       AES-NI 6-block parallel processing    default: off
84
 * USE_INTEL_SPEEDUP:       Intel AVX/AVX2 for AES acceleration   default: off
85
 * WOLFSSL_AES_SMALL_TABLES: Use smaller AES S-box tables         default: off
86
 * WOLFSSL_AES_NO_UNROLL:   Disable AES round loop unrolling      default: off
87
 * WOLFSSL_AES_TOUCH_LINES: Touch all cache lines for             default: off
88
 *                           side-channel resistance
89
 * WC_AES_BITSLICED:        Use bitsliced AES implementation      default: off
90
 * AES_GCM_GMULT_NCT:       GCM GMULT non-constant-time          default: off
91
 * NO_WOLFSSL_ALLOC_ALIGN:  Disable aligned memory allocation     default: off
92
 *
93
 * Hardware Acceleration (AES-specific):
94
 * WC_ASYNC_ENABLE_AES:     Enable async AES operations           default: off
95
 * WOLFSSL_CRYPTOCELL_AES:  CryptoCell AES acceleration           default: off
96
 * WOLFSSL_DEVCRYPTO_AES:   /dev/crypto AES acceleration          default: off
97
 * WOLFSSL_DEVCRYPTO_CBC:   /dev/crypto AES-CBC acceleration      default: off
98
 * WOLFSSL_KCAPI_AES:       Linux kernel crypto API for AES       default: off
99
 * WOLFSSL_NO_KCAPI_AES_CBC: Disable KCAPI AES-CBC                default: off
100
 * WOLFSSL_NRF51_AES:       nRF51 hardware AES                    default: off
101
 * WOLFSSL_PSA_NO_AES:      Disable PSA AES                       default: off
102
 * WOLFSSL_SCE_NO_AES:      Disable Renesas SCE AES               default: off
103
 * NO_IMX6_CAAM_AES:        Disable i.MX6 CAAM AES               default: off
104
 * WOLFSSL_AFALG_XILINX_AES: AF_ALG Xilinx AES acceleration      default: off
105
 * NO_WOLFSSL_ESP32_CRYPT_AES: Disable ESP32 AES acceleration     default: off
106
 * STM32_CRYPTO_AES_ONLY:   STM32 AES-only crypto mode            default: off
107
 *
108
 * Debug:
109
 * WC_DEBUG_CIPHER_LIFECYCLE: Debug cipher init/free lifecycle     default: off
110
 * WOLFSSL_HW_METRICS:      Track hardware acceleration usage     default: off
111
 */
112
113
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
114
115
#if !defined(NO_AES)
116
117
/* Tip: Locate the software cipher modes by searching for "Software AES" */
118
119
#if FIPS_VERSION3_GE(2,0,0)
120
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
121
    #define FIPS_NO_WRAPPERS
122
123
    #ifdef USE_WINDOWS_API
124
        #pragma code_seg(".fipsA$b")
125
        #pragma const_seg(".fipsB$b")
126
    #endif
127
#endif
128
129
#include <wolfssl/wolfcrypt/aes.h>
130
131
#ifdef WOLFSSL_AESNI
132
#include <wmmintrin.h>
133
#include <emmintrin.h>
134
#include <smmintrin.h>
135
#endif /* WOLFSSL_AESNI */
136
137
#include <wolfssl/wolfcrypt/cpuid.h>
138
139
#ifdef WOLF_CRYPTO_CB
140
    #include <wolfssl/wolfcrypt/cryptocb.h>
141
#endif
142
143
#ifdef WOLFSSL_SECO_CAAM
144
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
145
#endif
146
147
#ifdef WOLFSSL_IMXRT_DCP
148
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
149
#endif
150
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
151
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
152
#endif
153
154
#ifdef WOLFSSL_CMAC
155
    #include <wolfssl/wolfcrypt/cmac.h>
156
#endif
157
158
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
159
    #include <wolfssl/wolfcrypt/port/psa/psa.h>
160
#endif
161
162
#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
163
    #include <wolfssl/wolfcrypt/port/maxim/max3266x.h>
164
#ifdef MAX3266X_CB
165
    /* Revert back to SW so HW CB works */
166
    /* HW only works for AES: ECB, CBC, and partial via ECB for other modes */
167
    #include <wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h>
168
    /* Turn off MAX3266X_AES in the context of this file when using CB */
169
    #undef MAX3266X_AES
170
#endif
171
#endif
172
173
#if defined(WOLFSSL_TI_CRYPT)
174
    #include <wolfcrypt/src/port/ti/ti-aes.c>
175
176
    #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
177
        wc_AesEncryptDirect(aes, outBlock, inBlock)
178
    #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
179
        wc_AesDecryptDirect(aes, outBlock, inBlock)
180
#else
181
182
183
#if defined(WOLFSSL_PSOC6_CRYPTO)
184
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
185
#endif /* WOLFSSL_PSOC6_CRYPTO */
186
187
#ifdef NO_INLINE
188
    #include <wolfssl/wolfcrypt/misc.h>
189
#else
190
    #define WOLFSSL_MISC_INCLUDED
191
    #include <wolfcrypt/src/misc.c>
192
#endif
193
194
#if !defined(WOLFSSL_RISCV_ASM)
195
196
#ifdef WOLFSSL_IMX6_CAAM_BLOB
197
    /* case of possibly not using hardware acceleration for AES but using key
198
       blobs */
199
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
200
#endif
201
202
#ifdef DEBUG_AESNI
203
    #include <stdio.h>
204
#endif
205
206
#ifdef _MSC_VER
207
    /* 4127 warning constant while(1)  */
208
    #pragma warning(disable: 4127)
209
#endif
210
211
#if (!defined(WOLFSSL_ARMASM) && FIPS_VERSION3_GE(6,0,0)) || \
212
    FIPS_VERSION3_GE(7,0,0)
213
    const unsigned int wolfCrypt_FIPS_aes_ro_sanity[2] =
214
                                                     { 0x1a2b3c4d, 0x00000002 };
215
    int wolfCrypt_FIPS_AES_sanity(void)
216
    {
217
        return 0;
218
    }
219
#endif
220
221
/* Define AES implementation includes and functions */
222
#if defined(STM32_CRYPTO)
223
     /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
224
225
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
226
227
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
228
        Aes* aes, const byte* inBlock, byte* outBlock)
229
    {
230
        int ret = 0;
231
    #ifdef WOLFSSL_STM32_CUBEMX
232
        CRYP_HandleTypeDef hcryp;
233
    #else
234
        CRYP_InitTypeDef cryptInit;
235
        CRYP_KeyInitTypeDef keyInit;
236
    #endif
237
238
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
239
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
240
        if (ret < 0)
241
            return ret;
242
#endif
243
244
    #ifdef WOLFSSL_STM32U5_DHUK
245
        ret = wolfSSL_CryptHwMutexLock();
246
        if (ret != 0)
247
            return ret;
248
249
        /* Handle making use of wrapped key */
250
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
251
            CRYP_ConfigTypeDef Config = {0};
252
253
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key,
254
                aes->keylen, aes->dhukIV, aes->dhukIVLen);
255
            if (ret != HAL_OK) {
256
                WOLFSSL_MSG("Error with DHUK key unwrap");
257
                ret = BAD_FUNC_ARG;
258
            }
259
            /* reconfigure for using unwrapped key now */
260
            HAL_CRYP_GetConfig(&hcryp, &Config);
261
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
262
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
263
            Config.Algorithm = CRYP_AES_ECB;
264
            Config.DataType  = CRYP_DATATYPE_8B;
265
            Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
266
            HAL_CRYP_SetConfig(&hcryp, &Config);
267
        }
268
        else {
269
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
270
            if (ret == 0) {
271
                hcryp.Init.Algorithm  = CRYP_AES_ECB;
272
                ret = HAL_CRYP_Init(&hcryp);
273
                if (ret != HAL_OK) {
274
                    ret = BAD_FUNC_ARG;
275
                }
276
            }
277
        }
278
279
        if (ret == HAL_OK) {
280
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
281
                    (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
282
            if (ret != HAL_OK) {
283
                ret = WC_TIMEOUT_E;
284
            }
285
        }
286
        HAL_CRYP_DeInit(&hcryp);
287
    #elif defined(WOLFSSL_STM32_CUBEMX)
288
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
289
        if (ret != 0)
290
            return ret;
291
292
        ret = wolfSSL_CryptHwMutexLock();
293
        if (ret != 0)
294
            return ret;
295
296
    #if defined(STM32_HAL_V2)
297
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
298
    #elif defined(STM32_CRYPTO_AES_ONLY)
299
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
300
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
301
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
302
    #endif
303
        if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
304
            ret = BAD_FUNC_ARG;
305
        }
306
307
        if (ret == 0) {
308
        #if defined(STM32_HAL_V2)
309
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
310
                (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
311
        #elif defined(STM32_CRYPTO_AES_ONLY)
312
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
313
                outBlock, STM32_HAL_TIMEOUT);
314
        #else
315
            ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
316
                outBlock, STM32_HAL_TIMEOUT);
317
        #endif
318
            if (ret != HAL_OK) {
319
                ret = WC_TIMEOUT_E;
320
            }
321
            HAL_CRYP_DeInit(&hcryp);
322
        }
323
324
    #else /* Standard Peripheral Library */
325
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
326
        if (ret != 0)
327
            return ret;
328
329
        ret = wolfSSL_CryptHwMutexLock();
330
        if (ret != 0)
331
            return ret;
332
333
        /* reset registers to their default values */
334
        CRYP_DeInit();
335
336
        /* setup key */
337
        CRYP_KeyInit(&keyInit);
338
339
        /* set direction and mode */
340
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
341
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
342
        CRYP_Init(&cryptInit);
343
344
        /* enable crypto processor */
345
        CRYP_Cmd(ENABLE);
346
347
        /* flush IN/OUT FIFOs */
348
        CRYP_FIFOFlush();
349
350
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
351
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
352
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
353
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
354
355
        /* wait until the complete message has been processed */
356
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
357
358
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
359
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
360
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
361
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
362
363
        /* disable crypto processor */
364
        CRYP_Cmd(DISABLE);
365
    #endif /* WOLFSSL_STM32_CUBEMX */
366
        wolfSSL_CryptHwMutexUnLock();
367
        wc_Stm32_Aes_Cleanup();
368
369
        return ret;
370
    }
371
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
372
373
#ifdef HAVE_AES_DECRYPT
374
    #if defined(WOLFSSL_AES_DIRECT)
375
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
376
        Aes* aes, const byte* inBlock, byte* outBlock)
377
    {
378
        int ret = 0;
379
    #ifdef WOLFSSL_STM32_CUBEMX
380
        CRYP_HandleTypeDef hcryp;
381
    #else
382
        CRYP_InitTypeDef cryptInit;
383
        CRYP_KeyInitTypeDef keyInit;
384
    #endif
385
386
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
387
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
388
        if (ret < 0)
389
            return ret;
390
#endif
391
392
    #ifdef WOLFSSL_STM32U5_DHUK
393
        ret = wolfSSL_CryptHwMutexLock();
394
        if (ret != 0)
395
            return ret;
396
397
        /* Handle making use of wrapped key */
398
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
399
            CRYP_ConfigTypeDef Config;
400
401
            XMEMSET(&Config, 0, sizeof(Config));
402
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key,
403
                aes->keylen, aes->dhukIV, aes->dhukIVLen);
404
            if (ret != HAL_OK) {
405
                WOLFSSL_MSG("Error with DHUK unwrap");
406
                ret = BAD_FUNC_ARG;
407
            }
408
            /* reconfigure for using unwrapped key now */
409
            HAL_CRYP_GetConfig(&hcryp, &Config);
410
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
411
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
412
            Config.Algorithm = CRYP_AES_ECB;
413
            Config.DataType  = CRYP_DATATYPE_8B;
414
            Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
415
            HAL_CRYP_SetConfig(&hcryp, &Config);
416
        }
417
        else {
418
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
419
            if (ret == 0) {
420
                hcryp.Init.Algorithm  = CRYP_AES_ECB;
421
                ret = HAL_CRYP_Init(&hcryp);
422
                if (ret != HAL_OK) {
423
                    ret = BAD_FUNC_ARG;
424
                }
425
            }
426
        }
427
428
        if (ret == HAL_OK) {
429
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
430
                    (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
431
            if (ret != HAL_OK) {
432
                ret = WC_TIMEOUT_E;
433
            }
434
        }
435
        HAL_CRYP_DeInit(&hcryp);
436
    #elif defined(WOLFSSL_STM32_CUBEMX)
437
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
438
        if (ret != 0)
439
            return ret;
440
441
        ret = wolfSSL_CryptHwMutexLock();
442
        if (ret != 0)
443
            return ret;
444
445
    #if defined(STM32_HAL_V2)
446
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
447
    #elif defined(STM32_CRYPTO_AES_ONLY)
448
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
449
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
450
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
451
    #endif
452
        HAL_CRYP_Init(&hcryp);
453
454
    #if defined(STM32_HAL_V2)
455
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
456
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
457
    #elif defined(STM32_CRYPTO_AES_ONLY)
458
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
459
            outBlock, STM32_HAL_TIMEOUT);
460
    #else
461
        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
462
            outBlock, STM32_HAL_TIMEOUT);
463
    #endif
464
        if (ret != HAL_OK) {
465
            ret = WC_TIMEOUT_E;
466
        }
467
        HAL_CRYP_DeInit(&hcryp);
468
469
    #else /* Standard Peripheral Library */
470
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
471
        if (ret != 0)
472
            return ret;
473
474
        ret = wolfSSL_CryptHwMutexLock();
475
        if (ret != 0)
476
            return ret;
477
478
        /* reset registers to their default values */
479
        CRYP_DeInit();
480
481
        /* set direction and key */
482
        CRYP_KeyInit(&keyInit);
483
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
484
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
485
        CRYP_Init(&cryptInit);
486
487
        /* enable crypto processor */
488
        CRYP_Cmd(ENABLE);
489
490
        /* wait until decrypt key has been initialized */
491
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
492
493
        /* set direction and mode */
494
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
495
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
496
        CRYP_Init(&cryptInit);
497
498
        /* enable crypto processor */
499
        CRYP_Cmd(ENABLE);
500
501
        /* flush IN/OUT FIFOs */
502
        CRYP_FIFOFlush();
503
504
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
505
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
506
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
507
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
508
509
        /* wait until the complete message has been processed */
510
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
511
512
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
513
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
514
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
515
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
516
517
        /* disable crypto processor */
518
        CRYP_Cmd(DISABLE);
519
    #endif /* WOLFSSL_STM32_CUBEMX */
520
        wolfSSL_CryptHwMutexUnLock();
521
        wc_Stm32_Aes_Cleanup();
522
523
        return ret;
524
    }
525
    #endif /* WOLFSSL_AES_DIRECT */
526
#endif /* HAVE_AES_DECRYPT */
527
528
#elif defined(HAVE_COLDFIRE_SEC)
529
    /* Freescale Coldfire SEC support for CBC mode.
530
     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
531
    #include "sec.h"
532
    #include "mcf5475_sec.h"
533
    #include "mcf5475_siu.h"
534
#elif defined(FREESCALE_LTC)
535
    #include "fsl_ltc.h"
536
    #if defined(FREESCALE_LTC_AES_GCM)
537
        #undef NEED_AES_TABLES
538
        #undef GCM_TABLE
539
    #endif
540
541
        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
542
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
543
            Aes* aes, const byte* inBlock, byte* outBlock)
544
        {
545
            word32 keySize = 0;
546
            byte* key = (byte*)aes->key;
547
            int ret = wc_AesGetKeySize(aes, &keySize);
548
            if (ret != 0)
549
                return ret;
550
551
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
552
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
553
            if (ret < 0)
554
                return ret;
555
#endif
556
557
            if (wolfSSL_CryptHwMutexLock() == 0) {
558
                LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
559
                    key, keySize);
560
                wolfSSL_CryptHwMutexUnLock();
561
            }
562
            return 0;
563
        }
564
        #ifdef HAVE_AES_DECRYPT
565
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
566
            Aes* aes, const byte* inBlock, byte* outBlock)
567
        {
568
            word32 keySize = 0;
569
            byte* key = (byte*)aes->key;
570
            int ret = wc_AesGetKeySize(aes, &keySize);
571
            if (ret != 0)
572
                return ret;
573
574
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
575
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
576
            if (ret < 0)
577
                return ret;
578
#endif
579
580
            if (wolfSSL_CryptHwMutexLock() == 0) {
581
                LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
582
                    key, keySize, kLTC_EncryptKey);
583
                wolfSSL_CryptHwMutexUnLock();
584
            }
585
            return 0;
586
        }
587
        #endif
588
589
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
590
591
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
592
593
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
594
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
595
        Aes* aes, const byte* inBlock, byte* outBlock)
596
    {
597
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
598
        {
599
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
600
            if (ret < 0)
601
                return ret;
602
        }
603
#endif
604
        /* Thread mutex protection handled in Pic32Crypto */
605
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
606
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
607
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
608
    }
609
    #endif
610
611
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
612
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
613
        Aes* aes, const byte* inBlock, byte* outBlock)
614
    {
615
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
616
        {
617
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
618
            if (ret < 0)
619
                return ret;
620
        }
621
#endif
622
        /* Thread mutex protection handled in Pic32Crypto */
623
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
624
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
625
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
626
    }
627
    #endif
628
629
#elif defined(WOLFSSL_NRF51_AES)
630
    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
631
    #include "wolfssl/wolfcrypt/port/nrf51.h"
632
633
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
634
        Aes* aes, const byte* inBlock, byte* outBlock)
635
    {
636
        int ret;
637
638
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
639
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
640
        if (ret < 0)
641
            return ret;
642
#endif
643
644
        ret = wolfSSL_CryptHwMutexLock();
645
        if (ret == 0) {
646
            ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds,
647
                                    outBlock);
648
            wolfSSL_CryptHwMutexUnLock();
649
        }
650
        return ret;
651
    }
652
653
    #ifdef HAVE_AES_DECRYPT
654
        #error nRF51 AES Hardware does not support decrypt
655
    #endif /* HAVE_AES_DECRYPT */
656
657
#elif defined(WOLFSSL_ESP32_CRYPT) && \
658
     !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
659
    #include <esp_log.h>
660
    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
661
    #define TAG "aes"
662
663
    /* We'll use SW for fallback:
664
     *   unsupported key lengths. (e.g. ESP32-S3)
665
     *   chipsets not implemented.
666
     *   hardware busy. */
667
    #define NEED_AES_TABLES
668
    #define NEED_AES_HW_FALLBACK
669
    #define NEED_SOFTWARE_AES_SETKEY
670
    #undef  WOLFSSL_AES_DIRECT
671
    #define WOLFSSL_AES_DIRECT
672
673
    /* Encrypt: If we choose to never have a fallback to SW: */
674
    #if !defined(NEED_AES_HW_FALLBACK) && \
675
        (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
676
    /* calling this one when NO_AES_192 is defined */
677
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
678
        Aes* aes, const byte* inBlock, byte* outBlock)
679
    {
680
        int ret;
681
682
    #ifdef WC_DEBUG_CIPHER_LIFECYCLE
683
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
684
        if (ret < 0)
685
            return ret;
686
    #endif
687
688
        /* Thread mutex protection handled in esp_aes_hw_InUse */
689
    #ifdef NEED_AES_HW_FALLBACK
690
        if (wc_esp32AesSupportedKeyLen(aes)) {
691
            ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
692
        }
693
    #else
694
        ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
695
    #endif
696
        return ret;
697
    }
698
    #endif
699
700
    /* Decrypt: If we choose to never have a fallback to SW: */
701
    #if !defined(NEED_AES_HW_FALLBACK) && \
702
        (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
703
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
704
        Aes* aes, const byte* inBlock, byte* outBlock)
705
    {
706
        int ret = 0;
707
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
708
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
709
        if (ret < 0)
710
            return ret;
711
#endif
712
        /* Thread mutex protection handled in esp_aes_hw_InUse */
713
    #ifdef NEED_AES_HW_FALLBACK
714
        if (wc_esp32AesSupportedKeyLen(aes)) {
715
            ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
716
        }
717
        else {
718
            ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
719
        }
720
    #else
721
        /* if we don't need fallback, always use HW */
722
        ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
723
    #endif
724
        return ret;
725
    }
726
    #endif
727
728
#elif defined(WOLFSSL_AESNI)
729
730
    #define NEED_AES_TABLES
731
732
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
733
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
734
     */
735
736
    #ifndef AESNI_ALIGN
737
        #define AESNI_ALIGN 16
738
    #endif
739
740
    /* note that all write access to these static variables must be idempotent,
741
     * as arranged by Check_CPU_support_AES(), else they will be susceptible to
742
     * data races.
743
     */
744
    static int checkedAESNI = 0;
745
    static int haveAESNI  = 0;
746
    static cpuid_flags_t intel_flags = WC_CPUID_INITIALIZER;
747
748
    static WARN_UNUSED_RESULT int Check_CPU_support_AES(void)
749
    {
750
        cpuid_get_flags_ex(&intel_flags);
751
752
        return IS_INTEL_AESNI(intel_flags) != 0;
753
    }
754
755
756
    /* tell C compiler these are asm functions in case any mix up of ABI underscore
757
       prefix between clang/gcc/llvm etc */
758
    #ifdef HAVE_AES_CBC
759
        void AES_CBC_encrypt_AESNI(const unsigned char* in, unsigned char* out,
760
                             unsigned char* ivec, unsigned long length,
761
                             const unsigned char* KS, int nr)
762
                             XASM_LINK("AES_CBC_encrypt_AESNI");
763
764
        #ifdef HAVE_AES_DECRYPT
765
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
766
                void AES_CBC_decrypt_AESNI_by4(const unsigned char* in, unsigned char* out,
767
                                         unsigned char* ivec, unsigned long length,
768
                                         const unsigned char* KS, int nr)
769
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by4");
770
            #elif defined(WOLFSSL_AESNI_BY6)
771
                void AES_CBC_decrypt_AESNI_by6(const unsigned char* in, unsigned char* out,
772
                                         unsigned char* ivec, unsigned long length,
773
                                         const unsigned char* KS, int nr)
774
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by6");
775
            #else /* WOLFSSL_AESNI_BYx */
776
                void AES_CBC_decrypt_AESNI_by8(const unsigned char* in, unsigned char* out,
777
                                         unsigned char* ivec, unsigned long length,
778
                                         const unsigned char* KS, int nr)
779
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by8");
780
            #endif /* WOLFSSL_AESNI_BYx */
781
        #endif /* HAVE_AES_DECRYPT */
782
    #endif /* HAVE_AES_CBC */
783
784
    void AES_ECB_encrypt_AESNI(const unsigned char* in, unsigned char* out,
785
                         unsigned long length, const unsigned char* KS, int nr)
786
                         XASM_LINK("AES_ECB_encrypt_AESNI");
787
788
    #ifdef HAVE_AES_DECRYPT
789
        void AES_ECB_decrypt_AESNI(const unsigned char* in, unsigned char* out,
790
                             unsigned long length, const unsigned char* KS, int nr)
791
                             XASM_LINK("AES_ECB_decrypt_AESNI");
792
    #endif
793
794
    void AES_128_Key_Expansion_AESNI(const unsigned char* userkey,
795
                               unsigned char* key_schedule)
796
                               XASM_LINK("AES_128_Key_Expansion_AESNI");
797
798
    void AES_192_Key_Expansion_AESNI(const unsigned char* userkey,
799
                               unsigned char* key_schedule)
800
                               XASM_LINK("AES_192_Key_Expansion_AESNI");
801
802
    void AES_256_Key_Expansion_AESNI(const unsigned char* userkey,
803
                               unsigned char* key_schedule)
804
                               XASM_LINK("AES_256_Key_Expansion_AESNI");
805
806
807
    static WARN_UNUSED_RESULT int AES_set_encrypt_key_AESNI(
808
        const unsigned char *userKey, const int bits, Aes* aes)
809
    {
810
        int ret;
811
812
        ASSERT_SAVED_VECTOR_REGISTERS();
813
814
        if (!userKey || !aes)
815
            return BAD_FUNC_ARG;
816
817
        switch (bits) {
818
            case 128:
819
               AES_128_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 10;
820
               return 0;
821
            case 192:
822
               AES_192_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 12;
823
               return 0;
824
            case 256:
825
               AES_256_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 14;
826
               return 0;
827
            default:
828
                ret = BAD_FUNC_ARG;
829
        }
830
831
        return ret;
832
    }
833
834
    #ifdef HAVE_AES_DECRYPT
835
        static WARN_UNUSED_RESULT int AES_set_decrypt_key_AESNI(
836
            const unsigned char* userKey, const int bits, Aes* aes)
837
        {
838
            word32 nr;
839
            WC_DECLARE_VAR(temp_key, Aes, 1, 0);
840
            __m128i *Key_Schedule;
841
            __m128i *Temp_Key_Schedule;
842
843
            ASSERT_SAVED_VECTOR_REGISTERS();
844
845
            if (!userKey || !aes)
846
                return BAD_FUNC_ARG;
847
848
#ifdef WOLFSSL_SMALL_STACK
849
            if ((temp_key = (Aes *)XMALLOC(sizeof *aes, aes->heap,
850
                                           DYNAMIC_TYPE_AES)) == NULL)
851
                return MEMORY_E;
852
#endif
853
854
            if (AES_set_encrypt_key_AESNI(userKey,bits,temp_key)
855
                == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
856
                WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
857
                return BAD_FUNC_ARG;
858
            }
859
860
            Key_Schedule = (__m128i*)aes->key;
861
            Temp_Key_Schedule = (__m128i*)temp_key->key;
862
863
            nr = temp_key->rounds;
864
            aes->rounds = nr;
865
866
            Key_Schedule[nr] = Temp_Key_Schedule[0];
867
            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
868
            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
869
            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
870
            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
871
            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
872
            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
873
            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
874
            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
875
            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
876
877
            if (nr>10) {
878
                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
879
                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
880
            }
881
882
            if (nr>12) {
883
                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
884
                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
885
            }
886
887
            Key_Schedule[0] = Temp_Key_Schedule[nr];
888
889
            WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
890
891
            return 0;
892
        }
893
    #endif /* HAVE_AES_DECRYPT */
894
895
#elif defined(WOLFSSL_ARMASM)
896
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
897
static cpuid_flags_t cpuid_flags = WC_CPUID_INITIALIZER;
898
899
static void Check_CPU_support_HwCrypto(Aes* aes)
900
{
901
    cpuid_get_flags_ex(&cpuid_flags);
902
    aes->use_aes_hw_crypto = IS_AARCH64_AES(cpuid_flags);
903
#ifdef HAVE_AESGCM
904
    aes->use_pmull_hw_crypto = IS_AARCH64_PMULL(cpuid_flags);
905
    aes->use_sha3_hw_crypto = IS_AARCH64_SHA3(cpuid_flags);
906
#endif
907
}
908
#endif /* __aarch64__ && !WOLFSSL_ARMASM_NO_HW_CRYPTO */
909
910
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
911
    defined(WOLFSSL_AESGCM_STREAM)
912
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
913
    byte* outBlock)
914
{
915
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
916
#if !defined(__aarch64__)
917
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
918
#else
919
    if (aes->use_aes_hw_crypto) {
920
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
921
           (int)aes->rounds);
922
    }
923
    else
924
#endif /* !__aarch64__ */
925
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
926
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
927
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
928
    {
929
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
930
            (const unsigned char*)aes->key, aes->rounds);
931
    }
932
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
933
    {
934
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
935
            (int)aes->rounds);
936
    }
937
#endif
938
939
    return 0;
940
}
941
#endif
942
943
#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
944
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
945
    byte* outBlock)
946
{
947
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
948
#if !defined(__aarch64__)
949
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
950
#else
951
    if (aes->use_aes_hw_crypto) {
952
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
953
            (int)aes->rounds);
954
    }
955
    else
956
#endif /* !__aarch64__ */
957
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
958
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
959
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
960
    {
961
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
962
            (byte*)aes->key, (int)aes->rounds);
963
    }
964
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
965
    {
966
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
967
            (int)aes->rounds);
968
    }
969
#endif
970
    return 0;
971
}
972
#endif /* HAVE_AES_DECRYPT && WOLFSSL_AES_DIRECT */
973
974
#elif defined(FREESCALE_MMCAU)
975
    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
976
     * through the CAU/mmCAU library. Documentation located in
977
     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
978
     * Guide (See note in README). */
979
    #ifdef FREESCALE_MMCAU_CLASSIC
980
        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
981
        #include "cau_api.h"
982
    #else
983
        #include "fsl_mmcau.h"
984
    #endif
985
986
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
987
        Aes* aes, const byte* inBlock, byte* outBlock)
988
    {
989
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
990
        {
991
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
992
            if (ret < 0)
993
                return ret;
994
        }
995
#endif
996
997
        if (wolfSSL_CryptHwMutexLock() == 0) {
998
        #ifdef FREESCALE_MMCAU_CLASSIC
999
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1000
                WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
1001
                return BAD_ALIGN_E;
1002
            }
1003
            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1004
        #else
1005
            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1006
                                 outBlock);
1007
        #endif
1008
            wolfSSL_CryptHwMutexUnLock();
1009
        }
1010
        return 0;
1011
    }
1012
    #ifdef HAVE_AES_DECRYPT
1013
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1014
        Aes* aes, const byte* inBlock, byte* outBlock)
1015
    {
1016
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1017
        {
1018
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1019
            if (ret < 0)
1020
                return ret;
1021
        }
1022
#endif
1023
        if (wolfSSL_CryptHwMutexLock() == 0) {
1024
        #ifdef FREESCALE_MMCAU_CLASSIC
1025
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1026
                WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
1027
                return BAD_ALIGN_E;
1028
            }
1029
            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1030
        #else
1031
            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1032
                                 outBlock);
1033
        #endif
1034
            wolfSSL_CryptHwMutexUnLock();
1035
        }
1036
        return 0;
1037
    }
1038
    #endif /* HAVE_AES_DECRYPT */
1039
1040
#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
1041
        && !defined(WOLFSSL_QNX_CAAM)) || \
1042
      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
1043
        defined(HAVE_AESCCM))
1044
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1045
            Aes* aes, const byte* inBlock, byte* outBlock)
1046
        {
1047
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1048
            {
1049
                int ret =
1050
                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1051
                if (ret < 0)
1052
                    return ret;
1053
            }
1054
#endif
1055
            return wc_AesEncryptDirect(aes, outBlock, inBlock);
1056
        }
1057
1058
#elif defined(WOLFSSL_AFALG)
1059
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
1060
1061
#elif defined(WOLFSSL_DEVCRYPTO_AES)
1062
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
1063
1064
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
1065
    #include "hal_data.h"
1066
1067
    #ifndef WOLFSSL_SCE_AES256_HANDLE
1068
        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
1069
    #endif
1070
1071
    #ifndef WOLFSSL_SCE_AES192_HANDLE
1072
        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
1073
    #endif
1074
1075
    #ifndef WOLFSSL_SCE_AES128_HANDLE
1076
        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
1077
    #endif
1078
1079
    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
1080
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1081
    {
1082
        word32 ret;
1083
1084
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1085
                CRYPTO_WORD_ENDIAN_BIG) {
1086
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1087
        }
1088
1089
        switch (aes->keylen) {
1090
        #ifdef WOLFSSL_AES_128
1091
            case AES_128_KEY_SIZE:
1092
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
1093
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
1094
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1095
                        (word32*)outBlock);
1096
                break;
1097
        #endif
1098
        #ifdef WOLFSSL_AES_192
1099
            case AES_192_KEY_SIZE:
1100
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
1101
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
1102
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1103
                        (word32*)outBlock);
1104
                break;
1105
        #endif
1106
        #ifdef WOLFSSL_AES_256
1107
            case AES_256_KEY_SIZE:
1108
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
1109
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
1110
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1111
                        (word32*)outBlock);
1112
                break;
1113
        #endif
1114
            default:
1115
                WOLFSSL_MSG("Unknown key size");
1116
                return BAD_FUNC_ARG;
1117
        }
1118
1119
        if (ret != SSP_SUCCESS) {
1120
            /* revert input */
1121
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1122
            return WC_HW_E;
1123
        }
1124
1125
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1126
                CRYPTO_WORD_ENDIAN_BIG) {
1127
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1128
            if (inBlock != outBlock) {
1129
                /* revert input */
1130
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1131
            }
1132
        }
1133
        return 0;
1134
    }
1135
1136
    #if defined(HAVE_AES_DECRYPT)
1137
    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
1138
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1139
    {
1140
        word32 ret;
1141
1142
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1143
                CRYPTO_WORD_ENDIAN_BIG) {
1144
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1145
        }
1146
1147
        switch (aes->keylen) {
1148
        #ifdef WOLFSSL_AES_128
1149
            case AES_128_KEY_SIZE:
1150
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
1151
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
1152
                        (sz / sizeof(word32)), (word32*)inBlock,
1153
                        (word32*)outBlock);
1154
                break;
1155
        #endif
1156
        #ifdef WOLFSSL_AES_192
1157
            case AES_192_KEY_SIZE:
1158
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
1159
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
1160
                        (sz / sizeof(word32)), (word32*)inBlock,
1161
                        (word32*)outBlock);
1162
                break;
1163
        #endif
1164
        #ifdef WOLFSSL_AES_256
1165
            case AES_256_KEY_SIZE:
1166
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
1167
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
1168
                        (sz / sizeof(word32)), (word32*)inBlock,
1169
                        (word32*)outBlock);
1170
                break;
1171
        #endif
1172
            default:
1173
                WOLFSSL_MSG("Unknown key size");
1174
                return BAD_FUNC_ARG;
1175
        }
1176
        if (ret != SSP_SUCCESS) {
1177
            return WC_HW_E;
1178
        }
1179
1180
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1181
                CRYPTO_WORD_ENDIAN_BIG) {
1182
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1183
            if (inBlock != outBlock) {
1184
                /* revert input */
1185
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1186
            }
1187
        }
1188
1189
        return 0;
1190
    }
1191
    #endif /* HAVE_AES_DECRYPT */
1192
1193
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
1194
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1195
        Aes* aes, const byte* inBlock, byte* outBlock)
1196
    {
1197
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1198
        {
1199
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1200
            if (ret < 0)
1201
                return ret;
1202
        }
1203
#endif
1204
        return AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1205
    }
1206
    #endif
1207
1208
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1209
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1210
        Aes* aes, const byte* inBlock, byte* outBlock)
1211
    {
1212
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1213
        {
1214
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1215
            if (ret < 0)
1216
                return ret;
1217
        }
1218
#endif
1219
        return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1220
    }
1221
    #endif
1222
1223
#elif defined(WOLFSSL_KCAPI_AES)
1224
    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
1225
    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
1226
        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1227
        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
1228
        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
1229
        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
1230
1231
        #define NEED_AES_TABLES
1232
    #endif
1233
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
1234
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
1235
1236
#elif defined(WOLFSSL_RISCV_ASM)
1237
/* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
1238
1239
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1240
/* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
1241
1242
#elif defined(WOLFSSL_PSOC6_CRYPTO)
1243
1244
    #if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
1245
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1246
            Aes* aes, const byte* inBlock, byte* outBlock)
1247
        {
1248
            return wc_Psoc6_Aes_Encrypt(aes, inBlock, outBlock);
1249
        }
1250
    #endif
1251
1252
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1253
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
1254
            Aes* aes, const byte* inBlock, byte* outBlock)
1255
        {
1256
            return wc_Psoc6_Aes_Decrypt(aes, inBlock, outBlock);
1257
        }
1258
1259
    #endif
1260
#else
1261
1262
    /* using wolfCrypt software implementation */
1263
    #define NEED_AES_TABLES
1264
#endif
1265
1266
1267
1268
#if defined(WC_AES_BITSLICED) && !defined(HAVE_AES_ECB)
1269
    #error "When WC_AES_BITSLICED is defined, HAVE_AES_ECB is needed."
1270
#endif
1271
1272
#ifdef NEED_AES_TABLES
1273
1274
#ifndef WC_AES_BITSLICED
1275
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1276
#if !defined(WOLFSSL_ESP32_CRYPT) || \
1277
    (defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
1278
     defined(NEED_AES_HW_FALLBACK))
1279
static const FLASH_QUALIFIER word32 rcon[] = {
1280
    0x01000000, 0x02000000, 0x04000000, 0x08000000,
1281
    0x10000000, 0x20000000, 0x40000000, 0x80000000,
1282
    0x1B000000, 0x36000000,
1283
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1284
};
1285
#endif /* ESP32 */
1286
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1287
1288
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
1289
      defined(HAVE_AESCCM)
1290
#ifndef WOLFSSL_AES_SMALL_TABLES
1291
static const FLASH_QUALIFIER word32 Te[4][256] = {
1292
{
1293
    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1294
    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1295
    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1296
    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1297
    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1298
    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1299
    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1300
    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1301
    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1302
    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1303
    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1304
    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1305
    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1306
    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1307
    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1308
    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1309
    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1310
    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1311
    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1312
    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1313
    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1314
    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1315
    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1316
    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1317
    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1318
    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1319
    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1320
    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1321
    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1322
    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1323
    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1324
    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1325
    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1326
    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1327
    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1328
    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1329
    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1330
    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1331
    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1332
    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1333
    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1334
    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1335
    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1336
    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1337
    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1338
    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1339
    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1340
    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1341
    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1342
    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1343
    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1344
    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1345
    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1346
    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1347
    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1348
    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1349
    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1350
    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1351
    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1352
    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1353
    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1354
    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1355
    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1356
    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1357
},
1358
{
1359
    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1360
    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1361
    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1362
    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1363
    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1364
    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1365
    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1366
    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1367
    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1368
    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1369
    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1370
    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1371
    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1372
    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1373
    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1374
    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1375
    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1376
    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1377
    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1378
    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1379
    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1380
    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1381
    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1382
    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1383
    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1384
    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1385
    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1386
    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1387
    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1388
    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1389
    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1390
    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1391
    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1392
    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1393
    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1394
    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1395
    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1396
    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1397
    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1398
    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1399
    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1400
    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1401
    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1402
    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1403
    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1404
    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1405
    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1406
    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1407
    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1408
    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1409
    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1410
    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1411
    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1412
    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1413
    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1414
    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1415
    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1416
    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1417
    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1418
    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1419
    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1420
    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1421
    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1422
    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1423
},
1424
{
1425
    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1426
    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1427
    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1428
    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1429
    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1430
    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1431
    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1432
    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1433
    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1434
    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1435
    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1436
    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1437
    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1438
    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1439
    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1440
    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1441
    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1442
    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1443
    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1444
    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1445
    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1446
    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1447
    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1448
    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1449
    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1450
    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1451
    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1452
    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1453
    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1454
    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1455
    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1456
    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1457
    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1458
    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1459
    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1460
    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1461
    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1462
    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1463
    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1464
    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1465
    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1466
    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1467
    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1468
    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1469
    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1470
    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1471
    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1472
    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1473
    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1474
    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1475
    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1476
    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1477
    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1478
    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1479
    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1480
    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1481
    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1482
    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1483
    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1484
    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1485
    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1486
    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1487
    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1488
    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1489
},
1490
{
1491
    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1492
    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1493
    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1494
    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1495
    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1496
    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1497
    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1498
    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1499
    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1500
    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1501
    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1502
    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1503
    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1504
    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1505
    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1506
    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1507
    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1508
    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1509
    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1510
    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1511
    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1512
    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1513
    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1514
    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1515
    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1516
    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1517
    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1518
    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1519
    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1520
    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1521
    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1522
    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1523
    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1524
    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1525
    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1526
    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1527
    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1528
    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1529
    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1530
    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1531
    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1532
    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1533
    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1534
    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1535
    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1536
    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1537
    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1538
    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1539
    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1540
    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1541
    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1542
    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1543
    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1544
    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1545
    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1546
    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1547
    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1548
    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1549
    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1550
    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1551
    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1552
    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1553
    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1554
    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1555
}
1556
};
1557
1558
#ifdef HAVE_AES_DECRYPT
1559
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1560
static const FLASH_QUALIFIER word32 Td[4][256] = {
1561
{
1562
    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1563
    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1564
    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1565
    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1566
    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1567
    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1568
    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1569
    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1570
    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1571
    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1572
    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1573
    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1574
    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1575
    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1576
    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1577
    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1578
    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1579
    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1580
    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1581
    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1582
    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1583
    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1584
    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1585
    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1586
    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1587
    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1588
    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1589
    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1590
    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1591
    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1592
    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1593
    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1594
    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1595
    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1596
    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1597
    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1598
    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1599
    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1600
    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1601
    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1602
    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1603
    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1604
    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1605
    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1606
    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1607
    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1608
    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1609
    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1610
    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1611
    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1612
    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1613
    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1614
    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1615
    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1616
    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1617
    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1618
    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1619
    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1620
    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1621
    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1622
    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1623
    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1624
    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1625
    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1626
},
1627
{
1628
    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
1629
    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
1630
    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
1631
    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
1632
    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
1633
    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
1634
    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
1635
    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
1636
    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
1637
    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
1638
    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
1639
    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
1640
    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
1641
    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
1642
    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
1643
    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
1644
    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
1645
    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
1646
    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
1647
    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
1648
    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
1649
    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
1650
    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
1651
    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
1652
    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
1653
    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
1654
    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
1655
    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
1656
    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
1657
    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
1658
    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
1659
    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
1660
    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
1661
    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
1662
    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
1663
    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
1664
    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
1665
    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
1666
    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
1667
    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
1668
    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
1669
    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
1670
    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
1671
    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
1672
    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
1673
    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
1674
    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
1675
    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
1676
    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
1677
    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
1678
    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
1679
    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
1680
    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
1681
    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
1682
    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
1683
    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
1684
    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
1685
    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
1686
    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
1687
    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
1688
    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
1689
    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
1690
    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
1691
    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
1692
},
1693
{
1694
    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
1695
    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
1696
    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
1697
    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
1698
    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
1699
    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
1700
    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
1701
    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
1702
    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
1703
    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
1704
    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
1705
    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
1706
    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
1707
    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
1708
    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
1709
    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
1710
    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
1711
    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
1712
    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
1713
    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
1714
1715
    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
1716
    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
1717
    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
1718
    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
1719
    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
1720
    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
1721
    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
1722
    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
1723
    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
1724
    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
1725
    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
1726
    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
1727
    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
1728
    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
1729
    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
1730
    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
1731
    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
1732
    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
1733
    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
1734
    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
1735
    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
1736
    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
1737
    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
1738
    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
1739
    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
1740
    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
1741
    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
1742
    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
1743
    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
1744
    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
1745
    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
1746
    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
1747
    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
1748
    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
1749
    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
1750
    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
1751
    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
1752
    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
1753
    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
1754
    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
1755
    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
1756
    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
1757
    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
1758
    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
1759
},
1760
{
1761
    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
1762
    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
1763
    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
1764
    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
1765
    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
1766
    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
1767
    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
1768
    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
1769
    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
1770
    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
1771
    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
1772
    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
1773
    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
1774
    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
1775
    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
1776
    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
1777
    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
1778
    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
1779
    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
1780
    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
1781
    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
1782
    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
1783
    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
1784
    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
1785
    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
1786
    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
1787
    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
1788
    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
1789
    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
1790
    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
1791
    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
1792
    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
1793
    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
1794
    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
1795
    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
1796
    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
1797
    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
1798
    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
1799
    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
1800
    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
1801
    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
1802
    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
1803
    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
1804
    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
1805
    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
1806
    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
1807
    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
1808
    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
1809
    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
1810
    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
1811
    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
1812
    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
1813
    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
1814
    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
1815
    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
1816
    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
1817
    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
1818
    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
1819
    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
1820
    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
1821
    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
1822
    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
1823
    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
1824
    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
1825
}
1826
};
1827
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1828
#endif /* HAVE_AES_DECRYPT */
1829
#endif /* WOLFSSL_AES_SMALL_TABLES */
1830
1831
#ifdef HAVE_AES_DECRYPT
1832
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
1833
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)
1834
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1835
static const FLASH_QUALIFIER byte Td4[256] =
1836
{
1837
    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
1838
    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
1839
    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
1840
    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
1841
    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
1842
    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
1843
    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
1844
    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
1845
    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
1846
    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
1847
    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
1848
    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
1849
    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
1850
    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
1851
    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
1852
    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
1853
    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
1854
    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
1855
    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
1856
    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
1857
    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
1858
    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
1859
    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
1860
    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
1861
    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
1862
    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
1863
    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
1864
    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
1865
    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
1866
    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
1867
    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
1868
    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
1869
};
1870
#endif
1871
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1872
#endif /* HAVE_AES_DECRYPT */
1873
1874
#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
1875
1876
#ifdef WOLFSSL_AES_SMALL_TABLES
1877
static const byte Tsbox[256] = {
1878
    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
1879
    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
1880
    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
1881
    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
1882
    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
1883
    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
1884
    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
1885
    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
1886
    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
1887
    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
1888
    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
1889
    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
1890
    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
1891
    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
1892
    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
1893
    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
1894
    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
1895
    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
1896
    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
1897
    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
1898
    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
1899
    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
1900
    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
1901
    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
1902
    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
1903
    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
1904
    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
1905
    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
1906
    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
1907
    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
1908
    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
1909
    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
1910
};
1911
1912
#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
1913
1914
static WARN_UNUSED_RESULT word32 col_mul(
1915
    word32 t, int i2, int i3, int ia, int ib)
1916
{
1917
    byte t3 = GETBYTE(t, i3);
1918
    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
1919
1920
    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
1921
}
1922
1923
#if defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
1924
    defined(WOLFSSL_AES_DIRECT)
1925
static WARN_UNUSED_RESULT word32 inv_col_mul(
1926
    word32 t, int i9, int ib, int id, int ie)
1927
{
1928
    byte t9 = GETBYTE(t, i9);
1929
    byte tb = GETBYTE(t, ib);
1930
    byte td = GETBYTE(t, id);
1931
    byte te = GETBYTE(t, ie);
1932
    byte t0 = t9 ^ tb ^ td;
1933
    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
1934
}
1935
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1936
#endif /* WOLFSSL_AES_SMALL_TABLES */
1937
#endif
1938
#endif
1939
1940
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
1941
                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
1942
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
1943
      defined(HAVE_AESCCM)
1944
1945
1946
#ifndef WC_AES_BITSLICED
1947
1948
#ifndef WC_CACHE_LINE_SZ
1949
    #if defined(__x86_64__) || defined(_M_X64) || \
1950
       (defined(__ILP32__) && (__ILP32__ >= 1))
1951
1.90M
        #define WC_CACHE_LINE_SZ 64
1952
    #else
1953
        /* default cache line size */
1954
        #define WC_CACHE_LINE_SZ 32
1955
    #endif
1956
#endif
1957
1958
#ifndef WC_NO_CACHE_RESISTANT
1959
1960
#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
1961
    #define WOLFSSL_AES_TOUCH_LINES
1962
#endif
1963
1964
#ifndef WOLFSSL_AES_SMALL_TABLES
1965
/* load 4 Te Tables into cache by cache line stride */
1966
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
1967
28.9k
{
1968
28.9k
#ifndef WOLFSSL_AES_TOUCH_LINES
1969
28.9k
    volatile word32 x = 0;
1970
28.9k
    int i;
1971
28.9k
    int j;
1972
1973
144k
    for (i = 0; i < 4; i++) {
1974
        /* 256 elements, each one is 4 bytes */
1975
1.96M
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
1976
1.85M
            x &= Te[i][j];
1977
1.85M
        }
1978
115k
    }
1979
1980
28.9k
    return x;
1981
#else
1982
    return 0;
1983
#endif
1984
28.9k
}
1985
#else
1986
/* load sbox into cache by cache line stride */
1987
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
1988
{
1989
#ifndef WOLFSSL_AES_TOUCH_LINES
1990
    volatile word32 x = 0;
1991
    int i;
1992
1993
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
1994
        x &= Tsbox[i];
1995
    }
1996
1997
    return x;
1998
#else
1999
    return 0;
2000
#endif
2001
}
2002
#endif
2003
#endif
2004
2005
#ifdef WOLFSSL_AES_TOUCH_LINES
2006
#if WC_CACHE_LINE_SZ == 128
2007
    #define WC_CACHE_LINE_BITS      5
2008
    #define WC_CACHE_LINE_MASK_HI   0xe0
2009
    #define WC_CACHE_LINE_MASK_LO   0x1f
2010
    #define WC_CACHE_LINE_ADD       0x20
2011
#elif WC_CACHE_LINE_SZ == 64
2012
    #define WC_CACHE_LINE_BITS      4
2013
    #define WC_CACHE_LINE_MASK_HI   0xf0
2014
    #define WC_CACHE_LINE_MASK_LO   0x0f
2015
    #define WC_CACHE_LINE_ADD       0x10
2016
#elif WC_CACHE_LINE_SZ == 32
2017
    #define WC_CACHE_LINE_BITS      3
2018
    #define WC_CACHE_LINE_MASK_HI   0xf8
2019
    #define WC_CACHE_LINE_MASK_LO   0x07
2020
    #define WC_CACHE_LINE_ADD       0x08
2021
#elif WC_CACHE_LINE_SZ == 16
2022
    #define WC_CACHE_LINE_BITS      2
2023
    #define WC_CACHE_LINE_MASK_HI   0xfc
2024
    #define WC_CACHE_LINE_MASK_LO   0x03
2025
    #define WC_CACHE_LINE_ADD       0x04
2026
#else
2027
    #error Cache line size not supported
2028
#endif
2029
2030
#ifndef WOLFSSL_AES_SMALL_TABLES
2031
static word32 GetTable(const word32* t, byte o)
2032
{
2033
#if WC_CACHE_LINE_SZ == 64
2034
    word32 e;
2035
    byte hi = o & 0xf0;
2036
    byte lo = o & 0x0f;
2037
2038
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2039
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2040
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2041
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2042
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2043
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2044
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2045
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2046
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2047
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2048
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2049
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2050
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2051
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2052
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2053
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2054
2055
    return e;
2056
#else
2057
    word32 e = 0;
2058
    int i;
2059
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2060
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2061
2062
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2063
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2064
        hi -= WC_CACHE_LINE_ADD;
2065
    }
2066
2067
    return e;
2068
#endif
2069
}
2070
#endif
2071
2072
#ifdef WOLFSSL_AES_SMALL_TABLES
2073
static byte GetTable8(const byte* t, byte o)
2074
{
2075
#if WC_CACHE_LINE_SZ == 64
2076
    byte e;
2077
    byte hi = o & 0xf0;
2078
    byte lo = o & 0x0f;
2079
2080
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2081
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2082
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2083
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2084
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2085
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2086
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2087
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2088
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2089
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2090
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2091
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2092
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2093
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2094
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2095
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2096
2097
    return e;
2098
#else
2099
    byte e = 0;
2100
    int i;
2101
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2102
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2103
2104
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2105
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2106
        hi -= WC_CACHE_LINE_ADD;
2107
    }
2108
2109
    return e;
2110
#endif
2111
}
2112
#endif
2113
2114
#ifndef WOLFSSL_AES_SMALL_TABLES
2115
static void GetTable_Multi(const word32* t, word32* t0, byte o0,
2116
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2117
{
2118
    word32 e0 = 0;
2119
    word32 e1 = 0;
2120
    word32 e2 = 0;
2121
    word32 e3 = 0;
2122
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2123
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2124
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2125
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2126
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2127
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2128
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2129
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2130
    int i;
2131
2132
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2133
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2134
        hi0 -= WC_CACHE_LINE_ADD;
2135
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2136
        hi1 -= WC_CACHE_LINE_ADD;
2137
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2138
        hi2 -= WC_CACHE_LINE_ADD;
2139
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2140
        hi3 -= WC_CACHE_LINE_ADD;
2141
    }
2142
    *t0 = e0;
2143
    *t1 = e1;
2144
    *t2 = e2;
2145
    *t3 = e3;
2146
}
2147
static void XorTable_Multi(const word32* t, word32* t0, byte o0,
2148
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2149
{
2150
    word32 e0 = 0;
2151
    word32 e1 = 0;
2152
    word32 e2 = 0;
2153
    word32 e3 = 0;
2154
    byte hi0 = o0 & 0xf0;
2155
    byte lo0 = o0 & 0x0f;
2156
    byte hi1 = o1 & 0xf0;
2157
    byte lo1 = o1 & 0x0f;
2158
    byte hi2 = o2 & 0xf0;
2159
    byte lo2 = o2 & 0x0f;
2160
    byte hi3 = o3 & 0xf0;
2161
    byte lo3 = o3 & 0x0f;
2162
    int i;
2163
2164
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2165
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2166
        hi0 -= WC_CACHE_LINE_ADD;
2167
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2168
        hi1 -= WC_CACHE_LINE_ADD;
2169
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2170
        hi2 -= WC_CACHE_LINE_ADD;
2171
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2172
        hi3 -= WC_CACHE_LINE_ADD;
2173
    }
2174
    *t0 ^= e0;
2175
    *t1 ^= e1;
2176
    *t2 ^= e2;
2177
    *t3 ^= e3;
2178
}
2179
static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
2180
{
2181
    word32 e = 0;
2182
    int i;
2183
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2184
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2185
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2186
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2187
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2188
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2189
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2190
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2191
2192
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2193
        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
2194
             << 24;
2195
        hi0 -= WC_CACHE_LINE_ADD;
2196
        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
2197
             << 16;
2198
        hi1 -= WC_CACHE_LINE_ADD;
2199
        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
2200
             <<  8;
2201
        hi2 -= WC_CACHE_LINE_ADD;
2202
        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
2203
             <<  0;
2204
        hi3 -= WC_CACHE_LINE_ADD;
2205
    }
2206
2207
    return e;
2208
}
2209
#endif
2210
#else
2211
2212
45.7M
#define GetTable(t, o)  t[o]
2213
#define GetTable8(t, o) t[o]
2214
#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2215
    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
2216
#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2217
    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
2218
#define GetTable8_4(t, o0, o1, o2, o3) \
2219
52.5k
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
2220
52.5k
     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
2221
#endif
2222
2223
#ifndef HAVE_CUDA
2224
/* Encrypt a block using AES.
2225
 *
2226
 * @param [in]  aes       AES object.
2227
 * @param [in]  inBlock   Block to encrypt.
2228
 * @param [out] outBlock  Encrypted block.
2229
 * @param [in]  r         Rounds divided by 2.
2230
 */
2231
#define WC_AES_HAVE_PREFETCH_ARG
2232
static int always_prefetch = 0;
2233
WC_MAYBE_UNUSED static int never_prefetch = 1;
2234
WC_ARGS_NOT_NULL((1, 2, 3, 5))
2235
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2236
        word32 r, int *prefetch_ptr)
2237
239k
{
2238
239k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
2239
239k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
2240
239k
    const word32* rk;
2241
2242
#ifdef WC_C_DYNAMIC_FALLBACK
2243
    rk = aes->key_C_fallback;
2244
#else
2245
239k
    rk = aes->key;
2246
239k
#endif
2247
2248
    /*
2249
     * map byte array block to cipher state
2250
     * and add initial round key:
2251
     */
2252
239k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
2253
239k
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
2254
239k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
2255
239k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
2256
2257
239k
#ifdef LITTLE_ENDIAN_ORDER
2258
239k
    s0 = ByteReverseWord32(s0);
2259
239k
    s1 = ByteReverseWord32(s1);
2260
239k
    s2 = ByteReverseWord32(s2);
2261
239k
    s3 = ByteReverseWord32(s3);
2262
239k
#endif
2263
2264
    /* AddRoundKey */
2265
239k
    s0 ^= rk[0];
2266
239k
    s1 ^= rk[1];
2267
239k
    s2 ^= rk[2];
2268
239k
    s3 ^= rk[3];
2269
2270
239k
#ifndef WOLFSSL_AES_SMALL_TABLES
2271
2272
239k
#ifndef WC_NO_CACHE_RESISTANT
2273
239k
    if (*prefetch_ptr == 0) {
2274
28.9k
        s0 |= PreFetchTe();
2275
28.9k
        if (prefetch_ptr != &always_prefetch)
2276
7.17k
            *prefetch_ptr = 1;
2277
28.9k
    }
2278
#else
2279
    (void)prefetch_ptr;
2280
#endif
2281
2282
239k
#ifndef WOLFSSL_AES_TOUCH_LINES
2283
239k
#define ENC_ROUND_T_S(o)                                                       \
2284
1.34M
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
2285
1.34M
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
2286
1.34M
         rk[(o)+4];                                                            \
2287
1.34M
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
2288
1.34M
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
2289
1.34M
         rk[(o)+5];                                                            \
2290
1.34M
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
2291
1.34M
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
2292
1.34M
         rk[(o)+6];                                                            \
2293
1.34M
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
2294
1.34M
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
2295
1.34M
         rk[(o)+7]
2296
239k
#define ENC_ROUND_S_T(o)                                                       \
2297
1.10M
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
2298
1.10M
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
2299
1.10M
         rk[(o)+0];                                                            \
2300
1.10M
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
2301
1.10M
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
2302
1.10M
         rk[(o)+1];                                                            \
2303
1.10M
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
2304
1.10M
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
2305
1.10M
         rk[(o)+2];                                                            \
2306
1.10M
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
2307
1.10M
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
2308
1.10M
         rk[(o)+3]
2309
#else
2310
#define ENC_ROUND_T_S(o)                                                       \
2311
    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
2312
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
2313
    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
2314
                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
2315
    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
2316
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
2317
    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
2318
                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
2319
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
2320
2321
#define ENC_ROUND_S_T(o)                                                       \
2322
    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
2323
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
2324
    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
2325
                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
2326
    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
2327
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2328
    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
2329
                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
2330
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2331
#endif
2332
2333
239k
#ifndef WOLFSSL_AES_NO_UNROLL
2334
/* Unroll the loop. */
2335
239k
                       ENC_ROUND_T_S( 0);
2336
239k
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2337
239k
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2338
239k
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2339
239k
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2340
239k
    if (r > 5) {
2341
77.4k
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2342
77.4k
        if (r > 6) {
2343
66.4k
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2344
66.4k
        }
2345
77.4k
    }
2346
239k
    rk += r * 8;
2347
#else
2348
    /*
2349
     * Nr - 1 full rounds:
2350
     */
2351
2352
    for (;;) {
2353
        ENC_ROUND_T_S(0);
2354
2355
        rk += 8;
2356
        if (--r == 0) {
2357
            break;
2358
        }
2359
2360
        ENC_ROUND_S_T(0);
2361
    }
2362
#endif
2363
2364
    /*
2365
     * apply last round and
2366
     * map cipher state to byte array block:
2367
     */
2368
2369
239k
#ifndef WOLFSSL_AES_TOUCH_LINES
2370
239k
    s0 =
2371
239k
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2372
239k
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2373
239k
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2374
239k
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2375
239k
        rk[0];
2376
239k
    s1 =
2377
239k
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2378
239k
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2379
239k
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2380
239k
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2381
239k
        rk[1];
2382
239k
    s2 =
2383
239k
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2384
239k
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2385
239k
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2386
239k
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2387
239k
        rk[2];
2388
239k
    s3 =
2389
239k
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2390
239k
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2391
239k
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2392
239k
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2393
239k
        rk[3];
2394
#else
2395
{
2396
    word32 u0;
2397
    word32 u1;
2398
    word32 u2;
2399
    word32 u3;
2400
2401
    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
2402
    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
2403
                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
2404
    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
2405
    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
2406
    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
2407
                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
2408
    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
2409
    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
2410
    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
2411
                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
2412
    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
2413
    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
2414
    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
2415
                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
2416
    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
2417
    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
2418
}
2419
#endif
2420
2421
#else /* WOLFSSL_AES_SMALL_TABLES */
2422
2423
#ifndef WC_NO_CACHE_RESISTANT
2424
    if (*prefetch_ptr == 0) {
2425
        s0 |= PreFetchSBox();
2426
        if (prefetch_ptr != &always_prefetch)
2427
            *prefetch_ptr = 1;
2428
    }
2429
#else
2430
    (void)prefetch_ptr;
2431
#endif
2432
2433
    r *= 2;
2434
    /* Two rounds at a time */
2435
    for (rk += 4; r > 1; r--, rk += 4) {
2436
        t0 =
2437
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2438
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2439
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2440
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2441
        t1 =
2442
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2443
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2444
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2445
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2446
        t2 =
2447
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2448
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2449
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2450
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2451
        t3 =
2452
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2453
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2454
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2455
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2456
2457
        s0 =
2458
            (col_mul(t0, 3, 2, 0, 1) << 24) ^
2459
            (col_mul(t0, 2, 1, 0, 3) << 16) ^
2460
            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
2461
            (col_mul(t0, 0, 3, 2, 1)      ) ^
2462
            rk[0];
2463
        s1 =
2464
            (col_mul(t1, 3, 2, 0, 1) << 24) ^
2465
            (col_mul(t1, 2, 1, 0, 3) << 16) ^
2466
            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
2467
            (col_mul(t1, 0, 3, 2, 1)      ) ^
2468
            rk[1];
2469
        s2 =
2470
            (col_mul(t2, 3, 2, 0, 1) << 24) ^
2471
            (col_mul(t2, 2, 1, 0, 3) << 16) ^
2472
            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
2473
            (col_mul(t2, 0, 3, 2, 1)      ) ^
2474
            rk[2];
2475
        s3 =
2476
            (col_mul(t3, 3, 2, 0, 1) << 24) ^
2477
            (col_mul(t3, 2, 1, 0, 3) << 16) ^
2478
            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
2479
            (col_mul(t3, 0, 3, 2, 1)      ) ^
2480
            rk[3];
2481
    }
2482
2483
    t0 =
2484
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2485
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2486
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2487
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2488
    t1 =
2489
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2490
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2491
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2492
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2493
    t2 =
2494
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2495
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2496
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2497
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2498
    t3 =
2499
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2500
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2501
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2502
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2503
    s0 = t0 ^ rk[0];
2504
    s1 = t1 ^ rk[1];
2505
    s2 = t2 ^ rk[2];
2506
    s3 = t3 ^ rk[3];
2507
2508
#endif /* WOLFSSL_AES_SMALL_TABLES */
2509
2510
    /* write out */
2511
239k
#ifdef LITTLE_ENDIAN_ORDER
2512
239k
    s0 = ByteReverseWord32(s0);
2513
239k
    s1 = ByteReverseWord32(s1);
2514
239k
    s2 = ByteReverseWord32(s2);
2515
239k
    s3 = ByteReverseWord32(s3);
2516
239k
#endif
2517
2518
239k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2519
239k
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2520
239k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2521
239k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2522
239k
}
2523
2524
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2525
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
2526
    !defined(MAX3266X_AES)
2527
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
2528
/* Encrypt a number of blocks using AES.
2529
 *
2530
 * @param [in]  aes  AES object.
2531
 * @param [in]  in   Block to encrypt.
2532
 * @param [out] out  Encrypted block.
2533
 * @param [in]  sz   Number of blocks to encrypt.
2534
 */
2535
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2536
1.17k
{
2537
1.17k
    word32 i;
2538
1.17k
    int did_prefetches = 0;
2539
2540
13.0k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
2541
11.8k
        AesEncrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
2542
11.8k
        in += WC_AES_BLOCK_SIZE;
2543
11.8k
        out += WC_AES_BLOCK_SIZE;
2544
11.8k
    }
2545
1.17k
}
2546
#endif
2547
#endif
2548
#else
2549
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2550
        word32 r);
2551
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2552
#endif /* HAVE_CUDA */
2553
2554
#else
2555
2556
/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
2557
 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
2558
 */
2559
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
2560
static void bs_sub_bytes(bs_word u[8])
2561
{
2562
    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
2563
    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
2564
    bs_word y20, y21;
2565
    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
2566
    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
2567
    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
2568
    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
2569
    bs_word t40, t41, t42, t43, t44, t45;
2570
    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
2571
    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
2572
    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
2573
    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
2574
    bs_word tc20, tc21, tc26;
2575
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
2576
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
2577
2578
    U0 = u[7];
2579
    U1 = u[6];
2580
    U2 = u[5];
2581
    U3 = u[4];
2582
    U4 = u[3];
2583
    U5 = u[2];
2584
    U6 = u[1];
2585
    U7 = u[0];
2586
2587
    y14 = U3 ^ U5;
2588
    y13 = U0 ^ U6;
2589
    y9 = U0 ^ U3;
2590
    y8 = U0 ^ U5;
2591
    t0 = U1 ^ U2;
2592
    y1 = t0 ^ U7;
2593
    y4 = y1 ^ U3;
2594
    y12 = y13 ^ y14;
2595
    y2 = y1 ^ U0;
2596
    y5 = y1 ^ U6;
2597
    y3 = y5 ^ y8;
2598
    t1 = U4 ^ y12;
2599
    y15 = t1 ^ U5;
2600
    y20 = t1 ^ U1;
2601
    y6 = y15 ^ U7;
2602
    y10 = y15 ^ t0;
2603
    y11 = y20 ^ y9;
2604
    y7 = U7 ^ y11;
2605
    y17 = y10 ^ y11;
2606
    y19 = y10 ^ y8;
2607
    y16 = t0 ^ y11;
2608
    y21 = y13 ^ y16;
2609
    y18 = U0 ^ y16;
2610
    t2 = y12 & y15;
2611
    t3 = y3 & y6;
2612
    t4 = t3 ^ t2;
2613
    t5 = y4 & U7;
2614
    t6 = t5 ^ t2;
2615
    t7 = y13 & y16;
2616
    t8 = y5 & y1;
2617
    t9 = t8 ^ t7;
2618
    t10 = y2 & y7;
2619
    t11 = t10 ^ t7;
2620
    t12 = y9 & y11;
2621
    t13 = y14 & y17;
2622
    t14 = t13 ^ t12;
2623
    t15 = y8 & y10;
2624
    t16 = t15 ^ t12;
2625
    t17 = t4 ^ y20;
2626
    t18 = t6 ^ t16;
2627
    t19 = t9 ^ t14;
2628
    t20 = t11 ^ t16;
2629
    t21 = t17 ^ t14;
2630
    t22 = t18 ^ y19;
2631
    t23 = t19 ^ y21;
2632
    t24 = t20 ^ y18;
2633
    t25 = t21 ^ t22;
2634
    t26 = t21 & t23;
2635
    t27 = t24 ^ t26;
2636
    t28 = t25 & t27;
2637
    t29 = t28 ^ t22;
2638
    t30 = t23 ^ t24;
2639
    t31 = t22 ^ t26;
2640
    t32 = t31 & t30;
2641
    t33 = t32 ^ t24;
2642
    t34 = t23 ^ t33;
2643
    t35 = t27 ^ t33;
2644
    t36 = t24 & t35;
2645
    t37 = t36 ^ t34;
2646
    t38 = t27 ^ t36;
2647
    t39 = t29 & t38;
2648
    t40 = t25 ^ t39;
2649
    t41 = t40 ^ t37;
2650
    t42 = t29 ^ t33;
2651
    t43 = t29 ^ t40;
2652
    t44 = t33 ^ t37;
2653
    t45 = t42 ^ t41;
2654
    z0 = t44 & y15;
2655
    z1 = t37 & y6;
2656
    z2 = t33 & U7;
2657
    z3 = t43 & y16;
2658
    z4 = t40 & y1;
2659
    z5 = t29 & y7;
2660
    z6 = t42 & y11;
2661
    z7 = t45 & y17;
2662
    z8 = t41 & y10;
2663
    z9 = t44 & y12;
2664
    z10 = t37 & y3;
2665
    z11 = t33 & y4;
2666
    z12 = t43 & y13;
2667
    z13 = t40 & y5;
2668
    z14 = t29 & y2;
2669
    z15 = t42 & y9;
2670
    z16 = t45 & y14;
2671
    z17 = t41 & y8;
2672
    tc1 = z15 ^ z16;
2673
    tc2 = z10 ^ tc1;
2674
    tc3 = z9 ^ tc2;
2675
    tc4 = z0 ^ z2;
2676
    tc5 = z1 ^ z0;
2677
    tc6 = z3 ^ z4;
2678
    tc7 = z12 ^ tc4;
2679
    tc8 = z7 ^ tc6;
2680
    tc9 = z8 ^ tc7;
2681
    tc10 = tc8 ^ tc9;
2682
    tc11 = tc6 ^ tc5;
2683
    tc12 = z3 ^ z5;
2684
    tc13 = z13 ^ tc1;
2685
    tc14 = tc4 ^ tc12;
2686
    S3 = tc3 ^ tc11;
2687
    tc16 = z6 ^ tc8;
2688
    tc17 = z14 ^ tc10;
2689
    tc18 = tc13 ^ tc14;
2690
    S7 = ~(z12 ^ tc18);
2691
    tc20 = z15 ^ tc16;
2692
    tc21 = tc2 ^ z11;
2693
    S0 = tc3 ^ tc16;
2694
    S6 = ~(tc10 ^ tc18);
2695
    S4 = tc14 ^ S3;
2696
    S1 = ~(S3 ^ tc16);
2697
    tc26 = tc17 ^ tc20;
2698
    S2 = ~(tc26 ^ z17);
2699
    S5 = tc21 ^ tc17;
2700
2701
    u[0] = S7;
2702
    u[1] = S6;
2703
    u[2] = S5;
2704
    u[3] = S4;
2705
    u[4] = S3;
2706
    u[5] = S2;
2707
    u[6] = S1;
2708
    u[7] = S0;
2709
}
2710
2711
#define BS_MASK_BIT_SET(w, j, bmask) \
2712
    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
2713
2714
#define BS_TRANS_8(t, o, w, bmask, s)                   \
2715
    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
2716
    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
2717
    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
2718
    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
2719
    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
2720
    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
2721
    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
2722
    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2723
2724
static void bs_transpose(bs_word* t, bs_word* blocks)
2725
{
2726
    bs_word bmask = 1;
2727
    int i;
2728
2729
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2730
2731
    for (i = 0; i < BS_WORD_SIZE; i++) {
2732
        int j;
2733
        int o = 0;
2734
        for (j = 0; j < BS_BLOCK_WORDS; j++) {
2735
        #ifdef LITTLE_ENDIAN_ORDER
2736
            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
2737
        #else
2738
            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
2739
        #endif
2740
    #ifdef WOLFSSL_AES_NO_UNROLL
2741
            int k;
2742
            for (k = 0; k < BS_WORD_SIZE; k++) {
2743
                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
2744
            }
2745
    #else
2746
            BS_TRANS_8(t, o, w, bmask,  0);
2747
        #if BS_WORD_SIZE >= 16
2748
            BS_TRANS_8(t, o, w, bmask,  8);
2749
        #endif
2750
        #if BS_WORD_SIZE >= 32
2751
            BS_TRANS_8(t, o, w, bmask, 16);
2752
            BS_TRANS_8(t, o, w, bmask, 24);
2753
        #endif
2754
        #if BS_WORD_SIZE >= 64
2755
            BS_TRANS_8(t, o, w, bmask, 32);
2756
            BS_TRANS_8(t, o, w, bmask, 40);
2757
            BS_TRANS_8(t, o, w, bmask, 48);
2758
            BS_TRANS_8(t, o, w, bmask, 56);
2759
        #endif
2760
    #endif
2761
            o += BS_WORD_SIZE;
2762
        }
2763
        bmask <<= 1;
2764
    }
2765
}
2766
2767
#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
2768
    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
2769
    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
2770
    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
2771
    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
2772
    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
2773
    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
2774
    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
2775
    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2776
2777
static void bs_inv_transpose(bs_word* t, bs_word* blocks)
2778
{
2779
    int o;
2780
2781
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2782
2783
    for (o = 0; o < BS_BLOCK_WORDS; o++) {
2784
        int i;
2785
        for (i = 0; i < BS_WORD_SIZE; i++) {
2786
        #ifdef LITTLE_ENDIAN_ORDER
2787
            bs_word bmask = (bs_word)1 << i;
2788
        #else
2789
            bs_word bmask = bs_bswap((bs_word)1 << i);
2790
        #endif
2791
            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
2792
    #ifdef WOLFSSL_AES_NO_UNROLL
2793
            int j;
2794
            for (j = 0; j < BS_WORD_SIZE; j++) {
2795
                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
2796
            }
2797
    #else
2798
            BS_INV_TRANS_8(t, o, w, bmask, 0);
2799
        #if BS_WORD_SIZE >= 16
2800
            BS_INV_TRANS_8(t, o, w, bmask, 8);
2801
        #endif
2802
        #if BS_WORD_SIZE >= 32
2803
            BS_INV_TRANS_8(t, o, w, bmask, 16);
2804
            BS_INV_TRANS_8(t, o, w, bmask, 24);
2805
        #endif
2806
        #if BS_WORD_SIZE >= 64
2807
            BS_INV_TRANS_8(t, o, w, bmask, 32);
2808
            BS_INV_TRANS_8(t, o, w, bmask, 40);
2809
            BS_INV_TRANS_8(t, o, w, bmask, 48);
2810
            BS_INV_TRANS_8(t, o, w, bmask, 56);
2811
        #endif
2812
    #endif
2813
        }
2814
    }
2815
}
2816
2817
#define BS_ROW_OFF_0    0
2818
#define BS_ROW_OFF_1    32
2819
#define BS_ROW_OFF_2    64
2820
#define BS_ROW_OFF_3    96
2821
2822
#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
2823
#define BS_IDX_MASK     0x7f
2824
2825
#define BS_ASSIGN_8(d, od, s, os)   \
2826
    d[(od) + 0] = s[(os) + 0];      \
2827
    d[(od) + 1] = s[(os) + 1];      \
2828
    d[(od) + 2] = s[(os) + 2];      \
2829
    d[(od) + 3] = s[(os) + 3];      \
2830
    d[(od) + 4] = s[(os) + 4];      \
2831
    d[(od) + 5] = s[(os) + 5];      \
2832
    d[(od) + 6] = s[(os) + 6];      \
2833
    d[(od) + 7] = s[(os) + 7]
2834
2835
static void bs_shift_rows(bs_word* t, bs_word* b)
2836
{
2837
    int i;
2838
2839
    for (i = 0; i < 128; i += 32) {
2840
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
2841
        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
2842
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
2843
        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
2844
    }
2845
}
2846
2847
#define BS_SHIFT_OFF_0  0
2848
#define BS_SHIFT_OFF_1  8
2849
#define BS_SHIFT_OFF_2  16
2850
#define BS_SHIFT_OFF_3  24
2851
2852
/* Shift rows and mix columns.
2853
 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
2854
 */
2855
2856
#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
2857
        of      = br0[7] ^ br1[7];                                  \
2858
        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
2859
        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
2860
        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
2861
        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
2862
        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
2863
        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
2864
        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
2865
        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
2866
2867
static void bs_shift_mix(bs_word* t, bs_word* b)
2868
{
2869
    int i;
2870
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
2871
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
2872
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
2873
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
2874
2875
    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
2876
        bs_word* br0 = b + or0;
2877
        bs_word* br1 = b + or1;
2878
        bs_word* br2 = b + or2;
2879
        bs_word* br3 = b + or3;
2880
        bs_word of;
2881
2882
        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
2883
        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
2884
        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
2885
        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
2886
2887
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2888
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2889
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2890
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2891
    }
2892
}
2893
2894
static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
2895
{
2896
    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
2897
}
2898
2899
static void bs_sub_bytes_blocks(bs_word* b)
2900
{
2901
    int i;
2902
2903
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
2904
        bs_sub_bytes(b + i);
2905
    }
2906
}
2907
2908
static const FLASH_QUALIFIER byte bs_rcon[] = {
2909
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
2910
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
2911
};
2912
2913
static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
2914
    bs_word block[AES_BLOCK_BITS];
2915
    bs_word trans[AES_BLOCK_BITS];
2916
2917
    XMEMSET(block, 0, sizeof(block));
2918
    XMEMCPY(block, in, 4);
2919
2920
    bs_transpose(trans, block);
2921
    bs_sub_bytes_blocks(trans);
2922
    bs_inv_transpose(block, trans);
2923
2924
    XMEMCPY(out, block, 4);
2925
}
2926
2927
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
2928
    /* Rotate the input 8 bits to the left */
2929
#ifdef LITTLE_ENDIAN_ORDER
2930
    *(word32*)out = rotrFixed(*(word32*)in, 8);
2931
#else
2932
    *(word32*)out = rotlFixed(*(word32*)in, 8);
2933
#endif
2934
    bs_ke_sub_bytes(out, out);
2935
    /* On just the first byte, add 2^i to the byte */
2936
    out[0] ^= bs_rcon[i];
2937
}
2938
2939
static void bs_expand_key(unsigned char *in, word32 sz) {
2940
    unsigned char t[4];
2941
    word32 o;
2942
    word8 i = 0;
2943
2944
    if (sz == 176) {
2945
        /* Total of 11 rounds - AES-128. */
2946
        for (o = 16; o < sz; o += 16) {
2947
            bs_ke_transform(t, in + o - 4, i);
2948
            i++;
2949
            *(word32*)(in + o +  0) = *(word32*)(in + o - 16) ^
2950
                                      *(word32*) t;
2951
            *(word32*)(in + o +  4) = *(word32*)(in + o - 12) ^
2952
                                      *(word32*)(in + o +  0);
2953
            *(word32*)(in + o +  8) = *(word32*)(in + o -  8) ^
2954
                                      *(word32*)(in + o +  4);
2955
            *(word32*)(in + o + 12) = *(word32*)(in + o -  4) ^
2956
                                      *(word32*)(in + o +  8);
2957
        }
2958
    }
2959
    else if (sz == 208) {
2960
        /* Total of 13 rounds - AES-192. */
2961
        for (o = 24; o < sz; o += 24) {
2962
            bs_ke_transform(t, in + o - 4, i);
2963
            i++;
2964
            *(word32*)(in + o +  0) = *(word32*)(in + o - 24) ^
2965
                                      *(word32*) t;
2966
            *(word32*)(in + o +  4) = *(word32*)(in + o - 20) ^
2967
                                      *(word32*)(in + o +  0);
2968
            *(word32*)(in + o +  8) = *(word32*)(in + o - 16) ^
2969
                                      *(word32*)(in + o +  4);
2970
            *(word32*)(in + o + 12) = *(word32*)(in + o - 12) ^
2971
                                      *(word32*)(in + o +  8);
2972
            *(word32*)(in + o + 16) = *(word32*)(in + o -  8) ^
2973
                                      *(word32*)(in + o + 12);
2974
            *(word32*)(in + o + 20) = *(word32*)(in + o -  4) ^
2975
                                      *(word32*)(in + o + 16);
2976
        }
2977
    }
2978
    else if (sz == 240) {
2979
        /* Total of 15 rounds - AES-256. */
2980
        for (o = 32; o < sz; o += 16) {
2981
            if ((o & 0x1f) == 0) {
2982
                bs_ke_transform(t, in + o - 4, i);
2983
                i++;
2984
            }
2985
            else {
2986
                bs_ke_sub_bytes(t, in + o - 4);
2987
            }
2988
            *(word32*)(in + o +  0) = *(word32*)(in + o - 32) ^
2989
                                      *(word32*) t;
2990
            *(word32*)(in + o +  4) = *(word32*)(in + o - 28) ^
2991
                                      *(word32*)(in + o +  0);
2992
            *(word32*)(in + o +  8) = *(word32*)(in + o - 24) ^
2993
                                      *(word32*)(in + o +  4);
2994
            *(word32*)(in + o + 12) = *(word32*)(in + o - 20) ^
2995
                                      *(word32*)(in + o +  8);
2996
        }
2997
    }
2998
}
2999
3000
static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
3001
    word32 rounds)
3002
{
3003
    int i;
3004
    byte bs_key[15 * WC_AES_BLOCK_SIZE];
3005
    int ksSz = (rounds + 1) * WC_AES_BLOCK_SIZE;
3006
    bs_word block[AES_BLOCK_BITS];
3007
3008
    /* Fist round. */
3009
    XMEMCPY(bs_key, key, keyLen);
3010
    bs_expand_key(bs_key, ksSz);
3011
3012
    for (i = 0; i < ksSz; i += WC_AES_BLOCK_SIZE) {
3013
        int k;
3014
3015
        XMEMCPY(block, bs_key + i, WC_AES_BLOCK_SIZE);
3016
        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
3017
            int l;
3018
            for (l = 0; l < BS_BLOCK_WORDS; l++) {
3019
                block[k + l] = block[l];
3020
            }
3021
        }
3022
        bs_transpose(rk, block);
3023
        rk += AES_BLOCK_BITS;
3024
    }
3025
}
3026
3027
static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
3028
{
3029
    word32 i;
3030
    bs_word trans[AES_BLOCK_BITS];
3031
3032
    bs_transpose(trans, state);
3033
3034
    bs_add_round_key(trans, trans, rk);
3035
    for (i = 1; i < r; i++) {
3036
        bs_sub_bytes_blocks(trans);
3037
        bs_shift_mix(state, trans);
3038
        rk += AES_BLOCK_BITS;
3039
        bs_add_round_key(trans, state, rk);
3040
    }
3041
    bs_sub_bytes_blocks(trans);
3042
    bs_shift_rows(state, trans);
3043
    rk += AES_BLOCK_BITS;
3044
    bs_add_round_key(trans, state, rk);
3045
    bs_inv_transpose(state, trans);
3046
}
3047
3048
#ifndef HAVE_CUDA
3049
/* Encrypt a block using AES.
3050
 *
3051
 * @param [in]  aes       AES object.
3052
 * @param [in]  inBlock   Block to encrypt.
3053
 * @param [out] outBlock  Encrypted block.
3054
 * @param [in]  r         Rounds divided by 2.
3055
 */
3056
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3057
        word32 r)
3058
{
3059
    bs_word state[AES_BLOCK_BITS];
3060
3061
    (void)r;
3062
3063
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
3064
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
3065
3066
    bs_encrypt(state, aes->bs_key, aes->rounds);
3067
3068
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
3069
}
3070
3071
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3072
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3073
/* Encrypt a number of blocks using AES.
3074
 *
3075
 * @param [in]  aes  AES object.
3076
 * @param [in]  in   Block to encrypt.
3077
 * @param [out] out  Encrypted block.
3078
 * @param [in]  sz   Number of blocks to encrypt.
3079
 */
3080
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3081
{
3082
    bs_word state[AES_BLOCK_BITS];
3083
3084
    while (sz >= BS_BLOCK_SIZE) {
3085
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3086
        bs_encrypt(state, aes->bs_key, aes->rounds);
3087
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3088
        sz  -= BS_BLOCK_SIZE;
3089
        in  += BS_BLOCK_SIZE;
3090
        out += BS_BLOCK_SIZE;
3091
    }
3092
    if (sz > 0) {
3093
        XMEMCPY(state, in, sz);
3094
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3095
        bs_encrypt(state, aes->bs_key, aes->rounds);
3096
        XMEMCPY(out, state, sz);
3097
    }
3098
}
3099
#endif
3100
#else
3101
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3102
        word32 r);
3103
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
3104
#endif /* HAVE_CUDA */
3105
3106
#endif /* !WC_AES_BITSLICED */
3107
3108
#ifdef WC_AES_HAVE_PREFETCH_ARG
3109
#define wc_AesEncrypt(aes, inBlock, outBlock) \
3110
8.95k
    AesEncrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
3111
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesEncrypt_preFetchOpt(
3112
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
3113
#else
3114
#define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
3115
    wc_AesEncrypt(aes, inBlock, outBlock)
3116
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesEncrypt(
3117
    Aes* aes, const byte* inBlock, byte* outBlock)
3118
#endif
3119
228k
{
3120
#if defined(MAX3266X_AES)
3121
    word32 keySize;
3122
#endif
3123
#if defined(MAX3266X_CB)
3124
    int ret_cb;
3125
#endif
3126
228k
    word32 r;
3127
3128
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3129
    {
3130
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3131
        if (ret < 0)
3132
            return ret;
3133
    }
3134
#endif
3135
3136
228k
    r = aes->rounds >> 1;
3137
3138
228k
    if (r > 7 || r == 0) {
3139
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3140
0
        return KEYUSAGE_E;
3141
0
    }
3142
3143
#ifdef WOLFSSL_AESNI
3144
    if (aes->use_aesni) {
3145
        ASSERT_SAVED_VECTOR_REGISTERS();
3146
3147
        #ifdef DEBUG_AESNI
3148
            printf("about to aes encrypt\n");
3149
            printf("in  = %p\n", inBlock);
3150
            printf("out = %p\n", outBlock);
3151
            printf("aes->key = %p\n", aes->key);
3152
            printf("aes->rounds = %d\n", aes->rounds);
3153
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
3154
        #endif
3155
3156
        /* check alignment, decrypt doesn't need alignment */
3157
        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
3158
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
3159
            byte* tmp = (byte*)XMALLOC(WC_AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
3160
                                                      DYNAMIC_TYPE_TMP_BUFFER);
3161
            byte* tmp_align;
3162
            if (tmp == NULL)
3163
                return MEMORY_E;
3164
3165
            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
3166
3167
            XMEMCPY(tmp_align, inBlock, WC_AES_BLOCK_SIZE);
3168
            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, WC_AES_BLOCK_SIZE,
3169
                    (byte*)aes->key, (int)aes->rounds);
3170
            XMEMCPY(outBlock, tmp_align, WC_AES_BLOCK_SIZE);
3171
            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3172
            return 0;
3173
        #else
3174
            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
3175
            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
3176
            return BAD_ALIGN_E;
3177
        #endif
3178
        }
3179
3180
        AES_ECB_encrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3181
                        (int)aes->rounds);
3182
3183
        return 0;
3184
    }
3185
    else {
3186
        #ifdef DEBUG_AESNI
3187
            printf("Skipping AES-NI\n");
3188
        #endif
3189
    }
3190
#elif defined(WOLFSSL_ARMASM)
3191
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
3192
#if !defined(__aarch64__)
3193
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
3194
#else
3195
    if (aes->use_aes_hw_crypto) {
3196
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3197
            (int)aes->rounds);
3198
    }
3199
    else
3200
#endif /* !__aarch64__ */
3201
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
3202
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
3203
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
3204
    {
3205
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3206
            (const unsigned char*)aes->key, aes->rounds);
3207
    }
3208
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
3209
    {
3210
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3211
            (const unsigned char*)aes->key, aes->rounds);
3212
    }
3213
#endif
3214
    return 0;
3215
#endif /* WOLFSSL_AESNI */
3216
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3217
    AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3218
    return 0;
3219
#endif
3220
3221
#if defined(WOLFSSL_IMXRT_DCP)
3222
    if (aes->keylen == 16) {
3223
        DCPAesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3224
        return 0;
3225
    }
3226
#endif
3227
3228
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3229
    if (aes->useSWCrypt == 0) {
3230
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3231
                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
3232
    }
3233
#endif
3234
3235
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3236
    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
3237
    if (wc_esp32AesSupportedKeyLen(aes)) {
3238
        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
3239
    }
3240
    else {
3241
        /* For example, the ESP32-S3 does not support HW for len = 24,
3242
         * so fall back to SW */
3243
    #ifdef DEBUG_WOLFSSL
3244
        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
3245
                      aes->keylen);
3246
    #endif
3247
    }
3248
#endif
3249
3250
#if defined(MAX3266X_AES)
3251
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3252
        return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3253
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3254
                                    outBlock, (unsigned int)keySize);
3255
    }
3256
#endif
3257
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3258
    #ifndef WOLF_CRYPTO_CB_FIND
3259
    if (aes->devId != INVALID_DEVID)
3260
    #endif
3261
    {
3262
        ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock,
3263
                                            WC_AES_BLOCK_SIZE);
3264
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3265
            return ret_cb;
3266
        /* fall-through when unavailable */
3267
    }
3268
#endif
3269
3270
228k
#ifdef WC_AES_HAVE_PREFETCH_ARG
3271
228k
    AesEncrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
3272
#else
3273
    AesEncrypt_C(aes, inBlock, outBlock, r);
3274
#endif
3275
3276
228k
    return 0;
3277
228k
} /* wc_AesEncrypt */
3278
#endif
3279
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
3280
3281
#if defined(HAVE_AES_DECRYPT)
3282
#if ((defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3283
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)) && \
3284
    (defined(__aarch64__) || !defined(WOLFSSL_ARMASM))
3285
3286
#ifndef WC_AES_BITSLICED
3287
#ifndef WC_NO_CACHE_RESISTANT
3288
#ifndef WOLFSSL_AES_SMALL_TABLES
3289
/* load 4 Td Tables into cache by cache line stride */
3290
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
3291
799
{
3292
799
    volatile word32 x = 0;
3293
799
    int i;
3294
799
    int j;
3295
3296
3.99k
    for (i = 0; i < 4; i++) {
3297
        /* 256 elements, each one is 4 bytes */
3298
54.3k
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
3299
51.1k
            x &= Td[i][j];
3300
51.1k
        }
3301
3.19k
    }
3302
3303
799
    return x;
3304
799
}
3305
#endif /* !WOLFSSL_AES_SMALL_TABLES */
3306
3307
/* load Td Table4 into cache by cache line stride */
3308
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
3309
799
{
3310
799
#ifndef WOLFSSL_AES_TOUCH_LINES
3311
799
    volatile word32 x = 0;
3312
799
    int i;
3313
3314
3.99k
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
3315
3.19k
        x &= (word32)Td4[i];
3316
3.19k
    }
3317
3318
799
    return x;
3319
#else
3320
    return 0;
3321
#endif
3322
799
}
3323
#endif /* !WC_NO_CACHE_RESISTANT */
3324
3325
/* Decrypt a block using AES.
3326
 *
3327
 * @param [in]  aes       AES object.
3328
 * @param [in]  inBlock   Block to encrypt.
3329
 * @param [out] outBlock  Encrypted block.
3330
 * @param [in]  r         Rounds divided by 2.
3331
 */
3332
#ifndef WC_AES_HAVE_PREFETCH_ARG
3333
    #define WC_AES_HAVE_PREFETCH_ARG
3334
    static int always_prefetch = 0;
3335
    WC_MAYBE_UNUSED static int never_prefetch = 1;
3336
#endif
3337
WC_ARGS_NOT_NULL((1, 2, 3, 5))
3338
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3339
    word32 r, int *prefetch_ptr)
3340
13.1k
{
3341
13.1k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
3342
13.1k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
3343
13.1k
    const word32* rk;
3344
3345
#ifdef WC_C_DYNAMIC_FALLBACK
3346
    rk = aes->key_C_fallback;
3347
#else
3348
13.1k
    rk = aes->key;
3349
13.1k
#endif
3350
3351
    /*
3352
     * map byte array block to cipher state
3353
     * and add initial round key:
3354
     */
3355
13.1k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
3356
13.1k
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
3357
13.1k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
3358
13.1k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
3359
3360
13.1k
#ifdef LITTLE_ENDIAN_ORDER
3361
13.1k
    s0 = ByteReverseWord32(s0);
3362
13.1k
    s1 = ByteReverseWord32(s1);
3363
13.1k
    s2 = ByteReverseWord32(s2);
3364
13.1k
    s3 = ByteReverseWord32(s3);
3365
13.1k
#endif
3366
3367
13.1k
    s0 ^= rk[0];
3368
13.1k
    s1 ^= rk[1];
3369
13.1k
    s2 ^= rk[2];
3370
13.1k
    s3 ^= rk[3];
3371
3372
13.1k
#ifndef WOLFSSL_AES_SMALL_TABLES
3373
3374
13.1k
#ifndef WC_NO_CACHE_RESISTANT
3375
13.1k
    if (*prefetch_ptr == 0) {
3376
799
        s0 |= PreFetchTd();
3377
        /* don't set the prefetched flag here -- PreFetchTd4() is called
3378
         * below.
3379
         */
3380
799
    }
3381
#else
3382
    (void)prefetch_ptr;
3383
#endif
3384
3385
13.1k
#ifndef WOLFSSL_AES_TOUCH_LINES
3386
/* Unroll the loop. */
3387
13.1k
#define DEC_ROUND_T_S(o)                                            \
3388
81.2k
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
3389
81.2k
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
3390
81.2k
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
3391
81.2k
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
3392
81.2k
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
3393
81.2k
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
3394
81.2k
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
3395
81.2k
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
3396
13.1k
#define DEC_ROUND_S_T(o)                                            \
3397
68.0k
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
3398
68.0k
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
3399
68.0k
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
3400
68.0k
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
3401
68.0k
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
3402
68.0k
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
3403
68.0k
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
3404
68.0k
         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
3405
#else
3406
#define DEC_ROUND_T_S(o)                                                       \
3407
    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
3408
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
3409
    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
3410
                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
3411
    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
3412
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
3413
    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
3414
                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
3415
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
3416
3417
#define DEC_ROUND_S_T(o)                                                       \
3418
    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
3419
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
3420
    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
3421
                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
3422
    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
3423
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
3424
    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
3425
                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
3426
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
3427
#endif
3428
3429
13.1k
#ifndef WOLFSSL_AES_NO_UNROLL
3430
13.1k
                       DEC_ROUND_T_S( 0);
3431
13.1k
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3432
13.1k
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3433
13.1k
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3434
13.1k
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3435
13.1k
    if (r > 5) {
3436
7.84k
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3437
7.84k
        if (r > 6) {
3438
7.68k
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3439
7.68k
        }
3440
7.84k
    }
3441
13.1k
    rk += r * 8;
3442
#else
3443
3444
    /*
3445
     * Nr - 1 full rounds:
3446
     */
3447
3448
    for (;;) {
3449
        DEC_ROUND_T_S(0);
3450
3451
        rk += 8;
3452
        if (--r == 0) {
3453
            break;
3454
        }
3455
3456
        DEC_ROUND_S_T(0);
3457
    }
3458
#endif
3459
    /*
3460
     * apply last round and
3461
     * map cipher state to byte array block:
3462
     */
3463
3464
13.1k
#ifndef WC_NO_CACHE_RESISTANT
3465
13.1k
    if (*prefetch_ptr == 0) {
3466
799
        t0 |= PreFetchTd4();
3467
799
        if (prefetch_ptr != &always_prefetch)
3468
679
            *prefetch_ptr = 1;
3469
799
    }
3470
#else
3471
    (void)prefetch_ptr;
3472
#endif
3473
3474
13.1k
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3475
13.1k
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3476
13.1k
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3477
13.1k
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3478
13.1k
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3479
13.1k
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3480
13.1k
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3481
13.1k
                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
3482
3483
#else /* WOLFSSL_AES_SMALL_TABLES */
3484
3485
#ifndef WC_NO_CACHE_RESISTANT
3486
    if (*prefetch_ptr == 0) {
3487
        s0 |= PreFetchTd4();
3488
        if (prefetch_ptr != &always_prefetch)
3489
            *prefetch_ptr = 1;
3490
    }
3491
#else
3492
    (void)prefetch_ptr;
3493
#endif
3494
3495
    r *= 2;
3496
    for (rk += 4; r > 1; r--, rk += 4) {
3497
        t0 =
3498
            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3499
            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3500
            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3501
            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
3502
            rk[0];
3503
        t1 =
3504
            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3505
            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3506
            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3507
            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
3508
            rk[1];
3509
        t2 =
3510
            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3511
            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3512
            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3513
            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
3514
            rk[2];
3515
        t3 =
3516
            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3517
            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3518
            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3519
            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
3520
            rk[3];
3521
3522
        s0 =
3523
            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
3524
            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
3525
            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
3526
            (inv_col_mul(t0, 1, 3, 2, 0)      );
3527
        s1 =
3528
            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
3529
            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
3530
            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
3531
            (inv_col_mul(t1, 1, 3, 2, 0)      );
3532
        s2 =
3533
            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
3534
            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
3535
            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
3536
            (inv_col_mul(t2, 1, 3, 2, 0)      );
3537
        s3 =
3538
            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
3539
            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
3540
            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
3541
            (inv_col_mul(t3, 1, 3, 2, 0)      );
3542
    }
3543
3544
    t0 =
3545
        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3546
        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3547
        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3548
        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
3549
    t1 =
3550
        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3551
        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3552
        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3553
        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
3554
    t2 =
3555
        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3556
        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3557
        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3558
        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
3559
    t3 =
3560
        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3561
        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3562
        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3563
        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
3564
    s0 = t0 ^ rk[0];
3565
    s1 = t1 ^ rk[1];
3566
    s2 = t2 ^ rk[2];
3567
    s3 = t3 ^ rk[3];
3568
3569
#endif /* WOLFSSL_AES_SMALL_TABLES */
3570
3571
    /* write out */
3572
13.1k
#ifdef LITTLE_ENDIAN_ORDER
3573
13.1k
    s0 = ByteReverseWord32(s0);
3574
13.1k
    s1 = ByteReverseWord32(s1);
3575
13.1k
    s2 = ByteReverseWord32(s2);
3576
13.1k
    s3 = ByteReverseWord32(s3);
3577
13.1k
#endif
3578
3579
13.1k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
3580
13.1k
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
3581
13.1k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
3582
13.1k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
3583
3584
13.1k
}
3585
3586
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3587
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
3588
    !defined(MAX3266X_AES)
3589
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
3590
/* Decrypt a number of blocks using AES.
3591
 *
3592
 * @param [in]  aes  AES object.
3593
 * @param [in]  in   Block to encrypt.
3594
 * @param [out] out  Encrypted block.
3595
 * @param [in]  sz   Number of blocks to encrypt.
3596
 */
3597
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3598
279
{
3599
279
    word32 i;
3600
279
    int did_prefetches = 0;
3601
3602
2.47k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
3603
2.19k
        AesDecrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
3604
2.19k
        in += WC_AES_BLOCK_SIZE;
3605
2.19k
        out += WC_AES_BLOCK_SIZE;
3606
2.19k
    }
3607
279
}
3608
#endif
3609
#endif
3610
3611
#else /* WC_AES_BITSLICED */
3612
3613
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
3614
static void bs_inv_sub_bytes(bs_word u[8])
3615
{
3616
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
3617
    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
3618
    bs_word RTL0, RTL1, RTL2;
3619
    bs_word sa0, sa1;
3620
    bs_word sb0, sb1;
3621
    bs_word ab0, ab1, ab2, ab3;
3622
    bs_word ab20, ab21, ab22, ab23;
3623
    bs_word al, ah, aa, bl, bh, bb;
3624
    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
3625
    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
3626
    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
3627
    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
3628
    bs_word rr1, rr2;
3629
    bs_word r10, r11;
3630
    bs_word cp1, cp2, cp3, cp4;
3631
    bs_word vr1, vr2, vr3;
3632
    bs_word pr1, pr2, pr3;
3633
    bs_word wr1, wr2, wr3;
3634
    bs_word qr1, qr2, qr3;
3635
    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
3636
    bs_word tinv10, tinv11, tinv12, tinv13;
3637
    bs_word t01, t02;
3638
    bs_word d0, d1, d2, d3;
3639
    bs_word dl, dd, dh;
3640
    bs_word sd0, sd1;
3641
    bs_word p0, p1, p2, p3, p4, p6, p7;
3642
    bs_word X11, X13, X14, X16, X18, X19;
3643
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
3644
3645
    U0 = u[7];
3646
    U1 = u[6];
3647
    U2 = u[5];
3648
    U3 = u[4];
3649
    U4 = u[3];
3650
    U5 = u[2];
3651
    U6 = u[1];
3652
    U7 = u[0];
3653
3654
    Y0 = U0 ^ U3;
3655
    Y2 = ~(U1 ^ U3);
3656
    Y4 = U0 ^ Y2;
3657
    RTL0 = U6 ^ U7;
3658
    Y1 = Y2 ^ RTL0;
3659
    Y7 = ~(U2 ^ Y1);
3660
    RTL1 = U3 ^ U4;
3661
    Y6 = ~(U7 ^ RTL1);
3662
    Y3 = Y1 ^ RTL1;
3663
    RTL2 = ~(U0 ^ U2);
3664
    Y5 = U5 ^ RTL2;
3665
    sa1 = Y0 ^ Y2;
3666
    sa0 = Y1 ^ Y3;
3667
    sb1 = Y4 ^ Y6;
3668
    sb0 = Y5 ^ Y7;
3669
    ah = Y0 ^ Y1;
3670
    al = Y2 ^ Y3;
3671
    aa = sa0 ^ sa1;
3672
    bh = Y4 ^ Y5;
3673
    bl = Y6 ^ Y7;
3674
    bb = sb0 ^ sb1;
3675
    ab20 = sa0 ^ sb0;
3676
    ab22 = al ^ bl;
3677
    ab23 = Y3 ^ Y7;
3678
    ab21 = sa1 ^ sb1;
3679
    abcd1 = ah & bh;
3680
    rr1 = Y0 & Y4;
3681
    ph11 = ab20 ^ abcd1;
3682
    t01 = Y1 & Y5;
3683
    ph01 = t01 ^ abcd1;
3684
    abcd2 = al & bl;
3685
    r1 = Y2 & Y6;
3686
    pl11 = ab22 ^ abcd2;
3687
    r2 = Y3 & Y7;
3688
    pl01 = r2 ^ abcd2;
3689
    r3 = sa0 & sb0;
3690
    vr1 = aa & bb;
3691
    pr1 = vr1 ^ r3;
3692
    wr1 = sa1 & sb1;
3693
    qr1 = wr1 ^ r3;
3694
    ab0 = ph11 ^ rr1;
3695
    ab1 = ph01 ^ ab21;
3696
    ab2 = pl11 ^ r1;
3697
    ab3 = pl01 ^ qr1;
3698
    cp1 = ab0 ^ pr1;
3699
    cp2 = ab1 ^ qr1;
3700
    cp3 = ab2 ^ pr1;
3701
    cp4 = ab3 ^ ab23;
3702
    tinv1 = cp3 ^ cp4;
3703
    tinv2 = cp3 & cp1;
3704
    tinv3 = cp2 ^ tinv2;
3705
    tinv4 = cp1 ^ cp2;
3706
    tinv5 = cp4 ^ tinv2;
3707
    tinv6 = tinv5 & tinv4;
3708
    tinv7 = tinv3 & tinv1;
3709
    d2 = cp4 ^ tinv7;
3710
    d0 = cp2 ^ tinv6;
3711
    tinv8 = cp1 & cp4;
3712
    tinv9 = tinv4 & tinv8;
3713
    tinv10 = tinv4 ^ tinv2;
3714
    d1 = tinv9 ^ tinv10;
3715
    tinv11 = cp2 & cp3;
3716
    tinv12 = tinv1 & tinv11;
3717
    tinv13 = tinv1 ^ tinv2;
3718
    d3 = tinv12 ^ tinv13;
3719
    sd1 = d1 ^ d3;
3720
    sd0 = d0 ^ d2;
3721
    dl = d0 ^ d1;
3722
    dh = d2 ^ d3;
3723
    dd = sd0 ^ sd1;
3724
    abcd3 = dh & bh;
3725
    rr2 = d3 & Y4;
3726
    t02 = d2 & Y5;
3727
    abcd4 = dl & bl;
3728
    r4 = d1 & Y6;
3729
    r5 = d0 & Y7;
3730
    r6 = sd0 & sb0;
3731
    vr2 = dd & bb;
3732
    wr2 = sd1 & sb1;
3733
    abcd5 = dh & ah;
3734
    r7 = d3 & Y0;
3735
    r8 = d2 & Y1;
3736
    abcd6 = dl & al;
3737
    r9 = d1 & Y2;
3738
    r10 = d0 & Y3;
3739
    r11 = sd0 & sa0;
3740
    vr3 = dd & aa;
3741
    wr3 = sd1 & sa1;
3742
    ph12 = rr2 ^ abcd3;
3743
    ph02 = t02 ^ abcd3;
3744
    pl12 = r4 ^ abcd4;
3745
    pl02 = r5 ^ abcd4;
3746
    pr2 = vr2 ^ r6;
3747
    qr2 = wr2 ^ r6;
3748
    p0 = ph12 ^ pr2;
3749
    p1 = ph02 ^ qr2;
3750
    p2 = pl12 ^ pr2;
3751
    p3 = pl02 ^ qr2;
3752
    ph13 = r7 ^ abcd5;
3753
    ph03 = r8 ^ abcd5;
3754
    pl13 = r9 ^ abcd6;
3755
    pl03 = r10 ^ abcd6;
3756
    pr3 = vr3 ^ r11;
3757
    qr3 = wr3 ^ r11;
3758
    p4 = ph13 ^ pr3;
3759
    S7 = ph03 ^ qr3;
3760
    p6 = pl13 ^ pr3;
3761
    p7 = pl03 ^ qr3;
3762
    S3 = p1 ^ p6;
3763
    S6 = p2 ^ p6;
3764
    S0 = p3 ^ p6;
3765
    X11 = p0 ^ p2;
3766
    S5 = S0 ^ X11;
3767
    X13 = p4 ^ p7;
3768
    X14 = X11 ^ X13;
3769
    S1 = S3 ^ X14;
3770
    X16 = p1 ^ S7;
3771
    S2 = X14 ^ X16;
3772
    X18 = p0 ^ p4;
3773
    X19 = S5 ^ X16;
3774
    S4 = X18 ^ X19;
3775
3776
    u[0] = S7;
3777
    u[1] = S6;
3778
    u[2] = S5;
3779
    u[3] = S4;
3780
    u[4] = S3;
3781
    u[5] = S2;
3782
    u[6] = S1;
3783
    u[7] = S0;
3784
}
3785
3786
static void bs_inv_shift_rows(bs_word* b)
3787
{
3788
    bs_word t[AES_BLOCK_BITS];
3789
    int i;
3790
3791
    for (i = 0; i < 128; i += 32) {
3792
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
3793
        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
3794
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
3795
        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
3796
    }
3797
3798
    XMEMCPY(b, t, sizeof(t));
3799
}
3800
3801
#define O0  0
3802
#define O1  8
3803
#define O2  16
3804
#define O3  24
3805
3806
#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
3807
    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
3808
          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
3809
    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
3810
          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
3811
    of2 =                     b[O0+7] ^             b[O1+7] ^               \
3812
                    b[O2+7] ^ b[O3+7];                                      \
3813
                                                                            \
3814
    br[0] =                                                   b[O1+0] ^     \
3815
            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
3816
    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
3817
            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
3818
    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
3819
            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
3820
    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
3821
            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
3822
    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
3823
            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
3824
    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
3825
            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
3826
    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
3827
            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
3828
    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
3829
            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
3830
3831
/* Inverse mix columns and shift rows. */
3832
static void bs_inv_mix_shift(bs_word* t, bs_word* b)
3833
{
3834
    bs_word* bp = b;
3835
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
3836
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
3837
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
3838
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
3839
    int i;
3840
3841
    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
3842
        bs_word* br;
3843
        bs_word of0;
3844
        bs_word of1;
3845
        bs_word of2;
3846
3847
        br = t + or0;
3848
        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
3849
        br = t + or1;
3850
        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
3851
        br = t + or2;
3852
        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
3853
        br = t + or3;
3854
        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
3855
3856
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3857
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3858
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3859
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3860
3861
        bp += AES_BLOCK_BITS / 4;
3862
    }
3863
}
3864
3865
static void bs_inv_sub_bytes_blocks(bs_word* b)
3866
{
3867
    int i;
3868
3869
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
3870
        bs_inv_sub_bytes(b + i);
3871
    }
3872
}
3873
3874
static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
3875
{
3876
    int i;
3877
    bs_word trans[AES_BLOCK_BITS];
3878
3879
    bs_transpose(trans, state);
3880
3881
    rk += r * AES_BLOCK_BITS;
3882
    bs_add_round_key(trans, trans, rk);
3883
    bs_inv_shift_rows(trans);
3884
    bs_inv_sub_bytes_blocks(trans);
3885
    rk -= AES_BLOCK_BITS;
3886
    bs_add_round_key(trans, trans, rk);
3887
    for (i = (int)r - 2; i >= 0; i--) {
3888
        bs_inv_mix_shift(state, trans);
3889
        bs_inv_sub_bytes_blocks(state);
3890
        rk -= AES_BLOCK_BITS;
3891
        bs_add_round_key(trans, state, rk);
3892
    }
3893
3894
    bs_inv_transpose(state, trans);
3895
}
3896
3897
#ifdef WOLFSSL_AES_DIRECT
3898
/* Decrypt a block using AES.
3899
 *
3900
 * @param [in]  aes       AES object.
3901
 * @param [in]  inBlock   Block to encrypt.
3902
 * @param [out] outBlock  Encrypted block.
3903
 * @param [in]  r         Rounds divided by 2.
3904
 */
3905
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3906
    word32 r)
3907
{
3908
    bs_word state[AES_BLOCK_BITS];
3909
3910
    (void)r;
3911
3912
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
3913
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
3914
3915
    bs_decrypt(state, aes->bs_key, aes->rounds);
3916
3917
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
3918
}
3919
#endif
3920
3921
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3922
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3923
/* Decrypt a number of blocks using AES.
3924
 *
3925
 * @param [in]  aes  AES object.
3926
 * @param [in]  in   Block to encrypt.
3927
 * @param [out] out  Encrypted block.
3928
 * @param [in]  sz   Number of blocks to encrypt.
3929
 */
3930
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3931
{
3932
    bs_word state[AES_BLOCK_BITS];
3933
3934
    while (sz >= BS_BLOCK_SIZE) {
3935
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3936
        bs_decrypt(state, aes->bs_key, aes->rounds);
3937
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3938
        sz  -= BS_BLOCK_SIZE;
3939
        in  += BS_BLOCK_SIZE;
3940
        out += BS_BLOCK_SIZE;
3941
    }
3942
    if (sz > 0) {
3943
        XMEMCPY(state, in, sz);
3944
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3945
        bs_decrypt(state, aes->bs_key, aes->rounds);
3946
        XMEMCPY(out, state, sz);
3947
    }
3948
}
3949
#endif
3950
3951
#endif /* !WC_AES_BITSLICED */
3952
#endif
3953
3954
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3955
    defined(WOLFSSL_AES_DIRECT)
3956
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
3957
#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
3958
/* Software AES - ECB Decrypt */
3959
3960
#ifdef WC_AES_HAVE_PREFETCH_ARG
3961
#define wc_AesDecrypt(aes, inBlock, outBlock) \
3962
120
    AesDecrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
3963
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesDecrypt_preFetchOpt(
3964
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
3965
#else
3966
#define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
3967
    wc_AesDecrypt(aes, inBlock, outBlock)
3968
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
3969
    Aes* aes, const byte* inBlock, byte* outBlock)
3970
#endif
3971
10.9k
{
3972
#if defined(MAX3266X_AES)
3973
    word32 keySize;
3974
#endif
3975
#if defined(MAX3266X_CB)
3976
    int ret_cb;
3977
#endif
3978
10.9k
    word32 r;
3979
3980
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3981
    {
3982
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3983
        if (ret < 0)
3984
            return ret;
3985
    }
3986
#endif
3987
3988
10.9k
    r = aes->rounds >> 1;
3989
3990
10.9k
    if (r > 7 || r == 0) {
3991
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3992
0
        return KEYUSAGE_E;
3993
0
    }
3994
3995
#ifdef WOLFSSL_AESNI
3996
    if (aes->use_aesni) {
3997
        ASSERT_SAVED_VECTOR_REGISTERS();
3998
3999
        #ifdef DEBUG_AESNI
4000
            printf("about to aes decrypt\n");
4001
            printf("in  = %p\n", inBlock);
4002
            printf("out = %p\n", outBlock);
4003
            printf("aes->key = %p\n", aes->key);
4004
            printf("aes->rounds = %d\n", aes->rounds);
4005
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
4006
        #endif
4007
4008
        /* if input and output same will overwrite input iv */
4009
        if ((const byte*)aes->tmp != inBlock)
4010
            XMEMCPY(aes->tmp, inBlock, WC_AES_BLOCK_SIZE);
4011
        AES_ECB_decrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
4012
                        (int)aes->rounds);
4013
        return 0;
4014
    }
4015
    else {
4016
        #ifdef DEBUG_AESNI
4017
            printf("Skipping AES-NI\n");
4018
        #endif
4019
    }
4020
#elif defined(WOLFSSL_ARMASM)
4021
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4022
#if !defined(__aarch64__)
4023
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
4024
#else
4025
    if (aes->use_aes_hw_crypto) {
4026
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
4027
            (int)aes->rounds);
4028
    }
4029
    else
4030
#endif /* !__aarch64__ */
4031
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
4032
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
4033
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
4034
    {
4035
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4036
            (const unsigned char*)aes->key, aes->rounds);
4037
    }
4038
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
4039
    {
4040
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4041
            (const unsigned char*)aes->key, aes->rounds);
4042
    }
4043
#endif
4044
    return 0;
4045
#endif /* WOLFSSL_AESNI */
4046
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
4047
    return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
4048
#endif
4049
#if defined(WOLFSSL_IMXRT_DCP)
4050
    if (aes->keylen == 16) {
4051
        DCPAesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4052
        return 0;
4053
    }
4054
#endif
4055
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
4056
    if (aes->useSWCrypt == 0) {
4057
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
4058
                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
4059
    }
4060
#endif
4061
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
4062
    if (wc_esp32AesSupportedKeyLen(aes)) {
4063
        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
4064
    }
4065
    else {
4066
        /* For example, the ESP32-S3 does not support HW for len = 24,
4067
         * so fall back to SW */
4068
    #ifdef DEBUG_WOLFSSL
4069
        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
4070
                        "unsupported keylen = %d", aes->keylen);
4071
    #endif
4072
    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
4073
#endif
4074
4075
#if defined(MAX3266X_AES)
4076
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
4077
        return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
4078
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
4079
                                    outBlock, (unsigned int)keySize);
4080
    }
4081
#endif
4082
4083
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
4084
    #ifndef WOLF_CRYPTO_CB_FIND
4085
    if (aes->devId != INVALID_DEVID)
4086
    #endif
4087
    {
4088
        ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock,
4089
                                            WC_AES_BLOCK_SIZE);
4090
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4091
            return ret_cb;
4092
        /* fall-through when unavailable */
4093
    }
4094
#endif
4095
4096
10.9k
#ifdef WC_AES_HAVE_PREFETCH_ARG
4097
10.9k
    AesDecrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
4098
#else
4099
    AesDecrypt_C(aes, inBlock, outBlock, r);
4100
#endif
4101
4102
10.9k
    return 0;
4103
10.9k
} /* wc_AesDecrypt[_SW]() */
4104
#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
4105
#endif
4106
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
4107
#endif /* HAVE_AES_DECRYPT */
4108
4109
#endif /* NEED_AES_TABLES */
4110
4111
#ifndef WC_AES_HAVE_PREFETCH_ARG
4112
    #ifndef AesEncrypt_preFetchOpt
4113
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4114
            wc_AesEncrypt(aes, inBlock, outBlock)
4115
    #endif
4116
    #ifndef AesDecrypt_preFetchOpt
4117
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4118
            wc_AesDecrypt(aes, inBlock, outBlock)
4119
    #endif
4120
#endif
4121
4122
/* wc_AesSetKey */
4123
#if defined(STM32_CRYPTO)
4124
4125
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4126
            const byte* iv, int dir)
4127
    {
4128
        word32 *rk;
4129
4130
        (void)dir;
4131
4132
        if (aes == NULL || (keylen != 16 &&
4133
        #ifdef WOLFSSL_AES_192
4134
            keylen != 24 &&
4135
        #endif
4136
            keylen != 32)) {
4137
            return BAD_FUNC_ARG;
4138
        }
4139
4140
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4141
        {
4142
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4143
            if (ret < 0)
4144
                return ret;
4145
        }
4146
#endif
4147
4148
        rk = aes->key;
4149
        aes->keylen = keylen;
4150
        aes->rounds = keylen/4 + 6;
4151
        XMEMCPY(rk, userKey, keylen);
4152
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
4153
        ByteReverseWords(rk, rk, keylen);
4154
    #endif
4155
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4156
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4157
        defined(WOLFSSL_AES_CTS)
4158
        aes->left = 0;
4159
    #endif
4160
        return wc_AesSetIV(aes, iv);
4161
    }
4162
    #if defined(WOLFSSL_AES_DIRECT)
4163
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4164
                            const byte* iv, int dir)
4165
        {
4166
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4167
        }
4168
    #endif
4169
4170
#elif defined(HAVE_COLDFIRE_SEC)
4171
    #if defined (HAVE_THREADX)
4172
        #include "memory_pools.h"
4173
        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
4174
    #endif
4175
4176
    #define AES_BUFFER_SIZE (WC_AES_BLOCK_SIZE * 64)
4177
    static unsigned char *AESBuffIn = NULL;
4178
    static unsigned char *AESBuffOut = NULL;
4179
    static byte *secReg;
4180
    static byte *secKey;
4181
    static volatile SECdescriptorType *secDesc;
4182
4183
    static wolfSSL_Mutex Mutex_AesSEC;
4184
4185
    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
4186
    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
4187
4188
    extern volatile unsigned char __MBAR[];
4189
4190
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4191
        const byte* iv, int dir)
4192
    {
4193
        if (AESBuffIn == NULL) {
4194
        #if defined (HAVE_THREADX)
4195
            int s1, s2, s3, s4, s5;
4196
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
4197
                                  sizeof(SECdescriptorType), TX_NO_WAIT);
4198
            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
4199
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4200
            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
4201
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4202
            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
4203
                                  WC_AES_BLOCK_SIZE*2, TX_NO_WAIT);
4204
            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
4205
                                  WC_AES_BLOCK_SIZE, TX_NO_WAIT);
4206
4207
            if (s1 || s2 || s3 || s4 || s5)
4208
                return BAD_FUNC_ARG;
4209
        #else
4210
            #warning "Allocate non-Cache buffers"
4211
        #endif
4212
4213
            wc_InitMutex(&Mutex_AesSEC);
4214
        }
4215
4216
        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4217
            return BAD_FUNC_ARG;
4218
4219
        if (aes == NULL)
4220
            return BAD_FUNC_ARG;
4221
4222
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4223
        {
4224
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4225
            if (ret < 0)
4226
                return ret;
4227
        }
4228
#endif
4229
4230
        aes->keylen = keylen;
4231
        aes->rounds = keylen/4 + 6;
4232
        XMEMCPY(aes->key, userKey, keylen);
4233
4234
        if (iv)
4235
            XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4236
4237
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4238
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4239
        defined(WOLFSSL_AES_CTS)
4240
        aes->left = 0;
4241
    #endif
4242
4243
        return 0;
4244
    }
4245
#elif defined(FREESCALE_LTC)
4246
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
4247
        const byte* iv, int dir, int checkKeyLen)
4248
    {
4249
        if (aes == NULL)
4250
            return BAD_FUNC_ARG;
4251
4252
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4253
        {
4254
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4255
            if (ret < 0)
4256
                return ret;
4257
        }
4258
#endif
4259
4260
        if (checkKeyLen) {
4261
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4262
                return BAD_FUNC_ARG;
4263
        }
4264
        (void)dir;
4265
4266
        aes->rounds = keylen/4 + 6;
4267
        XMEMCPY(aes->key, userKey, keylen);
4268
4269
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4270
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4271
        defined(WOLFSSL_AES_CTS)
4272
        aes->left = 0;
4273
    #endif
4274
4275
        return wc_AesSetIV(aes, iv);
4276
    }
4277
4278
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4279
        const byte* iv, int dir)
4280
    {
4281
        if (aes == NULL || userKey == NULL) {
4282
            return BAD_FUNC_ARG;
4283
        }
4284
        if (keylen > sizeof(aes->key)) {
4285
            return BAD_FUNC_ARG;
4286
        }
4287
4288
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4289
    }
4290
4291
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4292
                        const byte* iv, int dir)
4293
    {
4294
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4295
    }
4296
#elif defined(WOLFSSL_NRF51_AES)
4297
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4298
        const byte* iv, int dir)
4299
    {
4300
        int ret;
4301
4302
        (void)dir;
4303
        (void)iv;
4304
4305
        if (aes == NULL || keylen != 16)
4306
            return BAD_FUNC_ARG;
4307
4308
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4309
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4310
        if (ret < 0)
4311
            return ret;
4312
#endif
4313
4314
        aes->keylen = keylen;
4315
        aes->rounds = keylen/4 + 6;
4316
        XMEMCPY(aes->key, userKey, keylen);
4317
        ret = nrf51_aes_set_key(userKey);
4318
4319
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4320
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4321
        defined(WOLFSSL_AES_CTS)
4322
        aes->left = 0;
4323
    #endif
4324
4325
        return ret;
4326
    }
4327
4328
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4329
                        const byte* iv, int dir)
4330
    {
4331
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4332
    }
4333
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4334
    /* This is the only definition for HW only.
4335
     * but needs to be renamed when fallback needed.
4336
     * See call in wc_AesSetKey() */
4337
    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
4338
        const byte* iv, int dir)
4339
    {
4340
        (void)dir;
4341
        (void)iv;
4342
        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
4343
        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
4344
            return BAD_FUNC_ARG;
4345
        }
4346
4347
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4348
        {
4349
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4350
            if (ret < 0)
4351
                return ret;
4352
        }
4353
#endif
4354
4355
    #if !defined(WOLFSSL_AES_128)
4356
        if (keylen == 16) {
4357
            return BAD_FUNC_ARG;
4358
        }
4359
    #endif
4360
4361
    #if !defined(WOLFSSL_AES_192)
4362
        if (keylen == 24) {
4363
            return BAD_FUNC_ARG;
4364
        }
4365
    #endif
4366
4367
    #if !defined(WOLFSSL_AES_256)
4368
        if (keylen == 32) {
4369
            return BAD_FUNC_ARG;
4370
        }
4371
    #endif
4372
4373
        aes->keylen = keylen;
4374
        aes->rounds = keylen/4 + 6;
4375
4376
        XMEMCPY(aes->key, userKey, keylen);
4377
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4378
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4379
            defined(WOLFSSL_AES_CTS)
4380
            aes->left = 0;
4381
        #endif
4382
        return wc_AesSetIV(aes, iv);
4383
    } /* wc_AesSetKey */
4384
4385
    /* end #elif ESP32 */
4386
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
4387
4388
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
4389
                    int dir)
4390
    {
4391
        SaSiError_t ret = SASI_OK;
4392
        SaSiAesIv_t iv_aes;
4393
4394
        if (aes == NULL ||
4395
           (keylen != AES_128_KEY_SIZE &&
4396
            keylen != AES_192_KEY_SIZE &&
4397
            keylen != AES_256_KEY_SIZE)) {
4398
            return BAD_FUNC_ARG;
4399
        }
4400
4401
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4402
        {
4403
            int ret2 =
4404
                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4405
            if (ret2 < 0)
4406
                return ret2;
4407
        }
4408
#endif
4409
4410
    #if defined(AES_MAX_KEY_SIZE)
4411
        if (keylen > (AES_MAX_KEY_SIZE/8)) {
4412
            return BAD_FUNC_ARG;
4413
        }
4414
    #endif
4415
        if (dir != AES_ENCRYPTION &&
4416
            dir != AES_DECRYPTION) {
4417
            return BAD_FUNC_ARG;
4418
        }
4419
4420
        if (dir == AES_ENCRYPTION) {
4421
            aes->ctx.mode = SASI_AES_ENCRYPT;
4422
            SaSi_AesInit(&aes->ctx.user_ctx,
4423
                         SASI_AES_ENCRYPT,
4424
                         SASI_AES_MODE_CBC,
4425
                         SASI_AES_PADDING_NONE);
4426
        }
4427
        else {
4428
            aes->ctx.mode = SASI_AES_DECRYPT;
4429
            SaSi_AesInit(&aes->ctx.user_ctx,
4430
                         SASI_AES_DECRYPT,
4431
                         SASI_AES_MODE_CBC,
4432
                         SASI_AES_PADDING_NONE);
4433
        }
4434
4435
        aes->keylen = keylen;
4436
        aes->rounds = keylen/4 + 6;
4437
        XMEMCPY(aes->key, userKey, keylen);
4438
4439
        aes->ctx.key.pKey = (byte*)aes->key;
4440
        aes->ctx.key.keySize= keylen;
4441
4442
        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
4443
                             SASI_AES_USER_KEY,
4444
                             &aes->ctx.key,
4445
                             sizeof(aes->ctx.key));
4446
        if (ret != SASI_OK) {
4447
            return BAD_FUNC_ARG;
4448
        }
4449
4450
        ret = wc_AesSetIV(aes, iv);
4451
4452
        if (iv)
4453
            XMEMCPY(iv_aes, iv, WC_AES_BLOCK_SIZE);
4454
        else
4455
            XMEMSET(iv_aes,  0, WC_AES_BLOCK_SIZE);
4456
4457
4458
        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
4459
        if (ret != SASI_OK) {
4460
            return ret;
4461
        }
4462
       return ret;
4463
    }
4464
    #if defined(WOLFSSL_AES_DIRECT)
4465
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4466
                            const byte* iv, int dir)
4467
        {
4468
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4469
        }
4470
    #endif
4471
4472
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
4473
    && !defined(WOLFSSL_QNX_CAAM)
4474
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4475
4476
#elif defined(WOLFSSL_AFALG)
4477
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4478
4479
#elif defined(WOLFSSL_DEVCRYPTO_AES)
4480
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
4481
4482
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4483
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
4484
4485
#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
4486
     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
4487
    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
4488
4489
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
4490
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4491
            const byte* iv, int dir)
4492
    {
4493
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4494
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4495
        defined(WOLFSSL_AES_CTS)
4496
        aes->left = 0;
4497
    #endif
4498
4499
        aes->keylen = (int)keylen;
4500
        aes->rounds = (keylen/4) + 6;
4501
4502
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4503
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
4504
#else
4505
        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
4506
4507
    #ifdef HAVE_AES_DECRYPT
4508
        if (dir == AES_DECRYPTION) {
4509
            AES_invert_key((byte*)aes->key, aes->rounds);
4510
        }
4511
    #else
4512
        (void)dir;
4513
    #endif
4514
#endif
4515
        return wc_AesSetIV(aes, iv);
4516
    }
4517
4518
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4519
            const byte* iv, int dir)
4520
    {
4521
        if ((aes == NULL) || (userKey == NULL)) {
4522
            return BAD_FUNC_ARG;
4523
        }
4524
4525
        switch (keylen) {
4526
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4527
        defined(WOLFSSL_AES_128)
4528
        case 16:
4529
    #endif
4530
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4531
        defined(WOLFSSL_AES_192)
4532
        case 24:
4533
    #endif
4534
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4535
        defined(WOLFSSL_AES_256)
4536
        case 32:
4537
    #endif
4538
            break;
4539
        default:
4540
            return BAD_FUNC_ARG;
4541
        }
4542
4543
    #ifdef WOLF_CRYPTO_CB
4544
        if (aes->devId != INVALID_DEVID) {
4545
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
4546
            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
4547
            if (ret == 0) {
4548
                /* Callback succeeded - SE owns the key */
4549
                aes->keylen = (int)keylen;
4550
                if (iv != NULL)
4551
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4552
                else
4553
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
4554
                return 0;
4555
            }
4556
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
4557
                aes->devCtx = NULL;
4558
                return ret;
4559
            }
4560
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
4561
        #endif
4562
            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
4563
            if (keylen > sizeof(aes->devKey)) {
4564
                return BAD_FUNC_ARG;
4565
            }
4566
            XMEMCPY(aes->devKey, userKey, keylen);
4567
        }
4568
    #endif
4569
4570
        return AesSetKey(aes, userKey, keylen, iv, dir);
4571
    }
4572
4573
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
4574
        /* AES-CTR and AES-DIRECT need to use this for key setup */
4575
        /* This function allows key sizes that are not 128/192/256 bits */
4576
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4577
                           const byte* iv, int dir)
4578
    {
4579
        if (aes == NULL) {
4580
            return BAD_FUNC_ARG;
4581
        }
4582
        if (keylen > sizeof(aes->key)) {
4583
            return BAD_FUNC_ARG;
4584
        }
4585
4586
        return AesSetKey(aes, userKey, keylen, iv, dir);
4587
    }
4588
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
4589
#elif defined(FREESCALE_MMCAU)
4590
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
4591
        const byte* iv, int dir, int checkKeyLen)
4592
    {
4593
        int ret;
4594
        byte* rk;
4595
        byte* tmpKey = (byte*)userKey;
4596
        int tmpKeyDynamic = 0;
4597
        word32 alignOffset = 0;
4598
4599
        (void)dir;
4600
4601
        if (aes == NULL)
4602
            return BAD_FUNC_ARG;
4603
4604
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4605
        {
4606
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4607
            if (ret < 0)
4608
                return ret;
4609
        }
4610
#endif
4611
4612
        if (checkKeyLen) {
4613
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4614
                return BAD_FUNC_ARG;
4615
        }
4616
4617
        rk = (byte*)aes->key;
4618
        if (rk == NULL)
4619
            return BAD_FUNC_ARG;
4620
4621
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4622
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4623
        defined(WOLFSSL_AES_CTS)
4624
        aes->left = 0;
4625
    #endif
4626
4627
        aes->rounds = keylen/4 + 6;
4628
4629
    #ifdef FREESCALE_MMCAU_CLASSIC
4630
        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
4631
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
4632
            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
4633
                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
4634
            if (tmp == NULL) {
4635
                return MEMORY_E;
4636
            }
4637
            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
4638
                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
4639
            tmpKey = tmp + alignOffset;
4640
            XMEMCPY(tmpKey, userKey, keylen);
4641
            tmpKeyDynamic = 1;
4642
        #else
4643
            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
4644
            return BAD_ALIGN_E;
4645
        #endif
4646
        }
4647
    #endif
4648
4649
        ret = wolfSSL_CryptHwMutexLock();
4650
        if(ret == 0) {
4651
        #ifdef FREESCALE_MMCAU_CLASSIC
4652
            cau_aes_set_key(tmpKey, keylen*8, rk);
4653
        #else
4654
            MMCAU_AES_SetKey(tmpKey, keylen, rk);
4655
        #endif
4656
            wolfSSL_CryptHwMutexUnLock();
4657
4658
            ret = wc_AesSetIV(aes, iv);
4659
        }
4660
4661
        if (tmpKeyDynamic == 1) {
4662
            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
4663
        }
4664
4665
        return ret;
4666
    }
4667
4668
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4669
        const byte* iv, int dir)
4670
    {
4671
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4672
    }
4673
4674
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4675
                        const byte* iv, int dir)
4676
    {
4677
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4678
    }
4679
4680
#elif defined(WOLFSSL_PSOC6_CRYPTO)
4681
4682
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4683
        const byte* iv, int dir)
4684
    {
4685
        return wc_Psoc6_Aes_SetKey(aes, userKey, keylen, iv, dir);
4686
    }
4687
4688
    #if defined(WOLFSSL_AES_DIRECT)
4689
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4690
                            const byte* iv, int dir)
4691
        {
4692
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4693
        }
4694
    #endif /* WOLFSSL_AES_DIRECT */
4695
#else
4696
    #define NEED_SOFTWARE_AES_SETKEY
4697
#endif
4698
4699
/* Either we fell though with no HW support at all,
4700
 * or perhaps there's HW support for *some* keylengths
4701
 * and we need both HW and SW. */
4702
#ifdef NEED_SOFTWARE_AES_SETKEY
4703
4704
#ifdef NEED_AES_TABLES
4705
4706
#ifndef WC_AES_BITSLICED
4707
#if !defined(WOLFSSL_ARMASM)
4708
/* Set the AES key and expand.
4709
 *
4710
 * @param [in]  aes    AES object.
4711
 * @param [in]  key    Block to encrypt.
4712
 * @param [in]  keySz  Number of bytes in key.
4713
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4714
 */
4715
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4716
6.59k
{
4717
#ifdef WC_C_DYNAMIC_FALLBACK
4718
    word32* rk = aes->key_C_fallback;
4719
#else
4720
6.59k
    word32* rk = aes->key;
4721
6.59k
#endif
4722
6.59k
    word32 temp;
4723
6.59k
    unsigned int i = 0;
4724
4725
6.59k
    XMEMCPY(rk, key, keySz);
4726
6.59k
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
4727
6.59k
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
4728
6.59k
    !defined(MAX3266X_AES)
4729
    /* Always reverse words when using only SW */
4730
6.59k
    {
4731
6.59k
        ByteReverseWords(rk, rk, keySz);
4732
6.59k
    }
4733
#else
4734
    /* Sometimes reverse words when using supported HW */
4735
    #if defined(WOLFSSL_ESPIDF)
4736
        /* Some platforms may need SW fallback (e.g. AES192) */
4737
        #if defined(NEED_AES_HW_FALLBACK)
4738
        {
4739
            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
4740
            if (wc_esp32AesSupportedKeyLen(aes)) {
4741
                /* don't reverse for HW supported key lengths */
4742
            }
4743
            else {
4744
                ByteReverseWords(rk, rk, keySz);
4745
            }
4746
        }
4747
        #else
4748
            /* If we don't need SW fallback, don't need to reverse words. */
4749
        #endif /* NEED_AES_HW_FALLBACK */
4750
    #endif /* WOLFSSL_ESPIDF */
4751
#endif /* LITTLE_ENDIAN_ORDER, etc */
4752
4753
6.59k
    switch (keySz) {
4754
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
4755
0
        defined(WOLFSSL_AES_128)
4756
3.55k
    case 16:
4757
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4758
        temp = (word32)-1;
4759
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4760
    #endif
4761
35.5k
        while (1)
4762
35.5k
        {
4763
35.5k
            temp  = rk[3];
4764
35.5k
            rk[4] = rk[0] ^
4765
35.5k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4766
35.5k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4767
35.5k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4768
35.5k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4769
35.5k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4770
        #else
4771
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4772
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4773
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4774
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4775
        #endif
4776
35.5k
                rcon[i];
4777
35.5k
            rk[5] = rk[1] ^ rk[4];
4778
35.5k
            rk[6] = rk[2] ^ rk[5];
4779
35.5k
            rk[7] = rk[3] ^ rk[6];
4780
35.5k
            if (++i == 10)
4781
3.55k
                break;
4782
31.9k
            rk += 4;
4783
31.9k
        }
4784
3.55k
        break;
4785
0
#endif /* 128 */
4786
4787
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
4788
0
        defined(WOLFSSL_AES_192)
4789
951
    case 24:
4790
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4791
        temp = (word32)-1;
4792
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4793
    #endif
4794
        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
4795
7.60k
        while (1)
4796
7.60k
        {
4797
7.60k
            temp = rk[ 5];
4798
7.60k
            rk[ 6] = rk[ 0] ^
4799
7.60k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4800
7.60k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4801
7.60k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4802
7.60k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4803
7.60k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4804
        #else
4805
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4806
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4807
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4808
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4809
        #endif
4810
7.60k
                rcon[i];
4811
7.60k
            rk[ 7] = rk[ 1] ^ rk[ 6];
4812
7.60k
            rk[ 8] = rk[ 2] ^ rk[ 7];
4813
7.60k
            rk[ 9] = rk[ 3] ^ rk[ 8];
4814
7.60k
            if (++i == 8)
4815
951
                break;
4816
6.65k
            rk[10] = rk[ 4] ^ rk[ 9];
4817
6.65k
            rk[11] = rk[ 5] ^ rk[10];
4818
6.65k
            rk += 6;
4819
6.65k
        }
4820
951
        break;
4821
0
#endif /* 192 */
4822
4823
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
4824
0
        defined(WOLFSSL_AES_256)
4825
2.09k
    case 32:
4826
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4827
        temp = (word32)-1;
4828
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4829
    #endif
4830
14.6k
        while (1)
4831
14.6k
        {
4832
14.6k
            temp = rk[ 7];
4833
14.6k
            rk[ 8] = rk[ 0] ^
4834
14.6k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4835
14.6k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4836
14.6k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4837
14.6k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4838
14.6k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4839
        #else
4840
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4841
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4842
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4843
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4844
        #endif
4845
14.6k
                rcon[i];
4846
14.6k
            rk[ 9] = rk[ 1] ^ rk[ 8];
4847
14.6k
            rk[10] = rk[ 2] ^ rk[ 9];
4848
14.6k
            rk[11] = rk[ 3] ^ rk[10];
4849
14.6k
            if (++i == 7)
4850
2.09k
                break;
4851
12.5k
            temp = rk[11];
4852
12.5k
            rk[12] = rk[ 4] ^
4853
12.5k
        #ifndef WOLFSSL_AES_SMALL_TABLES
4854
12.5k
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
4855
12.5k
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
4856
12.5k
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
4857
12.5k
                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
4858
        #else
4859
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
4860
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
4861
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
4862
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
4863
        #endif
4864
12.5k
            rk[13] = rk[ 5] ^ rk[12];
4865
12.5k
            rk[14] = rk[ 6] ^ rk[13];
4866
12.5k
            rk[15] = rk[ 7] ^ rk[14];
4867
4868
12.5k
            rk += 8;
4869
12.5k
        }
4870
2.09k
        break;
4871
6.59k
#endif /* 256 */
4872
6.59k
    } /* switch */
4873
6.59k
    ForceZero(&temp, sizeof(temp));
4874
4875
6.59k
#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
4876
6.59k
    if (dir == AES_DECRYPTION) {
4877
749
        unsigned int j;
4878
4879
#ifdef WC_C_DYNAMIC_FALLBACK
4880
        rk = aes->key_C_fallback;
4881
#else
4882
749
        rk = aes->key;
4883
749
#endif
4884
4885
        /* invert the order of the round keys: */
4886
4.98k
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
4887
4.23k
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
4888
4.23k
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
4889
4.23k
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
4890
4.23k
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
4891
4.23k
        }
4892
749
        ForceZero(&temp, sizeof(temp));
4893
749
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
4894
        /* apply the inverse MixColumn transform to all round keys but the
4895
           first and the last: */
4896
8.46k
        for (i = 1; i < aes->rounds; i++) {
4897
7.71k
            rk += 4;
4898
7.71k
            rk[0] =
4899
7.71k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
4900
7.71k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
4901
7.71k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
4902
7.71k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
4903
7.71k
            rk[1] =
4904
7.71k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
4905
7.71k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
4906
7.71k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
4907
7.71k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
4908
7.71k
            rk[2] =
4909
7.71k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
4910
7.71k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
4911
7.71k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
4912
7.71k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
4913
7.71k
            rk[3] =
4914
7.71k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
4915
7.71k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
4916
7.71k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
4917
7.71k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
4918
7.71k
        }
4919
749
    #endif
4920
749
    }
4921
#else
4922
    (void)dir;
4923
#endif /* HAVE_AES_DECRYPT */
4924
4925
#ifdef WOLFSSL_CHECK_MEM_ZERO
4926
    wc_MemZero_Check(&temp, sizeof(temp));
4927
#else
4928
6.59k
    (void)temp;
4929
6.59k
#endif
4930
6.59k
}
4931
#endif
4932
#else /* WC_AES_BITSLICED */
4933
/* Set the AES key and expand.
4934
 *
4935
 * @param [in]  aes    AES object.
4936
 * @param [in]  key    Block to encrypt.
4937
 * @param [in]  keySz  Number of bytes in key.
4938
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4939
 */
4940
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4941
{
4942
    /* No need to invert when decrypting. */
4943
    (void)dir;
4944
4945
    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
4946
}
4947
#endif /* WC_AES_BITSLICED */
4948
4949
#endif /* NEED_AES_TABLES */
4950
4951
#ifndef WOLFSSL_RISCV_ASM
4952
    /* Software AES - SetKey */
4953
    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
4954
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
4955
        int checkKeyLen)
4956
6.59k
    {
4957
6.59k
        int ret;
4958
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4959
        byte   local[32];
4960
        word32 localSz = 32;
4961
    #endif
4962
4963
6.59k
        if (aes == NULL)
4964
0
            return BAD_FUNC_ARG;
4965
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4966
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4967
        if (ret < 0)
4968
            return ret;
4969
#endif
4970
4971
6.59k
        switch (keylen) {
4972
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4973
0
        defined(WOLFSSL_AES_128)
4974
3.55k
        case 16:
4975
3.55k
    #endif
4976
3.55k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4977
3.55k
        defined(WOLFSSL_AES_192)
4978
4.50k
        case 24:
4979
4.50k
    #endif
4980
4.50k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4981
4.50k
        defined(WOLFSSL_AES_256)
4982
6.59k
        case 32:
4983
6.59k
    #endif
4984
6.59k
            break;
4985
0
        default:
4986
0
            return BAD_FUNC_ARG;
4987
6.59k
        }
4988
4989
6.59k
    #ifdef WOLF_CRYPTO_CB
4990
6.59k
        if (aes->devId != INVALID_DEVID) {
4991
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
4992
            ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
4993
            if (ret == 0) {
4994
                /* Callback succeeded - SE owns the key */
4995
                aes->keylen = (int)keylen;
4996
                if (iv != NULL)
4997
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4998
                else
4999
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5000
                return 0;
5001
            }
5002
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5003
                aes->devCtx = NULL;
5004
                return ret;
5005
            }
5006
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5007
        #endif
5008
            /* Standard CryptoCB path - copy key to devKey */
5009
918
            if (keylen > sizeof(aes->devKey)) {
5010
0
                return BAD_FUNC_ARG;
5011
0
            }
5012
918
            XMEMCPY(aes->devKey, userKey, keylen);
5013
918
        }
5014
6.59k
    #endif
5015
5016
    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
5017
        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
5018
            return WC_HW_E;
5019
        }
5020
    #endif
5021
5022
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5023
        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
5024
            keylen == (24 + WC_CAAM_BLOB_SZ) ||
5025
            keylen == (32 + WC_CAAM_BLOB_SZ)) {
5026
            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
5027
                return BAD_FUNC_ARG;
5028
            }
5029
5030
            /* set local values */
5031
            userKey = local;
5032
            keylen = localSz;
5033
        }
5034
    #endif
5035
5036
    #ifdef WOLFSSL_SECO_CAAM
5037
        /* if set to use hardware than import the key */
5038
        if (aes->devId == WOLFSSL_SECO_DEVID) {
5039
            int keyGroup = 1; /* group one was chosen arbitrarily */
5040
            unsigned int keyIdOut;
5041
            byte importiv[GCM_NONCE_MID_SZ];
5042
            int importivSz = GCM_NONCE_MID_SZ;
5043
            int keyType = 0;
5044
            WC_RNG rng;
5045
5046
            if (wc_InitRng(&rng) != 0) {
5047
                WOLFSSL_MSG("RNG init for IV failed");
5048
                return WC_HW_E;
5049
            }
5050
5051
            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
5052
                WOLFSSL_MSG("Generate IV failed");
5053
                wc_FreeRng(&rng);
5054
                return WC_HW_E;
5055
            }
5056
            wc_FreeRng(&rng);
5057
5058
            if (iv)
5059
                XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5060
            else
5061
                XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5062
5063
            switch (keylen) {
5064
                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
5065
                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
5066
                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
5067
            }
5068
5069
            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
5070
                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
5071
            if (keyIdOut == 0) {
5072
                return WC_HW_E;
5073
            }
5074
            aes->blackKey = keyIdOut;
5075
            return 0;
5076
        }
5077
    #endif
5078
5079
6.59k
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
5080
6.59k
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
5081
6.59k
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
5082
6.59k
        #ifdef WOLF_CRYPTO_CB
5083
6.59k
        if (aes->devId != INVALID_DEVID)
5084
918
        #endif
5085
918
        {
5086
918
            if (keylen > sizeof(aes->devKey)) {
5087
0
                return BAD_FUNC_ARG;
5088
0
            }
5089
918
            XMEMCPY(aes->devKey, userKey, keylen);
5090
918
        }
5091
6.59k
    #endif
5092
5093
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
5094
        if (checkKeyLen) {
5095
            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
5096
             * all key sizes. Otherwise this condition is never true. */
5097
            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
5098
                return BAD_FUNC_ARG;
5099
            }
5100
        }
5101
    #else
5102
6.59k
        (void) checkKeyLen;
5103
6.59k
    #endif
5104
5105
6.59k
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5106
6.59k
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5107
6.59k
        defined(WOLFSSL_AES_CTS)
5108
6.59k
        aes->left = 0;
5109
6.59k
    #endif
5110
5111
6.59k
        aes->keylen = (int)keylen;
5112
6.59k
        aes->rounds = (keylen/4) + 6;
5113
6.59k
        ret = wc_AesSetIV(aes, iv);
5114
6.59k
        if (ret != 0)
5115
0
            return ret;
5116
5117
#ifdef WC_C_DYNAMIC_FALLBACK
5118
#ifdef NEED_AES_TABLES
5119
        AesSetKey_C(aes, userKey, keylen, dir);
5120
#endif /* NEED_AES_TABLES */
5121
#endif /* WC_C_DYNAMIC_FALLBACK */
5122
5123
    #ifdef WOLFSSL_AESNI
5124
5125
       /* The dynamics for determining whether AES-NI will be used are tricky.
5126
        *
5127
        * First, we check for CPU support and cache the result -- if AES-NI is
5128
        * missing, we always shortcut to the AesSetKey_C() path.
5129
        *
5130
        * Second, if the CPU supports AES-NI, we confirm on a per-call basis
5131
        * that it's safe to use in the caller context, using
5132
        * SAVE_VECTOR_REGISTERS2().  This is an always-true no-op in user-space
5133
        * builds, but has substantive logic behind it in kernel module builds.
5134
        *
5135
        * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on
5136
        * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with
5137
        * success but with AES-NI disabled (the earlier AesSetKey_C() allows
5138
        * future encrypt/decrypt calls to succeed), otherwise we fail.
5139
        *
5140
        * Upon successful return, aes->use_aesni will have a zero value if
5141
        * AES-NI is disabled, and a nonzero value if it's enabled.
5142
        *
5143
        * An additional, optional semantic is available via
5144
        * WC_FLAG_DONT_USE_VECTOR_OPS, and is used in some kernel module builds
5145
        * to let the caller inhibit AES-NI.  When this macro is defined,
5146
        * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of
5147
        * uninitialized data in aes->use_aesni.  That's why support for
5148
        * WC_FLAG_DONT_USE_VECTOR_OPS must remain optional -- wc_AesInit() was
5149
        * only added in release 3.11.0, so legacy applications inevitably call
5150
        * wc_AesSetKey() on uninitialized Aes contexts.  This must continue to
5151
        * function correctly with default build settings.
5152
        */
5153
5154
        if (checkedAESNI == 0) {
5155
            haveAESNI  = Check_CPU_support_AES();
5156
            checkedAESNI = 1;
5157
        }
5158
        if (haveAESNI
5159
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS) && !defined(WC_C_DYNAMIC_FALLBACK)
5160
            && (aes->use_aesni != WC_FLAG_DONT_USE_VECTOR_OPS)
5161
#endif
5162
            )
5163
        {
5164
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS)
5165
            if (aes->use_aesni == WC_FLAG_DONT_USE_VECTOR_OPS) {
5166
                aes->use_aesni = 0;
5167
                return 0;
5168
            }
5169
#endif
5170
            aes->use_aesni = 0;
5171
            #ifdef WOLFSSL_KERNEL_MODE
5172
            /* runtime alignment check */
5173
            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
5174
                ret = BAD_ALIGN_E;
5175
            }
5176
            else
5177
            #endif /* WOLFSSL_KERNEL_MODE */
5178
            {
5179
                ret = SAVE_VECTOR_REGISTERS2();
5180
            }
5181
            if (ret == 0) {
5182
                if (dir == AES_ENCRYPTION)
5183
                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5184
#ifdef HAVE_AES_DECRYPT
5185
                else
5186
                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5187
#endif
5188
5189
                RESTORE_VECTOR_REGISTERS();
5190
5191
                if (ret == 0)
5192
                    aes->use_aesni = 1;
5193
                else {
5194
#ifdef WC_C_DYNAMIC_FALLBACK
5195
                    ret = 0;
5196
#endif
5197
                }
5198
                return ret;
5199
            } else {
5200
#ifdef WC_C_DYNAMIC_FALLBACK
5201
                return 0;
5202
#else
5203
                return ret;
5204
#endif
5205
            }
5206
        }
5207
        else {
5208
            aes->use_aesni = 0;
5209
#ifdef WC_C_DYNAMIC_FALLBACK
5210
            /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C()
5211
             * above.
5212
             */
5213
            return 0;
5214
#endif
5215
        }
5216
    #endif /* WOLFSSL_AESNI */
5217
5218
6.59k
#ifndef WC_C_DYNAMIC_FALLBACK
5219
5220
#if defined(WOLFSSL_ARMASM)
5221
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5222
    #ifndef __aarch64__
5223
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5224
    #else
5225
        Check_CPU_support_HwCrypto(aes);
5226
        if (aes->use_aes_hw_crypto) {
5227
            AES_set_key_AARCH64(userKey, keylen, (byte*)aes->key, dir);
5228
        }
5229
        else
5230
    #endif /* __aarch64__ */
5231
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
5232
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
5233
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
5234
        {
5235
            AES_set_encrypt_key_NEON(userKey, keylen * 8, (byte*)aes->key);
5236
        #ifdef HAVE_AES_DECRYPT
5237
            if (dir == AES_DECRYPTION) {
5238
                AES_invert_key_NEON((byte*)aes->key, aes->rounds);
5239
            }
5240
        #else
5241
            (void)dir;
5242
        #endif
5243
        }
5244
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5245
        {
5246
            AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5247
        #ifdef HAVE_AES_DECRYPT
5248
            if (dir == AES_DECRYPTION) {
5249
                AES_invert_key((byte*)aes->key, aes->rounds);
5250
            }
5251
        #else
5252
            (void)dir;
5253
        #endif
5254
        }
5255
    #endif
5256
        return 0;
5257
#else
5258
5259
    #ifdef WOLFSSL_KCAPI_AES
5260
        XMEMCPY(aes->devKey, userKey, keylen);
5261
        if (aes->init != 0) {
5262
            kcapi_cipher_destroy(aes->handle);
5263
            aes->handle = NULL;
5264
            aes->init = 0;
5265
        }
5266
        (void)dir;
5267
    #endif
5268
5269
6.59k
        if (keylen > sizeof(aes->key)) {
5270
0
            return BAD_FUNC_ARG;
5271
0
        }
5272
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
5273
        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
5274
                                  ((psa_algorithm_t)0), dir);
5275
#endif
5276
5277
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
5278
        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
5279
         * instead of SE05x crypto by setting useSWCrypt */
5280
        if (aes->useSWCrypt == 0) {
5281
            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
5282
            if (ret == 0) {
5283
                ret = wc_AesSetIV(aes, iv);
5284
            }
5285
            return ret;
5286
        }
5287
#endif
5288
5289
6.59k
        XMEMCPY(aes->key, userKey, keylen);
5290
5291
6.59k
#ifndef WC_AES_BITSLICED
5292
6.59k
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
5293
6.59k
        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
5294
6.59k
        && !defined(MAX3266X_AES)
5295
5296
        /* software */
5297
6.59k
        ByteReverseWords(aes->key, aes->key, keylen);
5298
5299
    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
5300
        if (wc_esp32AesSupportedKeyLen(aes)) {
5301
            /* supported lengths don't get reversed */
5302
            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
5303
        }
5304
        else {
5305
            word32* rk = aes->key;
5306
5307
            /* For example, the ESP32-S3 does not support HW for len = 24,
5308
             * so fall back to SW */
5309
        #ifdef DEBUG_WOLFSSL
5310
            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
5311
        #endif
5312
            XMEMCPY(rk, userKey, keylen);
5313
            /* When not ESP32 HW, we need to reverse endianness */
5314
            ByteReverseWords(rk, rk, keylen);
5315
        }
5316
    #endif
5317
5318
    #ifdef WOLFSSL_IMXRT_DCP
5319
        {
5320
            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
5321
            word32 temp = 0;
5322
            if (keylen == 16)
5323
                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
5324
            if (temp != 0)
5325
                return WC_HW_E;
5326
        }
5327
    #endif
5328
6.59k
#endif /* !WC_AES_BITSLICED */
5329
5330
6.59k
#ifdef NEED_AES_TABLES
5331
6.59k
        AesSetKey_C(aes, userKey, keylen, dir);
5332
6.59k
#endif /* NEED_AES_TABLES */
5333
5334
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
5335
        XMEMCPY((byte*)aes->key, userKey, keylen);
5336
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
5337
            ByteReverseWords(aes->key, aes->key, 32);
5338
        }
5339
#endif
5340
5341
    #if defined(WOLFSSL_DEVCRYPTO) && \
5342
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
5343
        aes->ctx.cfd = -1;
5344
    #endif
5345
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5346
        ForceZero(local, sizeof(local));
5347
    #endif
5348
6.59k
        return ret;
5349
6.59k
#endif
5350
5351
6.59k
#endif /* !WC_C_DYNAMIC_FALLBACK */
5352
5353
6.59k
    } /* wc_AesSetKeyLocal */
5354
5355
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5356
            const byte* iv, int dir)
5357
5.96k
    {
5358
5.96k
        if (aes == NULL) {
5359
0
            return BAD_FUNC_ARG;
5360
0
        }
5361
5.96k
        if (keylen > sizeof(aes->key)) {
5362
0
            return BAD_FUNC_ARG;
5363
0
        }
5364
5365
    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
5366
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
5367
        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
5368
        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
5369
            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
5370
            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
5371
        }
5372
        else {
5373
        #if  defined(WOLFSSL_HW_METRICS)
5374
            /* It is interesting to know how many times we could not complete
5375
             * AES in hardware due to unsupported lengths. */
5376
            wc_esp32AesUnupportedLengthCountAdd();
5377
        #endif
5378
        #ifdef DEBUG_WOLFSSL
5379
            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
5380
                           keylen);
5381
        #endif
5382
        }
5383
    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
5384
5385
5.96k
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
5386
5387
5.96k
    } /* wc_AesSetKey() */
5388
#endif
5389
5390
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5391
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5392
        /* This function allows key sizes that are not 128/192/256 bits */
5393
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5394
                           const byte* iv, int dir)
5395
631
    {
5396
631
        if (aes == NULL) {
5397
0
            return BAD_FUNC_ARG;
5398
0
        }
5399
631
        if (keylen > sizeof(aes->key)) {
5400
0
            return BAD_FUNC_ARG;
5401
0
        }
5402
5403
631
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
5404
631
    }
5405
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5406
#endif /* wc_AesSetKey block */
5407
5408
5409
/* wc_AesSetIV is shared between software and hardware */
5410
int wc_AesSetIV(Aes* aes, const byte* iv)
5411
7.28k
{
5412
7.28k
    if (aes == NULL)
5413
0
        return BAD_FUNC_ARG;
5414
5415
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5416
    {
5417
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5418
        if (ret < 0)
5419
            return ret;
5420
    }
5421
#endif
5422
5423
7.28k
    if (iv)
5424
3.91k
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5425
3.36k
    else
5426
3.36k
        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
5427
5428
7.28k
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5429
7.28k
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5430
7.28k
    defined(WOLFSSL_AES_CTS)
5431
    /* Clear any unused bytes from last cipher op. */
5432
7.28k
    aes->left = 0;
5433
7.28k
#endif
5434
5435
7.28k
    return 0;
5436
7.28k
}
5437
5438
#ifdef WOLFSSL_AESNI
5439
5440
#ifdef WC_C_DYNAMIC_FALLBACK
5441
5442
#define VECTOR_REGISTERS_PUSH {                                      \
5443
        int orig_use_aesni = aes->use_aesni;                         \
5444
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
5445
            aes->use_aesni = 0;                                      \
5446
        }                                                            \
5447
        WC_DO_NOTHING
5448
5449
#define VECTOR_REGISTERS_POP                                         \
5450
        if (aes->use_aesni)                                          \
5451
            RESTORE_VECTOR_REGISTERS();                              \
5452
        else                                                         \
5453
            aes->use_aesni = orig_use_aesni;                         \
5454
    }                                                                \
5455
    WC_DO_NOTHING
5456
5457
#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
5458
5459
#define VECTOR_REGISTERS_PUSH { \
5460
        WC_DO_NOTHING
5461
5462
#define VECTOR_REGISTERS_POP                                         \
5463
    }                                                                \
5464
    WC_DO_NOTHING
5465
5466
#else
5467
5468
#define VECTOR_REGISTERS_PUSH { \
5469
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
5470
            return ret;                                                  \
5471
        }                                                                \
5472
        WC_DO_NOTHING
5473
5474
#define VECTOR_REGISTERS_POP \
5475
        if (aes->use_aesni) {                                            \
5476
            RESTORE_VECTOR_REGISTERS();                                  \
5477
        }                                                                \
5478
    }                                                                    \
5479
    WC_DO_NOTHING
5480
5481
#endif
5482
5483
#else /* !WOLFSSL_AESNI */
5484
5485
13.6k
#define VECTOR_REGISTERS_PUSH WC_DO_NOTHING
5486
13.6k
#define VECTOR_REGISTERS_POP WC_DO_NOTHING
5487
5488
#endif /* !WOLFSSL_AESNI */
5489
5490
5491
/* AES-DIRECT */
5492
#if defined(WOLFSSL_AES_DIRECT)
5493
    #if defined(HAVE_COLDFIRE_SEC)
5494
        #error "Coldfire SEC doesn't yet support AES direct"
5495
5496
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
5497
        !defined(WOLFSSL_QNX_CAAM)
5498
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
5499
5500
    #elif defined(WOLFSSL_AFALG)
5501
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
5502
5503
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
5504
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
5505
5506
    #else
5507
5508
        /* Allow direct access to one block encrypt */
5509
        /* Note, the in and out args are swapped compared to wc_AesEncrypt(). */
5510
        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
5511
490
        {
5512
490
            int ret;
5513
5514
490
            if (aes == NULL || out == NULL || in == NULL)
5515
0
                return BAD_FUNC_ARG;
5516
490
            VECTOR_REGISTERS_PUSH;
5517
490
            ret = wc_AesEncrypt(aes, in, out);
5518
490
            VECTOR_REGISTERS_POP;
5519
490
            return ret;
5520
490
        }
5521
5522
        /* vector reg save/restore is explicit in all below calls to
5523
         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
5524
         * macro.
5525
         */
5526
611
        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
5527
5528
        #ifdef HAVE_AES_DECRYPT
5529
        /* Allow direct access to one block decrypt */
5530
        /* Note, the in and out args are swapped compared to wc_AesDecrypt(). */
5531
        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
5532
0
        {
5533
0
            int ret;
5534
5535
0
            if (aes == NULL)
5536
0
                return BAD_FUNC_ARG;
5537
0
            VECTOR_REGISTERS_PUSH;
5538
0
            ret = wc_AesDecrypt(aes, in, out);
5539
0
            VECTOR_REGISTERS_POP;
5540
0
            return ret;
5541
0
        }
5542
5543
120
        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
5544
5545
        #endif /* HAVE_AES_DECRYPT */
5546
    #endif /* AES direct block */
5547
#endif /* WOLFSSL_AES_DIRECT */
5548
5549
5550
/* AES-CBC */
5551
#ifdef HAVE_AES_CBC
5552
#if defined(STM32_CRYPTO)
5553
5554
#ifdef WOLFSSL_STM32U5_DHUK
5555
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5556
    {
5557
        int ret = 0;
5558
        CRYP_HandleTypeDef hcryp;
5559
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5560
5561
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5562
        if (sz % WC_AES_BLOCK_SIZE) {
5563
            return BAD_LENGTH_E;
5564
        }
5565
#endif
5566
        if (blocks == 0)
5567
            return 0;
5568
5569
        ret = wolfSSL_CryptHwMutexLock();
5570
        if (ret != 0) {
5571
            return ret;
5572
        }
5573
5574
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
5575
            CRYP_ConfigTypeDef Config;
5576
5577
            XMEMSET(&Config, 0, sizeof(Config));
5578
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen,
5579
                (const byte*)aes->dhukIV, aes->dhukIVLen);
5580
5581
            /* reconfigure for using unwrapped key now */
5582
            HAL_CRYP_GetConfig(&hcryp, &Config);
5583
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
5584
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
5585
            Config.Algorithm = CRYP_AES_CBC;
5586
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5587
            Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5588
            HAL_CRYP_SetConfig(&hcryp, &Config);
5589
        }
5590
        else {
5591
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
5592
            if (ret != 0) {
5593
                wolfSSL_CryptHwMutexUnLock();
5594
                return ret;
5595
            }
5596
            hcryp.Init.Algorithm  = CRYP_AES_CBC;
5597
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5598
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5599
            ret = HAL_CRYP_Init(&hcryp);
5600
        }
5601
5602
        if (ret == HAL_OK) {
5603
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5604
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5605
            if (ret != HAL_OK) {
5606
                ret = WC_TIMEOUT_E;
5607
            }
5608
5609
            /* store iv for next call */
5610
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5611
        }
5612
5613
        HAL_CRYP_DeInit(&hcryp);
5614
5615
        wolfSSL_CryptHwMutexUnLock();
5616
        wc_Stm32_Aes_Cleanup();
5617
5618
        return ret;
5619
    }
5620
    #ifdef HAVE_AES_DECRYPT
5621
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5622
    {
5623
        int ret = 0;
5624
        CRYP_HandleTypeDef hcryp;
5625
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5626
5627
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5628
        if (sz % WC_AES_BLOCK_SIZE) {
5629
            return BAD_LENGTH_E;
5630
        }
5631
#endif
5632
        if (blocks == 0)
5633
            return 0;
5634
5635
        ret = wolfSSL_CryptHwMutexLock();
5636
        if (ret != 0) {
5637
            return ret;
5638
        }
5639
5640
        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
5641
            CRYP_ConfigTypeDef Config;
5642
5643
            XMEMSET(&Config, 0, sizeof(Config));
5644
            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen,
5645
                aes->dhukIV, aes->dhukIVLen);
5646
5647
            /* reconfigure for using unwrapped key now */
5648
            HAL_CRYP_GetConfig(&hcryp, &Config);
5649
            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
5650
            Config.KeySelect = CRYP_KEYSEL_NORMAL;
5651
            Config.Algorithm = CRYP_AES_CBC;
5652
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5653
            Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5654
            HAL_CRYP_SetConfig(&hcryp, &Config);
5655
        }
5656
        else {
5657
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
5658
            if (ret != 0) {
5659
                wolfSSL_CryptHwMutexUnLock();
5660
                return ret;
5661
            }
5662
            hcryp.Init.Algorithm  = CRYP_AES_CBC;
5663
            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5664
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5665
            ret = HAL_CRYP_Init(&hcryp);
5666
        }
5667
5668
        if (ret == HAL_OK) {
5669
            /* if input and output same will overwrite input iv */
5670
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5671
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5672
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5673
            if (ret != HAL_OK) {
5674
                ret = WC_TIMEOUT_E;
5675
            }
5676
5677
            /* store iv for next call */
5678
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5679
        }
5680
5681
        HAL_CRYP_DeInit(&hcryp);
5682
        wolfSSL_CryptHwMutexUnLock();
5683
        wc_Stm32_Aes_Cleanup();
5684
5685
        return ret;
5686
    }
5687
    #endif /* HAVE_AES_DECRYPT */
5688
5689
#elif defined(WOLFSSL_STM32_CUBEMX)
5690
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5691
    {
5692
        int ret = 0;
5693
        CRYP_HandleTypeDef hcryp;
5694
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5695
5696
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5697
        if (sz % WC_AES_BLOCK_SIZE) {
5698
            return BAD_LENGTH_E;
5699
        }
5700
#endif
5701
        if (blocks == 0)
5702
            return 0;
5703
5704
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
5705
        if (ret != 0)
5706
            return ret;
5707
5708
        ret = wolfSSL_CryptHwMutexLock();
5709
        if (ret != 0) {
5710
            return ret;
5711
        }
5712
5713
    #if defined(STM32_HAL_V2)
5714
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
5715
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5716
    #elif defined(STM32_CRYPTO_AES_ONLY)
5717
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
5718
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
5719
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
5720
    #endif
5721
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5722
        ret = HAL_CRYP_Init(&hcryp);
5723
5724
        if (ret == HAL_OK) {
5725
        #if defined(STM32_HAL_V2)
5726
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5727
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5728
        #elif defined(STM32_CRYPTO_AES_ONLY)
5729
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
5730
                out, STM32_HAL_TIMEOUT);
5731
        #else
5732
            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
5733
                                        blocks * WC_AES_BLOCK_SIZE,
5734
                                        out, STM32_HAL_TIMEOUT);
5735
        #endif
5736
        }
5737
        if (ret != HAL_OK) {
5738
            ret = WC_TIMEOUT_E;
5739
        }
5740
5741
        /* store iv for next call */
5742
        XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5743
5744
        HAL_CRYP_DeInit(&hcryp);
5745
5746
        wolfSSL_CryptHwMutexUnLock();
5747
        wc_Stm32_Aes_Cleanup();
5748
5749
        return ret;
5750
    }
5751
    #ifdef HAVE_AES_DECRYPT
5752
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5753
    {
5754
        int ret = 0;
5755
        CRYP_HandleTypeDef hcryp;
5756
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5757
5758
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5759
        if (sz % WC_AES_BLOCK_SIZE) {
5760
            return BAD_LENGTH_E;
5761
        }
5762
#endif
5763
        if (blocks == 0)
5764
            return 0;
5765
5766
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
5767
        if (ret != 0)
5768
            return ret;
5769
5770
        ret = wolfSSL_CryptHwMutexLock();
5771
        if (ret != 0) {
5772
            return ret;
5773
        }
5774
5775
        /* if input and output same will overwrite input iv */
5776
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5777
5778
    #if defined(STM32_HAL_V2)
5779
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
5780
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5781
    #elif defined(STM32_CRYPTO_AES_ONLY)
5782
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
5783
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
5784
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
5785
    #endif
5786
5787
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5788
        ret = HAL_CRYP_Init(&hcryp);
5789
5790
        if (ret == HAL_OK) {
5791
        #if defined(STM32_HAL_V2)
5792
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5793
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5794
        #elif defined(STM32_CRYPTO_AES_ONLY)
5795
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
5796
                out, STM32_HAL_TIMEOUT);
5797
        #else
5798
            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
5799
                                        blocks * WC_AES_BLOCK_SIZE,
5800
                out, STM32_HAL_TIMEOUT);
5801
        #endif
5802
        }
5803
        if (ret != HAL_OK) {
5804
            ret = WC_TIMEOUT_E;
5805
        }
5806
5807
        /* store iv for next call */
5808
        XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5809
5810
        HAL_CRYP_DeInit(&hcryp);
5811
        wolfSSL_CryptHwMutexUnLock();
5812
        wc_Stm32_Aes_Cleanup();
5813
5814
        return ret;
5815
    }
5816
    #endif /* HAVE_AES_DECRYPT */
5817
5818
#else /* Standard Peripheral Library */
5819
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5820
    {
5821
        int ret;
5822
        word32 *iv;
5823
        CRYP_InitTypeDef cryptInit;
5824
        CRYP_KeyInitTypeDef keyInit;
5825
        CRYP_IVInitTypeDef ivInit;
5826
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5827
5828
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5829
        if (sz % WC_AES_BLOCK_SIZE) {
5830
            return BAD_LENGTH_E;
5831
        }
5832
#endif
5833
        if (blocks == 0)
5834
            return 0;
5835
5836
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
5837
        if (ret != 0)
5838
            return ret;
5839
5840
        ret = wolfSSL_CryptHwMutexLock();
5841
        if (ret != 0) {
5842
            return ret;
5843
        }
5844
5845
        /* reset registers to their default values */
5846
        CRYP_DeInit();
5847
5848
        /* set key */
5849
        CRYP_KeyInit(&keyInit);
5850
5851
        /* set iv */
5852
        iv = aes->reg;
5853
        CRYP_IVStructInit(&ivInit);
5854
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
5855
        ivInit.CRYP_IV0Left  = iv[0];
5856
        ivInit.CRYP_IV0Right = iv[1];
5857
        ivInit.CRYP_IV1Left  = iv[2];
5858
        ivInit.CRYP_IV1Right = iv[3];
5859
        CRYP_IVInit(&ivInit);
5860
5861
        /* set direction and mode */
5862
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
5863
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
5864
        CRYP_Init(&cryptInit);
5865
5866
        /* enable crypto processor */
5867
        CRYP_Cmd(ENABLE);
5868
5869
        while (blocks--) {
5870
            /* flush IN/OUT FIFOs */
5871
            CRYP_FIFOFlush();
5872
5873
            CRYP_DataIn(*(uint32_t*)&in[0]);
5874
            CRYP_DataIn(*(uint32_t*)&in[4]);
5875
            CRYP_DataIn(*(uint32_t*)&in[8]);
5876
            CRYP_DataIn(*(uint32_t*)&in[12]);
5877
5878
            /* wait until the complete message has been processed */
5879
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5880
5881
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5882
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5883
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5884
            *(uint32_t*)&out[12] = CRYP_DataOut();
5885
5886
            /* store iv for next call */
5887
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5888
5889
            sz  -= WC_AES_BLOCK_SIZE;
5890
            in  += WC_AES_BLOCK_SIZE;
5891
            out += WC_AES_BLOCK_SIZE;
5892
        }
5893
5894
        /* disable crypto processor */
5895
        CRYP_Cmd(DISABLE);
5896
        wolfSSL_CryptHwMutexUnLock();
5897
        wc_Stm32_Aes_Cleanup();
5898
5899
        return ret;
5900
    }
5901
5902
    #ifdef HAVE_AES_DECRYPT
5903
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5904
    {
5905
        int ret;
5906
        word32 *iv;
5907
        CRYP_InitTypeDef cryptInit;
5908
        CRYP_KeyInitTypeDef keyInit;
5909
        CRYP_IVInitTypeDef ivInit;
5910
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5911
5912
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5913
        if (sz % WC_AES_BLOCK_SIZE) {
5914
            return BAD_LENGTH_E;
5915
        }
5916
#endif
5917
        if (blocks == 0)
5918
            return 0;
5919
5920
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
5921
        if (ret != 0)
5922
            return ret;
5923
5924
        ret = wolfSSL_CryptHwMutexLock();
5925
        if (ret != 0) {
5926
            return ret;
5927
        }
5928
5929
        /* if input and output same will overwrite input iv */
5930
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5931
5932
        /* reset registers to their default values */
5933
        CRYP_DeInit();
5934
5935
        /* set direction and key */
5936
        CRYP_KeyInit(&keyInit);
5937
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5938
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
5939
        CRYP_Init(&cryptInit);
5940
5941
        /* enable crypto processor */
5942
        CRYP_Cmd(ENABLE);
5943
5944
        /* wait until key has been prepared */
5945
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5946
5947
        /* set direction and mode */
5948
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5949
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
5950
        CRYP_Init(&cryptInit);
5951
5952
        /* set iv */
5953
        iv = aes->reg;
5954
        CRYP_IVStructInit(&ivInit);
5955
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
5956
        ivInit.CRYP_IV0Left  = iv[0];
5957
        ivInit.CRYP_IV0Right = iv[1];
5958
        ivInit.CRYP_IV1Left  = iv[2];
5959
        ivInit.CRYP_IV1Right = iv[3];
5960
        CRYP_IVInit(&ivInit);
5961
5962
        /* enable crypto processor */
5963
        CRYP_Cmd(ENABLE);
5964
5965
        while (blocks--) {
5966
            /* flush IN/OUT FIFOs */
5967
            CRYP_FIFOFlush();
5968
5969
            CRYP_DataIn(*(uint32_t*)&in[0]);
5970
            CRYP_DataIn(*(uint32_t*)&in[4]);
5971
            CRYP_DataIn(*(uint32_t*)&in[8]);
5972
            CRYP_DataIn(*(uint32_t*)&in[12]);
5973
5974
            /* wait until the complete message has been processed */
5975
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5976
5977
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5978
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5979
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5980
            *(uint32_t*)&out[12] = CRYP_DataOut();
5981
5982
            /* store iv for next call */
5983
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5984
5985
            in  += WC_AES_BLOCK_SIZE;
5986
            out += WC_AES_BLOCK_SIZE;
5987
        }
5988
5989
        /* disable crypto processor */
5990
        CRYP_Cmd(DISABLE);
5991
        wolfSSL_CryptHwMutexUnLock();
5992
        wc_Stm32_Aes_Cleanup();
5993
5994
        return ret;
5995
    }
5996
    #endif /* HAVE_AES_DECRYPT */
5997
#endif /* WOLFSSL_STM32_CUBEMX */
5998
5999
#elif defined(HAVE_COLDFIRE_SEC)
6000
    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
6001
        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
6002
    {
6003
        #ifdef DEBUG_WOLFSSL
6004
            int i; int stat1, stat2; int ret;
6005
        #endif
6006
6007
        int size;
6008
        volatile int v;
6009
6010
        if ((pi == NULL) || (po == NULL))
6011
            return BAD_FUNC_ARG;    /*wrong pointer*/
6012
6013
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6014
        if (sz % WC_AES_BLOCK_SIZE) {
6015
            return BAD_LENGTH_E;
6016
        }
6017
#endif
6018
6019
        wc_LockMutex(&Mutex_AesSEC);
6020
6021
        /* Set descriptor for SEC */
6022
        secDesc->length1 = 0x0;
6023
        secDesc->pointer1 = NULL;
6024
6025
        secDesc->length2 = WC_AES_BLOCK_SIZE;
6026
        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
6027
6028
        switch(aes->rounds) {
6029
            case 10: secDesc->length3 = 16; break;
6030
            case 12: secDesc->length3 = 24; break;
6031
            case 14: secDesc->length3 = 32; break;
6032
        }
6033
        XMEMCPY(secKey, aes->key, secDesc->length3);
6034
6035
        secDesc->pointer3 = (byte *)secKey;
6036
        secDesc->pointer4 = AESBuffIn;
6037
        secDesc->pointer5 = AESBuffOut;
6038
        secDesc->length6 = 0x0;
6039
        secDesc->pointer6 = NULL;
6040
        secDesc->length7 = 0x0;
6041
        secDesc->pointer7 = NULL;
6042
        secDesc->nextDescriptorPtr = NULL;
6043
6044
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6045
        size = AES_BUFFER_SIZE;
6046
#endif
6047
        while (sz) {
6048
            secDesc->header = descHeader;
6049
            XMEMCPY(secReg, aes->reg, WC_AES_BLOCK_SIZE);
6050
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6051
            sz -= AES_BUFFER_SIZE;
6052
#else
6053
            if (sz < AES_BUFFER_SIZE) {
6054
                size = sz;
6055
                sz = 0;
6056
            } else {
6057
                size = AES_BUFFER_SIZE;
6058
                sz -= AES_BUFFER_SIZE;
6059
            }
6060
#endif
6061
6062
            secDesc->length4 = size;
6063
            secDesc->length5 = size;
6064
6065
            XMEMCPY(AESBuffIn, pi, size);
6066
            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
6067
                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-WC_AES_BLOCK_SIZE]),
6068
                        WC_AES_BLOCK_SIZE);
6069
            }
6070
6071
            /* Point SEC to the location of the descriptor */
6072
            MCF_SEC_FR0 = (uint32)secDesc;
6073
            /* Initialize SEC and wait for encryption to complete */
6074
            MCF_SEC_CCCR0 = 0x0000001a;
6075
            /* poll SISR to determine when channel is complete */
6076
            v=0;
6077
6078
            while ((secDesc->header>> 24) != 0xff) v++;
6079
6080
            #ifdef DEBUG_WOLFSSL
6081
                ret = MCF_SEC_SISRH;
6082
                stat1 = MCF_SEC_AESSR;
6083
                stat2 = MCF_SEC_AESISR;
6084
                if (ret & 0xe0000000) {
6085
                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
6086
                              "AESISR=%08x\n", i, ret, stat1, stat2);
6087
                }
6088
            #endif
6089
6090
            XMEMCPY(po, AESBuffOut, size);
6091
6092
            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
6093
                XMEMCPY((void*)aes->reg, (void*)&(po[size-WC_AES_BLOCK_SIZE]),
6094
                        WC_AES_BLOCK_SIZE);
6095
            } else {
6096
                XMEMCPY((void*)aes->reg, (void*)aes->tmp, WC_AES_BLOCK_SIZE);
6097
            }
6098
6099
            pi += size;
6100
            po += size;
6101
        }
6102
6103
        wc_UnLockMutex(&Mutex_AesSEC);
6104
        return 0;
6105
    }
6106
6107
    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6108
    {
6109
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
6110
    }
6111
6112
    #ifdef HAVE_AES_DECRYPT
6113
    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6114
    {
6115
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
6116
    }
6117
    #endif /* HAVE_AES_DECRYPT */
6118
6119
#elif defined(FREESCALE_LTC)
6120
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6121
    {
6122
        word32 keySize;
6123
        status_t status;
6124
        byte *iv, *enc_key;
6125
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6126
6127
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6128
        if (sz % WC_AES_BLOCK_SIZE) {
6129
            return BAD_LENGTH_E;
6130
        }
6131
#endif
6132
        if (blocks == 0)
6133
            return 0;
6134
6135
        iv      = (byte*)aes->reg;
6136
        enc_key = (byte*)aes->key;
6137
6138
        status = wc_AesGetKeySize(aes, &keySize);
6139
        if (status != 0) {
6140
            return status;
6141
        }
6142
6143
        status = wolfSSL_CryptHwMutexLock();
6144
        if (status != 0)
6145
            return status;
6146
        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6147
            iv, enc_key, keySize);
6148
        wolfSSL_CryptHwMutexUnLock();
6149
6150
        /* store iv for next call */
6151
        if (status == kStatus_Success) {
6152
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6153
        }
6154
6155
        return (status == kStatus_Success) ? 0 : -1;
6156
    }
6157
6158
    #ifdef HAVE_AES_DECRYPT
6159
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6160
    {
6161
        word32 keySize;
6162
        status_t status;
6163
        byte* iv, *dec_key;
6164
        byte temp_block[WC_AES_BLOCK_SIZE];
6165
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6166
6167
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6168
        if (sz % WC_AES_BLOCK_SIZE) {
6169
            return BAD_LENGTH_E;
6170
        }
6171
#endif
6172
        if (blocks == 0)
6173
            return 0;
6174
6175
        iv      = (byte*)aes->reg;
6176
        dec_key = (byte*)aes->key;
6177
6178
        status = wc_AesGetKeySize(aes, &keySize);
6179
        if (status != 0) {
6180
            return status;
6181
        }
6182
6183
        /* get IV for next call */
6184
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6185
6186
        status = wolfSSL_CryptHwMutexLock();
6187
        if (status != 0)
6188
            return status;
6189
        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6190
            iv, dec_key, keySize, kLTC_EncryptKey);
6191
        wolfSSL_CryptHwMutexUnLock();
6192
6193
        /* store IV for next call */
6194
        if (status == kStatus_Success) {
6195
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6196
        }
6197
6198
        return (status == kStatus_Success) ? 0 : -1;
6199
    }
6200
    #endif /* HAVE_AES_DECRYPT */
6201
6202
#elif defined(FREESCALE_MMCAU) && !defined(WOLFSSL_ARMASM)
6203
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6204
    {
6205
        int offset = 0;
6206
        byte *iv;
6207
        byte temp_block[WC_AES_BLOCK_SIZE];
6208
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6209
        int ret;
6210
6211
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6212
        if (sz % WC_AES_BLOCK_SIZE) {
6213
            return BAD_LENGTH_E;
6214
        }
6215
#endif
6216
        if (blocks == 0)
6217
            return 0;
6218
6219
        iv = (byte*)aes->reg;
6220
6221
        while (blocks--) {
6222
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
6223
6224
            /* XOR block with IV for CBC */
6225
            xorbuf(temp_block, iv, WC_AES_BLOCK_SIZE);
6226
6227
            ret = wc_AesEncrypt(aes, temp_block, out + offset);
6228
            if (ret != 0)
6229
                return ret;
6230
6231
            offset += WC_AES_BLOCK_SIZE;
6232
6233
            /* store IV for next block */
6234
            XMEMCPY(iv, out + offset - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6235
        }
6236
6237
        return 0;
6238
    }
6239
    #ifdef HAVE_AES_DECRYPT
6240
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6241
    {
6242
        int ret;
6243
        int offset = 0;
6244
        byte* iv;
6245
        byte temp_block[WC_AES_BLOCK_SIZE];
6246
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6247
6248
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6249
        if (sz % WC_AES_BLOCK_SIZE) {
6250
            return BAD_LENGTH_E;
6251
        }
6252
#endif
6253
        if (blocks == 0)
6254
            return 0;
6255
6256
        iv = (byte*)aes->reg;
6257
6258
        while (blocks--) {
6259
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
6260
6261
            ret = wc_AesDecrypt(aes, in + offset, out + offset);
6262
            if (ret != 0)
6263
                return ret;
6264
6265
            /* XOR block with IV for CBC */
6266
            xorbuf(out + offset, iv, WC_AES_BLOCK_SIZE);
6267
6268
            /* store IV for next block */
6269
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6270
6271
            offset += WC_AES_BLOCK_SIZE;
6272
        }
6273
        return 0;
6274
    }
6275
    #endif /* HAVE_AES_DECRYPT */
6276
6277
#elif defined(MAX3266X_AES)
6278
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6279
    {
6280
        word32 keySize;
6281
        int status;
6282
        byte *iv;
6283
6284
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
6285
            return BAD_FUNC_ARG;
6286
        }
6287
6288
        /* Always enforce a length check */
6289
        if (sz % WC_AES_BLOCK_SIZE) {
6290
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6291
            return BAD_LENGTH_E;
6292
        #else
6293
            return BAD_FUNC_ARG;
6294
        #endif
6295
        }
6296
        if (sz == 0) {
6297
            return 0;
6298
        }
6299
6300
        iv = (byte*)aes->reg;
6301
        status = wc_AesGetKeySize(aes, &keySize);
6302
        if (status != 0) {
6303
            return status;
6304
        }
6305
6306
        status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
6307
                                        MXC_TPU_MODE_CBC, sz, out,
6308
                                        (unsigned int)keySize);
6309
        /* store iv for next call */
6310
        if (status == 0) {
6311
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6312
        }
6313
        return (status == 0) ? 0 : -1;
6314
    }
6315
6316
    #ifdef HAVE_AES_DECRYPT
6317
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6318
    {
6319
        word32 keySize;
6320
        int status;
6321
        byte *iv;
6322
        byte temp_block[WC_AES_BLOCK_SIZE];
6323
6324
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
6325
            return BAD_FUNC_ARG;
6326
        }
6327
6328
        /* Always enforce a length check */
6329
        if (sz % WC_AES_BLOCK_SIZE) {
6330
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6331
            return BAD_LENGTH_E;
6332
        #else
6333
            return BAD_FUNC_ARG;
6334
        #endif
6335
        }
6336
        if (sz == 0) {
6337
            return 0;
6338
        }
6339
6340
        iv = (byte*)aes->reg;
6341
        status = wc_AesGetKeySize(aes, &keySize);
6342
        if (status != 0) {
6343
            return status;
6344
        }
6345
6346
        /* get IV for next call */
6347
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6348
        status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
6349
                                        MXC_TPU_MODE_CBC, sz, out,
6350
                                        keySize);
6351
6352
        /* store iv for next call */
6353
        if (status == 0) {
6354
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6355
        }
6356
        return (status == 0) ? 0 : -1;
6357
    }
6358
    #endif /* HAVE_AES_DECRYPT */
6359
6360
6361
6362
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
6363
6364
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6365
    {
6366
        int ret;
6367
6368
        if (sz == 0)
6369
            return 0;
6370
6371
        /* hardware fails on input that is not a multiple of AES block size */
6372
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6373
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6374
            return BAD_LENGTH_E;
6375
#else
6376
            return BAD_FUNC_ARG;
6377
#endif
6378
        }
6379
6380
        ret = wc_Pic32AesCrypt(
6381
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6382
            out, in, sz, PIC32_ENCRYPTION,
6383
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6384
6385
        /* store iv for next call */
6386
        if (ret == 0) {
6387
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6388
        }
6389
6390
        return ret;
6391
    }
6392
    #ifdef HAVE_AES_DECRYPT
6393
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6394
    {
6395
        int ret;
6396
        byte scratch[WC_AES_BLOCK_SIZE];
6397
6398
        if (sz == 0)
6399
            return 0;
6400
6401
        /* hardware fails on input that is not a multiple of AES block size */
6402
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6403
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6404
            return BAD_LENGTH_E;
6405
#else
6406
            return BAD_FUNC_ARG;
6407
#endif
6408
        }
6409
        XMEMCPY(scratch, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6410
6411
        ret = wc_Pic32AesCrypt(
6412
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6413
            out, in, sz, PIC32_DECRYPTION,
6414
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6415
6416
        /* store iv for next call */
6417
        if (ret == 0) {
6418
            XMEMCPY((byte*)aes->reg, scratch, WC_AES_BLOCK_SIZE);
6419
        }
6420
6421
        return ret;
6422
    }
6423
    #endif /* HAVE_AES_DECRYPT */
6424
#elif defined(WOLFSSL_ESP32_CRYPT) && \
6425
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6426
6427
    /* We'll use SW for fall back:
6428
     *   unsupported key lengths
6429
     *   hardware busy */
6430
    #define NEED_SW_AESCBC
6431
    #define NEED_AESCBC_HW_FALLBACK
6432
6433
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
6434
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6435
    {
6436
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6437
    }
6438
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6439
    {
6440
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6441
    }
6442
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6443
        !defined(WOLFSSL_QNX_CAAM)
6444
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6445
6446
#elif defined(WOLFSSL_AFALG)
6447
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6448
6449
#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
6450
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
6451
6452
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
6453
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6454
6455
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
6456
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
6457
6458
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6459
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
6460
6461
#elif defined(WOLFSSL_PSOC6_CRYPTO)
6462
6463
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6464
    {
6465
        return wc_Psoc6_Aes_CbcEncrypt(aes, out, in, sz);
6466
    }
6467
6468
    #if defined(HAVE_AES_DECRYPT)
6469
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6470
    {
6471
        return wc_Psoc6_Aes_CbcDecrypt(aes, out, in, sz);
6472
    }
6473
    #endif /* HAVE_AES_DECRYPT */
6474
6475
#else
6476
    /* Reminder: Some HW implementations may also define this as needed.
6477
     * (e.g. for unsupported key length fallback)  */
6478
    #define NEED_SW_AESCBC
6479
#endif
6480
6481
#ifdef NEED_SW_AESCBC
6482
    /* Software AES - CBC Encrypt */
6483
6484
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6485
666
    {
6486
666
#if !defined(WOLFSSL_ARMASM)
6487
666
        word32 blocks;
6488
666
        int ret;
6489
666
#endif
6490
6491
666
        if (aes == NULL || out == NULL || in == NULL) {
6492
0
            return BAD_FUNC_ARG;
6493
0
        }
6494
6495
666
        if (sz == 0) {
6496
0
            return 0;
6497
0
        }
6498
6499
666
#if !defined(WOLFSSL_ARMASM)
6500
666
        blocks = sz / WC_AES_BLOCK_SIZE;
6501
666
#endif
6502
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6503
        if (sz % WC_AES_BLOCK_SIZE) {
6504
            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
6505
            return BAD_LENGTH_E;
6506
        }
6507
#endif
6508
6509
    #ifdef WOLFSSL_IMXRT_DCP
6510
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
6511
        if (aes->keylen == 16)
6512
            return DCPAesCbcEncrypt(aes, out, in, sz);
6513
    #endif
6514
6515
666
    #ifdef WOLF_CRYPTO_CB
6516
666
        #ifndef WOLF_CRYPTO_CB_FIND
6517
666
        if (aes->devId != INVALID_DEVID)
6518
0
        #endif
6519
0
        {
6520
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6521
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6522
0
                return crypto_cb_ret;
6523
            /* fall-through when unavailable */
6524
0
        }
6525
666
    #endif
6526
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
6527
        /* if async and byte count above threshold */
6528
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
6529
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
6530
        #if defined(HAVE_CAVIUM)
6531
            return NitroxAesCbcEncrypt(aes, out, in, sz);
6532
        #elif defined(HAVE_INTEL_QA)
6533
            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
6534
                (const byte*)aes->devKey, aes->keylen,
6535
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6536
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
6537
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
6538
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
6539
                sw->aes.aes = aes;
6540
                sw->aes.out = out;
6541
                sw->aes.in = in;
6542
                sw->aes.sz = sz;
6543
                return WC_PENDING_E;
6544
            }
6545
        #endif
6546
        }
6547
    #endif /* WOLFSSL_ASYNC_CRYPT */
6548
6549
#if defined(WOLFSSL_ARMASM)
6550
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
6551
    #if !defined(__aarch64__)
6552
        AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
6553
            (int)aes->rounds);
6554
    #else
6555
        if (aes->use_aes_hw_crypto) {
6556
            AES_CBC_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
6557
                (byte*)aes->key, (int)aes->rounds);
6558
        }
6559
        else
6560
    #endif /* __aarch64__ */
6561
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
6562
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
6563
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
6564
        {
6565
            AES_CBC_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
6566
                aes->rounds, (unsigned char*)aes->reg);
6567
        }
6568
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6569
        {
6570
            AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
6571
                aes->rounds, (unsigned char*)aes->reg);
6572
        }
6573
    #endif
6574
        return 0;
6575
#else
6576
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
6577
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
6578
        if (aes->useSWCrypt == 0) {
6579
            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
6580
                                   kAlgorithm_SSS_AES_CBC);
6581
        }
6582
        else
6583
    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
6584
        if (wc_esp32AesSupportedKeyLen(aes)) {
6585
            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
6586
            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
6587
        }
6588
        else {
6589
            /* For example, the ESP32-S3 does not support HW for len = 24,
6590
             * so fall back to SW */
6591
        #ifdef DEBUG_WOLFSSL
6592
            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
6593
                          "unsupported keylen = %d", aes->keylen);
6594
        #endif
6595
        }
6596
    #elif defined(WOLFSSL_AESNI)
6597
        VECTOR_REGISTERS_PUSH;
6598
        if (aes->use_aesni) {
6599
            #ifdef DEBUG_AESNI
6600
                printf("about to aes cbc encrypt\n");
6601
                printf("in  = %p\n", in);
6602
                printf("out = %p\n", out);
6603
                printf("aes->key = %p\n", aes->key);
6604
                printf("aes->reg = %p\n", aes->reg);
6605
                printf("aes->rounds = %d\n", aes->rounds);
6606
                printf("sz = %d\n", sz);
6607
            #endif
6608
6609
            /* check alignment, decrypt doesn't need alignment */
6610
            if ((wc_ptr_t)in % AESNI_ALIGN) {
6611
            #ifndef NO_WOLFSSL_ALLOC_ALIGN
6612
                byte* tmp = (byte*)XMALLOC(sz + WC_AES_BLOCK_SIZE + AESNI_ALIGN,
6613
                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
6614
                byte* tmp_align;
6615
                if (tmp == NULL)
6616
                    ret = MEMORY_E;
6617
                else {
6618
                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
6619
                    XMEMCPY(tmp_align, in, sz);
6620
                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
6621
                                          (byte*)aes->key, (int)aes->rounds);
6622
                    /* store iv for next call */
6623
                    XMEMCPY(aes->reg, tmp_align + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6624
6625
                    XMEMCPY(out, tmp_align, sz);
6626
                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
6627
                    ret = 0;
6628
                }
6629
            #else
6630
                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
6631
                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
6632
                ret = BAD_ALIGN_E;
6633
            #endif
6634
            } else {
6635
                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6636
                                      (int)aes->rounds);
6637
                /* store iv for next call */
6638
                XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6639
6640
                ret = 0;
6641
            }
6642
        }
6643
        else
6644
    #endif
6645
666
        {
6646
666
#ifdef WC_AES_HAVE_PREFETCH_ARG
6647
666
            int did_prefetches = 0;
6648
666
#endif
6649
666
            ret = 0;
6650
5.19k
            while (blocks--) {
6651
4.52k
                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
6652
4.52k
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
6653
4.52k
                                                (byte*)aes->reg,
6654
4.52k
                                                &did_prefetches);
6655
4.52k
                if (ret != 0)
6656
0
                    break;
6657
4.52k
                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
6658
6659
4.52k
                out += WC_AES_BLOCK_SIZE;
6660
4.52k
                in  += WC_AES_BLOCK_SIZE;
6661
4.52k
            }
6662
666
        }
6663
6664
    #ifdef WOLFSSL_AESNI
6665
        VECTOR_REGISTERS_POP;
6666
    #endif
6667
6668
666
        return ret;
6669
666
#endif
6670
666
    } /* wc_AesCbcEncrypt */
6671
6672
#ifdef HAVE_AES_DECRYPT
6673
    /* Software AES - CBC Decrypt */
6674
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6675
400
    {
6676
400
#if !defined(WOLFSSL_ARMASM)
6677
400
        word32 blocks;
6678
400
        int ret;
6679
400
#endif
6680
6681
400
        if (aes == NULL || out == NULL || in == NULL) {
6682
0
            return BAD_FUNC_ARG;
6683
0
        }
6684
6685
400
        if (sz == 0) {
6686
0
            return 0;
6687
0
        }
6688
6689
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
6690
        if (wc_esp32AesSupportedKeyLen(aes)) {
6691
            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
6692
            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
6693
        }
6694
        else {
6695
            /* For example, the ESP32-S3 does not support HW for len = 24,
6696
             * so fall back to SW */
6697
        #ifdef DEBUG_WOLFSSL
6698
            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
6699
                          "unsupported keylen = %d", aes->keylen);
6700
        #endif
6701
        }
6702
    #endif
6703
6704
400
#if !defined(WOLFSSL_ARMASM)
6705
400
        blocks = sz / WC_AES_BLOCK_SIZE;
6706
400
#endif
6707
400
        if (sz % WC_AES_BLOCK_SIZE) {
6708
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6709
            return BAD_LENGTH_E;
6710
#else
6711
0
            return BAD_FUNC_ARG;
6712
0
#endif
6713
0
        }
6714
6715
    #ifdef WOLFSSL_IMXRT_DCP
6716
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
6717
        if (aes->keylen == 16)
6718
            return DCPAesCbcDecrypt(aes, out, in, sz);
6719
    #endif
6720
6721
400
    #ifdef WOLF_CRYPTO_CB
6722
400
        #ifndef WOLF_CRYPTO_CB_FIND
6723
400
        if (aes->devId != INVALID_DEVID)
6724
0
        #endif
6725
0
        {
6726
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6727
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6728
0
                return crypto_cb_ret;
6729
            /* fall-through when unavailable */
6730
0
        }
6731
400
    #endif
6732
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
6733
        /* if async and byte count above threshold */
6734
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
6735
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
6736
        #if defined(HAVE_CAVIUM)
6737
            return NitroxAesCbcDecrypt(aes, out, in, sz);
6738
        #elif defined(HAVE_INTEL_QA)
6739
            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
6740
                (const byte*)aes->devKey, aes->keylen,
6741
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6742
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
6743
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
6744
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
6745
                sw->aes.aes = aes;
6746
                sw->aes.out = out;
6747
                sw->aes.in = in;
6748
                sw->aes.sz = sz;
6749
                return WC_PENDING_E;
6750
            }
6751
        #endif
6752
        }
6753
    #endif
6754
6755
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
6756
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
6757
        if (aes->useSWCrypt == 0) {
6758
            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
6759
                                   kAlgorithm_SSS_AES_CBC);
6760
        }
6761
    #endif
6762
6763
#if defined(WOLFSSL_ARMASM)
6764
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
6765
    #if !defined(__aarch64__)
6766
        AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
6767
            (int)aes->rounds);
6768
    #else
6769
        if (aes->use_aes_hw_crypto) {
6770
            AES_CBC_decrypt_AARCH64(in, out, sz, (byte*)aes->reg,
6771
                (byte*)aes->key, (int)aes->rounds);
6772
        }
6773
        else
6774
    #endif /* !__aarch64__ */
6775
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
6776
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
6777
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
6778
        if (sz >= 64)
6779
    #endif
6780
        {
6781
            AES_CBC_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
6782
                aes->rounds, (unsigned char*)aes->reg);
6783
        }
6784
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
6785
        else
6786
    #endif
6787
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
6788
    #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6789
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
6790
        {
6791
            AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
6792
                aes->rounds, (unsigned char*)aes->reg);
6793
        }
6794
    #endif
6795
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
6796
        return 0;
6797
#else
6798
400
        VECTOR_REGISTERS_PUSH;
6799
6800
    #ifdef WOLFSSL_AESNI
6801
        if (aes->use_aesni) {
6802
            #ifdef DEBUG_AESNI
6803
                printf("about to aes cbc decrypt\n");
6804
                printf("in  = %p\n", in);
6805
                printf("out = %p\n", out);
6806
                printf("aes->key = %p\n", aes->key);
6807
                printf("aes->reg = %p\n", aes->reg);
6808
                printf("aes->rounds = %d\n", aes->rounds);
6809
                printf("sz = %d\n", sz);
6810
            #endif
6811
6812
            /* if input and output same will overwrite input iv */
6813
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6814
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
6815
            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6816
                            aes->rounds);
6817
            #elif defined(WOLFSSL_AESNI_BY6)
6818
            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6819
                            aes->rounds);
6820
            #else /* WOLFSSL_AESNI_BYx */
6821
            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6822
                            (int)aes->rounds);
6823
            #endif /* WOLFSSL_AESNI_BYx */
6824
            /* store iv for next call */
6825
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6826
            ret = 0;
6827
        }
6828
        else
6829
    #endif
6830
400
        {
6831
400
            ret = 0;
6832
#ifdef WC_AES_BITSLICED
6833
            if (in != out) {
6834
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
6835
6836
                while (blocks > BS_WORD_SIZE) {
6837
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
6838
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6839
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
6840
                              WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
6841
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
6842
                            WC_AES_BLOCK_SIZE);
6843
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6844
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6845
                    blocks -= BS_WORD_SIZE;
6846
                }
6847
                if (blocks > 0) {
6848
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
6849
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6850
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
6851
                              WC_AES_BLOCK_SIZE * (blocks - 1));
6852
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (blocks - 1)),
6853
                            WC_AES_BLOCK_SIZE);
6854
                    blocks = 0;
6855
                }
6856
            }
6857
            else {
6858
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
6859
                int i;
6860
6861
                while (blocks > BS_WORD_SIZE) {
6862
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
6863
                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * WC_AES_BLOCK_SIZE,
6864
                            WC_AES_BLOCK_SIZE);
6865
                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
6866
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
6867
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
6868
                                  WC_AES_BLOCK_SIZE);
6869
                    }
6870
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6871
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6872
6873
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6874
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6875
                    blocks -= BS_WORD_SIZE;
6876
                }
6877
                if (blocks > 0) {
6878
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
6879
                    XMEMCPY(aes->tmp, in + (blocks - 1) * WC_AES_BLOCK_SIZE,
6880
                            WC_AES_BLOCK_SIZE);
6881
                    for (i = blocks-1; i >= 1; i--) {
6882
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
6883
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
6884
                                  WC_AES_BLOCK_SIZE);
6885
                    }
6886
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6887
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6888
6889
                    blocks = 0;
6890
                }
6891
            }
6892
#else
6893
400
#ifdef WC_AES_HAVE_PREFETCH_ARG
6894
400
            {
6895
400
            int did_prefetches = 0;
6896
400
#endif
6897
11.2k
            while (blocks--) {
6898
10.8k
                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
6899
10.8k
                ret = AesDecrypt_preFetchOpt(aes, in, out, &did_prefetches);
6900
10.8k
                if (ret != 0)
6901
0
                    return ret;
6902
10.8k
                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6903
                /* store iv for next call */
6904
10.8k
                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6905
6906
10.8k
                out += WC_AES_BLOCK_SIZE;
6907
10.8k
                in  += WC_AES_BLOCK_SIZE;
6908
10.8k
            }
6909
400
#ifdef WC_AES_HAVE_PREFETCH_ARG
6910
400
            }
6911
400
#endif
6912
400
#endif
6913
400
        }
6914
6915
400
        VECTOR_REGISTERS_POP;
6916
6917
400
        return ret;
6918
400
#endif
6919
400
    }
6920
#endif /* HAVE_AES_DECRYPT */
6921
6922
#endif /* AES-CBC block */
6923
#endif /* HAVE_AES_CBC */
6924
6925
/* AES-CTR */
6926
#if defined(WOLFSSL_AES_COUNTER)
6927
6928
    #ifdef STM32_CRYPTO
6929
        #define NEED_AES_CTR_SOFT
6930
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
6931
6932
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
6933
        {
6934
            int ret = 0;
6935
        #ifdef WOLFSSL_STM32_CUBEMX
6936
            CRYP_HandleTypeDef hcryp;
6937
            #ifdef STM32_HAL_V2
6938
            word32 iv[WC_AES_BLOCK_SIZE/sizeof(word32)];
6939
            #endif
6940
        #else
6941
            word32 *iv;
6942
            CRYP_InitTypeDef cryptInit;
6943
            CRYP_KeyInitTypeDef keyInit;
6944
            CRYP_IVInitTypeDef ivInit;
6945
        #endif
6946
6947
        #ifdef WOLFSSL_STM32_CUBEMX
6948
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6949
            if (ret != 0) {
6950
                return ret;
6951
            }
6952
6953
            ret = wolfSSL_CryptHwMutexLock();
6954
            if (ret != 0) {
6955
                return ret;
6956
            }
6957
6958
        #if defined(STM32_HAL_V2)
6959
            hcryp.Init.Algorithm  = CRYP_AES_CTR;
6960
            ByteReverseWords(iv, aes->reg, WC_AES_BLOCK_SIZE);
6961
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
6962
        #elif defined(STM32_CRYPTO_AES_ONLY)
6963
            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
6964
            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
6965
            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6966
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6967
        #else
6968
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6969
        #endif
6970
            HAL_CRYP_Init(&hcryp);
6971
6972
        #if defined(STM32_HAL_V2)
6973
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, WC_AES_BLOCK_SIZE,
6974
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6975
        #elif defined(STM32_CRYPTO_AES_ONLY)
6976
            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
6977
                out, STM32_HAL_TIMEOUT);
6978
        #else
6979
            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
6980
                out, STM32_HAL_TIMEOUT);
6981
        #endif
6982
            if (ret != HAL_OK) {
6983
                ret = WC_TIMEOUT_E;
6984
            }
6985
            HAL_CRYP_DeInit(&hcryp);
6986
6987
        #else /* Standard Peripheral Library */
6988
            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6989
            if (ret != 0) {
6990
                return ret;
6991
            }
6992
6993
            ret = wolfSSL_CryptHwMutexLock();
6994
            if (ret != 0) {
6995
                return ret;
6996
            }
6997
6998
            /* reset registers to their default values */
6999
            CRYP_DeInit();
7000
7001
            /* set key */
7002
            CRYP_KeyInit(&keyInit);
7003
7004
            /* set iv */
7005
            iv = aes->reg;
7006
            CRYP_IVStructInit(&ivInit);
7007
            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
7008
            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
7009
            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
7010
            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
7011
            CRYP_IVInit(&ivInit);
7012
7013
            /* set direction and mode */
7014
            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
7015
            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
7016
            CRYP_Init(&cryptInit);
7017
7018
            /* enable crypto processor */
7019
            CRYP_Cmd(ENABLE);
7020
7021
            /* flush IN/OUT FIFOs */
7022
            CRYP_FIFOFlush();
7023
7024
            CRYP_DataIn(*(uint32_t*)&in[0]);
7025
            CRYP_DataIn(*(uint32_t*)&in[4]);
7026
            CRYP_DataIn(*(uint32_t*)&in[8]);
7027
            CRYP_DataIn(*(uint32_t*)&in[12]);
7028
7029
            /* wait until the complete message has been processed */
7030
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
7031
7032
            *(uint32_t*)&out[0]  = CRYP_DataOut();
7033
            *(uint32_t*)&out[4]  = CRYP_DataOut();
7034
            *(uint32_t*)&out[8]  = CRYP_DataOut();
7035
            *(uint32_t*)&out[12] = CRYP_DataOut();
7036
7037
            /* disable crypto processor */
7038
            CRYP_Cmd(DISABLE);
7039
        #endif /* WOLFSSL_STM32_CUBEMX */
7040
7041
            wolfSSL_CryptHwMutexUnLock();
7042
            wc_Stm32_Aes_Cleanup();
7043
            return ret;
7044
        }
7045
7046
7047
    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
7048
7049
        #define NEED_AES_CTR_SOFT
7050
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
7051
7052
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
7053
        {
7054
            word32 tmpIv[WC_AES_BLOCK_SIZE / sizeof(word32)];
7055
            XMEMCPY(tmpIv, aes->reg, WC_AES_BLOCK_SIZE);
7056
            return wc_Pic32AesCrypt(
7057
                aes->key, aes->keylen, tmpIv, WC_AES_BLOCK_SIZE,
7058
                out, in, WC_AES_BLOCK_SIZE,
7059
                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
7060
        }
7061
7062
    #elif defined(HAVE_COLDFIRE_SEC)
7063
        #error "Coldfire SEC doesn't currently support AES-CTR mode"
7064
7065
    #elif defined(FREESCALE_LTC)
7066
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7067
        {
7068
            int ret = 0;
7069
            word32 keySize;
7070
            byte *iv, *enc_key;
7071
            byte* tmp;
7072
7073
            if (aes == NULL || out == NULL || in == NULL) {
7074
                return BAD_FUNC_ARG;
7075
            }
7076
7077
            /* consume any unused bytes left in aes->tmp */
7078
            tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7079
            while (aes->left && sz) {
7080
                *(out++) = *(in++) ^ *(tmp++);
7081
                aes->left--;
7082
                sz--;
7083
            }
7084
7085
            if (sz) {
7086
                iv      = (byte*)aes->reg;
7087
                enc_key = (byte*)aes->key;
7088
7089
                ret = wc_AesGetKeySize(aes, &keySize);
7090
                if (ret != 0)
7091
                    return ret;
7092
7093
                ret = wolfSSL_CryptHwMutexLock();
7094
                if (ret != 0)
7095
                    return ret;
7096
                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
7097
                    iv, enc_key, keySize, (byte*)aes->tmp,
7098
                    (uint32_t*)&aes->left);
7099
                wolfSSL_CryptHwMutexUnLock();
7100
            }
7101
7102
            return ret;
7103
        }
7104
7105
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
7106
        !defined(WOLFSSL_QNX_CAAM)
7107
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
7108
7109
    #elif defined(WOLFSSL_AFALG)
7110
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
7111
7112
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
7113
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
7114
7115
    #elif defined(WOLFSSL_ESP32_CRYPT) && \
7116
        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
7117
        /* esp32 doesn't support CRT mode by hw.     */
7118
        /* use aes ecnryption plus sw implementation */
7119
        #define NEED_AES_CTR_SOFT
7120
7121
    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
7122
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
7123
    #else
7124
7125
        /* Use software based AES counter */
7126
        #define NEED_AES_CTR_SOFT
7127
    #endif
7128
7129
    #ifdef NEED_AES_CTR_SOFT
7130
        #ifndef WOLFSSL_ARMASM
7131
        /* Increment AES counter */
7132
        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
7133
2.65k
        {
7134
            /* in network byte order so start at end and work back */
7135
2.65k
            int i;
7136
3.76k
            for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
7137
3.76k
                if (++inOutCtr[i])  /* we're done unless we overflow */
7138
2.65k
                    return;
7139
3.76k
            }
7140
2.65k
        }
7141
        #endif
7142
7143
        /* Software AES - CTR Encrypt */
7144
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7145
844
        {
7146
844
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
7147
844
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7148
844
            byte scratch[WC_AES_BLOCK_SIZE];
7149
844
    #endif
7150
844
    #if !defined(WOLFSSL_ARMASM)
7151
844
            int ret = 0;
7152
844
    #endif
7153
844
            word32 processed;
7154
844
#ifdef WC_AES_HAVE_PREFETCH_ARG
7155
844
            int did_prefetches = 0;
7156
844
#endif
7157
7158
844
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
7159
844
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7160
844
            XMEMSET(scratch, 0, sizeof(scratch));
7161
844
    #endif
7162
7163
844
            if (aes == NULL || out == NULL || in == NULL) {
7164
0
                return BAD_FUNC_ARG;
7165
0
            }
7166
7167
844
        #ifdef WOLF_CRYPTO_CB
7168
844
            #ifndef WOLF_CRYPTO_CB_FIND
7169
844
            if (aes->devId != INVALID_DEVID)
7170
0
            #endif
7171
0
            {
7172
0
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
7173
0
                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7174
0
                    return crypto_cb_ret;
7175
                /* fall-through when unavailable */
7176
0
            }
7177
844
        #endif
7178
7179
            /* consume any unused bytes left in aes->tmp */
7180
844
            processed = min(aes->left, sz);
7181
844
            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
7182
844
                      processed);
7183
844
            out += processed;
7184
844
            in += processed;
7185
844
            aes->left -= processed;
7186
844
            sz -= processed;
7187
7188
    #if defined(WOLFSSL_ARMASM)
7189
        #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7190
            #ifndef __aarch64__
7191
            AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
7192
                (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
7193
            #else
7194
            if (aes->use_aes_hw_crypto) {
7195
                AES_CTR_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7196
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
7197
                return 0;
7198
            }
7199
            else
7200
            #endif /* !__aarch64__ */
7201
        #endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7202
        #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7203
            {
7204
                word32 numBlocks;
7205
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7206
                /* consume any unused bytes left in aes->tmp */
7207
                while ((aes->left != 0) && (sz != 0)) {
7208
                   *(out++) = *(in++) ^ *(tmp++);
7209
                   aes->left--;
7210
                   sz--;
7211
                }
7212
7213
                /* do as many block size ops as possible */
7214
                numBlocks = sz / WC_AES_BLOCK_SIZE;
7215
                if (numBlocks > 0) {
7216
                #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
7217
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7218
                    if (sz >= 32)
7219
                #endif
7220
                    {
7221
                        AES_CTR_encrypt_NEON(in, out,
7222
                            numBlocks * WC_AES_BLOCK_SIZE, (byte*)aes->key,
7223
                            aes->rounds, (byte*)aes->reg);
7224
                    }
7225
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7226
                    else
7227
                #endif
7228
                #endif
7229
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7230
                    {
7231
                        AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
7232
                            (byte*)aes->key, aes->rounds, (byte*)aes->reg);
7233
                    }
7234
                #endif
7235
7236
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
7237
                    out += numBlocks * WC_AES_BLOCK_SIZE;
7238
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
7239
                }
7240
7241
                /* handle non block size remaining */
7242
                if (sz) {
7243
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
7244
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
7245
7246
                #if defined(__aarch64__) && \
7247
                    !defined(WOLFSSL_ARMASM_NO_NEON) && \
7248
                    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7249
                    {
7250
                        AES_CTR_encrypt_NEON(zeros, (byte*)aes->tmp,
7251
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7252
                            (byte*)aes->reg);
7253
                    }
7254
                #else
7255
                    {
7256
                        AES_CTR_encrypt(zeros, (byte*)aes->tmp,
7257
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7258
                            (byte*)aes->reg);
7259
                    }
7260
                #endif
7261
7262
                    aes->left = WC_AES_BLOCK_SIZE;
7263
                    tmp = (byte*)aes->tmp;
7264
7265
                    while (sz--) {
7266
                        *(out++) = *(in++) ^ *(tmp++);
7267
                        aes->left--;
7268
                    }
7269
                }
7270
            }
7271
        #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
7272
            return 0;
7273
    #else
7274
844
            VECTOR_REGISTERS_PUSH;
7275
7276
844
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
7277
844
            !defined(XTRANSFORM_AESCTRBLOCK)
7278
844
            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
7279
386
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
7280
386
                byte* counter = (byte*)aes->reg;
7281
386
                byte* c = out;
7282
2.17k
                while (blocks--) {
7283
1.78k
                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
7284
1.78k
                    c += WC_AES_BLOCK_SIZE;
7285
1.78k
                    IncrementAesCounter(counter);
7286
1.78k
                }
7287
7288
                /* reset number of blocks and then do encryption */
7289
386
                blocks = sz / WC_AES_BLOCK_SIZE;
7290
386
                wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
7291
386
                xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
7292
386
                in += WC_AES_BLOCK_SIZE * blocks;
7293
386
                out += WC_AES_BLOCK_SIZE * blocks;
7294
386
                sz -= blocks * WC_AES_BLOCK_SIZE;
7295
386
            }
7296
458
            else
7297
458
        #endif
7298
458
            {
7299
            #ifdef WOLFSSL_CHECK_MEM_ZERO
7300
                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
7301
                    WC_AES_BLOCK_SIZE);
7302
            #endif
7303
                /* do as many block size ops as possible */
7304
879
                while (sz >= WC_AES_BLOCK_SIZE) {
7305
                #ifdef XTRANSFORM_AESCTRBLOCK
7306
                    XTRANSFORM_AESCTRBLOCK(aes, out, in);
7307
                #else
7308
421
                    ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7309
421
                                                    scratch,
7310
421
                                                    &did_prefetches);
7311
421
                    if (ret != 0)
7312
0
                        break;
7313
421
                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
7314
421
                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
7315
421
                #endif
7316
421
                    IncrementAesCounter((byte*)aes->reg);
7317
7318
421
                    out += WC_AES_BLOCK_SIZE;
7319
421
                    in  += WC_AES_BLOCK_SIZE;
7320
421
                    sz  -= WC_AES_BLOCK_SIZE;
7321
421
                    aes->left = 0;
7322
421
                }
7323
458
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
7324
458
            }
7325
7326
            /* handle non block size remaining and store unused byte count in left */
7327
844
            if ((ret == 0) && sz) {
7328
450
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7329
450
                                                (byte*)aes->tmp,
7330
450
                                                &did_prefetches);
7331
450
                if (ret == 0) {
7332
450
                    IncrementAesCounter((byte*)aes->reg);
7333
450
                    aes->left = WC_AES_BLOCK_SIZE - sz;
7334
450
                    xorbufout(out, in, aes->tmp, sz);
7335
450
                }
7336
450
            }
7337
7338
844
            if (ret < 0)
7339
0
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
7340
7341
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7342
            wc_MemZero_Check(scratch, WC_AES_BLOCK_SIZE);
7343
        #endif
7344
7345
844
            VECTOR_REGISTERS_POP;
7346
7347
844
            return ret;
7348
844
    #endif
7349
844
        }
7350
7351
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
7352
                                        const byte* iv, int dir)
7353
0
        {
7354
0
            if (aes == NULL) {
7355
0
                return BAD_FUNC_ARG;
7356
0
            }
7357
0
            if (len > sizeof(aes->key)) {
7358
0
                return BAD_FUNC_ARG;
7359
0
            }
7360
7361
0
            return wc_AesSetKey(aes, key, len, iv, dir);
7362
0
        }
7363
7364
    #endif /* NEED_AES_CTR_SOFT */
7365
7366
#endif /* WOLFSSL_AES_COUNTER */
7367
7368
#ifndef WC_AES_HAVE_PREFETCH_ARG
7369
    #ifndef AesEncrypt_preFetchOpt
7370
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
7371
            wc_AesEncrypt(aes, inBlock, outBlock)
7372
    #endif
7373
    #ifndef AesDecrypt_preFetchOpt
7374
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
7375
            wc_AesDecrypt(aes, inBlock, outBlock)
7376
    #endif
7377
#endif
7378
7379
#else  /* WOLFSSL_RISCV_ASM */
7380
7381
#define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
7382
    wc_AesEncryptDirect(aes, outBlock, inBlock)
7383
#define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
7384
    wc_AesDecryptDirect(aes, outBlock, inBlock)
7385
7386
#endif /* WOLFSSL_RISCV_ASM */
7387
7388
/*
7389
 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
7390
 * of two parts in order:
7391
 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
7392
 *      to the implicit IV.
7393
 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
7394
 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
7395
 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
7396
 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
7397
 * block counter during the encryption.
7398
 */
7399
7400
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
7401
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
7402
2.24k
{
7403
2.24k
    int i;
7404
2.47k
    for (i = (int)ctrSz - 1; i >= 0; i--) {
7405
2.47k
        if (++ctr[i])
7406
2.24k
            break;
7407
2.47k
    }
7408
2.24k
}
7409
#endif /* HAVE_AESGCM || HAVE_AESCCM */
7410
7411
7412
#ifdef HAVE_AESGCM
7413
7414
#ifdef WOLFSSL_AESGCM_STREAM
7415
    /* Access initialization counter data. */
7416
907
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
7417
    /* Access counter data. */
7418
6.19k
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
7419
    /* Access tag data. */
7420
17.2k
    #define AES_TAG(aes)            ((aes)->streamData + 2 * WC_AES_BLOCK_SIZE)
7421
    /* Access last GHASH block. */
7422
    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE)
7423
    /* Access last encrypted block. */
7424
7.90k
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
7425
7426
8.64k
    #define GHASH_ONE_BLOCK     GHASH_ONE_BLOCK_SW
7427
#endif
7428
7429
#if defined(HAVE_COLDFIRE_SEC)
7430
    #error "Coldfire SEC doesn't currently support AES-GCM mode"
7431
7432
#endif
7433
7434
#if defined(WOLFSSL_RISCV_ASM)
7435
    /* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
7436
7437
#elif defined(WOLFSSL_AFALG)
7438
    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
7439
7440
#elif defined(WOLFSSL_KCAPI_AES)
7441
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
7442
7443
#elif defined(WOLFSSL_DEVCRYPTO_AES)
7444
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
7445
7446
#else /* software + AESNI implementation */
7447
7448
#if !defined(FREESCALE_LTC_AES_GCM)
7449
#if (!(defined(__aarch64__) && defined(WOLFSSL_ARMASM))) || \
7450
    defined(WOLFSSL_AESGCM_STREAM)
7451
static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
7452
51.9k
{
7453
51.9k
    int i;
7454
7455
    /* in network byte order so start at end and work back */
7456
52.0k
    for (i = WC_AES_BLOCK_SIZE - 1; i >= WC_AES_BLOCK_SIZE - CTR_SZ; i--) {
7457
52.0k
        if (++inOutCtr[i])  /* we're done unless we overflow */
7458
51.9k
            return;
7459
52.0k
    }
7460
51.9k
}
7461
#endif
7462
#endif /* !FREESCALE_LTC_AES_GCM */
7463
7464
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
7465
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7466
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
7467
7468
static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
7469
5.16k
{
7470
    /* Multiply the sz by 8 */
7471
5.16k
    word32 szHi = (sz >> (8*sizeof(sz) - 3));
7472
5.16k
    sz <<= 3;
7473
7474
    /* copy over the words of the sz into the destination buffer */
7475
5.16k
    buf[0] = (byte)(szHi >> 24);
7476
5.16k
    buf[1] = (byte)(szHi >> 16);
7477
5.16k
    buf[2] = (byte)(szHi >>  8);
7478
5.16k
    buf[3] = (byte)szHi;
7479
5.16k
    buf[4] = (byte)(sz >> 24);
7480
5.16k
    buf[5] = (byte)(sz >> 16);
7481
5.16k
    buf[6] = (byte)(sz >>  8);
7482
5.16k
    buf[7] = (byte)sz;
7483
5.16k
}
7484
7485
7486
static WC_INLINE void RIGHTSHIFTX(byte* x)
7487
5.31k
{
7488
5.31k
    int i;
7489
5.31k
    int carryIn = 0;
7490
5.31k
    volatile byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
7491
7492
90.4k
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
7493
85.1k
        int carryOut = (x[i] & 0x01) << 7;
7494
85.1k
        x[i] = (byte) ((x[i] >> 1) | carryIn);
7495
85.1k
        carryIn = carryOut;
7496
85.1k
    }
7497
5.31k
    x[0] ^= borrow;
7498
5.31k
}
7499
7500
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
7501
7502
7503
#ifdef GCM_TABLE
7504
7505
void GenerateM0(Gcm* gcm)
7506
{
7507
    int i, j;
7508
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
7509
7510
    XMEMCPY(m[128], gcm->H, WC_AES_BLOCK_SIZE);
7511
7512
    for (i = 64; i > 0; i /= 2) {
7513
        XMEMCPY(m[i], m[i*2], WC_AES_BLOCK_SIZE);
7514
        RIGHTSHIFTX(m[i]);
7515
    }
7516
7517
    for (i = 2; i < 256; i *= 2) {
7518
        for (j = 1; j < i; j++) {
7519
            XMEMCPY(m[i+j], m[i], WC_AES_BLOCK_SIZE);
7520
            xorbuf(m[i+j], m[j], WC_AES_BLOCK_SIZE);
7521
        }
7522
    }
7523
7524
    XMEMSET(m[0], 0, WC_AES_BLOCK_SIZE);
7525
}
7526
7527
#elif defined(GCM_TABLE_4BIT)
7528
7529
#if !defined(WC_16BIT_CPU)
7530
static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
7531
28.3k
{
7532
28.3k
    int i;
7533
453k
    for (i = 15; i > 0; i--)
7534
425k
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
7535
28.3k
    r8[0] = (byte)(z8[0] >> 4);
7536
28.3k
}
7537
#endif
7538
7539
void GenerateM0(Gcm* gcm)
7540
1.77k
{
7541
1.77k
#if !defined(WC_16BIT_CPU)
7542
1.77k
    int i;
7543
1.77k
#endif
7544
1.77k
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
7545
7546
    /* 0 times -> 0x0 */
7547
1.77k
    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
7548
    /* 1 times -> 0x8 */
7549
1.77k
    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
7550
    /* 2 times -> 0x4 */
7551
1.77k
    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
7552
1.77k
    RIGHTSHIFTX(m[0x4]);
7553
    /* 4 times -> 0x2 */
7554
1.77k
    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
7555
1.77k
    RIGHTSHIFTX(m[0x2]);
7556
    /* 8 times -> 0x1 */
7557
1.77k
    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
7558
1.77k
    RIGHTSHIFTX(m[0x1]);
7559
7560
    /* 0x3 */
7561
1.77k
    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
7562
1.77k
    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
7563
7564
    /* 0x5 -> 0x7 */
7565
1.77k
    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
7566
1.77k
    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
7567
1.77k
    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
7568
1.77k
    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
7569
1.77k
    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
7570
1.77k
    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
7571
7572
    /* 0x9 -> 0xf */
7573
1.77k
    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
7574
1.77k
    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
7575
1.77k
    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
7576
1.77k
    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
7577
1.77k
    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
7578
1.77k
    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
7579
1.77k
    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
7580
1.77k
    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
7581
1.77k
    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
7582
1.77k
    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
7583
1.77k
    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
7584
1.77k
    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
7585
1.77k
    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
7586
1.77k
    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
7587
7588
1.77k
#if !defined(WC_16BIT_CPU)
7589
30.1k
    for (i = 0; i < 16; i++) {
7590
28.3k
        Shift4_M0(m[16+i], m[i]);
7591
28.3k
    }
7592
1.77k
#endif
7593
7594
#if defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7595
    for (i = 0; i < 32; i++) {
7596
    #if !defined(__aarch64__)
7597
        word32* m32 = (word32*)gcm->M0[i];
7598
        m32[0] = ByteReverseWord32(m32[0]);
7599
        m32[1] = ByteReverseWord32(m32[1]);
7600
        m32[2] = ByteReverseWord32(m32[2]);
7601
        m32[3] = ByteReverseWord32(m32[3]);
7602
    #else
7603
        word64* m64 = (word64*)gcm->M0[i];
7604
        m64[0] = ByteReverseWord64(m64[0]);
7605
        m64[1] = ByteReverseWord64(m64[1]);
7606
    #endif
7607
    }
7608
#endif
7609
7610
1.77k
}
7611
7612
#endif /* GCM_TABLE */
7613
#endif
7614
7615
#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
7616
    #define HAVE_INTEL_AVX1
7617
    #define HAVE_INTEL_AVX2
7618
#endif
7619
7620
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \
7621
    defined(WC_C_DYNAMIC_FALLBACK)
7622
void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m)
7623
                           XASM_LINK("GCM_generate_m0_aesni");
7624
#ifdef HAVE_INTEL_AVX1
7625
void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m)
7626
                          XASM_LINK("GCM_generate_m0_avx1");
7627
#endif
7628
#ifdef HAVE_INTEL_AVX2
7629
void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
7630
                          XASM_LINK("GCM_generate_m0_avx2");
7631
#endif
7632
#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */
7633
7634
/* Software AES - GCM SetKey */
7635
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
7636
1.77k
{
7637
1.77k
    int  ret;
7638
1.77k
    byte iv[WC_AES_BLOCK_SIZE];
7639
7640
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
7641
        byte   local[32];
7642
        word32 localSz = 32;
7643
7644
        if (len == (16 + WC_CAAM_BLOB_SZ) ||
7645
          len == (24 + WC_CAAM_BLOB_SZ) ||
7646
          len == (32 + WC_CAAM_BLOB_SZ)) {
7647
            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
7648
                 return BAD_FUNC_ARG;
7649
            }
7650
7651
            /* set local values */
7652
            key = local;
7653
            len = localSz;
7654
        }
7655
    #endif
7656
7657
1.77k
    if (!((len == 16) || (len == 24) || (len == 32)))
7658
0
        return BAD_FUNC_ARG;
7659
7660
1.77k
    if (aes == NULL || key == NULL) {
7661
#ifdef WOLFSSL_IMX6_CAAM_BLOB
7662
        ForceZero(local, sizeof(local));
7663
#endif
7664
0
        return BAD_FUNC_ARG;
7665
0
    }
7666
#ifdef OPENSSL_EXTRA
7667
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
7668
    aes->gcm.aadLen = 0;
7669
#endif
7670
1.77k
    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
7671
1.77k
    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
7672
1.77k
#ifdef WOLFSSL_AESGCM_STREAM
7673
1.77k
    aes->gcmKeySet = 1;
7674
1.77k
#endif
7675
    #if defined(WOLFSSL_SECO_CAAM)
7676
        if (aes->devId == WOLFSSL_SECO_DEVID) {
7677
            return ret;
7678
        }
7679
    #endif /* WOLFSSL_SECO_CAAM */
7680
7681
    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
7682
        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
7683
        return ret;
7684
    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
7685
7686
#if defined(WOLFSSL_ARMASM)
7687
    if (ret == 0) {
7688
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7689
    #if !defined(__aarch64__)
7690
        AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
7691
    #else
7692
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
7693
            AES_GCM_set_key_AARCH64(iv, (byte*)aes->key, aes->gcm.H,
7694
                aes->rounds);
7695
        }
7696
        else
7697
    #endif /* !__aarch64__ */
7698
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7699
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
7700
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7701
        {
7702
            AES_ECB_encrypt_NEON(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
7703
                (const unsigned char*)aes->key, aes->rounds);
7704
        }
7705
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7706
        {
7707
            AES_ECB_encrypt(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
7708
                (const unsigned char*)aes->key, aes->rounds);
7709
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
7710
            GenerateM0(&aes->gcm);
7711
        #endif /* GCM_TABLE */
7712
        }
7713
#endif
7714
    }
7715
#else
7716
1.77k
#if !defined(FREESCALE_LTC_AES_GCM) && !defined(WOLFSSL_PSOC6_CRYPTO)
7717
7718
7719
#ifdef WOLF_CRYPTO_CB_AES_SETKEY
7720
    if ((ret == 0) && (aes->devId != INVALID_DEVID && aes->devCtx != NULL)) {
7721
        /* SE owns key - skip H and M table generation */
7722
    }
7723
    else
7724
#endif
7725
1.77k
    if (ret == 0) {
7726
1.77k
        VECTOR_REGISTERS_PUSH;
7727
7728
        /* Generate H = AES_Encrypt(key, 0^128) */
7729
1.77k
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
7730
7731
1.77k
        if (ret == 0) {
7732
1.77k
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
7733
    #if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT)
7734
            if (aes->use_aesni) {
7735
        #if defined(WC_C_DYNAMIC_FALLBACK)
7736
            #ifdef HAVE_INTEL_AVX2
7737
                if (IS_INTEL_AVX2(intel_flags)) {
7738
                    GCM_generate_m0_avx2(aes->gcm.H,
7739
                        (byte*)aes->gcm.M0);
7740
                }
7741
                else
7742
            #endif
7743
            #if defined(HAVE_INTEL_AVX1)
7744
                if (IS_INTEL_AVX1(intel_flags)) {
7745
                    GCM_generate_m0_avx1(aes->gcm.H,
7746
                        (byte*)aes->gcm.M0);
7747
                }
7748
                else
7749
            #endif
7750
                {
7751
                    GCM_generate_m0_aesni(aes->gcm.H,
7752
                        (byte*)aes->gcm.M0);
7753
                }
7754
        #endif /* WC_C_DYNAMIC_FALLBACK */
7755
            }
7756
            else
7757
    #endif /* AESNI */
7758
1.77k
            {
7759
1.77k
                GenerateM0(&aes->gcm);
7760
1.77k
            }
7761
1.77k
#endif /* GCM_TABLE || GCM_TABLE_4BIT */
7762
1.77k
        }
7763
7764
1.77k
        VECTOR_REGISTERS_POP;
7765
1.77k
    }
7766
1.77k
#endif /* !FREESCALE_LTC_AES_GCM && !WOLFSSL_PSOC6_CRYPTO */
7767
1.77k
#endif
7768
7769
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
7770
    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
7771
#endif
7772
7773
1.77k
#ifdef WOLF_CRYPTO_CB
7774
1.77k
    if (aes->devId != INVALID_DEVID) {
7775
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
7776
        if (aes->devCtx != NULL) {
7777
            /* SE owns key - don't copy to devKey */
7778
        }
7779
        else
7780
    #endif
7781
0
        {
7782
0
            XMEMCPY(aes->devKey, key, len);
7783
0
        }
7784
0
    }
7785
1.77k
#endif
7786
7787
#ifdef WOLFSSL_IMX6_CAAM_BLOB
7788
    ForceZero(local, sizeof(local));
7789
#endif
7790
1.77k
    return ret;
7791
1.77k
}
7792
7793
7794
#ifdef WOLFSSL_AESNI
7795
7796
void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
7797
                     const unsigned char* addt, const unsigned char* ivec,
7798
                     unsigned char *tag, word32 nbytes,
7799
                     word32 abytes, word32 ibytes,
7800
                     word32 tbytes, const unsigned char* key, int nr)
7801
                     XASM_LINK("AES_GCM_encrypt_aesni");
7802
#ifdef HAVE_INTEL_AVX1
7803
void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
7804
                          const unsigned char* addt, const unsigned char* ivec,
7805
                          unsigned char *tag, word32 nbytes,
7806
                          word32 abytes, word32 ibytes,
7807
                          word32 tbytes, const unsigned char* key,
7808
                          int nr)
7809
                          XASM_LINK("AES_GCM_encrypt_avx1");
7810
#ifdef HAVE_INTEL_AVX2
7811
void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
7812
                          const unsigned char* addt, const unsigned char* ivec,
7813
                          unsigned char *tag, word32 nbytes,
7814
                          word32 abytes, word32 ibytes,
7815
                          word32 tbytes, const unsigned char* key,
7816
                          int nr)
7817
                          XASM_LINK("AES_GCM_encrypt_avx2");
7818
#endif /* HAVE_INTEL_AVX2 */
7819
#endif /* HAVE_INTEL_AVX1 */
7820
7821
#ifdef HAVE_AES_DECRYPT
7822
void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
7823
                     const unsigned char* addt, const unsigned char* ivec,
7824
                     const unsigned char *tag, word32 nbytes, word32 abytes,
7825
                     word32 ibytes, word32 tbytes, const unsigned char* key,
7826
                     int nr, int* res)
7827
                     XASM_LINK("AES_GCM_decrypt_aesni");
7828
#ifdef HAVE_INTEL_AVX1
7829
void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
7830
                          const unsigned char* addt, const unsigned char* ivec,
7831
                          const unsigned char *tag, word32 nbytes,
7832
                          word32 abytes, word32 ibytes, word32 tbytes,
7833
                          const unsigned char* key, int nr, int* res)
7834
                          XASM_LINK("AES_GCM_decrypt_avx1");
7835
#ifdef HAVE_INTEL_AVX2
7836
void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
7837
                          const unsigned char* addt, const unsigned char* ivec,
7838
                          const unsigned char *tag, word32 nbytes,
7839
                          word32 abytes, word32 ibytes, word32 tbytes,
7840
                          const unsigned char* key, int nr, int* res)
7841
                          XASM_LINK("AES_GCM_decrypt_avx2");
7842
#endif /* HAVE_INTEL_AVX2 */
7843
#endif /* HAVE_INTEL_AVX1 */
7844
#endif /* HAVE_AES_DECRYPT */
7845
7846
#endif /* WOLFSSL_AESNI */
7847
7848
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
7849
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7850
#if defined(GCM_SMALL)
7851
static void GMULT(byte* X, byte* Y)
7852
{
7853
    byte Z[WC_AES_BLOCK_SIZE];
7854
    byte V[WC_AES_BLOCK_SIZE];
7855
    int i, j;
7856
7857
    XMEMSET(Z, 0, WC_AES_BLOCK_SIZE);
7858
    XMEMCPY(V, X, WC_AES_BLOCK_SIZE);
7859
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++)
7860
    {
7861
        byte y = Y[i];
7862
        for (j = 0; j < 8; j++)
7863
        {
7864
            if (y & 0x80) {
7865
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
7866
            }
7867
7868
            RIGHTSHIFTX(V);
7869
            y = y << 1;
7870
        }
7871
    }
7872
    XMEMCPY(X, Z, WC_AES_BLOCK_SIZE);
7873
}
7874
7875
7876
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7877
    word32 cSz, byte* s, word32 sSz)
7878
{
7879
    byte x[WC_AES_BLOCK_SIZE];
7880
    byte scratch[WC_AES_BLOCK_SIZE];
7881
    word32 blocks, partial;
7882
    byte* h;
7883
7884
    if (gcm == NULL) {
7885
        return;
7886
    }
7887
7888
    h = gcm->H;
7889
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
7890
7891
    /* Hash in A, the Additional Authentication Data */
7892
    if (aSz != 0 && a != NULL) {
7893
        blocks = aSz / WC_AES_BLOCK_SIZE;
7894
        partial = aSz % WC_AES_BLOCK_SIZE;
7895
        while (blocks--) {
7896
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
7897
            GMULT(x, h);
7898
            a += WC_AES_BLOCK_SIZE;
7899
        }
7900
        if (partial != 0) {
7901
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7902
            XMEMCPY(scratch, a, partial);
7903
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7904
            GMULT(x, h);
7905
        }
7906
    }
7907
7908
    /* Hash in C, the Ciphertext */
7909
    if (cSz != 0 && c != NULL) {
7910
        blocks = cSz / WC_AES_BLOCK_SIZE;
7911
        partial = cSz % WC_AES_BLOCK_SIZE;
7912
        while (blocks--) {
7913
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
7914
            GMULT(x, h);
7915
            c += WC_AES_BLOCK_SIZE;
7916
        }
7917
        if (partial != 0) {
7918
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7919
            XMEMCPY(scratch, c, partial);
7920
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7921
            GMULT(x, h);
7922
        }
7923
    }
7924
7925
    /* Hash in the lengths of A and C in bits */
7926
    FlattenSzInBits(&scratch[0], aSz);
7927
    FlattenSzInBits(&scratch[8], cSz);
7928
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7929
    GMULT(x, h);
7930
7931
    /* Copy the result into s. */
7932
    XMEMCPY(s, x, sSz);
7933
}
7934
7935
#ifdef WOLFSSL_AESGCM_STREAM
7936
/* No extra initialization for small implementation.
7937
 *
7938
 * @param [in] aes  AES GCM object.
7939
 */
7940
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7941
7942
/* GHASH one block of data..
7943
 *
7944
 * XOR block into tag and GMULT with H.
7945
 *
7946
 * @param [in, out] aes    AES GCM object.
7947
 * @param [in]      block  Block of AAD or cipher text.
7948
 */
7949
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
7950
    do {                                                \
7951
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
7952
        GMULT(AES_TAG(aes), (aes)->gcm.H);              \
7953
    }                                                   \
7954
    while (0)
7955
#endif /* WOLFSSL_AESGCM_STREAM */
7956
7957
#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) &&  \
7958
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7959
static void GCM_gmult_len_armasm_C(
7960
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
7961
{
7962
    byte Z[AES_BLOCK_SIZE];
7963
    byte V[AES_BLOCK_SIZE];
7964
    int i;
7965
    int j;
7966
7967
    while (len >= AES_BLOCK_SIZE) {
7968
        xorbuf(x, a, AES_BLOCK_SIZE);
7969
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
7970
        XMEMCPY(V, x, AES_BLOCK_SIZE);
7971
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
7972
            byte y = h[i];
7973
            for (j = 0; j < 8; j++) {
7974
                if (y & 0x80) {
7975
                    xorbuf(Z, V, AES_BLOCK_SIZE);
7976
                }
7977
                RIGHTSHIFTX(V);
7978
                y = y << 1;
7979
            }
7980
        }
7981
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
7982
        len -= AES_BLOCK_SIZE;
7983
        a += AES_BLOCK_SIZE;
7984
    }
7985
}
7986
7987
#define GCM_GMULT_LEN(gcm, x, a, len) \
7988
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
7989
#endif /* WOLFSSL_ARMASM && !__aarch64__ && !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7990
7991
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
7992
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7993
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
7994
#define GCM_GMULT_LEN(gcm, x, a, len) \
7995
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
7996
#else
7997
#define GCM_GMULT_LEN(gcm, x, a, len) \
7998
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
7999
#endif
8000
#endif
8001
8002
#elif defined(GCM_TABLE)
8003
8004
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
8005
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8006
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
8007
#define GCM_GMULT_LEN(gcm, x, a, len) \
8008
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
8009
#else
8010
#define GCM_GMULT_LEN(gcm, x, a, len) \
8011
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
8012
#endif
8013
#else
8014
ALIGN16 static const byte R[256][2] = {
8015
    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
8016
    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
8017
    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
8018
    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
8019
    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
8020
    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
8021
    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
8022
    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
8023
    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
8024
    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
8025
    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
8026
    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
8027
    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
8028
    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
8029
    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
8030
    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
8031
    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
8032
    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
8033
    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
8034
    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
8035
    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
8036
    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
8037
    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
8038
    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
8039
    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
8040
    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
8041
    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
8042
    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
8043
    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
8044
    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
8045
    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
8046
    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
8047
    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
8048
    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
8049
    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
8050
    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
8051
    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
8052
    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
8053
    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
8054
    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
8055
    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
8056
    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
8057
    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
8058
    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
8059
    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
8060
    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
8061
    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
8062
    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
8063
    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
8064
    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
8065
    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
8066
    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
8067
    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
8068
    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
8069
    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
8070
    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
8071
    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
8072
    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
8073
    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
8074
    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
8075
    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
8076
    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
8077
    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
8078
    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
8079
8080
8081
static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE])
8082
{
8083
#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
8084
    int i, j;
8085
    byte Z[WC_AES_BLOCK_SIZE];
8086
    byte a;
8087
8088
    XMEMSET(Z, 0, sizeof(Z));
8089
8090
    for (i = 15; i > 0; i--) {
8091
        xorbuf(Z, m[x[i]], WC_AES_BLOCK_SIZE);
8092
        a = Z[15];
8093
8094
        for (j = 15; j > 0; j--) {
8095
            Z[j] = Z[j-1];
8096
        }
8097
8098
        Z[0]  = R[a][0];
8099
        Z[1] ^= R[a][1];
8100
    }
8101
    xorbuf(Z, m[x[0]], WC_AES_BLOCK_SIZE);
8102
8103
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
8104
#elif defined(WC_32BIT_CPU)
8105
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
8106
    byte a;
8107
    word32* pZ;
8108
    word32* pm;
8109
    word32* px = (word32*)(x);
8110
    int i;
8111
8112
    pZ = (word32*)(Z + 15 + 1);
8113
    pm = (word32*)(m[x[15]]);
8114
    pZ[0] = pm[0];
8115
    pZ[1] = pm[1];
8116
    pZ[2] = pm[2];
8117
    pZ[3] = pm[3];
8118
    a = Z[16 + 15];
8119
    Z[15]  = R[a][0];
8120
    Z[16] ^= R[a][1];
8121
    for (i = 14; i > 0; i--) {
8122
        pZ = (word32*)(Z + i + 1);
8123
        pm = (word32*)(m[x[i]]);
8124
        pZ[0] ^= pm[0];
8125
        pZ[1] ^= pm[1];
8126
        pZ[2] ^= pm[2];
8127
        pZ[3] ^= pm[3];
8128
        a = Z[16 + i];
8129
        Z[i]    = R[a][0];
8130
        Z[i+1] ^= R[a][1];
8131
    }
8132
    pZ = (word32*)(Z + 1);
8133
    pm = (word32*)(m[x[0]]);
8134
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
8135
    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
8136
#else
8137
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
8138
    byte a;
8139
    word64* pZ;
8140
    word64* pm;
8141
    word64* px = (word64*)(x);
8142
    int i;
8143
8144
    pZ = (word64*)(Z + 15 + 1);
8145
    pm = (word64*)(m[x[15]]);
8146
    pZ[0] = pm[0];
8147
    pZ[1] = pm[1];
8148
    a = Z[16 + 15];
8149
    Z[15]  = R[a][0];
8150
    Z[16] ^= R[a][1];
8151
    for (i = 14; i > 0; i--) {
8152
        pZ = (word64*)(Z + i + 1);
8153
        pm = (word64*)(m[x[i]]);
8154
        pZ[0] ^= pm[0];
8155
        pZ[1] ^= pm[1];
8156
        a = Z[16 + i];
8157
        Z[i]    = R[a][0];
8158
        Z[i+1] ^= R[a][1];
8159
    }
8160
    pZ = (word64*)(Z + 1);
8161
    pm = (word64*)(m[x[0]]);
8162
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
8163
#endif
8164
}
8165
#endif
8166
8167
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8168
    word32 cSz, byte* s, word32 sSz)
8169
{
8170
    byte x[WC_AES_BLOCK_SIZE];
8171
    byte scratch[WC_AES_BLOCK_SIZE];
8172
    word32 blocks, partial;
8173
8174
    if (gcm == NULL) {
8175
        return;
8176
    }
8177
8178
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
8179
8180
    /* Hash in A, the Additional Authentication Data */
8181
    if (aSz != 0 && a != NULL) {
8182
        blocks = aSz / WC_AES_BLOCK_SIZE;
8183
        partial = aSz % WC_AES_BLOCK_SIZE;
8184
    #ifdef GCM_GMULT_LEN
8185
        if (blocks > 0) {
8186
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
8187
            a += blocks * WC_AES_BLOCK_SIZE;
8188
        }
8189
        if (partial != 0) {
8190
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8191
            XMEMCPY(scratch, a, partial);
8192
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8193
        }
8194
    #else
8195
        while (blocks--) {
8196
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
8197
            GMULT(x, gcm->M0);
8198
            a += WC_AES_BLOCK_SIZE;
8199
        }
8200
        if (partial != 0) {
8201
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8202
            XMEMCPY(scratch, a, partial);
8203
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8204
            GMULT(x, gcm->M0);
8205
        }
8206
    #endif
8207
    }
8208
8209
    /* Hash in C, the Ciphertext */
8210
    if (cSz != 0 && c != NULL) {
8211
        blocks = cSz / WC_AES_BLOCK_SIZE;
8212
        partial = cSz % WC_AES_BLOCK_SIZE;
8213
    #ifdef GCM_GMULT_LEN
8214
        if (blocks > 0) {
8215
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
8216
            c += blocks * WC_AES_BLOCK_SIZE;
8217
        }
8218
        if (partial != 0) {
8219
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8220
            XMEMCPY(scratch, c, partial);
8221
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8222
        }
8223
    #else
8224
        while (blocks--) {
8225
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
8226
            GMULT(x, gcm->M0);
8227
            c += WC_AES_BLOCK_SIZE;
8228
        }
8229
        if (partial != 0) {
8230
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8231
            XMEMCPY(scratch, c, partial);
8232
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8233
            GMULT(x, gcm->M0);
8234
        }
8235
    #endif
8236
    }
8237
8238
    /* Hash in the lengths of A and C in bits */
8239
    FlattenSzInBits(&scratch[0], aSz);
8240
    FlattenSzInBits(&scratch[8], cSz);
8241
#ifdef GCM_GMULT_LEN
8242
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8243
#else
8244
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8245
    GMULT(x, gcm->M0);
8246
#endif
8247
8248
    /* Copy the result into s. */
8249
    XMEMCPY(s, x, sSz);
8250
}
8251
8252
#ifdef WOLFSSL_AESGCM_STREAM
8253
/* No extra initialization for table implementation.
8254
 *
8255
 * @param [in] aes  AES GCM object.
8256
 */
8257
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8258
8259
/* GHASH one block of data..
8260
 *
8261
 * XOR block into tag and GMULT with H using pre-computed table.
8262
 *
8263
 * @param [in, out] aes    AES GCM object.
8264
 * @param [in]      block  Block of AAD or cipher text.
8265
 */
8266
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
8267
    do {                                                \
8268
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
8269
        GMULT(AES_TAG(aes), aes->gcm.M0);               \
8270
    }                                                   \
8271
    while (0)
8272
#endif /* WOLFSSL_AESGCM_STREAM */
8273
/* end GCM_TABLE */
8274
#elif defined(GCM_TABLE_4BIT)
8275
8276
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
8277
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8278
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
8279
#define GCM_GMULT_LEN(gcm, x, a, len) \
8280
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
8281
#define GMULT(x, m)                                                      \
8282
    GCM_gmult_NEON(x, (const byte**)m)
8283
#else
8284
#define GCM_GMULT_LEN(gcm, x, a, len) \
8285
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
8286
#define GMULT(x, m)                                                      \
8287
    GCM_gmult(x, (const byte**)m)
8288
#endif
8289
#else
8290
/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
8291
 *  R shifts right a reverse bit pair of bytes such that:
8292
 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
8293
 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
8294
 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
8295
 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
8296
 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
8297
 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
8298
 *  To calculate te rest, XOR result for each bit.
8299
 *   e.g. 6 = 4 ^ 2 => 48,c0
8300
 *
8301
 * Second half is same values rotated by 4-bits.
8302
 */
8303
#if defined(WC_16BIT_CPU)
8304
static const byte R[16][2] = {
8305
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
8306
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
8307
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
8308
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
8309
};
8310
#elif defined(BIG_ENDIAN_ORDER)
8311
static const word16 R[32] = {
8312
          0x0000,       0x1c20,       0x3840,       0x2460,
8313
          0x7080,       0x6ca0,       0x48c0,       0x54e0,
8314
          0xe100,       0xfd20,       0xd940,       0xc560,
8315
          0x9180,       0x8da0,       0xa9c0,       0xb5e0,
8316
8317
          0x0000,       0x01c2,       0x0384,       0x0246,
8318
          0x0708,       0x06ca,       0x048c,       0x054e,
8319
          0x0e10,       0x0fd2,       0x0d94,       0x0c56,
8320
          0x0918,       0x08da,       0x0a9c,       0x0b5e,
8321
};
8322
#else
8323
static const word16 R[32] = {
8324
          0x0000,       0x201c,       0x4038,       0x6024,
8325
          0x8070,       0xa06c,       0xc048,       0xe054,
8326
          0x00e1,       0x20fd,       0x40d9,       0x60c5,
8327
          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
8328
8329
          0x0000,       0xc201,       0x8403,       0x4602,
8330
          0x0807,       0xca06,       0x8c04,       0x4e05,
8331
          0x100e,       0xd20f,       0x940d,       0x560c,
8332
          0x1809,       0xda08,       0x9c0a,       0x5e0b,
8333
};
8334
#endif
8335
8336
/* Multiply in GF(2^128) defined by polynomial:
8337
 *   x^128 + x^7 + x^2 + x^1 + 1.
8338
 *
8339
 * H: hash key = encrypt(key, 0)
8340
 * x = x * H in field
8341
 *
8342
 * x: cumulative result
8343
 * m: 4-bit table
8344
 *    [0..15] * H
8345
 */
8346
#if defined(WC_16BIT_CPU)
8347
static void GMULT(byte *x, byte m[16][WC_AES_BLOCK_SIZE])
8348
{
8349
    int i, j, n;
8350
    byte Z[WC_AES_BLOCK_SIZE];
8351
    byte a;
8352
8353
    XMEMSET(Z, 0, sizeof(Z));
8354
8355
    for (i = 15; i >= 0; i--) {
8356
        for (n = 0; n < 2; n++) {
8357
            if (n == 0)
8358
                xorbuf(Z, m[x[i] & 0xf], WC_AES_BLOCK_SIZE);
8359
            else {
8360
                xorbuf(Z, m[x[i] >> 4], WC_AES_BLOCK_SIZE);
8361
                if (i == 0)
8362
                    break;
8363
            }
8364
            a = Z[15] & 0xf;
8365
8366
            for (j = 15; j > 0; j--)
8367
                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
8368
            Z[0] >>= 4;
8369
8370
            Z[0] ^= R[a][0];
8371
            Z[1] ^= R[a][1];
8372
        }
8373
    }
8374
8375
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
8376
}
8377
#elif defined(WC_32BIT_CPU) && defined(BIG_ENDIAN_ORDER)
8378
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
8379
{
8380
    int i;
8381
    word32 z8[4] = {0, 0, 0, 0};
8382
    byte a;
8383
    word32* x8 = (word32*)x;
8384
    word32* m8;
8385
    byte xi;
8386
8387
    for (i = 15; i > 0; i--) {
8388
        xi = x[i];
8389
8390
        /* XOR in (msn * H) */
8391
        m8 = (word32*)m[xi & 0xf];
8392
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8393
8394
        /* Cache top byte for remainder calculations - lost in rotate. */
8395
        a = (byte)(z8[3] & 0xff);
8396
8397
        /* Rotate Z by 8-bits */
8398
        z8[3] = (z8[2] << 24) | (z8[3] >> 8);
8399
        z8[2] = (z8[1] << 24) | (z8[2] >> 8);
8400
        z8[1] = (z8[0] << 24) | (z8[1] >> 8);
8401
        z8[0] >>= 8;
8402
8403
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
8404
        z8[0] ^= ((word32)R[16 + (a & 0xf)]) << 16;
8405
8406
        xi >>= 4;
8407
        /* XOR in next significant nibble (XORed with H) * remainder */
8408
        m8 = (word32*)m[xi];
8409
        a ^= (byte)(m8[3] >> 12) & 0xf;
8410
        a ^= (byte)((m8[3] << 4) & 0xf0);
8411
        z8[0] ^= ((word32)R[a >> 4]) << 16;
8412
8413
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
8414
        m8 = (word32*)m[16 + xi];
8415
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
8416
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
8417
    }
8418
8419
    xi = x[0];
8420
8421
    /* XOR in most significant nibble * H */
8422
    m8 = (word32*)m[xi & 0xf];
8423
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8424
8425
    /* Cache top byte for remainder calculations - lost in rotate. */
8426
    a = (byte)(z8[3] & 0x0f);
8427
8428
    z8[3] = (z8[2] << 28) | (z8[3] >> 4);
8429
    z8[2] = (z8[1] << 28) | (z8[2] >> 4);
8430
    z8[1] = (z8[0] << 28) | (z8[1] >> 4);
8431
    z8[0] >>= 4;
8432
8433
    /* XOR in most significant nibble * remainder */
8434
    z8[0] ^= ((word32)R[a]) << 16;
8435
    /* XOR in next significant nibble * H */
8436
    m8 = (word32*)m[xi >> 4];
8437
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8438
8439
    /* Write back result. */
8440
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
8441
}
8442
#elif defined(WC_32BIT_CPU)
8443
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
8444
{
8445
    int i;
8446
    word32 z8[4] = {0, 0, 0, 0};
8447
    byte a;
8448
    word32* x8 = (word32*)x;
8449
    word32* m8;
8450
    byte xi;
8451
    word32 n7, n6, n5, n4, n3, n2, n1, n0;
8452
8453
    for (i = 15; i > 0; i--) {
8454
        xi = x[i];
8455
8456
        /* XOR in (msn * H) */
8457
        m8 = (word32*)m[xi & 0xf];
8458
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8459
8460
        /* Cache top byte for remainder calculations - lost in rotate. */
8461
        a = (byte)(z8[3] >> 24);
8462
8463
        /* Rotate Z by 8-bits */
8464
        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
8465
        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
8466
        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
8467
        z8[0] <<= 8;
8468
8469
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
8470
        z8[0] ^= (word32)R[16 + (a & 0xf)];
8471
8472
        xi >>= 4;
8473
        /* XOR in next significant nibble (XORed with H) * remainder */
8474
        m8 = (word32*)m[xi];
8475
        a ^= (byte)(m8[3] >> 20);
8476
        z8[0] ^= (word32)R[a >> 4];
8477
8478
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
8479
        m8 = (word32*)m[16 + xi];
8480
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
8481
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
8482
    }
8483
8484
    xi = x[0];
8485
8486
    /* XOR in most significant nibble * H */
8487
    m8 = (word32*)m[xi & 0xf];
8488
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8489
8490
    /* Cache top byte for remainder calculations - lost in rotate. */
8491
    a = (z8[3] >> 24) & 0xf;
8492
8493
    /* Rotate z by 4-bits */
8494
    n7 = z8[3] & 0xf0f0f0f0ULL;
8495
    n6 = z8[3] & 0x0f0f0f0fULL;
8496
    n5 = z8[2] & 0xf0f0f0f0ULL;
8497
    n4 = z8[2] & 0x0f0f0f0fULL;
8498
    n3 = z8[1] & 0xf0f0f0f0ULL;
8499
    n2 = z8[1] & 0x0f0f0f0fULL;
8500
    n1 = z8[0] & 0xf0f0f0f0ULL;
8501
    n0 = z8[0] & 0x0f0f0f0fULL;
8502
    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
8503
    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
8504
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
8505
    z8[0] = (n1 >> 4) | (n0 << 12);
8506
8507
    /* XOR in most significant nibble * remainder */
8508
    z8[0] ^= (word32)R[a];
8509
    /* XOR in next significant nibble * H */
8510
    m8 = (word32*)m[xi >> 4];
8511
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
8512
8513
    /* Write back result. */
8514
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
8515
}
8516
#elif defined(WC_64BIT_CPU) && defined(BIG_ENDIAN_ORDER)
8517
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
8518
{
8519
    int i;
8520
    word64 z8[2] = {0, 0};
8521
    byte a;
8522
    word64* x8 = (word64*)x;
8523
    word64* m8;
8524
    byte xi;
8525
8526
    for (i = 15; i > 0; i--) {
8527
        xi = x[i];
8528
8529
        /* XOR in (msn * H) */
8530
        m8 = (word64*)m[xi & 0xf];
8531
        z8[0] ^= m8[0];
8532
        z8[1] ^= m8[1];
8533
8534
        /* Cache top byte for remainder calculations - lost in rotate. */
8535
        a = (byte)(z8[1] & 0xff);
8536
8537
        /* Rotate Z by 8-bits */
8538
        z8[1] = (z8[0] << 56) | (z8[1] >> 8);
8539
        z8[0] >>= 8;
8540
8541
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
8542
        m8 = (word64*)m[16 + (xi >> 4)];
8543
        z8[0] ^= m8[0];
8544
        z8[1] ^= m8[1];
8545
8546
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
8547
        z8[0] ^= ((word64)R[16 + (a & 0xf)]) << 48;
8548
        /* XOR in next significant nibble (XORed with H) * remainder */
8549
        m8 = (word64*)m[xi >> 4];
8550
        a ^= (byte)(m8[1] >> 12) & 0xf;
8551
        a ^= (byte)((m8[1] << 4) & 0xf0);
8552
        z8[0] ^= ((word64)R[a >> 4]) << 48;
8553
    }
8554
8555
    xi = x[0];
8556
8557
    /* XOR in most significant nibble * H */
8558
    m8 = (word64*)m[xi & 0xf];
8559
    z8[0] ^= m8[0];
8560
    z8[1] ^= m8[1];
8561
8562
    /* Cache top byte for remainder calculations - lost in rotate. */
8563
    a = (byte)(z8[1] & 0x0f);
8564
8565
    /* Rotate z by 4-bits */
8566
    z8[1] = (z8[0] << 60) | (z8[1] >> 4);
8567
    z8[0] >>= 4;
8568
8569
    /* XOR in next significant nibble * H */
8570
    m8 = (word64*)m[xi >> 4];
8571
    z8[0] ^= m8[0];
8572
    z8[1] ^= m8[1];
8573
    /* XOR in most significant nibble * remainder */
8574
    z8[0] ^= ((word64)R[a]) << 48;
8575
8576
    /* Write back result. */
8577
    x8[0] = z8[0];
8578
    x8[1] = z8[1];
8579
}
8580
#else
8581
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
8582
57.7k
{
8583
57.7k
    int i;
8584
57.7k
    word64 z8[2] = {0, 0};
8585
57.7k
    byte a;
8586
57.7k
    word64* x8 = (word64*)x;
8587
57.7k
    word64* m8;
8588
57.7k
    word64 n0, n1, n2, n3;
8589
57.7k
    byte xi;
8590
8591
924k
    for (i = 15; i > 0; i--) {
8592
866k
        xi = x[i];
8593
8594
        /* XOR in (msn * H) */
8595
866k
        m8 = (word64*)m[xi & 0xf];
8596
866k
        z8[0] ^= m8[0];
8597
866k
        z8[1] ^= m8[1];
8598
8599
        /* Cache top byte for remainder calculations - lost in rotate. */
8600
866k
        a = (byte)(z8[1] >> 56);
8601
8602
        /* Rotate Z by 8-bits */
8603
866k
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
8604
866k
        z8[0] <<= 8;
8605
8606
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
8607
866k
        m8 = (word64*)m[16 + (xi >> 4)];
8608
866k
        z8[0] ^= m8[0];
8609
866k
        z8[1] ^= m8[1];
8610
8611
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
8612
866k
        z8[0] ^= (word64)R[16 + (a & 0xf)];
8613
        /* XOR in next significant nibble (XORed with H) * remainder */
8614
866k
        m8 = (word64*)m[xi >> 4];
8615
866k
        a ^= (byte)(m8[1] >> 52);
8616
866k
        z8[0] ^= (word64)R[a >> 4];
8617
866k
    }
8618
8619
57.7k
    xi = x[0];
8620
8621
    /* XOR in most significant nibble * H */
8622
57.7k
    m8 = (word64*)m[xi & 0xf];
8623
57.7k
    z8[0] ^= m8[0];
8624
57.7k
    z8[1] ^= m8[1];
8625
8626
    /* Cache top byte for remainder calculations - lost in rotate. */
8627
57.7k
    a = (z8[1] >> 56) & 0xf;
8628
8629
    /* Rotate z by 4-bits */
8630
57.7k
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
8631
57.7k
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
8632
57.7k
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
8633
57.7k
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
8634
57.7k
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
8635
57.7k
    z8[0] = (n1 >> 4) | (n0 << 12);
8636
8637
    /* XOR in next significant nibble * H */
8638
57.7k
    m8 = (word64*)m[xi >> 4];
8639
57.7k
    z8[0] ^= m8[0];
8640
57.7k
    z8[1] ^= m8[1];
8641
    /* XOR in most significant nibble * remainder */
8642
57.7k
    z8[0] ^= (word64)R[a];
8643
8644
    /* Write back result. */
8645
57.7k
    x8[0] = z8[0];
8646
57.7k
    x8[1] = z8[1];
8647
57.7k
}
8648
#endif
8649
#endif
8650
8651
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8652
    word32 cSz, byte* s, word32 sSz)
8653
1.67k
{
8654
1.67k
    byte x[WC_AES_BLOCK_SIZE];
8655
1.67k
    byte scratch[WC_AES_BLOCK_SIZE];
8656
1.67k
    word32 blocks, partial;
8657
8658
1.67k
    if (gcm == NULL) {
8659
0
        return;
8660
0
    }
8661
8662
1.67k
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
8663
8664
    /* Hash in A, the Additional Authentication Data */
8665
1.67k
    if (aSz != 0 && a != NULL) {
8666
1.67k
        blocks = aSz / WC_AES_BLOCK_SIZE;
8667
1.67k
        partial = aSz % WC_AES_BLOCK_SIZE;
8668
    #ifdef GCM_GMULT_LEN
8669
        if (blocks > 0) {
8670
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
8671
            a += blocks * WC_AES_BLOCK_SIZE;
8672
        }
8673
        if (partial != 0) {
8674
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8675
            XMEMCPY(scratch, a, partial);
8676
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8677
        }
8678
    #else
8679
1.67k
        while (blocks--) {
8680
0
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
8681
0
            GMULT(x, gcm->M0);
8682
0
            a += WC_AES_BLOCK_SIZE;
8683
0
        }
8684
1.67k
        if (partial != 0) {
8685
1.67k
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8686
1.67k
            XMEMCPY(scratch, a, partial);
8687
1.67k
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8688
1.67k
            GMULT(x, gcm->M0);
8689
1.67k
        }
8690
1.67k
    #endif
8691
1.67k
    }
8692
8693
    /* Hash in C, the Ciphertext */
8694
1.67k
    if (cSz != 0 && c != NULL) {
8695
1.67k
        blocks = cSz / WC_AES_BLOCK_SIZE;
8696
1.67k
        partial = cSz % WC_AES_BLOCK_SIZE;
8697
    #ifdef GCM_GMULT_LEN
8698
        if (blocks > 0) {
8699
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
8700
            c += blocks * WC_AES_BLOCK_SIZE;
8701
        }
8702
        if (partial != 0) {
8703
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8704
            XMEMCPY(scratch, c, partial);
8705
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8706
        }
8707
    #else
8708
45.9k
        while (blocks--) {
8709
44.2k
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
8710
44.2k
            GMULT(x, gcm->M0);
8711
44.2k
            c += WC_AES_BLOCK_SIZE;
8712
44.2k
        }
8713
1.67k
        if (partial != 0) {
8714
1.54k
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8715
1.54k
            XMEMCPY(scratch, c, partial);
8716
1.54k
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8717
1.54k
            GMULT(x, gcm->M0);
8718
1.54k
        }
8719
1.67k
    #endif
8720
1.67k
    }
8721
8722
    /* Hash in the lengths of A and C in bits */
8723
1.67k
    FlattenSzInBits(&scratch[0], aSz);
8724
1.67k
    FlattenSzInBits(&scratch[8], cSz);
8725
#ifdef GCM_GMULT_LEN
8726
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8727
#else
8728
1.67k
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8729
1.67k
    GMULT(x, gcm->M0);
8730
1.67k
#endif
8731
8732
    /* Copy the result into s. */
8733
1.67k
    XMEMCPY(s, x, sSz);
8734
1.67k
}
8735
8736
#ifdef WOLFSSL_AESGCM_STREAM
8737
/* No extra initialization for 4-bit table implementation.
8738
 *
8739
 * @param [in] aes  AES GCM object.
8740
 */
8741
3.54k
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8742
8743
#ifdef GCM_GMULT_LEN
8744
/* GHASH one block of data.
8745
 *
8746
 * @param [in, out] aes    AES GCM object.
8747
 * @param [in]      block  Block of AAD or cipher text.
8748
 */
8749
#define GHASH_ONE_BLOCK_SW(aes, block)                                  \
8750
   GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
8751
#else
8752
/* GHASH one block of data.
8753
 *
8754
 * XOR block into tag and GMULT with H using pre-computed table.
8755
 *
8756
 * @param [in, out] aes    AES GCM object.
8757
 * @param [in]      block  Block of AAD or cipher text.
8758
 */
8759
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
8760
8.64k
    do {                                                \
8761
8.64k
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
8762
8.64k
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
8763
8.64k
    }                                                   \
8764
8.64k
    while (0)
8765
#endif
8766
#endif /* WOLFSSL_AESGCM_STREAM */
8767
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
8768
8769
#if !defined(FREESCALE_LTC_AES_GCM)
8770
static void GMULT(word64* X, word64* Y)
8771
{
8772
    word64 Z[2] = {0,0};
8773
    word64 V[2];
8774
    int i, j;
8775
    word64 v1;
8776
    V[0] = X[0];  V[1] = X[1];
8777
8778
    for (i = 0; i < 2; i++)
8779
    {
8780
        word64 y = Y[i];
8781
        for (j = 0; j < 64; j++)
8782
        {
8783
#ifndef AES_GCM_GMULT_NCT
8784
            word64 mask = 0 - (y >> 63);
8785
            Z[0] ^= V[0] & mask;
8786
            Z[1] ^= V[1] & mask;
8787
#else
8788
            if (y & 0x8000000000000000ULL) {
8789
                Z[0] ^= V[0];
8790
                Z[1] ^= V[1];
8791
            }
8792
#endif
8793
8794
            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
8795
            V[1] >>= 1;
8796
            V[1] |= V[0] << 63;
8797
            V[0] >>= 1;
8798
            V[0] ^= v1;
8799
            y <<= 1;
8800
        }
8801
    }
8802
    X[0] = Z[0];
8803
    X[1] = Z[1];
8804
}
8805
8806
8807
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8808
    word32 cSz, byte* s, word32 sSz)
8809
{
8810
    word64 x[2] = {0,0};
8811
    word32 blocks, partial;
8812
    word64 bigH[2];
8813
8814
    if (gcm == NULL) {
8815
        return;
8816
    }
8817
8818
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
8819
    #ifdef LITTLE_ENDIAN_ORDER
8820
        ByteReverseWords64(bigH, bigH, WC_AES_BLOCK_SIZE);
8821
    #endif
8822
8823
    /* Hash in A, the Additional Authentication Data */
8824
    if (aSz != 0 && a != NULL) {
8825
        word64 bigA[2];
8826
        blocks = aSz / WC_AES_BLOCK_SIZE;
8827
        partial = aSz % WC_AES_BLOCK_SIZE;
8828
        while (blocks--) {
8829
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
8830
            #ifdef LITTLE_ENDIAN_ORDER
8831
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
8832
            #endif
8833
            x[0] ^= bigA[0];
8834
            x[1] ^= bigA[1];
8835
            GMULT(x, bigH);
8836
            a += WC_AES_BLOCK_SIZE;
8837
        }
8838
        if (partial != 0) {
8839
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
8840
            XMEMCPY(bigA, a, partial);
8841
            #ifdef LITTLE_ENDIAN_ORDER
8842
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
8843
            #endif
8844
            x[0] ^= bigA[0];
8845
            x[1] ^= bigA[1];
8846
            GMULT(x, bigH);
8847
        }
8848
#ifdef OPENSSL_EXTRA
8849
        /* store AAD partial tag for next call */
8850
        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
8851
        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
8852
        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
8853
        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
8854
#endif
8855
    }
8856
8857
    /* Hash in C, the Ciphertext */
8858
    if (cSz != 0 && c != NULL) {
8859
        word64 bigC[2];
8860
        blocks = cSz / WC_AES_BLOCK_SIZE;
8861
        partial = cSz % WC_AES_BLOCK_SIZE;
8862
#ifdef OPENSSL_EXTRA
8863
        /* Start from last AAD partial tag */
8864
        if(gcm->aadLen) {
8865
            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
8866
            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
8867
         }
8868
#endif
8869
        while (blocks--) {
8870
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
8871
            #ifdef LITTLE_ENDIAN_ORDER
8872
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
8873
            #endif
8874
            x[0] ^= bigC[0];
8875
            x[1] ^= bigC[1];
8876
            GMULT(x, bigH);
8877
            c += WC_AES_BLOCK_SIZE;
8878
        }
8879
        if (partial != 0) {
8880
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
8881
            XMEMCPY(bigC, c, partial);
8882
            #ifdef LITTLE_ENDIAN_ORDER
8883
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
8884
            #endif
8885
            x[0] ^= bigC[0];
8886
            x[1] ^= bigC[1];
8887
            GMULT(x, bigH);
8888
        }
8889
    }
8890
8891
    /* Hash in the lengths in bits of A and C */
8892
    {
8893
        word64 len[2];
8894
        len[0] = aSz; len[1] = cSz;
8895
#ifdef OPENSSL_EXTRA
8896
        if (gcm->aadLen)
8897
            len[0] = (word64)gcm->aadLen;
8898
#endif
8899
        /* Lengths are in bytes. Convert to bits. */
8900
        len[0] *= 8;
8901
        len[1] *= 8;
8902
8903
        x[0] ^= len[0];
8904
        x[1] ^= len[1];
8905
        GMULT(x, bigH);
8906
    }
8907
    #ifdef LITTLE_ENDIAN_ORDER
8908
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
8909
    #endif
8910
    XMEMCPY(s, x, sSz);
8911
}
8912
#endif /* !FREESCALE_LTC_AES_GCM */
8913
8914
#ifdef WOLFSSL_AESGCM_STREAM
8915
8916
#ifdef LITTLE_ENDIAN_ORDER
8917
8918
/* No extra initialization for small implementation.
8919
 *
8920
 * @param [in] aes  AES GCM object.
8921
 */
8922
#define GHASH_INIT_EXTRA(aes)                                               \
8923
    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, WC_AES_BLOCK_SIZE)
8924
8925
/* GHASH one block of data..
8926
 *
8927
 * XOR block into tag and GMULT with H.
8928
 *
8929
 * @param [in, out] aes    AES GCM object.
8930
 * @param [in]      block  Block of AAD or cipher text.
8931
 */
8932
#define GHASH_ONE_BLOCK_SW(aes, block)                              \
8933
    do {                                                            \
8934
        word64* x = (word64*)AES_TAG(aes);                          \
8935
        word64* h = (word64*)aes->gcm.H;                            \
8936
        word64 block64[2];                                          \
8937
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);                 \
8938
        ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE);    \
8939
        x[0] ^= block64[0];                                         \
8940
        x[1] ^= block64[1];                                         \
8941
        GMULT(x, h);                                                \
8942
    }                                                               \
8943
    while (0)
8944
8945
#ifdef OPENSSL_EXTRA
8946
/* GHASH in AAD and cipher text lengths in bits.
8947
 *
8948
 * Convert tag back to little-endian.
8949
 *
8950
 * @param [in, out] aes  AES GCM object.
8951
 */
8952
#define GHASH_LEN_BLOCK(aes)                            \
8953
    do {                                                \
8954
        word64* x = (word64*)AES_TAG(aes);              \
8955
        word64* h = (word64*)aes->gcm.H;                \
8956
        word64 len[2];                                  \
8957
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8958
        if (aes->gcm.aadLen)                            \
8959
            len[0] = (word64)aes->gcm.aadLen;           \
8960
        /* Lengths are in bytes. Convert to bits. */    \
8961
        len[0] *= 8;                                    \
8962
        len[1] *= 8;                                    \
8963
                                                        \
8964
        x[0] ^= len[0];                                 \
8965
        x[1] ^= len[1];                                 \
8966
        GMULT(x, h);                                    \
8967
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
8968
    }                                                   \
8969
    while (0)
8970
#else
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
        word64* x = (word64*)AES_TAG(aes);              \
8980
        word64* h = (word64*)aes->gcm.H;                \
8981
        word64 len[2];                                  \
8982
        len[0] = aes->aSz; len[1] = aes->cSz;           \
8983
        /* Lengths are in bytes. Convert to bits. */    \
8984
        len[0] *= 8;                                    \
8985
        len[1] *= 8;                                    \
8986
                                                        \
8987
        x[0] ^= len[0];                                 \
8988
        x[1] ^= len[1];                                 \
8989
        GMULT(x, h);                                    \
8990
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
8991
    }                                                   \
8992
    while (0)
8993
#endif
8994
8995
#else
8996
8997
/* No extra initialization for small implementation.
8998
 *
8999
 * @param [in] aes  AES GCM object.
9000
 */
9001
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9002
9003
/* GHASH one block of data..
9004
 *
9005
 * XOR block into tag and GMULT with H.
9006
 *
9007
 * @param [in, out] aes    AES GCM object.
9008
 * @param [in]      block  Block of AAD or cipher text.
9009
 */
9010
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9011
    do {                                                \
9012
        word64* x = (word64*)AES_TAG(aes);              \
9013
        word64* h = (word64*)aes->gcm.H;                \
9014
        word64 block64[2];                              \
9015
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);        \
9016
        x[0] ^= block64[0];                             \
9017
        x[1] ^= block64[1];                             \
9018
        GMULT(x, h);                                    \
9019
    }                                                   \
9020
    while (0)
9021
9022
#ifdef OPENSSL_EXTRA
9023
/* GHASH in AAD and cipher text lengths in bits.
9024
 *
9025
 * Convert tag back to little-endian.
9026
 *
9027
 * @param [in, out] aes  AES GCM object.
9028
 */
9029
#define GHASH_LEN_BLOCK(aes)                            \
9030
    do {                                                \
9031
        word64* x = (word64*)AES_TAG(aes);              \
9032
        word64* h = (word64*)aes->gcm.H;                \
9033
        word64 len[2];                                  \
9034
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9035
        if (aes->gcm.aadLen)                            \
9036
            len[0] = (word64)aes->gcm.aadLen;           \
9037
        /* Lengths are in bytes. Convert to bits. */    \
9038
        len[0] *= 8;                                    \
9039
        len[1] *= 8;                                    \
9040
                                                        \
9041
        x[0] ^= len[0];                                 \
9042
        x[1] ^= len[1];                                 \
9043
        GMULT(x, h);                                    \
9044
    }                                                   \
9045
    while (0)
9046
#else
9047
/* GHASH in AAD and cipher text lengths in bits.
9048
 *
9049
 * Convert tag back to little-endian.
9050
 *
9051
 * @param [in, out] aes  AES GCM object.
9052
 */
9053
#define GHASH_LEN_BLOCK(aes)                            \
9054
    do {                                                \
9055
        word64* x = (word64*)AES_TAG(aes);              \
9056
        word64* h = (word64*)aes->gcm.H;                \
9057
        word64 len[2];                                  \
9058
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9059
        /* Lengths are in bytes. Convert to bits. */    \
9060
        len[0] *= 8;                                    \
9061
        len[1] *= 8;                                    \
9062
                                                        \
9063
        x[0] ^= len[0];                                 \
9064
        x[1] ^= len[1];                                 \
9065
        GMULT(x, h);                                    \
9066
    }                                                   \
9067
    while (0)
9068
#endif
9069
9070
#endif /* !LITTLE_ENDIAN_ORDER */
9071
9072
#endif /* WOLFSSL_AESGCM_STREAM */
9073
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
9074
#else /* GCM_WORD32 */
9075
9076
static void GMULT(word32* X, word32* Y)
9077
{
9078
    word32 Z[4] = {0,0,0,0};
9079
    word32 V[4];
9080
    int i, j;
9081
9082
    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
9083
9084
    for (i = 0; i < 4; i++)
9085
    {
9086
        word32 y = Y[i];
9087
        for (j = 0; j < 32; j++)
9088
        {
9089
            if (y & 0x80000000) {
9090
                Z[0] ^= V[0];
9091
                Z[1] ^= V[1];
9092
                Z[2] ^= V[2];
9093
                Z[3] ^= V[3];
9094
            }
9095
9096
            if (V[3] & 0x00000001) {
9097
                V[3] >>= 1;
9098
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
9099
                V[2] >>= 1;
9100
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
9101
                V[1] >>= 1;
9102
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
9103
                V[0] >>= 1;
9104
                V[0] ^= 0xE1000000;
9105
            } else {
9106
                V[3] >>= 1;
9107
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
9108
                V[2] >>= 1;
9109
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
9110
                V[1] >>= 1;
9111
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
9112
                V[0] >>= 1;
9113
            }
9114
            y <<= 1;
9115
        }
9116
    }
9117
    X[0] = Z[0];
9118
    X[1] = Z[1];
9119
    X[2] = Z[2];
9120
    X[3] = Z[3];
9121
}
9122
9123
9124
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9125
    word32 cSz, byte* s, word32 sSz)
9126
{
9127
    word32 x[4] = {0,0,0,0};
9128
    word32 blocks, partial;
9129
    word32 bigH[4];
9130
9131
    if (gcm == NULL) {
9132
        return;
9133
    }
9134
9135
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
9136
    #ifdef LITTLE_ENDIAN_ORDER
9137
        ByteReverseWords(bigH, bigH, WC_AES_BLOCK_SIZE);
9138
    #endif
9139
9140
    /* Hash in A, the Additional Authentication Data */
9141
    if (aSz != 0 && a != NULL) {
9142
        word32 bigA[4];
9143
        blocks = aSz / WC_AES_BLOCK_SIZE;
9144
        partial = aSz % WC_AES_BLOCK_SIZE;
9145
        while (blocks--) {
9146
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
9147
            #ifdef LITTLE_ENDIAN_ORDER
9148
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
9149
            #endif
9150
            x[0] ^= bigA[0];
9151
            x[1] ^= bigA[1];
9152
            x[2] ^= bigA[2];
9153
            x[3] ^= bigA[3];
9154
            GMULT(x, bigH);
9155
            a += WC_AES_BLOCK_SIZE;
9156
        }
9157
        if (partial != 0) {
9158
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
9159
            XMEMCPY(bigA, a, partial);
9160
            #ifdef LITTLE_ENDIAN_ORDER
9161
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
9162
            #endif
9163
            x[0] ^= bigA[0];
9164
            x[1] ^= bigA[1];
9165
            x[2] ^= bigA[2];
9166
            x[3] ^= bigA[3];
9167
            GMULT(x, bigH);
9168
        }
9169
    }
9170
9171
    /* Hash in C, the Ciphertext */
9172
    if (cSz != 0 && c != NULL) {
9173
        word32 bigC[4];
9174
        blocks = cSz / WC_AES_BLOCK_SIZE;
9175
        partial = cSz % WC_AES_BLOCK_SIZE;
9176
        while (blocks--) {
9177
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
9178
            #ifdef LITTLE_ENDIAN_ORDER
9179
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
9180
            #endif
9181
            x[0] ^= bigC[0];
9182
            x[1] ^= bigC[1];
9183
            x[2] ^= bigC[2];
9184
            x[3] ^= bigC[3];
9185
            GMULT(x, bigH);
9186
            c += WC_AES_BLOCK_SIZE;
9187
        }
9188
        if (partial != 0) {
9189
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
9190
            XMEMCPY(bigC, c, partial);
9191
            #ifdef LITTLE_ENDIAN_ORDER
9192
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
9193
            #endif
9194
            x[0] ^= bigC[0];
9195
            x[1] ^= bigC[1];
9196
            x[2] ^= bigC[2];
9197
            x[3] ^= bigC[3];
9198
            GMULT(x, bigH);
9199
        }
9200
    }
9201
9202
    /* Hash in the lengths in bits of A and C */
9203
    {
9204
        word32 len[4];
9205
9206
        /* Lengths are in bytes. Convert to bits. */
9207
        len[0] = (aSz >> (8*sizeof(aSz) - 3));
9208
        len[1] = aSz << 3;
9209
        len[2] = (cSz >> (8*sizeof(cSz) - 3));
9210
        len[3] = cSz << 3;
9211
9212
        x[0] ^= len[0];
9213
        x[1] ^= len[1];
9214
        x[2] ^= len[2];
9215
        x[3] ^= len[3];
9216
        GMULT(x, bigH);
9217
    }
9218
    #ifdef LITTLE_ENDIAN_ORDER
9219
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
9220
    #endif
9221
    XMEMCPY(s, x, sSz);
9222
}
9223
9224
#ifdef WOLFSSL_AESGCM_STREAM
9225
#ifdef LITTLE_ENDIAN_ORDER
9226
/* Little-endian 32-bit word implementation requires byte reversal of H.
9227
 *
9228
 * H is all-zeros block encrypted with key.
9229
 *
9230
 * @param [in, out] aes  AES GCM object.
9231
 */
9232
#define GHASH_INIT_EXTRA(aes) \
9233
    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, WC_AES_BLOCK_SIZE)
9234
9235
/* GHASH one block of data..
9236
 *
9237
 * XOR block, in big-endian form, into tag and GMULT with H.
9238
 *
9239
 * @param [in, out] aes    AES GCM object.
9240
 * @param [in]      block  Block of AAD or cipher text.
9241
 */
9242
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
9243
    do {                                                        \
9244
        word32* x = (word32*)AES_TAG(aes);                      \
9245
        word32* h = (word32*)aes->gcm.H;                        \
9246
        word32 bigEnd[4];                                       \
9247
        XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE);              \
9248
        ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE);    \
9249
        x[0] ^= bigEnd[0];                                      \
9250
        x[1] ^= bigEnd[1];                                      \
9251
        x[2] ^= bigEnd[2];                                      \
9252
        x[3] ^= bigEnd[3];                                      \
9253
        GMULT(x, h);                                            \
9254
    }                                                           \
9255
    while (0)
9256
9257
/* GHASH in AAD and cipher text lengths in bits.
9258
 *
9259
 * Convert tag back to little-endian.
9260
 *
9261
 * @param [in, out] aes  AES GCM object.
9262
 */
9263
#define GHASH_LEN_BLOCK(aes)                                \
9264
    do {                                                    \
9265
        word32 len[4];                                      \
9266
        word32* x = (word32*)AES_TAG(aes);                  \
9267
        word32* h = (word32*)aes->gcm.H;                    \
9268
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
9269
        len[1] = aes->aSz << 3;                             \
9270
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
9271
        len[3] = aes->cSz << 3;                             \
9272
        x[0] ^= len[0];                                     \
9273
        x[1] ^= len[1];                                     \
9274
        x[2] ^= len[2];                                     \
9275
        x[3] ^= len[3];                                     \
9276
        GMULT(x, h);                                        \
9277
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);          \
9278
    }                                                       \
9279
    while (0)
9280
#else
9281
/* No extra initialization for 32-bit word implementation.
9282
 *
9283
 * @param [in] aes  AES GCM object.
9284
 */
9285
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9286
9287
/* GHASH one block of data..
9288
 *
9289
 * XOR block into tag and GMULT with H.
9290
 *
9291
 * @param [in, out] aes    AES GCM object.
9292
 * @param [in]      block  Block of AAD or cipher text.
9293
 */
9294
#define GHASH_ONE_BLOCK_SW(aes, block)                      \
9295
    do {                                                    \
9296
        word32* x = (word32*)AES_TAG(aes);                  \
9297
        word32* h = (word32*)aes->gcm.H;                    \
9298
        word32 block32[4];                                  \
9299
        XMEMCPY(block32, block, WC_AES_BLOCK_SIZE);         \
9300
        x[0] ^= block32[0];                                 \
9301
        x[1] ^= block32[1];                                 \
9302
        x[2] ^= block32[2];                                 \
9303
        x[3] ^= block32[3];                                 \
9304
        GMULT(x, h);                                        \
9305
    }                                                       \
9306
    while (0)
9307
9308
/* GHASH in AAD and cipher text lengths in bits.
9309
 *
9310
 * @param [in, out] aes  AES GCM object.
9311
 */
9312
#define GHASH_LEN_BLOCK(aes)                                \
9313
    do {                                                    \
9314
        word32 len[4];                                      \
9315
        word32* x = (word32*)AES_TAG(aes);                  \
9316
        word32* h = (word32*)aes->gcm.H;                    \
9317
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
9318
        len[1] = aes->aSz << 3;                             \
9319
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
9320
        len[3] = aes->cSz << 3;                             \
9321
        x[0] ^= len[0];                                     \
9322
        x[1] ^= len[1];                                     \
9323
        x[2] ^= len[2];                                     \
9324
        x[3] ^= len[3];                                     \
9325
        GMULT(x, h);                                        \
9326
    }                                                       \
9327
    while (0)
9328
#endif /* LITTLE_ENDIAN_ORDER */
9329
#endif /* WOLFSSL_AESGCM_STREAM */
9330
#endif /* end GCM_WORD32 */
9331
#endif
9332
9333
#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
9334
#ifdef WOLFSSL_AESGCM_STREAM
9335
#ifndef GHASH_LEN_BLOCK
9336
/* Hash in the lengths of the AAD and cipher text in bits.
9337
 *
9338
 * Default implementation.
9339
 *
9340
 * @param [in, out] aes  AES GCM object.
9341
 */
9342
#define GHASH_LEN_BLOCK(aes)                      \
9343
907
    do {                                          \
9344
907
        byte scratch[WC_AES_BLOCK_SIZE];          \
9345
907
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
9346
907
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
9347
907
        GHASH_ONE_BLOCK(aes, scratch);            \
9348
907
    }                                             \
9349
907
    while (0)
9350
#endif
9351
9352
/* Initialize a GHASH for streaming operations.
9353
 *
9354
 * @param [in, out] aes  AES GCM object.
9355
 */
9356
2.64k
static void GHASH_INIT(Aes* aes) {
9357
    /* Set tag to all zeros as initial value. */
9358
2.64k
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
9359
    /* Reset counts of AAD and cipher text. */
9360
2.64k
    aes->aOver = 0;
9361
2.64k
    aes->cOver = 0;
9362
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
9363
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
9364
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
9365
        ; /* Don't do extra initialization. */
9366
    }
9367
    else
9368
#endif
9369
2.64k
    {
9370
        /* Extra initialization based on implementation. */
9371
2.64k
        GHASH_INIT_EXTRA(aes);
9372
2.64k
    }
9373
2.64k
}
9374
9375
/* Update the GHASH with AAD and/or cipher text.
9376
 *
9377
 * @param [in,out] aes   AES GCM object.
9378
 * @param [in]     a     Additional authentication data buffer.
9379
 * @param [in]     aSz   Size of data in AAD buffer.
9380
 * @param [in]     c     Cipher text buffer.
9381
 * @param [in]     cSz   Size of data in cipher text buffer.
9382
 */
9383
static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
9384
    word32 cSz)
9385
9.15k
{
9386
9.15k
    word32 blocks;
9387
9.15k
    word32 partial;
9388
9389
    /* Hash in A, the Additional Authentication Data */
9390
9.15k
    if (aSz != 0 && a != NULL) {
9391
        /* Update count of AAD we have hashed. */
9392
448
        aes->aSz += aSz;
9393
        /* Check if we have unprocessed data. */
9394
448
        if (aes->aOver > 0) {
9395
            /* Calculate amount we can use - fill up the block. */
9396
253
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
9397
253
            if (sz > aSz) {
9398
122
                sz = (byte)aSz;
9399
122
            }
9400
            /* Copy extra into last GHASH block array and update count. */
9401
253
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
9402
253
            aes->aOver = (byte)(aes->aOver + sz);
9403
253
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
9404
                /* We have filled up the block and can process. */
9405
131
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
9406
                /* Reset count. */
9407
131
                aes->aOver = 0;
9408
131
            }
9409
            /* Used up some data. */
9410
253
            aSz -= sz;
9411
253
            a += sz;
9412
253
        }
9413
9414
        /* Calculate number of blocks of AAD and the leftover. */
9415
448
        blocks = aSz / WC_AES_BLOCK_SIZE;
9416
448
        partial = aSz % WC_AES_BLOCK_SIZE;
9417
        /* GHASH full blocks now. */
9418
1.72k
        while (blocks--) {
9419
1.27k
            GHASH_ONE_BLOCK(aes, a);
9420
1.27k
            a += WC_AES_BLOCK_SIZE;
9421
1.27k
        }
9422
448
        if (partial != 0) {
9423
            /* Cache the partial block. */
9424
301
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
9425
301
            aes->aOver = (byte)partial;
9426
301
        }
9427
448
    }
9428
9.15k
    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
9429
        /* No more AAD coming and we have a partial block. */
9430
        /* Fill the rest of the block with zeros. */
9431
73
        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
9432
73
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
9433
        /* GHASH last AAD block. */
9434
73
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
9435
        /* Clear partial count for next time through. */
9436
73
        aes->aOver = 0;
9437
73
    }
9438
9439
    /* Hash in C, the Ciphertext */
9440
9.15k
    if (cSz != 0 && c != NULL) {
9441
        /* Update count of cipher text we have hashed. */
9442
1.47k
        aes->cSz += cSz;
9443
1.47k
        if (aes->cOver > 0) {
9444
            /* Calculate amount we can use - fill up the block. */
9445
647
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
9446
647
            if (sz > cSz) {
9447
439
                sz = (byte)cSz;
9448
439
            }
9449
647
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
9450
            /* Update count of unused encrypted counter. */
9451
647
            aes->cOver = (byte)(aes->cOver + sz);
9452
647
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
9453
                /* We have filled up the block and can process. */
9454
208
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
9455
                /* Reset count. */
9456
208
                aes->cOver = 0;
9457
208
            }
9458
            /* Used up some data. */
9459
647
            cSz -= sz;
9460
647
            c += sz;
9461
647
        }
9462
9463
        /* Calculate number of blocks of cipher text and the leftover. */
9464
1.47k
        blocks = cSz / WC_AES_BLOCK_SIZE;
9465
1.47k
        partial = cSz % WC_AES_BLOCK_SIZE;
9466
        /* GHASH full blocks now. */
9467
7.12k
        while (blocks--) {
9468
5.64k
            GHASH_ONE_BLOCK(aes, c);
9469
5.64k
            c += WC_AES_BLOCK_SIZE;
9470
5.64k
        }
9471
1.47k
        if (partial != 0) {
9472
            /* Cache the partial block. */
9473
552
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
9474
552
            aes->cOver = (byte)partial;
9475
552
        }
9476
1.47k
    }
9477
9.15k
}
9478
9479
/* Finalize the GHASH calculation.
9480
 *
9481
 * Complete hashing cipher text and hash the AAD and cipher text lengths.
9482
 *
9483
 * @param [in, out] aes  AES GCM object.
9484
 * @param [out]     s    Authentication tag.
9485
 * @param [in]      sSz  Size of authentication tag required.
9486
 */
9487
static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
9488
907
{
9489
    /* AAD block incomplete when > 0 */
9490
907
    byte over = aes->aOver;
9491
9492
907
    if (aes->cOver > 0) {
9493
        /* Cipher text block incomplete. */
9494
319
        over = aes->cOver;
9495
319
    }
9496
907
    if (over > 0) {
9497
        /* Zeroize the unused part of the block. */
9498
406
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
9499
406
            (size_t)WC_AES_BLOCK_SIZE - over);
9500
        /* Hash the last block of cipher text. */
9501
406
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
9502
406
    }
9503
    /* Hash in the lengths of AAD and cipher text in bits */
9504
907
    GHASH_LEN_BLOCK(aes);
9505
    /* Copy the result into s. */
9506
907
    XMEMCPY(s, AES_TAG(aes), sSz);
9507
    /* reset aes->gcm.H in case of reuse */
9508
907
    GHASH_INIT_EXTRA(aes);
9509
907
}
9510
#endif /* WOLFSSL_AESGCM_STREAM */
9511
9512
9513
#ifdef FREESCALE_LTC_AES_GCM
9514
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
9515
                   const byte* iv, word32 ivSz,
9516
                   byte* authTag, word32 authTagSz,
9517
                   const byte* authIn, word32 authInSz)
9518
{
9519
    status_t status;
9520
    word32 keySize;
9521
9522
    /* argument checks */
9523
    if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE || ivSz == 0) {
9524
        return BAD_FUNC_ARG;
9525
    }
9526
9527
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
9528
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
9529
        return BAD_FUNC_ARG;
9530
    }
9531
9532
    status = wc_AesGetKeySize(aes, &keySize);
9533
    if (status)
9534
        return status;
9535
9536
    status = wolfSSL_CryptHwMutexLock();
9537
    if (status != 0)
9538
        return status;
9539
9540
    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
9541
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
9542
    wolfSSL_CryptHwMutexUnLock();
9543
9544
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
9545
}
9546
9547
#else
9548
9549
#ifdef STM32_CRYPTO_AES_GCM
9550
9551
/* this function supports inline encrypt */
9552
static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
9553
                                  Aes* aes, byte* out, const byte* in, word32 sz,
9554
                                  const byte* iv, word32 ivSz,
9555
                                  byte* authTag, word32 authTagSz,
9556
                                  const byte* authIn, word32 authInSz)
9557
{
9558
    int ret;
9559
#ifdef WOLFSSL_STM32_CUBEMX
9560
    CRYP_HandleTypeDef hcryp;
9561
#else
9562
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
9563
#endif
9564
    word32 keySize;
9565
#ifdef WOLFSSL_STM32_CUBEMX
9566
    int status = HAL_OK;
9567
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
9568
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
9569
#else
9570
    int status = SUCCESS;
9571
#endif
9572
    word32 partial = sz % WC_AES_BLOCK_SIZE;
9573
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
9574
    word32 ctrInit[WC_AES_BLOCK_SIZE/sizeof(word32)];
9575
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
9576
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
9577
    byte* authInPadded = NULL;
9578
    int authPadSz, wasAlloc = 0, useSwGhash = 0;
9579
9580
    ret = wc_AesGetKeySize(aes, &keySize);
9581
    if (ret != 0)
9582
        return ret;
9583
9584
#ifdef WOLFSSL_STM32_CUBEMX
9585
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
9586
    if (ret != 0)
9587
        return ret;
9588
#endif
9589
9590
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
9591
    if (ivSz == GCM_NONCE_MID_SZ) {
9592
        byte* pCtr = (byte*)ctr;
9593
        XMEMCPY(ctr, iv, ivSz);
9594
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
9595
    }
9596
    else {
9597
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
9598
    }
9599
    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
9600
9601
    /* Authentication buffer */
9602
#if STM_CRYPT_HEADER_WIDTH == 1
9603
    authPadSz = 0; /* CubeHAL supports byte mode */
9604
#else
9605
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
9606
#endif
9607
#ifdef WOLFSSL_STM32MP13
9608
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
9609
     * minimum of 16 bytes for the auth */
9610
    if ((authInSz > 0) && (authInSz < 16)) {
9611
        authPadSz = 16 - authInSz;
9612
    }
9613
#endif
9614
    if (authPadSz != 0) {
9615
        if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) {
9616
            authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
9617
        }
9618
        if (authPadSz <= sizeof(authhdr)) {
9619
            authInPadded = (byte*)authhdr;
9620
        }
9621
        else {
9622
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
9623
                DYNAMIC_TYPE_TMP_BUFFER);
9624
            if (authInPadded == NULL) {
9625
                wolfSSL_CryptHwMutexUnLock();
9626
                return MEMORY_E;
9627
            }
9628
            wasAlloc = 1;
9629
        }
9630
        XMEMSET(authInPadded, 0, authPadSz);
9631
        XMEMCPY(authInPadded, authIn, authInSz);
9632
    } else {
9633
        authPadSz = authInSz;
9634
        authInPadded = (byte*)authIn;
9635
    }
9636
9637
    /* for cases where hardware cannot be used for authTag calculate it */
9638
    /* if IV is not 12 calculate GHASH using software */
9639
    if (ivSz != GCM_NONCE_MID_SZ
9640
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
9641
        /* or hardware that does not support partial block */
9642
        || sz == 0 || partial != 0
9643
    #endif
9644
    #if STM_CRYPT_HEADER_WIDTH == 4
9645
        /* or authIn is not a multiple of 4  */
9646
        || authPadSz != authInSz
9647
    #endif
9648
    ) {
9649
        useSwGhash = 1;
9650
    }
9651
9652
    /* Hardware requires counter + 1 */
9653
    IncrementGcmCounter((byte*)ctr);
9654
9655
    ret = wolfSSL_CryptHwMutexLock();
9656
    if (ret != 0) {
9657
        return ret;
9658
    }
9659
9660
#ifdef WOLFSSL_STM32_CUBEMX
9661
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
9662
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
9663
9664
#if defined(STM32_HAL_V2)
9665
    hcryp.Init.Algorithm = CRYP_AES_GCM;
9666
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
9667
    #ifdef CRYP_KEYIVCONFIG_ONCE
9668
    /* allows repeated calls to HAL_CRYP_Encrypt */
9669
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
9670
    #endif
9671
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
9672
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
9673
    HAL_CRYP_Init(&hcryp);
9674
9675
    #ifndef CRYP_KEYIVCONFIG_ONCE
9676
    /* GCM payload phase - can handle partial blocks */
9677
    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
9678
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
9679
    #else
9680
    /* GCM payload phase - blocks */
9681
    if (blocks) {
9682
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
9683
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
9684
    }
9685
    /* GCM payload phase - partial remainder */
9686
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
9687
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9688
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9689
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
9690
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
9691
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9692
    }
9693
    #endif
9694
    if (status == HAL_OK && !useSwGhash) {
9695
        /* Compute the authTag */
9696
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
9697
            STM32_HAL_TIMEOUT);
9698
    }
9699
#elif defined(STM32_CRYPTO_AES_ONLY)
9700
    /* Set the CRYP parameters */
9701
    hcryp.Init.HeaderSize = authPadSz;
9702
    if (authPadSz == 0)
9703
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
9704
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
9705
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
9706
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
9707
    HAL_CRYP_Init(&hcryp);
9708
9709
    /* GCM init phase */
9710
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9711
    if (status == HAL_OK) {
9712
        /* GCM header phase */
9713
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
9714
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9715
    }
9716
    if (status == HAL_OK) {
9717
        /* GCM payload phase - blocks */
9718
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
9719
        if (blocks) {
9720
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
9721
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9722
        }
9723
    }
9724
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
9725
        /* GCM payload phase - partial remainder */
9726
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9727
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9728
        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
9729
                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
9730
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9731
    }
9732
    if (status == HAL_OK && !useSwGhash) {
9733
        /* GCM final phase */
9734
        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
9735
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
9736
    }
9737
#else
9738
    hcryp.Init.HeaderSize = authPadSz;
9739
    HAL_CRYP_Init(&hcryp);
9740
    if (blocks) {
9741
        /* GCM payload phase - blocks */
9742
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
9743
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9744
    }
9745
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
9746
        /* GCM payload phase - partial remainder */
9747
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9748
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9749
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
9750
            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
9751
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9752
    }
9753
    if (status == HAL_OK && !useSwGhash) {
9754
        /* Compute the authTag */
9755
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
9756
    }
9757
#endif
9758
9759
    if (status != HAL_OK)
9760
        ret = AES_GCM_AUTH_E;
9761
    HAL_CRYP_DeInit(&hcryp);
9762
9763
#else /* Standard Peripheral Library */
9764
    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
9765
    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
9766
                         (uint8_t*)keyCopy,      keySize * 8,
9767
                         (uint8_t*)in,           sz,
9768
                         (uint8_t*)authInPadded, authInSz,
9769
                         (uint8_t*)out,          (uint8_t*)tag);
9770
    if (status != SUCCESS)
9771
        ret = AES_GCM_AUTH_E;
9772
#endif /* WOLFSSL_STM32_CUBEMX */
9773
    wolfSSL_CryptHwMutexUnLock();
9774
    wc_Stm32_Aes_Cleanup();
9775
9776
    if (ret == 0) {
9777
        /* return authTag */
9778
        if (authTag) {
9779
            if (useSwGhash) {
9780
                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
9781
                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
9782
                if (ret == 0) {
9783
                    xorbuf(authTag, tag, authTagSz);
9784
                }
9785
            }
9786
            else {
9787
                /* use hardware calculated tag */
9788
                XMEMCPY(authTag, tag, authTagSz);
9789
            }
9790
        }
9791
    }
9792
9793
    /* Free memory */
9794
    if (wasAlloc) {
9795
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
9796
    }
9797
9798
    return ret;
9799
}
9800
9801
#endif /* STM32_CRYPTO_AES_GCM */
9802
9803
#if !defined(WOLFSSL_ARMASM)
9804
#ifdef WOLFSSL_AESNI
9805
/* For performance reasons, this code needs to be not inlined. */
9806
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
9807
                      Aes* aes, byte* out, const byte* in, word32 sz,
9808
                      const byte* iv, word32 ivSz,
9809
                      byte* authTag, word32 authTagSz,
9810
                      const byte* authIn, word32 authInSz);
9811
#else
9812
static
9813
#endif
9814
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
9815
                      Aes* aes, byte* out, const byte* in, word32 sz,
9816
                      const byte* iv, word32 ivSz,
9817
                      byte* authTag, word32 authTagSz,
9818
                      const byte* authIn, word32 authInSz)
9819
{
9820
    int ret = 0;
9821
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
9822
    word32 partial = sz % WC_AES_BLOCK_SIZE;
9823
    const byte* p = in;
9824
    byte* c = out;
9825
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
9826
    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
9827
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
9828
#ifdef WC_AES_HAVE_PREFETCH_ARG
9829
    int did_prefetches = 0;
9830
#endif
9831
9832
    if (ivSz == GCM_NONCE_MID_SZ) {
9833
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
9834
        XMEMCPY(counter, iv, ivSz);
9835
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
9836
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
9837
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
9838
    }
9839
    else {
9840
        /* Counter is GHASH of IV. */
9841
#ifdef OPENSSL_EXTRA
9842
        word32 aadTemp = aes->gcm.aadLen;
9843
        aes->gcm.aadLen = 0;
9844
#endif
9845
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
9846
#ifdef OPENSSL_EXTRA
9847
        aes->gcm.aadLen = aadTemp;
9848
#endif
9849
    }
9850
    XMEMCPY(initialCounter, counter, WC_AES_BLOCK_SIZE);
9851
9852
#ifdef WOLFSSL_PIC32MZ_CRYPT
9853
    if (blocks) {
9854
        /* use initial IV for HW, but don't use it below */
9855
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
9856
9857
        ret = wc_Pic32AesCrypt(
9858
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
9859
            out, in, (blocks * WC_AES_BLOCK_SIZE),
9860
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
9861
        if (ret != 0)
9862
            return ret;
9863
    }
9864
    /* process remainder using partial handling */
9865
#endif
9866
9867
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
9868
    /* some hardware acceleration can gain performance from doing AES encryption
9869
     * of the whole buffer at once */
9870
    if (c != p && blocks > 0) { /* can not handle inline encryption */
9871
        while (blocks--) {
9872
            IncrementGcmCounter(counter);
9873
            XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
9874
            c += WC_AES_BLOCK_SIZE;
9875
        }
9876
9877
        /* reset number of blocks and then do encryption */
9878
        blocks = sz / WC_AES_BLOCK_SIZE;
9879
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
9880
        xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
9881
        p += WC_AES_BLOCK_SIZE * blocks;
9882
    }
9883
    else
9884
#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
9885
    {
9886
        while (blocks--) {
9887
            IncrementGcmCounter(counter);
9888
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
9889
            ret = AesEncrypt_preFetchOpt(aes, counter, scratch,
9890
                                            &did_prefetches);
9891
            if (ret != 0)
9892
                return ret;
9893
            xorbufout(c, scratch, p, WC_AES_BLOCK_SIZE);
9894
        #endif
9895
            p += WC_AES_BLOCK_SIZE;
9896
            c += WC_AES_BLOCK_SIZE;
9897
        }
9898
    }
9899
9900
    if (partial != 0) {
9901
        IncrementGcmCounter(counter);
9902
        ret = AesEncrypt_preFetchOpt(aes, counter, scratch, &did_prefetches);
9903
        if (ret != 0)
9904
            return ret;
9905
        xorbufout(c, scratch, p, partial);
9906
    }
9907
    if (authTag) {
9908
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
9909
        ret = AesEncrypt_preFetchOpt(aes, initialCounter, scratch,
9910
                                        &did_prefetches);
9911
        if (ret != 0)
9912
            return ret;
9913
        xorbuf(authTag, scratch, authTagSz);
9914
#ifdef OPENSSL_EXTRA
9915
        if (!in && !sz)
9916
            /* store AAD size for next call */
9917
            aes->gcm.aadLen = authInSz;
9918
#endif
9919
    }
9920
9921
    return ret;
9922
}
9923
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
9924
static int AES_GCM_encrypt_ARM(Aes* aes, byte* out, const byte* in,
9925
    word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
9926
    const byte* authIn, word32 authInSz)
9927
{
9928
    word32 blocks;
9929
    word32 partial;
9930
    byte counter[WC_AES_BLOCK_SIZE];
9931
    byte initialCounter[WC_AES_BLOCK_SIZE];
9932
    byte x[WC_AES_BLOCK_SIZE];
9933
    byte scratch[WC_AES_BLOCK_SIZE];
9934
9935
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
9936
    if (ivSz == GCM_NONCE_MID_SZ) {
9937
        XMEMCPY(initialCounter, iv, ivSz);
9938
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
9939
    }
9940
    else {
9941
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
9942
    }
9943
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
9944
9945
    /* Hash in the Additional Authentication Data */
9946
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9947
    if (authInSz != 0 && authIn != NULL) {
9948
        blocks = authInSz / WC_AES_BLOCK_SIZE;
9949
        partial = authInSz % WC_AES_BLOCK_SIZE;
9950
        if (blocks > 0) {
9951
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
9952
            authIn += blocks * WC_AES_BLOCK_SIZE;
9953
        }
9954
        if (partial != 0) {
9955
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9956
            XMEMCPY(scratch, authIn, partial);
9957
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
9958
        }
9959
    }
9960
9961
    /* do as many blocks as possible */
9962
    blocks = sz / WC_AES_BLOCK_SIZE;
9963
    partial = sz % WC_AES_BLOCK_SIZE;
9964
    if (blocks > 0) {
9965
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
9966
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
9967
        if (sz >= 32)
9968
    #endif
9969
        {
9970
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
9971
                (const unsigned char*)aes->key, aes->rounds, counter);
9972
        }
9973
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
9974
        else
9975
    #endif
9976
    #endif
9977
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
9978
        {
9979
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
9980
                (const unsigned char*)aes->key, aes->rounds, counter);
9981
        }
9982
    #endif
9983
        GCM_GMULT_LEN(&aes->gcm, x, out, blocks * WC_AES_BLOCK_SIZE);
9984
        in += blocks * WC_AES_BLOCK_SIZE;
9985
        out += blocks * WC_AES_BLOCK_SIZE;
9986
    }
9987
    /* take care of partial block sizes leftover */
9988
    if (partial != 0) {
9989
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
9990
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
9991
        {
9992
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
9993
                (const unsigned char*)aes->key, aes->rounds, counter);
9994
        }
9995
    #else
9996
        {
9997
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
9998
                (const unsigned char*)aes->key, aes->rounds, counter);
9999
        }
10000
    #endif
10001
        XMEMCPY(out, scratch, partial);
10002
10003
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10004
        XMEMCPY(scratch, out, partial);
10005
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10006
    }
10007
10008
    /* Hash in the lengths of A and C in bits */
10009
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10010
    FlattenSzInBits(&scratch[0], authInSz);
10011
    FlattenSzInBits(&scratch[8], sz);
10012
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10013
    if (authTagSz > WC_AES_BLOCK_SIZE) {
10014
        XMEMCPY(authTag, x, WC_AES_BLOCK_SIZE);
10015
    }
10016
    else {
10017
        /* authTagSz can be smaller than WC_AES_BLOCK_SIZE */
10018
        XMEMCPY(authTag, x, authTagSz);
10019
    }
10020
10021
    /* Auth tag calculation. */
10022
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10023
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10024
    {
10025
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10026
            (const unsigned char*)aes->key, aes->rounds);
10027
    }
10028
#else
10029
    {
10030
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10031
            (const unsigned char*)aes->key, aes->rounds);
10032
    }
10033
#endif
10034
    xorbuf(authTag, scratch, authTagSz);
10035
10036
    return 0;
10037
}
10038
#endif
10039
10040
/* Software AES - GCM Encrypt */
10041
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10042
                   const byte* iv, word32 ivSz,
10043
                   byte* authTag, word32 authTagSz,
10044
                   const byte* authIn, word32 authInSz)
10045
856
{
10046
856
    int ret;
10047
10048
    /* argument checks */
10049
856
    if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE || ivSz == 0 ||
10050
856
        ((authTagSz > 0) && (authTag == NULL)) ||
10051
856
        ((authInSz > 0) && (authIn == NULL)))
10052
0
    {
10053
0
        return BAD_FUNC_ARG;
10054
0
    }
10055
10056
856
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
10057
0
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
10058
0
        return BAD_FUNC_ARG;
10059
0
    }
10060
10061
856
#ifdef WOLF_CRYPTO_CB
10062
856
    #ifndef WOLF_CRYPTO_CB_FIND
10063
856
    if (aes->devId != INVALID_DEVID)
10064
0
    #endif
10065
0
    {
10066
0
        int crypto_cb_ret =
10067
0
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
10068
0
                                      authTagSz, authIn, authInSz);
10069
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
10070
0
            return crypto_cb_ret;
10071
        /* fall-through when unavailable */
10072
0
    }
10073
856
#endif
10074
10075
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
10076
    /* if async and byte count above threshold */
10077
    /* only 12-byte IV is supported in HW */
10078
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
10079
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
10080
    #if defined(HAVE_CAVIUM)
10081
        #ifdef HAVE_CAVIUM_V
10082
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
10083
            return NitroxAesGcmEncrypt(aes, out, in, sz,
10084
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10085
                authTag, authTagSz, authIn, authInSz);
10086
        }
10087
        #endif
10088
    #elif defined(HAVE_INTEL_QA)
10089
        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
10090
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10091
            authTag, authTagSz, authIn, authInSz);
10092
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
10093
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
10094
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
10095
            sw->aes.aes = aes;
10096
            sw->aes.out = out;
10097
            sw->aes.in = in;
10098
            sw->aes.sz = sz;
10099
            sw->aes.iv = iv;
10100
            sw->aes.ivSz = ivSz;
10101
            sw->aes.authTag = authTag;
10102
            sw->aes.authTagSz = authTagSz;
10103
            sw->aes.authIn = authIn;
10104
            sw->aes.authInSz = authInSz;
10105
            return WC_PENDING_E;
10106
        }
10107
    #endif
10108
    }
10109
#endif /* WOLFSSL_ASYNC_CRYPT */
10110
10111
#ifdef WOLFSSL_SILABS_SE_ACCEL
10112
    return wc_AesGcmEncrypt_silabs(
10113
        aes, out, in, sz,
10114
        iv, ivSz,
10115
        authTag, authTagSz,
10116
        authIn, authInSz);
10117
#endif
10118
10119
#ifdef STM32_CRYPTO_AES_GCM
10120
    return wc_AesGcmEncrypt_STM32(
10121
        aes, out, in, sz, iv, ivSz,
10122
        authTag, authTagSz, authIn, authInSz);
10123
#endif /* STM32_CRYPTO_AES_GCM */
10124
10125
#if defined(WOLFSSL_PSOC6_CRYPTO)
10126
    return wc_Psoc6_Aes_GcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
10127
                                   authTagSz, authIn, authInSz);
10128
#endif /* WOLFSSL_PSOC6_CRYPTO */
10129
10130
856
    VECTOR_REGISTERS_PUSH;
10131
10132
#if defined(WOLFSSL_ARMASM)
10133
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
10134
#if !defined(__aarch64__)
10135
    AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
10136
        authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
10137
        aes->rounds);
10138
    ret = 0;
10139
#else
10140
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10141
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
10142
        if (aes->use_sha3_hw_crypto) {
10143
            AES_GCM_encrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
10144
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
10145
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
10146
        }
10147
        else
10148
    #endif
10149
        {
10150
            AES_GCM_encrypt_AARCH64(in, out, sz, iv, ivSz, authTag, authTagSz,
10151
                authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
10152
                (byte*)aes->reg, aes->rounds);
10153
        }
10154
        ret = 0;
10155
    }
10156
    else
10157
#endif /* !__aarch64__ */
10158
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
10159
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10160
    {
10161
        ret = AES_GCM_encrypt_ARM(aes, out, in, sz, iv, ivSz, authTag,
10162
            authTagSz, authIn, authInSz);
10163
    }
10164
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
10165
#else
10166
#ifdef WOLFSSL_AESNI
10167
    if (aes->use_aesni) {
10168
#ifdef HAVE_INTEL_AVX2
10169
        if (IS_INTEL_AVX2(intel_flags)) {
10170
            AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10171
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
10172
            ret = 0;
10173
        }
10174
        else
10175
#endif
10176
#if defined(HAVE_INTEL_AVX1)
10177
        if (IS_INTEL_AVX1(intel_flags)) {
10178
            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10179
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
10180
            ret = 0;
10181
        } else
10182
#endif
10183
        {
10184
            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10185
                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
10186
            ret = 0;
10187
        }
10188
    }
10189
    else
10190
#endif /* WOLFSSL_AESNI */
10191
856
    {
10192
856
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
10193
856
                                authIn, authInSz);
10194
856
    }
10195
856
#endif
10196
10197
856
    VECTOR_REGISTERS_POP;
10198
10199
856
    return ret;
10200
856
}
10201
#endif
10202
10203
10204
/* AES GCM Decrypt */
10205
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
10206
#ifdef FREESCALE_LTC_AES_GCM
10207
int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10208
                   const byte* iv, word32 ivSz,
10209
                   const byte* authTag, word32 authTagSz,
10210
                   const byte* authIn, word32 authInSz)
10211
{
10212
    int ret;
10213
    word32 keySize;
10214
    status_t status;
10215
10216
    /* argument checks */
10217
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
10218
     * in and out are don't cares, as this is is the GMAC case. */
10219
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
10220
        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE || authTagSz == 0 ||
10221
        ivSz == 0 || ((authInSz > 0) && (authIn == NULL)))
10222
    {
10223
        return BAD_FUNC_ARG;
10224
    }
10225
10226
    ret = wc_AesGetKeySize(aes, &keySize);
10227
    if (ret != 0) {
10228
        return ret;
10229
    }
10230
10231
    status = wolfSSL_CryptHwMutexLock();
10232
    if (status != 0)
10233
        return status;
10234
10235
    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
10236
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
10237
    wolfSSL_CryptHwMutexUnLock();
10238
10239
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
10240
}
10241
10242
#else
10243
10244
#ifdef STM32_CRYPTO_AES_GCM
10245
/* this function supports inline decrypt */
10246
static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
10247
                                  Aes* aes, byte* out,
10248
                                  const byte* in, word32 sz,
10249
                                  const byte* iv, word32 ivSz,
10250
                                  const byte* authTag, word32 authTagSz,
10251
                                  const byte* authIn, word32 authInSz)
10252
{
10253
    int ret;
10254
#ifdef WOLFSSL_STM32_CUBEMX
10255
    int status = HAL_OK;
10256
    CRYP_HandleTypeDef hcryp;
10257
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10258
#else
10259
    int status = SUCCESS;
10260
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
10261
#endif
10262
    word32 keySize;
10263
    word32 partial = sz % WC_AES_BLOCK_SIZE;
10264
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
10265
    word32 tagExpected[WC_AES_BLOCK_SIZE/sizeof(word32)];
10266
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
10267
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10268
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10269
    byte* authInPadded = NULL;
10270
    int authPadSz, wasAlloc = 0, tagComputed = 0;
10271
10272
    ret = wc_AesGetKeySize(aes, &keySize);
10273
    if (ret != 0)
10274
        return ret;
10275
10276
#ifdef WOLFSSL_STM32_CUBEMX
10277
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
10278
    if (ret != 0)
10279
        return ret;
10280
#endif
10281
10282
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
10283
    if (ivSz == GCM_NONCE_MID_SZ) {
10284
        byte* pCtr = (byte*)ctr;
10285
        XMEMCPY(ctr, iv, ivSz);
10286
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
10287
    }
10288
    else {
10289
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
10290
    }
10291
10292
    /* Make copy of expected authTag, which could get corrupted in some
10293
     * Cube HAL versions without proper partial block support.
10294
     * For TLS blocks the authTag is after the output buffer, so save it */
10295
    XMEMCPY(tagExpected, authTag, authTagSz);
10296
10297
    /* Authentication buffer */
10298
#if STM_CRYPT_HEADER_WIDTH == 1
10299
    authPadSz = 0; /* CubeHAL supports byte mode */
10300
#else
10301
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
10302
#endif
10303
#ifdef WOLFSSL_STM32MP13
10304
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
10305
     * minimum of 16 bytes for the auth */
10306
    if ((authInSz > 0) && (authInSz < 16)) {
10307
        authPadSz = 16 - authInSz;
10308
    }
10309
#else
10310
    if (authPadSz != 0) {
10311
        authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
10312
    }
10313
    else {
10314
        authPadSz = authInSz;
10315
    }
10316
#endif
10317
10318
    /* for cases where hardware cannot be used for authTag calculate it */
10319
    /* if IV is not 12 calculate GHASH using software */
10320
    if (ivSz != GCM_NONCE_MID_SZ
10321
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
10322
        /* or hardware that does not support partial block */
10323
        || sz == 0 || partial != 0
10324
    #endif
10325
    #if STM_CRYPT_HEADER_WIDTH == 4
10326
        /* or authIn is not a multiple of 4  */
10327
        || authPadSz != authInSz
10328
    #endif
10329
    ) {
10330
        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
10331
        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
10332
        if (ret != 0)
10333
            return ret;
10334
        xorbuf(tag, partialBlock, sizeof(tag));
10335
        tagComputed = 1;
10336
    }
10337
10338
    /* if using hardware for authentication tag make sure its aligned and zero padded */
10339
    if (authPadSz != authInSz && !tagComputed) {
10340
        if (authPadSz <= sizeof(authhdr)) {
10341
            authInPadded = (byte*)authhdr;
10342
        }
10343
        else {
10344
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
10345
                DYNAMIC_TYPE_TMP_BUFFER);
10346
            if (authInPadded == NULL) {
10347
                wolfSSL_CryptHwMutexUnLock();
10348
                return MEMORY_E;
10349
            }
10350
            wasAlloc = 1;
10351
        }
10352
        XMEMSET(authInPadded, 0, authPadSz);
10353
        XMEMCPY(authInPadded, authIn, authInSz);
10354
    } else {
10355
        authInPadded = (byte*)authIn;
10356
    }
10357
10358
    /* Hardware requires counter + 1 */
10359
    IncrementGcmCounter((byte*)ctr);
10360
10361
    ret = wolfSSL_CryptHwMutexLock();
10362
    if (ret != 0) {
10363
        if (wasAlloc) {
10364
            XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
10365
        }
10366
        return ret;
10367
    }
10368
10369
#ifdef WOLFSSL_STM32_CUBEMX
10370
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10371
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
10372
10373
#if defined(STM32_HAL_V2)
10374
    hcryp.Init.Algorithm = CRYP_AES_GCM;
10375
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
10376
    #ifdef CRYP_KEYIVCONFIG_ONCE
10377
    /* allows repeated calls to HAL_CRYP_Decrypt */
10378
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
10379
    #endif
10380
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
10381
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10382
    HAL_CRYP_Init(&hcryp);
10383
10384
    #ifndef CRYP_KEYIVCONFIG_ONCE
10385
    /* GCM payload phase - can handle partial blocks */
10386
    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
10387
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
10388
    #else
10389
    /* GCM payload phase - blocks */
10390
    if (blocks) {
10391
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
10392
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
10393
    }
10394
    /* GCM payload phase - partial remainder */
10395
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10396
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10397
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10398
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
10399
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
10400
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10401
    }
10402
    #endif
10403
    if (status == HAL_OK && !tagComputed) {
10404
        /* Compute the authTag */
10405
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
10406
            STM32_HAL_TIMEOUT);
10407
    }
10408
#elif defined(STM32_CRYPTO_AES_ONLY)
10409
    /* Set the CRYP parameters */
10410
    hcryp.Init.HeaderSize = authPadSz;
10411
    if (authPadSz == 0)
10412
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
10413
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
10414
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
10415
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
10416
    HAL_CRYP_Init(&hcryp);
10417
10418
    /* GCM init phase */
10419
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10420
    if (status == HAL_OK) {
10421
        /* GCM header phase */
10422
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
10423
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10424
    }
10425
    if (status == HAL_OK) {
10426
        /* GCM payload phase - blocks */
10427
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
10428
        if (blocks) {
10429
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
10430
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10431
        }
10432
    }
10433
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
10434
        /* GCM payload phase - partial remainder */
10435
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10436
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10437
        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
10438
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
10439
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10440
    }
10441
    if (status == HAL_OK && tagComputed == 0) {
10442
        /* GCM final phase */
10443
        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
10444
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
10445
    }
10446
#else
10447
    hcryp.Init.HeaderSize = authPadSz;
10448
    HAL_CRYP_Init(&hcryp);
10449
    if (blocks) {
10450
        /* GCM payload phase - blocks */
10451
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
10452
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10453
    }
10454
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10455
        /* GCM payload phase - partial remainder */
10456
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10457
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10458
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
10459
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
10460
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10461
    }
10462
    if (status == HAL_OK && tagComputed == 0) {
10463
        /* Compute the authTag */
10464
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
10465
    }
10466
#endif
10467
10468
    if (status != HAL_OK)
10469
        ret = AES_GCM_AUTH_E;
10470
10471
    HAL_CRYP_DeInit(&hcryp);
10472
10473
#else /* Standard Peripheral Library */
10474
    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
10475
10476
    /* Input size and auth size need to be the actual sizes, even though
10477
     * they are not block aligned, because this length (in bits) is used
10478
     * in the final GHASH. */
10479
    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
10480
    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
10481
                         (uint8_t*)keyCopy,      keySize * 8,
10482
                         (uint8_t*)in,           sz,
10483
                         (uint8_t*)authInPadded, authInSz,
10484
                         (uint8_t*)out,          (uint8_t*)partialBlock);
10485
    if (status != SUCCESS)
10486
        ret = AES_GCM_AUTH_E;
10487
    if (tagComputed == 0)
10488
        XMEMCPY(tag, partialBlock, authTagSz);
10489
#endif /* WOLFSSL_STM32_CUBEMX */
10490
    wolfSSL_CryptHwMutexUnLock();
10491
    wc_Stm32_Aes_Cleanup();
10492
10493
    /* Check authentication tag */
10494
    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
10495
        ret = AES_GCM_AUTH_E;
10496
    }
10497
10498
    /* Free memory */
10499
    if (wasAlloc) {
10500
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
10501
    }
10502
10503
    return ret;
10504
}
10505
10506
#endif /* STM32_CRYPTO_AES_GCM */
10507
10508
#if !defined(WOLFSSL_ARMASM)
10509
#ifdef WOLFSSL_AESNI
10510
/* For performance reasons, this code needs to be not inlined. */
10511
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
10512
                      Aes* aes, byte* out, const byte* in, word32 sz,
10513
                      const byte* iv, word32 ivSz,
10514
                      const byte* authTag, word32 authTagSz,
10515
                      const byte* authIn, word32 authInSz);
10516
#else
10517
static
10518
#endif
10519
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
10520
                      Aes* aes, byte* out, const byte* in, word32 sz,
10521
                      const byte* iv, word32 ivSz,
10522
                      const byte* authTag, word32 authTagSz,
10523
                      const byte* authIn, word32 authInSz)
10524
0
{
10525
0
    int ret;
10526
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10527
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
10528
0
    const byte* c = in;
10529
0
    byte* p = out;
10530
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
10531
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
10532
0
    ALIGN16 byte Tprime[WC_AES_BLOCK_SIZE];
10533
0
    ALIGN16 byte EKY0[WC_AES_BLOCK_SIZE];
10534
0
    volatile sword32 res;
10535
10536
0
    if (ivSz == GCM_NONCE_MID_SZ) {
10537
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
10538
0
        XMEMCPY(counter, iv, ivSz);
10539
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
10540
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
10541
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
10542
0
    }
10543
0
    else {
10544
        /* Counter is GHASH of IV. */
10545
#ifdef OPENSSL_EXTRA
10546
        word32 aadTemp = aes->gcm.aadLen;
10547
        aes->gcm.aadLen = 0;
10548
#endif
10549
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
10550
#ifdef OPENSSL_EXTRA
10551
        aes->gcm.aadLen = aadTemp;
10552
#endif
10553
0
    }
10554
10555
    /* Calc the authTag again using received auth data and the cipher text */
10556
0
    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
10557
0
    ret = wc_AesEncrypt(aes, counter, EKY0);
10558
0
    if (ret != 0)
10559
0
        return ret;
10560
0
    xorbuf(Tprime, EKY0, sizeof(Tprime));
10561
#ifdef WC_AES_GCM_DEC_AUTH_EARLY
10562
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
10563
     * the pairwise bytes in the strings.
10564
     */
10565
    res = ConstantCompare(authTag, Tprime, authTagSz);
10566
    /* convert positive retval from ConstantCompare() to all-1s word, in
10567
     * constant time.
10568
     */
10569
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
10570
    ret = res & AES_GCM_AUTH_E;
10571
    if (ret != 0)
10572
        return ret;
10573
#endif
10574
10575
#ifdef OPENSSL_EXTRA
10576
    if (!out) {
10577
        /* authenticated, non-confidential data */
10578
        /* store AAD size for next call */
10579
        aes->gcm.aadLen = authInSz;
10580
    }
10581
#endif
10582
10583
#if defined(WOLFSSL_PIC32MZ_CRYPT)
10584
    if (blocks) {
10585
        /* use initial IV for HW, but don't use it below */
10586
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
10587
10588
        ret = wc_Pic32AesCrypt(
10589
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
10590
            out, in, (blocks * WC_AES_BLOCK_SIZE),
10591
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
10592
        if (ret != 0)
10593
            return ret;
10594
    }
10595
    /* process remainder using partial handling */
10596
#endif
10597
10598
0
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
10599
    /* some hardware acceleration can gain performance from doing AES encryption
10600
     * of the whole buffer at once */
10601
0
    if (c != p && blocks > 0) { /* can not handle inline decryption */
10602
0
        while (blocks--) {
10603
0
            IncrementGcmCounter(counter);
10604
0
            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
10605
0
            p += WC_AES_BLOCK_SIZE;
10606
0
        }
10607
10608
        /* reset number of blocks and then do encryption */
10609
0
        blocks = sz / WC_AES_BLOCK_SIZE;
10610
10611
0
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
10612
0
        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
10613
0
        c += WC_AES_BLOCK_SIZE * blocks;
10614
0
    }
10615
0
    else
10616
0
#endif /* HAVE_AES_ECB && !PIC32MZ */
10617
0
    {
10618
0
        while (blocks--) {
10619
0
            IncrementGcmCounter(counter);
10620
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
10621
0
            ret = wc_AesEncrypt(aes, counter, scratch);
10622
0
            if (ret != 0)
10623
0
                return ret;
10624
0
            xorbufout(p, scratch, c, WC_AES_BLOCK_SIZE);
10625
0
        #endif
10626
0
            p += WC_AES_BLOCK_SIZE;
10627
0
            c += WC_AES_BLOCK_SIZE;
10628
0
        }
10629
0
    }
10630
10631
0
    if (partial != 0) {
10632
0
        IncrementGcmCounter(counter);
10633
0
        ret = wc_AesEncrypt(aes, counter, scratch);
10634
0
        if (ret != 0)
10635
0
            return ret;
10636
0
        xorbuf(scratch, c, partial);
10637
0
        XMEMCPY(p, scratch, partial);
10638
0
    }
10639
10640
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
10641
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
10642
     * the pairwise bytes in the strings.
10643
     */
10644
0
    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
10645
    /* convert positive retval from ConstantCompare() to all-1s word, in
10646
     * constant time.
10647
     */
10648
0
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
10649
    /* now use res as a mask for constant time return of ret, unless tag
10650
     * mismatch, whereupon AES_GCM_AUTH_E is returned.
10651
     */
10652
0
    ret = (ret & ~res);
10653
0
    ret |= (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
10654
0
#endif
10655
0
    return ret;
10656
0
}
10657
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10658
static int AES_GCM_decrypt_ARM(Aes* aes, byte* out, const byte* in,
10659
    word32 sz, const byte* iv, word32 ivSz, const byte* authTag,
10660
    word32 authTagSz, const byte* authIn, word32 authInSz)
10661
{
10662
    word32 blocks;
10663
    word32 partial;
10664
    byte counter[WC_AES_BLOCK_SIZE];
10665
    byte initialCounter[WC_AES_BLOCK_SIZE];
10666
    byte scratch[WC_AES_BLOCK_SIZE];
10667
    byte x[WC_AES_BLOCK_SIZE];
10668
10669
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
10670
    if (ivSz == GCM_NONCE_MID_SZ) {
10671
        XMEMCPY(initialCounter, iv, ivSz);
10672
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
10673
    }
10674
    else {
10675
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
10676
    }
10677
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
10678
10679
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
10680
    /* Hash in the Additional Authentication Data */
10681
    if (authInSz != 0 && authIn != NULL) {
10682
        blocks = authInSz / WC_AES_BLOCK_SIZE;
10683
        partial = authInSz % WC_AES_BLOCK_SIZE;
10684
        if (blocks > 0) {
10685
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
10686
            authIn += blocks * WC_AES_BLOCK_SIZE;
10687
        }
10688
        if (partial != 0) {
10689
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10690
            XMEMCPY(scratch, authIn, partial);
10691
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10692
        }
10693
    }
10694
10695
    blocks = sz / WC_AES_BLOCK_SIZE;
10696
    partial = sz % WC_AES_BLOCK_SIZE;
10697
    /* do as many blocks as possible */
10698
    if (blocks > 0) {
10699
        GCM_GMULT_LEN(&aes->gcm, x, in, blocks * WC_AES_BLOCK_SIZE);
10700
10701
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
10702
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10703
        if (sz >= 32)
10704
    #endif
10705
        {
10706
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
10707
                (const unsigned char*)aes->key, aes->rounds, counter);
10708
        }
10709
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10710
        else
10711
    #endif
10712
    #endif
10713
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10714
        {
10715
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
10716
                (const unsigned char*)aes->key, aes->rounds, counter);
10717
        }
10718
    #endif
10719
        in += blocks * WC_AES_BLOCK_SIZE;
10720
        out += blocks * WC_AES_BLOCK_SIZE;
10721
    }
10722
    if (partial != 0) {
10723
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10724
        XMEMCPY(scratch, in, partial);
10725
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10726
10727
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10728
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10729
        {
10730
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
10731
                (const unsigned char*)aes->key, aes->rounds, counter);
10732
        }
10733
    #else
10734
        {
10735
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
10736
                (const unsigned char*)aes->key, aes->rounds, counter);
10737
        }
10738
    #endif
10739
        XMEMCPY(out, scratch, partial);
10740
    }
10741
10742
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10743
    FlattenSzInBits(&scratch[0], authInSz);
10744
    FlattenSzInBits(&scratch[8], sz);
10745
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10746
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10747
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10748
    {
10749
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10750
            (const unsigned char*)aes->key, aes->rounds);
10751
    }
10752
#else
10753
    {
10754
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10755
            (const unsigned char*)aes->key, aes->rounds);
10756
    }
10757
#endif
10758
    xorbuf(x, scratch, authTagSz);
10759
    if (authTag != NULL) {
10760
        if (ConstantCompare(authTag, x, authTagSz) != 0) {
10761
            return AES_GCM_AUTH_E;
10762
        }
10763
    }
10764
10765
    return 0;
10766
}
10767
#endif
10768
10769
/* Software AES - GCM Decrypt */
10770
int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10771
                     const byte* iv, word32 ivSz,
10772
                     const byte* authTag, word32 authTagSz,
10773
                     const byte* authIn, word32 authInSz)
10774
820
{
10775
820
    int ret;
10776
#ifdef WOLFSSL_AESNI
10777
    int res = WC_NO_ERR_TRACE(AES_GCM_AUTH_E);
10778
#endif
10779
10780
    /* argument checks */
10781
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
10782
     * in and out are don't cares, as this is is the GMAC case. */
10783
820
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
10784
820
        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE || authTagSz == 0 ||
10785
820
        ivSz == 0) {
10786
10787
0
        return BAD_FUNC_ARG;
10788
0
    }
10789
10790
820
#ifdef WOLF_CRYPTO_CB
10791
820
    #ifndef WOLF_CRYPTO_CB_FIND
10792
820
    if (aes->devId != INVALID_DEVID)
10793
0
    #endif
10794
0
    {
10795
0
        int crypto_cb_ret =
10796
0
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
10797
0
                                      authTag, authTagSz, authIn, authInSz);
10798
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
10799
0
            return crypto_cb_ret;
10800
        /* fall-through when unavailable */
10801
0
    }
10802
820
#endif
10803
10804
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
10805
    /* if async and byte count above threshold */
10806
    /* only 12-byte IV is supported in HW */
10807
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
10808
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
10809
    #if defined(HAVE_CAVIUM)
10810
        #ifdef HAVE_CAVIUM_V
10811
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
10812
            return NitroxAesGcmDecrypt(aes, out, in, sz,
10813
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10814
                authTag, authTagSz, authIn, authInSz);
10815
        }
10816
        #endif
10817
    #elif defined(HAVE_INTEL_QA)
10818
        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
10819
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10820
            authTag, authTagSz, authIn, authInSz);
10821
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
10822
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
10823
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
10824
            sw->aes.aes = aes;
10825
            sw->aes.out = out;
10826
            sw->aes.in = in;
10827
            sw->aes.sz = sz;
10828
            sw->aes.iv = iv;
10829
            sw->aes.ivSz = ivSz;
10830
            sw->aes.authTag = (byte*)authTag;
10831
            sw->aes.authTagSz = authTagSz;
10832
            sw->aes.authIn = authIn;
10833
            sw->aes.authInSz = authInSz;
10834
            return WC_PENDING_E;
10835
        }
10836
    #endif
10837
    }
10838
#endif /* WOLFSSL_ASYNC_CRYPT */
10839
10840
#ifdef WOLFSSL_SILABS_SE_ACCEL
10841
    return wc_AesGcmDecrypt_silabs(
10842
        aes, out, in, sz, iv, ivSz,
10843
        authTag, authTagSz, authIn, authInSz);
10844
10845
#endif
10846
10847
#ifdef STM32_CRYPTO_AES_GCM
10848
    /* The STM standard peripheral library API's doesn't support partial blocks */
10849
    return wc_AesGcmDecrypt_STM32(
10850
        aes, out, in, sz, iv, ivSz,
10851
        authTag, authTagSz, authIn, authInSz);
10852
#endif /* STM32_CRYPTO_AES_GCM */
10853
10854
#if defined(WOLFSSL_PSOC6_CRYPTO)
10855
    return wc_Psoc6_Aes_GcmDecrypt(aes, out, in, sz, iv, ivSz, authTag,
10856
                                   authTagSz, authIn, authInSz);
10857
#endif /* WOLFSSL_PSOC6_CRYPTO */
10858
10859
820
    VECTOR_REGISTERS_PUSH;
10860
10861
#if defined(WOLFSSL_ARMASM)
10862
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
10863
#ifndef __aarch64__
10864
    {
10865
    #ifdef OPENSSL_EXTRA
10866
        word32 reg[WC_AES_BLOCK_SIZE / sizeof(word32)];
10867
        XMEMCPY(reg, aes->reg, sizeof(reg));
10868
    #endif
10869
        ret = AES_GCM_decrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
10870
            authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
10871
            (byte*)aes->reg, aes->rounds);
10872
    #ifdef OPENSSL_EXTRA
10873
        XMEMCPY(aes->reg, reg, sizeof(reg));
10874
    #endif
10875
    }
10876
#else
10877
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10878
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
10879
        if (aes->use_sha3_hw_crypto) {
10880
            ret = AES_GCM_decrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
10881
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
10882
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
10883
        }
10884
        else
10885
    #endif
10886
        {
10887
            ret = AES_GCM_decrypt_AARCH64(in, out, sz, iv, ivSz, authTag,
10888
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
10889
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
10890
        }
10891
    }
10892
    else
10893
#endif /* !__aarch64__ */
10894
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
10895
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10896
    {
10897
        ret = AES_GCM_decrypt_ARM(aes, out, in, sz, iv, ivSz, authTag,
10898
            authTagSz, authIn, authInSz);
10899
    }
10900
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
10901
#else
10902
#ifdef WOLFSSL_AESNI
10903
    if (aes->use_aesni) {
10904
#ifdef HAVE_INTEL_AVX2
10905
        if (IS_INTEL_AVX2(intel_flags)) {
10906
            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10907
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
10908
            if (res == 0)
10909
                ret = AES_GCM_AUTH_E;
10910
            else
10911
                ret = 0;
10912
        }
10913
        else
10914
#endif
10915
#if defined(HAVE_INTEL_AVX1)
10916
        if (IS_INTEL_AVX1(intel_flags)) {
10917
            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10918
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
10919
            if (res == 0)
10920
                ret = AES_GCM_AUTH_E;
10921
            else
10922
                ret = 0;
10923
        }
10924
        else
10925
#endif
10926
        {
10927
            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10928
                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
10929
            if (res == 0)
10930
                ret = AES_GCM_AUTH_E;
10931
            else
10932
                ret = 0;
10933
        }
10934
    }
10935
    else
10936
#endif /* WOLFSSL_AESNI */
10937
820
    {
10938
820
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
10939
820
                                                             authIn, authInSz);
10940
820
    }
10941
820
#endif
10942
10943
820
    VECTOR_REGISTERS_POP;
10944
10945
820
    return ret;
10946
820
}
10947
#endif
10948
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
10949
10950
#ifdef WOLFSSL_AESGCM_STREAM
10951
10952
/* Initialize the AES GCM cipher with an IV. C implementation.
10953
 *
10954
 * @param [in, out] aes   AES object.
10955
 * @param [in]      iv    IV/nonce buffer.
10956
 * @param [in]      ivSz  Length of IV/nonce data.
10957
 */
10958
static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
10959
2.64k
{
10960
2.64k
    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
10961
2.64k
    int ret;
10962
10963
2.64k
    if (ivSz == GCM_NONCE_MID_SZ) {
10964
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
10965
2.64k
        XMEMCPY(counter, iv, ivSz);
10966
2.64k
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
10967
2.64k
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
10968
2.64k
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
10969
2.64k
    }
10970
0
    else {
10971
        /* Counter is GHASH of IV. */
10972
    #ifdef OPENSSL_EXTRA
10973
        word32 aadTemp = aes->gcm.aadLen;
10974
        aes->gcm.aadLen = 0;
10975
    #endif
10976
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
10977
    #ifdef OPENSSL_EXTRA
10978
        aes->gcm.aadLen = aadTemp;
10979
    #endif
10980
0
    }
10981
10982
    /* Copy in the counter for use with cipher. */
10983
2.64k
    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
10984
    /* Encrypt initial counter into a buffer for GCM. */
10985
2.64k
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
10986
2.64k
    if (ret != 0)
10987
0
        return ret;
10988
    /* Reset state fields. */
10989
2.64k
    aes->over = 0;
10990
2.64k
    aes->aSz = 0;
10991
2.64k
    aes->cSz = 0;
10992
    /* Initialization for GHASH. */
10993
2.64k
    GHASH_INIT(aes);
10994
10995
2.64k
    return 0;
10996
2.64k
}
10997
10998
/* Update the AES GCM cipher with data. C implementation.
10999
 *
11000
 * Only enciphers data.
11001
 *
11002
 * @param [in, out] aes  AES object.
11003
 * @param [in]      out  Cipher text or plaintext buffer.
11004
 * @param [in]      in   Plaintext or cipher text buffer.
11005
 * @param [in]      sz   Length of data.
11006
 */
11007
static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
11008
    Aes* aes, byte* out, const byte* in, word32 sz)
11009
9.15k
{
11010
9.15k
    word32 blocks;
11011
9.15k
    word32 partial;
11012
9.15k
    int ret;
11013
11014
    /* Check if previous encrypted block was not used up. */
11015
9.15k
    if (aes->over > 0) {
11016
6.44k
        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
11017
6.44k
        if (pSz > sz) pSz = (byte)sz;
11018
11019
        /* Use some/all of last encrypted block. */
11020
6.44k
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
11021
6.44k
        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
11022
11023
        /* Some data used. */
11024
6.44k
        sz  -= pSz;
11025
6.44k
        in  += pSz;
11026
6.44k
        out += pSz;
11027
6.44k
    }
11028
11029
    /* Calculate the number of blocks needing to be encrypted and any leftover.
11030
     */
11031
9.15k
    blocks  = sz / WC_AES_BLOCK_SIZE;
11032
9.15k
    partial = sz & (WC_AES_BLOCK_SIZE - 1);
11033
11034
9.15k
#if defined(HAVE_AES_ECB)
11035
    /* Some hardware acceleration can gain performance from doing AES encryption
11036
     * of the whole buffer at once.
11037
     * Overwrites the cipher text before using plaintext - no inline encryption.
11038
     */
11039
9.15k
    if ((out != in) && blocks > 0) {
11040
448
        word32 b;
11041
        /* Place incrementing counter blocks into cipher text. */
11042
4.08k
        for (b = 0; b < blocks; b++) {
11043
3.63k
            IncrementGcmCounter(AES_COUNTER(aes));
11044
3.63k
            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
11045
3.63k
        }
11046
11047
        /* Encrypt counter blocks. */
11048
448
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
11049
        /* XOR in plaintext. */
11050
448
        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
11051
        /* Skip over processed data. */
11052
448
        in += WC_AES_BLOCK_SIZE * blocks;
11053
448
        out += WC_AES_BLOCK_SIZE * blocks;
11054
448
    }
11055
8.70k
    else
11056
8.70k
#endif /* HAVE_AES_ECB */
11057
8.70k
    {
11058
        /* Encrypt block by block. */
11059
10.7k
        while (blocks--) {
11060
2.00k
            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
11061
2.00k
            IncrementGcmCounter(AES_COUNTER(aes));
11062
            /* Encrypt counter into a buffer. */
11063
2.00k
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
11064
2.00k
            if (ret != 0)
11065
0
                return ret;
11066
            /* XOR plain text into encrypted counter into cipher text buffer. */
11067
2.00k
            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
11068
            /* Data complete. */
11069
2.00k
            in  += WC_AES_BLOCK_SIZE;
11070
2.00k
            out += WC_AES_BLOCK_SIZE;
11071
2.00k
        }
11072
8.70k
    }
11073
11074
9.15k
    if (partial != 0) {
11075
        /* Generate an extra block and use up as much as needed. */
11076
552
        IncrementGcmCounter(AES_COUNTER(aes));
11077
        /* Encrypt counter into cache. */
11078
552
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
11079
552
        if (ret != 0)
11080
0
            return ret;
11081
        /* XOR plain text into encrypted counter into cipher text buffer. */
11082
552
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
11083
        /* Keep amount of encrypted block used. */
11084
552
        aes->over = (byte)partial;
11085
552
    }
11086
11087
9.15k
    return 0;
11088
9.15k
}
11089
11090
/* Calculates authentication tag for AES GCM. C implementation.
11091
 *
11092
 * @param [in, out] aes        AES object.
11093
 * @param [out]     authTag    Buffer to store authentication tag in.
11094
 * @param [in]      authTagSz  Length of tag to create.
11095
 */
11096
static WARN_UNUSED_RESULT int AesGcmFinal_C(
11097
    Aes* aes, byte* authTag, word32 authTagSz)
11098
907
{
11099
    /* Calculate authentication tag. */
11100
907
    GHASH_FINAL(aes, authTag, authTagSz);
11101
    /* XOR in as much of encrypted counter as is required. */
11102
907
    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
11103
#ifdef OPENSSL_EXTRA
11104
    /* store AAD size for next call */
11105
    aes->gcm.aadLen = aes->aSz;
11106
#endif
11107
    /* Zeroize last block to protect sensitive data. */
11108
907
    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
11109
11110
907
    return 0;
11111
907
}
11112
11113
#ifdef WOLFSSL_AESNI
11114
11115
#ifdef __cplusplus
11116
    extern "C" {
11117
#endif
11118
11119
/* Assembly code implementations in: aes_gcm_asm.S */
11120
#ifdef HAVE_INTEL_AVX2
11121
extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
11122
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
11123
    unsigned char* counter, unsigned char* initCtr);
11124
extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
11125
    unsigned int abytes, unsigned char* tag, unsigned char* h);
11126
extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
11127
    unsigned char* out, const unsigned char* in, unsigned char* counter);
11128
extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
11129
    unsigned char* tag, unsigned char* h);
11130
11131
extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
11132
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11133
    unsigned char* tag, unsigned char* h, unsigned char* counter);
11134
extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
11135
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11136
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
11137
#endif
11138
#ifdef HAVE_INTEL_AVX1
11139
extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
11140
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
11141
    unsigned char* counter, unsigned char* initCtr);
11142
extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
11143
    unsigned int abytes, unsigned char* tag, unsigned char* h);
11144
extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
11145
    unsigned char* out, const unsigned char* in, unsigned char* counter);
11146
extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
11147
    unsigned char* tag, unsigned char* h);
11148
11149
extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
11150
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11151
    unsigned char* tag, unsigned char* h, unsigned char* counter);
11152
extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
11153
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11154
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
11155
#endif
11156
extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
11157
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
11158
    unsigned char* counter, unsigned char* initCtr);
11159
extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
11160
    unsigned int abytes, unsigned char* tag, unsigned char* h);
11161
extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
11162
    unsigned char* out, const unsigned char* in, unsigned char* counter);
11163
extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
11164
    unsigned char* tag, unsigned char* h);
11165
11166
extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
11167
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11168
    unsigned char* tag, unsigned char* h, unsigned char* counter);
11169
extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
11170
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11171
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
11172
11173
#ifdef __cplusplus
11174
    } /* extern "C" */
11175
#endif
11176
11177
/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
11178
 *
11179
 * @param [in, out] aes   AES object.
11180
 * @param [in]      iv    IV/nonce buffer.
11181
 * @param [in]      ivSz  Length of IV/nonce data.
11182
 */
11183
static WARN_UNUSED_RESULT int AesGcmInit_aesni(
11184
    Aes* aes, const byte* iv, word32 ivSz)
11185
{
11186
    ASSERT_SAVED_VECTOR_REGISTERS();
11187
11188
    /* Reset state fields. */
11189
    aes->over = 0;
11190
    aes->aSz = 0;
11191
    aes->cSz = 0;
11192
    /* Set tag to all zeros as initial value. */
11193
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
11194
    /* Reset counts of AAD and cipher text. */
11195
    aes->aOver = 0;
11196
    aes->cOver = 0;
11197
11198
#ifdef HAVE_INTEL_AVX2
11199
    if (IS_INTEL_AVX2(intel_flags)) {
11200
        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11201
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11202
    }
11203
    else
11204
#endif
11205
#ifdef HAVE_INTEL_AVX1
11206
    if (IS_INTEL_AVX1(intel_flags)) {
11207
        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11208
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11209
    }
11210
    else
11211
#endif
11212
    {
11213
        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11214
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11215
    }
11216
11217
    return 0;
11218
}
11219
11220
/* Update the AES GCM for encryption with authentication data.
11221
 *
11222
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
11223
 *
11224
 * @param [in, out] aes   AES object.
11225
 * @param [in]      a     Buffer holding authentication data.
11226
 * @param [in]      aSz   Length of authentication data in bytes.
11227
 * @param [in]      endA  Whether no more authentication data is expected.
11228
 */
11229
static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
11230
    Aes* aes, const byte* a, word32 aSz, int endA)
11231
{
11232
    word32 blocks;
11233
    int partial;
11234
11235
    ASSERT_SAVED_VECTOR_REGISTERS();
11236
11237
    if (aSz != 0 && a != NULL) {
11238
        /* Total count of AAD updated. */
11239
        aes->aSz += aSz;
11240
        /* Check if we have unprocessed data. */
11241
        if (aes->aOver > 0) {
11242
            /* Calculate amount we can use - fill up the block. */
11243
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
11244
            if (sz > aSz) {
11245
                sz = (byte)aSz;
11246
            }
11247
            /* Copy extra into last GHASH block array and update count. */
11248
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
11249
            aes->aOver = (byte)(aes->aOver + sz);
11250
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
11251
                /* We have filled up the block and can process. */
11252
            #ifdef HAVE_INTEL_AVX2
11253
                if (IS_INTEL_AVX2(intel_flags)) {
11254
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11255
                                             aes->gcm.H);
11256
                }
11257
                else
11258
            #endif
11259
            #ifdef HAVE_INTEL_AVX1
11260
                if (IS_INTEL_AVX1(intel_flags)) {
11261
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11262
                                             aes->gcm.H);
11263
                }
11264
                else
11265
            #endif
11266
                {
11267
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11268
                                              aes->gcm.H);
11269
                }
11270
                /* Reset count. */
11271
                aes->aOver = 0;
11272
            }
11273
            /* Used up some data. */
11274
            aSz -= sz;
11275
            a += sz;
11276
        }
11277
11278
        /* Calculate number of blocks of AAD and the leftover. */
11279
        blocks = aSz / WC_AES_BLOCK_SIZE;
11280
        partial = aSz % WC_AES_BLOCK_SIZE;
11281
        if (blocks > 0) {
11282
            /* GHASH full blocks now. */
11283
        #ifdef HAVE_INTEL_AVX2
11284
            if (IS_INTEL_AVX2(intel_flags)) {
11285
                AES_GCM_aad_update_avx2(a, blocks * WC_AES_BLOCK_SIZE,
11286
                                        AES_TAG(aes), aes->gcm.H);
11287
            }
11288
            else
11289
        #endif
11290
        #ifdef HAVE_INTEL_AVX1
11291
            if (IS_INTEL_AVX1(intel_flags)) {
11292
                AES_GCM_aad_update_avx1(a, blocks * WC_AES_BLOCK_SIZE,
11293
                                        AES_TAG(aes), aes->gcm.H);
11294
            }
11295
            else
11296
        #endif
11297
            {
11298
                AES_GCM_aad_update_aesni(a, blocks * WC_AES_BLOCK_SIZE,
11299
                                         AES_TAG(aes), aes->gcm.H);
11300
            }
11301
            /* Skip over to end of AAD blocks. */
11302
            a += blocks * WC_AES_BLOCK_SIZE;
11303
        }
11304
        if (partial != 0) {
11305
            /* Cache the partial block. */
11306
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
11307
            aes->aOver = (byte)partial;
11308
        }
11309
    }
11310
    if (endA && (aes->aOver > 0)) {
11311
        /* No more AAD coming and we have a partial block. */
11312
        /* Fill the rest of the block with zeros. */
11313
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
11314
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
11315
        /* GHASH last AAD block. */
11316
    #ifdef HAVE_INTEL_AVX2
11317
        if (IS_INTEL_AVX2(intel_flags)) {
11318
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11319
                                     aes->gcm.H);
11320
        }
11321
        else
11322
    #endif
11323
    #ifdef HAVE_INTEL_AVX1
11324
        if (IS_INTEL_AVX1(intel_flags)) {
11325
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11326
                                     aes->gcm.H);
11327
        }
11328
        else
11329
    #endif
11330
        {
11331
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11332
                                      aes->gcm.H);
11333
        }
11334
        /* Clear partial count for next time through. */
11335
        aes->aOver = 0;
11336
    }
11337
11338
    return 0;
11339
}
11340
11341
/* Update the AES GCM for encryption with data and/or authentication data.
11342
 *
11343
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
11344
 *
11345
 * @param [in, out] aes  AES object.
11346
 * @param [out]     c    Buffer to hold cipher text.
11347
 * @param [in]      p    Buffer holding plaintext.
11348
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11349
 * @param [in]      a    Buffer holding authentication data.
11350
 * @param [in]      aSz  Length of authentication data in bytes.
11351
 */
11352
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
11353
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
11354
{
11355
    word32 blocks;
11356
    int partial;
11357
    int ret;
11358
11359
    ASSERT_SAVED_VECTOR_REGISTERS();
11360
11361
    /* Hash in A, the Authentication Data */
11362
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
11363
    if (ret != 0)
11364
        return ret;
11365
11366
    /* Encrypt plaintext and Hash in C, the Cipher text */
11367
    if (cSz != 0 && c != NULL) {
11368
        /* Update count of cipher text we have hashed. */
11369
        aes->cSz += cSz;
11370
        if (aes->cOver > 0) {
11371
            /* Calculate amount we can use - fill up the block. */
11372
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11373
            if (sz > cSz) {
11374
                sz = (byte)cSz;
11375
            }
11376
            /* Encrypt some of the plaintext. */
11377
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
11378
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11379
            /* Update count of unused encrypted counter. */
11380
            aes->cOver = (byte)(aes->cOver + sz);
11381
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11382
                /* We have filled up the block and can process. */
11383
            #ifdef HAVE_INTEL_AVX2
11384
                if (IS_INTEL_AVX2(intel_flags)) {
11385
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11386
                                             aes->gcm.H);
11387
                }
11388
                else
11389
            #endif
11390
            #ifdef HAVE_INTEL_AVX1
11391
                if (IS_INTEL_AVX1(intel_flags)) {
11392
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11393
                                             aes->gcm.H);
11394
                }
11395
                else
11396
            #endif
11397
                {
11398
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11399
                                              aes->gcm.H);
11400
                }
11401
                /* Reset count. */
11402
                aes->cOver = 0;
11403
            }
11404
            /* Used up some data. */
11405
            cSz -= sz;
11406
            p += sz;
11407
            c += sz;
11408
        }
11409
11410
        /* Calculate number of blocks of plaintext and the leftover. */
11411
        blocks = cSz / WC_AES_BLOCK_SIZE;
11412
        partial = cSz % WC_AES_BLOCK_SIZE;
11413
        if (blocks > 0) {
11414
            /* Encrypt and GHASH full blocks now. */
11415
        #ifdef HAVE_INTEL_AVX2
11416
            if (IS_INTEL_AVX2(intel_flags)) {
11417
                AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
11418
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11419
                    AES_COUNTER(aes));
11420
            }
11421
            else
11422
        #endif
11423
        #ifdef HAVE_INTEL_AVX1
11424
            if (IS_INTEL_AVX1(intel_flags)) {
11425
                AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
11426
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11427
                    AES_COUNTER(aes));
11428
            }
11429
            else
11430
        #endif
11431
            {
11432
                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
11433
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11434
                    AES_COUNTER(aes));
11435
            }
11436
            /* Skip over to end of blocks. */
11437
            p += blocks * WC_AES_BLOCK_SIZE;
11438
            c += blocks * WC_AES_BLOCK_SIZE;
11439
        }
11440
        if (partial != 0) {
11441
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
11442
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11443
        #ifdef HAVE_INTEL_AVX2
11444
            if (IS_INTEL_AVX2(intel_flags)) {
11445
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
11446
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11447
            }
11448
            else
11449
        #endif
11450
        #ifdef HAVE_INTEL_AVX1
11451
            if (IS_INTEL_AVX1(intel_flags)) {
11452
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
11453
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11454
            }
11455
            else
11456
        #endif
11457
            {
11458
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
11459
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11460
            }
11461
            /* XOR the remaining plaintext to calculate cipher text.
11462
             * Keep cipher text for GHASH of last partial block.
11463
             */
11464
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
11465
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
11466
            /* Update count of the block used. */
11467
            aes->cOver = (byte)partial;
11468
        }
11469
    }
11470
    return 0;
11471
}
11472
11473
/* Finalize the AES GCM for encryption and calculate the authentication tag.
11474
 *
11475
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
11476
 *
11477
 * @param [in, out] aes        AES object.
11478
 * @param [in]      authTag    Buffer to hold authentication tag.
11479
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11480
 * @return  0 on success.
11481
 */
11482
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
11483
    Aes* aes, byte* authTag, word32 authTagSz)
11484
{
11485
    /* AAD block incomplete when > 0 */
11486
    byte over = aes->aOver;
11487
11488
    ASSERT_SAVED_VECTOR_REGISTERS();
11489
11490
    if (aes->cOver > 0) {
11491
        /* Cipher text block incomplete. */
11492
        over = aes->cOver;
11493
    }
11494
    if (over > 0) {
11495
        /* Fill the rest of the block with zeros. */
11496
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
11497
        /* GHASH last cipher block. */
11498
    #ifdef HAVE_INTEL_AVX2
11499
        if (IS_INTEL_AVX2(intel_flags)) {
11500
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11501
                                     aes->gcm.H);
11502
        }
11503
        else
11504
    #endif
11505
    #ifdef HAVE_INTEL_AVX1
11506
        if (IS_INTEL_AVX1(intel_flags)) {
11507
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11508
                                     aes->gcm.H);
11509
        }
11510
        else
11511
    #endif
11512
        {
11513
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11514
                                      aes->gcm.H);
11515
        }
11516
    }
11517
    /* Calculate the authentication tag. */
11518
#ifdef HAVE_INTEL_AVX2
11519
    if (IS_INTEL_AVX2(intel_flags)) {
11520
        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11521
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11522
    }
11523
    else
11524
#endif
11525
#ifdef HAVE_INTEL_AVX1
11526
    if (IS_INTEL_AVX1(intel_flags)) {
11527
        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11528
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11529
    }
11530
    else
11531
#endif
11532
    {
11533
        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11534
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11535
    }
11536
11537
    return 0;
11538
}
11539
11540
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
11541
11542
#ifdef __cplusplus
11543
    extern "C" {
11544
#endif
11545
11546
/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
11547
#ifdef HAVE_INTEL_AVX2
11548
extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
11549
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11550
    unsigned char* tag, unsigned char* h, unsigned char* counter);
11551
extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
11552
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11553
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
11554
#endif
11555
#ifdef HAVE_INTEL_AVX1
11556
extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
11557
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11558
    unsigned char* tag, unsigned char* h, unsigned char* counter);
11559
extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
11560
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11561
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
11562
#endif
11563
extern void AES_GCM_decrypt_update_aesni(const unsigned char* key, int nr,
11564
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11565
    unsigned char* tag, unsigned char* h, unsigned char* counter);
11566
extern void AES_GCM_decrypt_final_aesni(unsigned char* tag,
11567
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11568
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
11569
11570
#ifdef __cplusplus
11571
    } /* extern "C" */
11572
#endif
11573
11574
/* Update the AES GCM for decryption with data and/or authentication data.
11575
 *
11576
 * @param [in, out] aes  AES object.
11577
 * @param [out]     p    Buffer to hold plaintext.
11578
 * @param [in]      c    Buffer holding cipher text.
11579
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11580
 * @param [in]      a    Buffer holding authentication data.
11581
 * @param [in]      aSz  Length of authentication data in bytes.
11582
 */
11583
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
11584
    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
11585
{
11586
    word32 blocks;
11587
    int partial;
11588
    int ret;
11589
11590
    ASSERT_SAVED_VECTOR_REGISTERS();
11591
11592
    /* Hash in A, the Authentication Data */
11593
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
11594
    if (ret != 0)
11595
        return ret;
11596
11597
    /* Hash in C, the Cipher text, and decrypt. */
11598
    if (cSz != 0 && p != NULL) {
11599
        /* Update count of cipher text we have hashed. */
11600
        aes->cSz += cSz;
11601
        if (aes->cOver > 0) {
11602
            /* Calculate amount we can use - fill up the block. */
11603
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11604
            if (sz > cSz) {
11605
                sz = (byte)cSz;
11606
            }
11607
            /* Keep a copy of the cipher text for GHASH. */
11608
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
11609
            /* Decrypt some of the cipher text. */
11610
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
11611
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11612
            /* Update count of unused encrypted counter. */
11613
            aes->cOver = (byte)(aes->cOver + sz);
11614
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11615
                /* We have filled up the block and can process. */
11616
            #ifdef HAVE_INTEL_AVX2
11617
                if (IS_INTEL_AVX2(intel_flags)) {
11618
                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
11619
                                             aes->gcm.H);
11620
                }
11621
                else
11622
            #endif
11623
            #ifdef HAVE_INTEL_AVX1
11624
                if (IS_INTEL_AVX1(intel_flags)) {
11625
                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
11626
                                             aes->gcm.H);
11627
                }
11628
                else
11629
            #endif
11630
                {
11631
                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
11632
                                              aes->gcm.H);
11633
                }
11634
                /* Reset count. */
11635
                aes->cOver = 0;
11636
            }
11637
            /* Used up some data. */
11638
            cSz -= sz;
11639
            c += sz;
11640
            p += sz;
11641
        }
11642
11643
        /* Calculate number of blocks of plaintext and the leftover. */
11644
        blocks = cSz / WC_AES_BLOCK_SIZE;
11645
        partial = cSz % WC_AES_BLOCK_SIZE;
11646
        if (blocks > 0) {
11647
            /* Decrypt and GHASH full blocks now. */
11648
        #ifdef HAVE_INTEL_AVX2
11649
            if (IS_INTEL_AVX2(intel_flags)) {
11650
                AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
11651
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11652
                    AES_COUNTER(aes));
11653
            }
11654
            else
11655
        #endif
11656
        #ifdef HAVE_INTEL_AVX1
11657
            if (IS_INTEL_AVX1(intel_flags)) {
11658
                AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
11659
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11660
                    AES_COUNTER(aes));
11661
            }
11662
            else
11663
        #endif
11664
            {
11665
                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
11666
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11667
                    AES_COUNTER(aes));
11668
            }
11669
            /* Skip over to end of blocks. */
11670
            c += blocks * WC_AES_BLOCK_SIZE;
11671
            p += blocks * WC_AES_BLOCK_SIZE;
11672
        }
11673
        if (partial != 0) {
11674
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
11675
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11676
        #ifdef HAVE_INTEL_AVX2
11677
            if (IS_INTEL_AVX2(intel_flags)) {
11678
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
11679
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11680
            }
11681
            else
11682
        #endif
11683
        #ifdef HAVE_INTEL_AVX1
11684
            if (IS_INTEL_AVX1(intel_flags)) {
11685
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
11686
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11687
            }
11688
            else
11689
        #endif
11690
            {
11691
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
11692
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11693
            }
11694
            /* Keep cipher text for GHASH of last partial block. */
11695
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
11696
            /* XOR the remaining cipher text to calculate plaintext. */
11697
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
11698
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
11699
            /* Update count of the block used. */
11700
            aes->cOver = (byte)partial;
11701
        }
11702
    }
11703
11704
    return 0;
11705
}
11706
11707
/* Finalize the AES GCM for decryption and check the authentication tag.
11708
 *
11709
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
11710
 *
11711
 * @param [in, out] aes        AES object.
11712
 * @param [in]      authTag    Buffer holding authentication tag.
11713
 * @param [in]      authTagSz  Length of authentication tag in bytes.
11714
 * @return  0 on success.
11715
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
11716
 *          value.
11717
 */
11718
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
11719
    Aes* aes, const byte* authTag, word32 authTagSz)
11720
{
11721
    int ret = 0;
11722
    int res;
11723
    /* AAD block incomplete when > 0 */
11724
    byte over = aes->aOver;
11725
    byte *lastBlock = AES_LASTGBLOCK(aes);
11726
11727
    ASSERT_SAVED_VECTOR_REGISTERS();
11728
11729
    if (aes->cOver > 0) {
11730
        /* Cipher text block incomplete. */
11731
        over = aes->cOver;
11732
        lastBlock = AES_LASTBLOCK(aes);
11733
    }
11734
    if (over > 0) {
11735
        /* Zeroize the unused part of the block. */
11736
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
11737
        /* Hash the last block of cipher text. */
11738
    #ifdef HAVE_INTEL_AVX2
11739
        if (IS_INTEL_AVX2(intel_flags)) {
11740
            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
11741
        }
11742
        else
11743
    #endif
11744
    #ifdef HAVE_INTEL_AVX1
11745
        if (IS_INTEL_AVX1(intel_flags)) {
11746
            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
11747
        }
11748
        else
11749
    #endif
11750
        {
11751
            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
11752
        }
11753
    }
11754
    /* Calculate and compare the authentication tag. */
11755
#ifdef HAVE_INTEL_AVX2
11756
    if (IS_INTEL_AVX2(intel_flags)) {
11757
        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11758
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11759
    }
11760
    else
11761
#endif
11762
#ifdef HAVE_INTEL_AVX1
11763
    if (IS_INTEL_AVX1(intel_flags)) {
11764
        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11765
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11766
    }
11767
    else
11768
#endif
11769
    {
11770
        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11771
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11772
    }
11773
11774
    /* Return error code when calculated doesn't match input. */
11775
    if (res == 0) {
11776
        ret = AES_GCM_AUTH_E;
11777
    }
11778
    return ret;
11779
}
11780
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
11781
#endif /* WOLFSSL_AESNI */
11782
11783
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11784
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11785
/* Initialize the AES GCM cipher with an IV. Aarch64 HW Crypto implementations.
11786
 *
11787
 * @param [in, out] aes   AES object.
11788
 * @param [in]      iv    IV/nonce buffer.
11789
 * @param [in]      ivSz  Length of IV/nonce data.
11790
 */
11791
static WARN_UNUSED_RESULT int AesGcmInit_AARCH64(Aes* aes, const byte* iv,
11792
    word32 ivSz)
11793
{
11794
    /* Reset state fields. */
11795
    aes->over = 0;
11796
    aes->aSz = 0;
11797
    aes->cSz = 0;
11798
    /* Set tag to all zeros as initial value. */
11799
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
11800
    /* Reset counts of AAD and cipher text. */
11801
    aes->aOver = 0;
11802
    aes->cOver = 0;
11803
11804
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11805
    if (aes->use_sha3_hw_crypto) {
11806
        AES_GCM_init_AARCH64_EOR3((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11807
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11808
    }
11809
    else
11810
#endif
11811
    {
11812
        AES_GCM_init_AARCH64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11813
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11814
    }
11815
11816
    return 0;
11817
}
11818
11819
/* Update the AES GCM for encryption with authentication data.
11820
 *
11821
 * Implementation uses AARCH64 optimized assembly code.
11822
 *
11823
 * @param [in, out] aes   AES object.
11824
 * @param [in]      a     Buffer holding authentication data.
11825
 * @param [in]      aSz   Length of authentication data in bytes.
11826
 * @param [in]      endA  Whether no more authentication data is expected.
11827
 */
11828
static WARN_UNUSED_RESULT int AesGcmAadUpdate_AARCH64(
11829
    Aes* aes, const byte* a, word32 aSz, int endA)
11830
{
11831
    word32 blocks;
11832
    int partial;
11833
11834
    if (aSz != 0 && a != NULL) {
11835
        /* Total count of AAD updated. */
11836
        aes->aSz += aSz;
11837
        /* Check if we have unprocessed data. */
11838
        if (aes->aOver > 0) {
11839
            /* Calculate amount we can use - fill up the block. */
11840
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
11841
            if (sz > aSz) {
11842
                sz = (byte)aSz;
11843
            }
11844
            /* Copy extra into last GHASH block array and update count. */
11845
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
11846
            aes->aOver = (byte)(aes->aOver + sz);
11847
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
11848
                /* We have filled up the block and can process. */
11849
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11850
                if (aes->use_sha3_hw_crypto) {
11851
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
11852
                        AES_TAG(aes), aes->gcm.H);
11853
                }
11854
                else
11855
            #endif
11856
                {
11857
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
11858
                        AES_TAG(aes), aes->gcm.H);
11859
                }
11860
                /* Reset count. */
11861
                aes->aOver = 0;
11862
            }
11863
            /* Used up some data. */
11864
            aSz -= sz;
11865
            a += sz;
11866
        }
11867
11868
        /* Calculate number of blocks of AAD and the leftover. */
11869
        blocks = aSz / WC_AES_BLOCK_SIZE;
11870
        partial = aSz % WC_AES_BLOCK_SIZE;
11871
        if (blocks > 0) {
11872
            /* GHASH full blocks now. */
11873
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11874
            if (aes->use_sha3_hw_crypto) {
11875
                AES_GCM_aad_update_AARCH64_EOR3(a, blocks * WC_AES_BLOCK_SIZE,
11876
                    AES_TAG(aes), aes->gcm.H);
11877
            }
11878
            else
11879
        #endif
11880
            {
11881
                AES_GCM_aad_update_AARCH64(a, blocks * WC_AES_BLOCK_SIZE,
11882
                    AES_TAG(aes), aes->gcm.H);
11883
            }
11884
            /* Skip over to end of AAD blocks. */
11885
            a += blocks * WC_AES_BLOCK_SIZE;
11886
        }
11887
        if (partial != 0) {
11888
            /* Cache the partial block. */
11889
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
11890
            aes->aOver = (byte)partial;
11891
        }
11892
    }
11893
    if (endA && (aes->aOver > 0)) {
11894
        /* No more AAD coming and we have a partial block. */
11895
        /* Fill the rest of the block with zeros. */
11896
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
11897
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
11898
        /* GHASH last AAD block. */
11899
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11900
        if (aes->use_sha3_hw_crypto) {
11901
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
11902
                AES_TAG(aes), aes->gcm.H);
11903
        }
11904
        else
11905
    #endif
11906
        {
11907
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
11908
                AES_TAG(aes), aes->gcm.H);
11909
        }
11910
        /* Clear partial count for next time through. */
11911
        aes->aOver = 0;
11912
    }
11913
11914
    return 0;
11915
}
11916
11917
/* Update the AES GCM for encryption with data and/or authentication data.
11918
 *
11919
 * Implementation uses AARCH64 optimized assembly code.
11920
 *
11921
 * @param [in, out] aes  AES object.
11922
 * @param [out]     c    Buffer to hold cipher text.
11923
 * @param [in]      p    Buffer holding plaintext.
11924
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11925
 * @param [in]      a    Buffer holding authentication data.
11926
 * @param [in]      aSz  Length of authentication data in bytes.
11927
 */
11928
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_AARCH64(
11929
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
11930
{
11931
    word32 blocks;
11932
    int partial;
11933
    int ret;
11934
11935
    /* Hash in A, the Authentication Data */
11936
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, (cSz > 0) && (c != NULL));
11937
    if (ret != 0)
11938
        return ret;
11939
11940
    /* Encrypt plaintext and Hash in C, the Cipher text */
11941
    if (cSz != 0 && c != NULL) {
11942
        /* Update count of cipher text we have hashed. */
11943
        aes->cSz += cSz;
11944
        if (aes->cOver > 0) {
11945
            /* Calculate amount we can use - fill up the block. */
11946
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11947
            if (sz > cSz) {
11948
                sz = (byte)cSz;
11949
            }
11950
            /* Encrypt some of the plaintext. */
11951
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
11952
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11953
            /* Update count of unused encrypted counter. */
11954
            aes->cOver = (byte)(aes->cOver + sz);
11955
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11956
                /* We have filled up the block and can process. */
11957
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11958
                if (aes->use_sha3_hw_crypto) {
11959
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
11960
                        AES_TAG(aes), aes->gcm.H);
11961
                }
11962
                else
11963
            #endif
11964
                {
11965
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
11966
                        AES_TAG(aes), aes->gcm.H);
11967
                }
11968
                /* Reset count. */
11969
                aes->cOver = 0;
11970
            }
11971
            /* Used up some data. */
11972
            cSz -= sz;
11973
            p += sz;
11974
            c += sz;
11975
        }
11976
11977
        /* Calculate number of blocks of plaintext and the leftover. */
11978
        blocks = cSz / WC_AES_BLOCK_SIZE;
11979
        partial = cSz % WC_AES_BLOCK_SIZE;
11980
        if (blocks > 0) {
11981
            /* Encrypt and GHASH full blocks now. */
11982
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11983
            if (aes->use_sha3_hw_crypto) {
11984
                AES_GCM_encrypt_update_AARCH64_EOR3((byte*)aes->key,
11985
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
11986
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11987
            }
11988
            else
11989
        #endif
11990
            {
11991
                AES_GCM_encrypt_update_AARCH64((byte*)aes->key,
11992
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
11993
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
11994
            }
11995
            /* Skip over to end of blocks. */
11996
            p += blocks * WC_AES_BLOCK_SIZE;
11997
            c += blocks * WC_AES_BLOCK_SIZE;
11998
        }
11999
        if (partial != 0) {
12000
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
12001
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
12002
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12003
            if (aes->use_sha3_hw_crypto) {
12004
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
12005
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
12006
                    AES_COUNTER(aes));
12007
            }
12008
            else
12009
        #endif
12010
            {
12011
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
12012
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12013
            }
12014
            /* XOR the remaining plaintext to calculate cipher text.
12015
             * Keep cipher text for GHASH of last partial block.
12016
             */
12017
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
12018
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
12019
            /* Update count of the block used. */
12020
            aes->cOver = (byte)partial;
12021
        }
12022
    }
12023
    return 0;
12024
}
12025
12026
/* Finalize the AES GCM for encryption and calculate the authentication tag.
12027
 *
12028
 * Calls ARCH64 optimized assembly code.
12029
 *
12030
 * @param [in, out] aes        AES object.
12031
 * @param [in]      authTag    Buffer to hold authentication tag.
12032
 * @param [in]      authTagSz  Length of authentication tag in bytes.
12033
 * @return  0 on success.
12034
 */
12035
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_AARCH64(Aes* aes,
12036
    byte* authTag, word32 authTagSz)
12037
{
12038
    /* AAD block incomplete when > 0 */
12039
    byte over = aes->aOver;
12040
12041
    ASSERT_SAVED_VECTOR_REGISTERS();
12042
12043
    if (aes->cOver > 0) {
12044
        /* Cipher text block incomplete. */
12045
        over = aes->cOver;
12046
    }
12047
    if (over > 0) {
12048
        /* Fill the rest of the block with zeros. */
12049
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
12050
            (size_t)WC_AES_BLOCK_SIZE - over);
12051
        /* GHASH last cipher block. */
12052
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12053
        if (aes->use_sha3_hw_crypto) {
12054
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes), AES_TAG(aes),
12055
                aes->gcm.H);
12056
        }
12057
        else
12058
    #endif
12059
        {
12060
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes), AES_TAG(aes),
12061
                aes->gcm.H);
12062
        }
12063
    }
12064
    /* Calculate the authentication tag. */
12065
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12066
    if (aes->use_sha3_hw_crypto) {
12067
        AES_GCM_encrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
12068
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12069
    }
12070
    else
12071
#endif
12072
    {
12073
        AES_GCM_encrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
12074
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12075
    }
12076
12077
    return 0;
12078
}
12079
12080
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
12081
/* Update the AES GCM for decryption with data and/or authentication data.
12082
 *
12083
 * @param [in, out] aes  AES object.
12084
 * @param [out]     p    Buffer to hold plaintext.
12085
 * @param [in]      c    Buffer holding cipher text.
12086
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
12087
 * @param [in]      a    Buffer holding authentication data.
12088
 * @param [in]      aSz  Length of authentication data in bytes.
12089
 */
12090
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_AARCH64(Aes* aes, byte* p,
12091
    const byte* c, word32 cSz, const byte* a, word32 aSz)
12092
{
12093
    word32 blocks;
12094
    int partial;
12095
    int ret;
12096
12097
    /* Hash in A, the Authentication Data */
12098
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, cSz > 0);
12099
    if (ret != 0)
12100
        return ret;
12101
12102
    /* Hash in C, the Cipher text, and decrypt. */
12103
    if (cSz != 0 && p != NULL) {
12104
        /* Update count of cipher text we have hashed. */
12105
        aes->cSz += cSz;
12106
        if (aes->cOver > 0) {
12107
            /* Calculate amount we can use - fill up the block. */
12108
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
12109
            if (sz > cSz) {
12110
                sz = (byte)cSz;
12111
            }
12112
            /* Keep a copy of the cipher text for GHASH. */
12113
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
12114
            /* Decrypt some of the cipher text. */
12115
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
12116
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
12117
            /* Update count of unused encrypted counter. */
12118
            aes->cOver = (byte)(aes->cOver + sz);
12119
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
12120
                /* We have filled up the block and can process. */
12121
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12122
                if (aes->use_sha3_hw_crypto) {
12123
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTBLOCK(aes),
12124
                        AES_TAG(aes), aes->gcm.H);
12125
                }
12126
                else
12127
            #endif
12128
                {
12129
                    AES_GCM_ghash_block_AARCH64(AES_LASTBLOCK(aes),
12130
                        AES_TAG(aes), aes->gcm.H);
12131
                }
12132
                /* Reset count. */
12133
                aes->cOver = 0;
12134
            }
12135
            /* Used up some data. */
12136
            cSz -= sz;
12137
            c += sz;
12138
            p += sz;
12139
        }
12140
12141
        /* Calculate number of blocks of plaintext and the leftover. */
12142
        blocks = cSz / WC_AES_BLOCK_SIZE;
12143
        partial = cSz % WC_AES_BLOCK_SIZE;
12144
        if (blocks > 0) {
12145
            /* Decrypt and GHASH full blocks now. */
12146
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12147
            if (aes->use_sha3_hw_crypto) {
12148
                AES_GCM_decrypt_update_AARCH64_EOR3((byte*)aes->key,
12149
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
12150
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
12151
            }
12152
            else
12153
        #endif
12154
            {
12155
                AES_GCM_decrypt_update_AARCH64((byte*)aes->key,
12156
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
12157
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
12158
            }
12159
            /* Skip over to end of blocks. */
12160
            c += blocks * WC_AES_BLOCK_SIZE;
12161
            p += blocks * WC_AES_BLOCK_SIZE;
12162
        }
12163
        if (partial != 0) {
12164
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
12165
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
12166
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12167
            if (aes->use_sha3_hw_crypto) {
12168
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
12169
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
12170
                    AES_COUNTER(aes));
12171
            }
12172
            else
12173
        #endif
12174
            {
12175
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
12176
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12177
            }
12178
            /* Keep cipher text for GHASH of last partial block. */
12179
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
12180
            /* XOR the remaining cipher text to calculate plaintext. */
12181
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
12182
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
12183
            /* Update count of the block used. */
12184
            aes->cOver = (byte)partial;
12185
        }
12186
    }
12187
12188
    return 0;
12189
}
12190
12191
/* Finalize the AES GCM for decryption and check the authentication tag.
12192
 *
12193
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
12194
 *
12195
 * @param [in, out] aes        AES object.
12196
 * @param [in]      authTag    Buffer holding authentication tag.
12197
 * @param [in]      authTagSz  Length of authentication tag in bytes.
12198
 * @return  0 on success.
12199
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
12200
 *          value.
12201
 */
12202
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_AARCH64(
12203
    Aes* aes, const byte* authTag, word32 authTagSz)
12204
{
12205
    int ret = 0;
12206
    int res;
12207
    /* AAD block incomplete when > 0 */
12208
    byte over = aes->aOver;
12209
    byte *lastBlock = AES_LASTGBLOCK(aes);
12210
12211
    ASSERT_SAVED_VECTOR_REGISTERS();
12212
12213
    if (aes->cOver > 0) {
12214
        /* Cipher text block incomplete. */
12215
        over = aes->cOver;
12216
        lastBlock = AES_LASTBLOCK(aes);
12217
    }
12218
    if (over > 0) {
12219
        /* Zeroize the unused part of the block. */
12220
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
12221
        /* Hash the last block of cipher text. */
12222
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12223
        if (aes->use_sha3_hw_crypto) {
12224
            AES_GCM_ghash_block_AARCH64_EOR3(lastBlock, AES_TAG(aes),
12225
                aes->gcm.H);
12226
        }
12227
        else
12228
    #endif
12229
        {
12230
            AES_GCM_ghash_block_AARCH64(lastBlock, AES_TAG(aes), aes->gcm.H);
12231
        }
12232
    }
12233
    /* Calculate and compare the authentication tag. */
12234
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12235
    if (aes->use_sha3_hw_crypto) {
12236
        AES_GCM_decrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
12237
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
12238
    }
12239
    else
12240
#endif
12241
    {
12242
        AES_GCM_decrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
12243
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
12244
    }
12245
12246
    /* Return error code when calculated doesn't match input. */
12247
    if (res == 0) {
12248
        ret = AES_GCM_AUTH_E;
12249
    }
12250
    return ret;
12251
}
12252
#endif
12253
#endif
12254
12255
/* Initialize an AES GCM cipher for encryption or decryption.
12256
 *
12257
 * Must call wc_AesInit() before calling this function.
12258
 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
12259
 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
12260
 *
12261
 * @param [in, out] aes   AES object.
12262
 * @param [in]      key   Buffer holding key.
12263
 * @param [in]      len   Length of key in bytes.
12264
 * @param [in]      iv    Buffer holding IV/nonce.
12265
 * @param [in]      ivSz  Length of IV/nonce in bytes.
12266
 * @return  0 on success.
12267
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
12268
 *          is NULL, or the IV is NULL and no previous IV has been set.
12269
 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
12270
 */
12271
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
12272
    word32 ivSz)
12273
2.64k
{
12274
2.64k
    int ret = 0;
12275
12276
    /* Check validity of parameters. */
12277
2.64k
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
12278
2.64k
            ((ivSz == 0) && (iv != NULL)) ||
12279
2.64k
            ((ivSz > 0) && (iv == NULL))) {
12280
0
        ret = BAD_FUNC_ARG;
12281
0
    }
12282
12283
2.64k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
12284
2.64k
    if ((ret == 0) && (aes->streamData == NULL)) {
12285
        /* Allocate buffers for streaming. */
12286
980
        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
12287
980
        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
12288
980
                                                              DYNAMIC_TYPE_AES);
12289
980
        if (aes->streamData == NULL) {
12290
0
            ret = MEMORY_E;
12291
0
        }
12292
980
    }
12293
2.64k
#endif
12294
12295
    /* Set the key if passed in. */
12296
2.64k
    if ((ret == 0) && (key != NULL)) {
12297
980
        ret = wc_AesGcmSetKey(aes, key, len);
12298
980
    }
12299
12300
2.64k
    if (ret == 0) {
12301
        /* Set the IV passed in if it is smaller than a block. */
12302
2.64k
        if ((iv != NULL) && (ivSz <= WC_AES_BLOCK_SIZE)) {
12303
2.64k
            XMEMMOVE((byte*)aes->reg, iv, ivSz);
12304
2.64k
            aes->nonceSz = ivSz;
12305
2.64k
        }
12306
        /* No IV passed in, check for cached IV. */
12307
2.64k
        if ((iv == NULL) && (aes->nonceSz != 0)) {
12308
            /* Use the cached copy. */
12309
0
            iv = (byte*)aes->reg;
12310
0
            ivSz = aes->nonceSz;
12311
0
        }
12312
12313
2.64k
        if (iv != NULL) {
12314
            /* Initialize with the IV. */
12315
12316
        #ifdef WOLFSSL_AESNI
12317
            if (aes->use_aesni) {
12318
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
12319
                ret = AesGcmInit_aesni(aes, iv, ivSz);
12320
                RESTORE_VECTOR_REGISTERS();
12321
            }
12322
            else
12323
        #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12324
              !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12325
            if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12326
                ret = AesGcmInit_AARCH64(aes, iv, ivSz);
12327
            }
12328
            else
12329
        #endif /* WOLFSSL_AESNI */
12330
2.64k
            {
12331
2.64k
                ret = AesGcmInit_C(aes, iv, ivSz);
12332
2.64k
            }
12333
12334
2.64k
            if (ret == 0)
12335
2.64k
                aes->nonceSet = 1;
12336
2.64k
        }
12337
2.64k
    }
12338
12339
2.64k
    return ret;
12340
2.64k
}
12341
12342
/* Initialize an AES GCM cipher for encryption.
12343
 *
12344
 * Must call wc_AesInit() before calling this function.
12345
 *
12346
 * @param [in, out] aes   AES object.
12347
 * @param [in]      key   Buffer holding key.
12348
 * @param [in]      len   Length of key in bytes.
12349
 * @param [in]      iv    Buffer holding IV/nonce.
12350
 * @param [in]      ivSz  Length of IV/nonce in bytes.
12351
 * @return  0 on success.
12352
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
12353
 *          is NULL, or the IV is NULL and no previous IV has been set.
12354
 */
12355
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
12356
    word32 ivSz)
12357
0
{
12358
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
12359
0
}
12360
12361
/* Initialize an AES GCM cipher for encryption. Get IV.
12362
 *
12363
 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
12364
 * function.
12365
 * Must call wc_AesInit() before calling this function.
12366
 *
12367
 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
12368
 *
12369
 * @param [in, out] aes   AES object.
12370
 * @param [in]      key   Buffer holding key.
12371
 * @param [in]      len   Length of key in bytes.
12372
 * @param [in]      iv    Buffer holding IV/nonce.
12373
 * @param [in]      ivSz  Length of IV/nonce in bytes.
12374
 * @return  0 on success.
12375
 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
12376
 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
12377
 *          nonce size.
12378
 */
12379
int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
12380
    word32 ivOutSz)
12381
0
{
12382
0
    int ret;
12383
12384
    /* Check validity of parameters. */
12385
0
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
12386
0
        ret = BAD_FUNC_ARG;
12387
0
    }
12388
0
    else {
12389
        /* Copy out the IV including generated part for decryption. */
12390
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
12391
        /* Initialize AES GCM cipher with key and cached Iv. */
12392
0
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
12393
0
    }
12394
12395
0
    return ret;
12396
0
}
12397
12398
/* Update the AES GCM for encryption with data and/or authentication data. */
12399
int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
12400
    const byte* authIn, word32 authInSz)
12401
7.09k
{
12402
7.09k
    int ret = 0;
12403
12404
    /* Check validity of parameters. */
12405
7.09k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
12406
1.14k
            ((out == NULL) || (in == NULL)))) {
12407
0
        ret = BAD_FUNC_ARG;
12408
0
    }
12409
12410
    /* Check key has been set. */
12411
7.09k
    if ((ret == 0) && (!aes->gcmKeySet)) {
12412
0
        ret = MISSING_KEY;
12413
0
    }
12414
    /* Check IV has been set. */
12415
7.09k
    if ((ret == 0) && (!aes->nonceSet)) {
12416
0
        ret = MISSING_IV;
12417
0
    }
12418
12419
7.09k
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
12420
557
        aes->invokeCtr[0]++;
12421
557
        if (aes->invokeCtr[0] == 0) {
12422
0
            aes->invokeCtr[1]++;
12423
0
            if (aes->invokeCtr[1] == 0)
12424
0
                ret = AES_GCM_OVERFLOW_E;
12425
0
        }
12426
557
    }
12427
12428
7.09k
    if (ret == 0) {
12429
        /* Encrypt with AAD and/or plaintext. */
12430
12431
    #ifdef WOLFSSL_AESNI
12432
        if (aes->use_aesni) {
12433
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12434
            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
12435
            RESTORE_VECTOR_REGISTERS();
12436
        }
12437
        else
12438
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12439
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12440
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12441
            ret = AesGcmEncryptUpdate_AARCH64(aes, out, in, sz, authIn,
12442
                authInSz);
12443
        }
12444
        else
12445
    #endif
12446
7.09k
        {
12447
            /* Encrypt the plaintext. */
12448
7.09k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
12449
7.09k
            if (ret == 0) {
12450
                /* Update the authentication tag with any authentication data and the
12451
                 * new cipher text. */
12452
7.09k
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
12453
7.09k
            }
12454
7.09k
        }
12455
7.09k
    }
12456
12457
7.09k
    return ret;
12458
7.09k
}
12459
12460
/* Finalize the AES GCM for encryption and return the authentication tag.
12461
 *
12462
 * Must set key and IV before calling this function.
12463
 * Must call wc_AesGcmInit() before calling this function.
12464
 *
12465
 * @param [in, out] aes        AES object.
12466
 * @param [out]     authTag    Buffer to hold authentication tag.
12467
 * @param [in]      authTagSz  Length of authentication tag in bytes.
12468
 * @return  0 on success.
12469
 */
12470
int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
12471
499
{
12472
499
    int ret = 0;
12473
12474
    /* Check validity of parameters. */
12475
499
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
12476
499
            (authTagSz == 0)) {
12477
0
        ret = BAD_FUNC_ARG;
12478
0
    }
12479
12480
    /* Check key has been set. */
12481
499
    if ((ret == 0) && (!aes->gcmKeySet)) {
12482
0
        ret = MISSING_KEY;
12483
0
    }
12484
    /* Check IV has been set. */
12485
499
    if ((ret == 0) && (!aes->nonceSet)) {
12486
0
        ret = MISSING_IV;
12487
0
    }
12488
12489
499
    if (ret == 0) {
12490
        /* Calculate authentication tag. */
12491
    #ifdef WOLFSSL_AESNI
12492
        if (aes->use_aesni) {
12493
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12494
            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
12495
            RESTORE_VECTOR_REGISTERS();
12496
        }
12497
        else
12498
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12499
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12500
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12501
            ret = AesGcmEncryptFinal_AARCH64(aes, authTag, authTagSz);
12502
        }
12503
        else
12504
    #endif
12505
499
        {
12506
499
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
12507
499
        }
12508
499
    }
12509
12510
499
    if ((ret == 0) && aes->ctrSet) {
12511
499
        IncCtr((byte*)aes->reg, aes->nonceSz);
12512
499
    }
12513
12514
499
    return ret;
12515
499
}
12516
12517
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
12518
/* Initialize an AES GCM cipher for decryption.
12519
 *
12520
 * Must call wc_AesInit() before calling this function.
12521
 *
12522
 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
12523
 * instead.
12524
 *
12525
 * @param [in, out] aes   AES object.
12526
 * @param [in]      key   Buffer holding key.
12527
 * @param [in]      len   Length of key in bytes.
12528
 * @param [in]      iv    Buffer holding IV/nonce.
12529
 * @param [in]      ivSz  Length of IV/nonce in bytes.
12530
 * @return  0 on success.
12531
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
12532
 *          is NULL, or the IV is NULL and no previous IV has been set.
12533
 */
12534
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
12535
    word32 ivSz)
12536
0
{
12537
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
12538
0
}
12539
12540
/* Update the AES GCM for decryption with data and/or authentication data. */
12541
int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
12542
    const byte* authIn, word32 authInSz)
12543
2.05k
{
12544
2.05k
    int ret = 0;
12545
12546
    /* Check validity of parameters. */
12547
2.05k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
12548
332
            ((out == NULL) || (in == NULL)))) {
12549
0
        ret = BAD_FUNC_ARG;
12550
0
    }
12551
12552
    /* Check key has been set. */
12553
2.05k
    if ((ret == 0) && (!aes->gcmKeySet)) {
12554
0
        ret = MISSING_KEY;
12555
0
    }
12556
    /* Check IV has been set. */
12557
2.05k
    if ((ret == 0) && (!aes->nonceSet)) {
12558
0
        ret = MISSING_IV;
12559
0
    }
12560
12561
2.05k
    if (ret == 0) {
12562
        /* Decrypt with AAD and/or cipher text. */
12563
    #ifdef WOLFSSL_AESNI
12564
        if (aes->use_aesni) {
12565
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12566
            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
12567
            RESTORE_VECTOR_REGISTERS();
12568
        }
12569
        else
12570
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12571
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12572
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12573
            ret = AesGcmDecryptUpdate_AARCH64(aes, out, in, sz, authIn,
12574
                authInSz);
12575
        }
12576
        else
12577
    #endif
12578
2.05k
        {
12579
            /* Update the authentication tag with any authentication data and
12580
             * cipher text. */
12581
2.05k
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
12582
            /* Decrypt the cipher text. */
12583
2.05k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
12584
2.05k
        }
12585
2.05k
    }
12586
12587
2.05k
    return ret;
12588
2.05k
}
12589
12590
/* Finalize the AES GCM for decryption and check the authentication tag.
12591
 *
12592
 * Must set key and IV before calling this function.
12593
 * Must call wc_AesGcmInit() before calling this function.
12594
 *
12595
 * @param [in, out] aes        AES object.
12596
 * @param [in]      authTag    Buffer holding authentication tag.
12597
 * @param [in]      authTagSz  Length of authentication tag in bytes.
12598
 * @return  0 on success.
12599
 */
12600
int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
12601
408
{
12602
408
    int ret = 0;
12603
12604
    /* Check validity of parameters. */
12605
408
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
12606
408
            (authTagSz == 0)) {
12607
0
        ret = BAD_FUNC_ARG;
12608
0
    }
12609
12610
    /* Check key has been set. */
12611
408
    if ((ret == 0) && (!aes->gcmKeySet)) {
12612
0
        ret = MISSING_KEY;
12613
0
    }
12614
    /* Check IV has been set. */
12615
408
    if ((ret == 0) && (!aes->nonceSet)) {
12616
0
        ret = MISSING_IV;
12617
0
    }
12618
12619
408
    if (ret == 0) {
12620
        /* Calculate authentication tag and compare with one passed in.. */
12621
    #ifdef WOLFSSL_AESNI
12622
        if (aes->use_aesni) {
12623
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12624
            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
12625
            RESTORE_VECTOR_REGISTERS();
12626
        }
12627
        else
12628
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12629
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12630
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12631
            ret = AesGcmDecryptFinal_AARCH64(aes, authTag, authTagSz);
12632
        }
12633
        else
12634
    #endif
12635
408
        {
12636
408
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
12637
            /* Calculate authentication tag. */
12638
408
            ret = AesGcmFinal_C(aes, calcTag, WC_AES_BLOCK_SIZE);
12639
408
            if (ret == 0) {
12640
                /* Check calculated tag matches the one passed in. */
12641
408
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
12642
154
                    ret = AES_GCM_AUTH_E;
12643
154
                }
12644
408
            }
12645
408
        }
12646
408
    }
12647
12648
408
    return ret;
12649
408
}
12650
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
12651
#endif /* WOLFSSL_AESGCM_STREAM */
12652
#endif /* WOLFSSL_XILINX_CRYPT */
12653
#endif /* end of block for AESGCM implementation selection */
12654
12655
12656
/* Common to all, abstract functions that build off of lower level AESGCM
12657
 * functions */
12658
#ifndef WC_NO_RNG
12659
12660
2.56k
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
12661
2.56k
    return (ivSz == GCM_NONCE_MIN_SZ ||
12662
2.56k
            ivSz == GCM_NONCE_MID_SZ ||
12663
0
            ivSz == GCM_NONCE_MAX_SZ);
12664
2.56k
}
12665
12666
12667
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
12668
2.45k
{
12669
2.45k
    int ret = 0;
12670
12671
2.45k
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
12672
0
        ret = BAD_FUNC_ARG;
12673
0
    }
12674
12675
2.45k
    if (ret == 0) {
12676
2.45k
        XMEMCPY((byte*)aes->reg, iv, ivSz);
12677
12678
        /* If the IV is 96, allow for a 2^64 invocation counter.
12679
         * For any other size for the nonce, limit the invocation
12680
         * counter to 32-bits. (SP 800-38D 8.3) */
12681
2.45k
        aes->invokeCtr[0] = 0;
12682
2.45k
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
12683
2.45k
    #ifdef WOLFSSL_AESGCM_STREAM
12684
2.45k
        aes->ctrSet = 1;
12685
2.45k
    #endif
12686
2.45k
        aes->nonceSz = ivSz;
12687
2.45k
    }
12688
12689
2.45k
    return ret;
12690
2.45k
}
12691
12692
12693
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
12694
                   const byte* ivFixed, word32 ivFixedSz,
12695
                   WC_RNG* rng)
12696
104
{
12697
104
    int ret = 0;
12698
12699
104
    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
12700
104
        (ivFixed == NULL && ivFixedSz != 0) ||
12701
104
        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
12702
12703
0
        ret = BAD_FUNC_ARG;
12704
0
    }
12705
12706
104
    if (ret == 0) {
12707
104
        byte* iv = (byte*)aes->reg;
12708
12709
104
        if (ivFixedSz)
12710
104
            XMEMCPY(iv, ivFixed, ivFixedSz);
12711
12712
104
        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
12713
104
    }
12714
12715
104
    if (ret == 0) {
12716
        /* If the IV is 96, allow for a 2^64 invocation counter.
12717
         * For any other size for the nonce, limit the invocation
12718
         * counter to 32-bits. (SP 800-38D 8.3) */
12719
102
        aes->invokeCtr[0] = 0;
12720
102
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
12721
102
    #ifdef WOLFSSL_AESGCM_STREAM
12722
102
        aes->ctrSet = 1;
12723
102
    #endif
12724
102
        aes->nonceSz = ivSz;
12725
102
    }
12726
12727
104
    return ret;
12728
104
}
12729
12730
12731
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
12732
                        byte* ivOut, word32 ivOutSz,
12733
                        byte* authTag, word32 authTagSz,
12734
                        const byte* authIn, word32 authInSz)
12735
856
{
12736
856
    int ret = 0;
12737
12738
856
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
12739
856
        ivOut == NULL || ivOutSz != aes->nonceSz ||
12740
856
        (authIn == NULL && authInSz != 0)) {
12741
12742
0
        ret = BAD_FUNC_ARG;
12743
0
    }
12744
12745
856
    if (ret == 0) {
12746
856
        aes->invokeCtr[0]++;
12747
856
        if (aes->invokeCtr[0] == 0) {
12748
0
            aes->invokeCtr[1]++;
12749
0
            if (aes->invokeCtr[1] == 0)
12750
0
                ret = AES_GCM_OVERFLOW_E;
12751
0
        }
12752
856
    }
12753
12754
856
    if (ret == 0) {
12755
856
        XMEMCPY(ivOut, aes->reg, ivOutSz);
12756
856
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
12757
856
                               (byte*)aes->reg, ivOutSz,
12758
856
                               authTag, authTagSz,
12759
856
                               authIn, authInSz);
12760
856
        if (ret == 0)
12761
856
            IncCtr((byte*)aes->reg, ivOutSz);
12762
856
    }
12763
12764
856
    return ret;
12765
856
}
12766
12767
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
12768
            const byte* authIn, word32 authInSz,
12769
            byte* authTag, word32 authTagSz, WC_RNG* rng)
12770
0
{
12771
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
12772
0
    int ret;
12773
12774
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
12775
0
        authTag == NULL || authTagSz == 0 || rng == NULL) {
12776
12777
0
        return BAD_FUNC_ARG;
12778
0
    }
12779
12780
0
#ifdef WOLFSSL_SMALL_STACK
12781
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
12782
#else
12783
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12784
#endif
12785
0
    if (ret != 0)
12786
0
        return ret;
12787
12788
0
    ret = wc_AesGcmSetKey(aes, key, keySz);
12789
0
    if (ret == 0)
12790
0
        ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
12791
0
    if (ret == 0)
12792
0
        ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
12793
0
                                  authTag, authTagSz, authIn, authInSz);
12794
12795
0
#ifdef WOLFSSL_SMALL_STACK
12796
0
    wc_AesDelete(aes, NULL);
12797
#else
12798
    wc_AesFree(aes);
12799
#endif
12800
12801
0
    return ret;
12802
0
}
12803
12804
int wc_GmacVerify(const byte* key, word32 keySz,
12805
                  const byte* iv, word32 ivSz,
12806
                  const byte* authIn, word32 authInSz,
12807
                  const byte* authTag, word32 authTagSz)
12808
0
{
12809
0
    int ret;
12810
0
#ifdef HAVE_AES_DECRYPT
12811
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
12812
12813
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
12814
0
        authTag == NULL || authTagSz == 0 || authTagSz > WC_AES_BLOCK_SIZE) {
12815
12816
0
        return BAD_FUNC_ARG;
12817
0
    }
12818
12819
0
#ifdef WOLFSSL_SMALL_STACK
12820
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
12821
#else
12822
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12823
#endif
12824
0
    if (ret == 0) {
12825
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
12826
0
        if (ret == 0)
12827
0
            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
12828
0
                                  authTag, authTagSz, authIn, authInSz);
12829
12830
0
    }
12831
0
#ifdef WOLFSSL_SMALL_STACK
12832
0
    wc_AesDelete(aes, NULL);
12833
#else
12834
    wc_AesFree(aes);
12835
#endif
12836
#else
12837
    (void)key;
12838
    (void)keySz;
12839
    (void)iv;
12840
    (void)ivSz;
12841
    (void)authIn;
12842
    (void)authInSz;
12843
    (void)authTag;
12844
    (void)authTagSz;
12845
    ret = NOT_COMPILED_IN;
12846
#endif
12847
0
    return ret;
12848
0
}
12849
12850
#endif /* WC_NO_RNG */
12851
12852
12853
int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
12854
0
{
12855
0
    if (gmac == NULL || key == NULL) {
12856
0
        return BAD_FUNC_ARG;
12857
0
    }
12858
0
    return wc_AesGcmSetKey(&gmac->aes, key, len);
12859
0
}
12860
12861
12862
int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
12863
                              const byte* authIn, word32 authInSz,
12864
                              byte* authTag, word32 authTagSz)
12865
0
{
12866
0
    if (gmac == NULL) {
12867
0
        return BAD_FUNC_ARG;
12868
0
    }
12869
12870
0
    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
12871
0
                                         authTag, authTagSz, authIn, authInSz);
12872
0
}
12873
12874
#endif /* HAVE_AESGCM */
12875
12876
#ifdef HAVE_AESCCM
12877
12878
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
12879
638
{
12880
638
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
12881
0
        return BAD_FUNC_ARG;
12882
12883
638
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
12884
638
}
12885
12886
12887
/* Checks if the tag size is an accepted value based on RFC 3610 section 2
12888
 * returns 0 if tag size is ok
12889
 */
12890
int wc_AesCcmCheckTagSize(int sz)
12891
3.30k
{
12892
    /* values here are from RFC 3610 section 2 */
12893
3.30k
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
12894
2.58k
            && sz != 16) {
12895
0
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
12896
0
        return BAD_FUNC_ARG;
12897
0
    }
12898
3.30k
    return 0;
12899
3.30k
}
12900
12901
#if defined(WOLFSSL_RISCV_ASM)
12902
    /* implementation located in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
12903
12904
#elif defined(HAVE_COLDFIRE_SEC)
12905
    #error "Coldfire SEC doesn't currently support AES-CCM mode"
12906
12907
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
12908
        !defined(WOLFSSL_QNX_CAAM)
12909
    /* implemented in wolfcrypt/src/port/caam_aes.c */
12910
12911
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
12912
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
12913
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12914
                   const byte* nonce, word32 nonceSz,
12915
                   byte* authTag, word32 authTagSz,
12916
                   const byte* authIn, word32 authInSz)
12917
{
12918
    return wc_AesCcmEncrypt_silabs(
12919
        aes, out, in, inSz,
12920
        nonce, nonceSz,
12921
        authTag, authTagSz,
12922
        authIn, authInSz);
12923
}
12924
12925
#ifdef HAVE_AES_DECRYPT
12926
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12927
                   const byte* nonce, word32 nonceSz,
12928
                   const byte* authTag, word32 authTagSz,
12929
                   const byte* authIn, word32 authInSz)
12930
{
12931
    return wc_AesCcmDecrypt_silabs(
12932
        aes, out, in, inSz,
12933
        nonce, nonceSz,
12934
        authTag, authTagSz,
12935
        authIn, authInSz);
12936
}
12937
#endif
12938
#elif defined(FREESCALE_LTC)
12939
12940
/* return 0 on success */
12941
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12942
                   const byte* nonce, word32 nonceSz,
12943
                   byte* authTag, word32 authTagSz,
12944
                   const byte* authIn, word32 authInSz)
12945
{
12946
    byte *key;
12947
    word32 keySize;
12948
    status_t status;
12949
12950
    /* sanity check on arguments */
12951
    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
12952
     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
12953
     * don't allow it here either.
12954
     */
12955
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
12956
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
12957
        return BAD_FUNC_ARG;
12958
    }
12959
12960
    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
12961
        return BAD_FUNC_ARG;
12962
    }
12963
12964
    key = (byte*)aes->key;
12965
12966
    status = wc_AesGetKeySize(aes, &keySize);
12967
    if (status != 0) {
12968
        return status;
12969
    }
12970
12971
    status = wolfSSL_CryptHwMutexLock();
12972
    if (status != 0)
12973
        return status;
12974
12975
    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
12976
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
12977
    wolfSSL_CryptHwMutexUnLock();
12978
12979
    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
12980
}
12981
12982
#ifdef HAVE_AES_DECRYPT
12983
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
12984
                   const byte* nonce, word32 nonceSz,
12985
                   const byte* authTag, word32 authTagSz,
12986
                   const byte* authIn, word32 authInSz)
12987
{
12988
    byte *key;
12989
    word32 keySize;
12990
    status_t status;
12991
12992
    /* sanity check on arguments */
12993
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
12994
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
12995
        return BAD_FUNC_ARG;
12996
    }
12997
12998
    key = (byte*)aes->key;
12999
13000
    status = wc_AesGetKeySize(aes, &keySize);
13001
    if (status != 0) {
13002
        return status;
13003
    }
13004
13005
    status = wolfSSL_CryptHwMutexLock();
13006
    if (status != 0)
13007
        return status;
13008
    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
13009
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
13010
    wolfSSL_CryptHwMutexUnLock();
13011
13012
    if (status != kStatus_Success) {
13013
        XMEMSET(out, 0, inSz);
13014
        return AES_CCM_AUTH_E;
13015
    }
13016
    return 0;
13017
}
13018
#endif /* HAVE_AES_DECRYPT */
13019
13020
#else
13021
13022
/* Software CCM */
13023
static WARN_UNUSED_RESULT int roll_x(
13024
    Aes* aes, const byte* in, word32 inSz, byte* out)
13025
3.30k
{
13026
3.30k
    int ret;
13027
13028
    /* process the bulk of the data */
13029
56.4k
    while (inSz >= WC_AES_BLOCK_SIZE) {
13030
53.1k
        xorbuf(out, in, WC_AES_BLOCK_SIZE);
13031
53.1k
        in += WC_AES_BLOCK_SIZE;
13032
53.1k
        inSz -= WC_AES_BLOCK_SIZE;
13033
13034
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
13035
         * roll_x() after the AES cache lines are already hot -- no need to
13036
         * absorb additional prefetch overhead here.
13037
         */
13038
53.1k
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
13039
53.1k
        if (ret != 0)
13040
0
            return ret;
13041
53.1k
    }
13042
13043
    /* process remainder of the data */
13044
3.30k
    if (inSz > 0) {
13045
3.19k
        xorbuf(out, in, inSz);
13046
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
13047
         * roll_x() after the AES cache lines are already hot -- no need to
13048
         * absorb additional prefetch overhead here.
13049
         */
13050
3.19k
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
13051
3.19k
        if (ret != 0)
13052
0
            return ret;
13053
3.19k
    }
13054
13055
3.30k
    return 0;
13056
3.30k
}
13057
13058
static WARN_UNUSED_RESULT int roll_auth(
13059
    Aes* aes, const byte* in, word32 inSz, byte* out)
13060
3.30k
{
13061
3.30k
    word32 authLenSz;
13062
3.30k
    word32 remainder;
13063
3.30k
    int ret;
13064
13065
    /* encode the length in */
13066
3.30k
    if (inSz <= 0xFEFF) {
13067
3.30k
        authLenSz = 2;
13068
3.30k
        out[0] ^= (byte)(inSz >> 8);
13069
3.30k
        out[1] ^= (byte)inSz;
13070
3.30k
    }
13071
0
    else {
13072
0
        authLenSz = 6;
13073
0
        out[0] ^= 0xFF;
13074
0
        out[1] ^= 0xFE;
13075
0
        out[2] ^= (byte)(inSz >> 24);
13076
0
        out[3] ^= (byte)(inSz >> 16);
13077
0
        out[4] ^= (byte)(inSz >>  8);
13078
0
        out[5] ^= (byte)inSz;
13079
0
    }
13080
    /* Note, the protocol handles auth data up to 2^64, but we are
13081
     * using 32-bit sizes right now, so the bigger data isn't handled
13082
     * else {}
13083
     */
13084
13085
    /* start fill out the rest of the first block */
13086
3.30k
    remainder = WC_AES_BLOCK_SIZE - authLenSz;
13087
3.30k
    if (inSz >= remainder) {
13088
        /* plenty of bulk data to fill the remainder of this block */
13089
0
        xorbuf(out + authLenSz, in, remainder);
13090
0
        inSz -= remainder;
13091
0
        in += remainder;
13092
0
    }
13093
3.30k
    else {
13094
        /* not enough bulk data, copy what is available, and pad zero */
13095
3.30k
        xorbuf(out + authLenSz, in, inSz);
13096
3.30k
        inSz = 0;
13097
3.30k
    }
13098
    /* wc_AesCcmEncrypt() and wc_AesCcmDecrypt() only call roll_auth() after the
13099
     * AES cache lines are already hot -- no need to absorb additional prefetch
13100
     * overhead here.
13101
     */
13102
3.30k
    ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
13103
13104
3.30k
    if ((ret == 0) && (inSz > 0)) {
13105
0
        ret = roll_x(aes, in, inSz, out);
13106
0
    }
13107
13108
3.30k
    return ret;
13109
3.30k
}
13110
13111
13112
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
13113
53.1k
{
13114
53.1k
    word32 i;
13115
13116
53.3k
    for (i = 0; i < lenSz; i++) {
13117
53.3k
        if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
13118
53.3k
    }
13119
53.1k
}
13120
13121
#ifdef WOLFSSL_AESNI
13122
static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
13123
{
13124
    word32 i;
13125
13126
    /* B+1 = B */
13127
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 1, B, WC_AES_BLOCK_SIZE);
13128
    /* B+2,B+3 = B,B+1 */
13129
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 2, B, WC_AES_BLOCK_SIZE * 2);
13130
13131
    for (i = 0; i < lenSz; i++) {
13132
        if (++B[WC_AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
13133
    }
13134
    B[WC_AES_BLOCK_SIZE * 3 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 3 - 1] + 2U);
13135
    if (B[WC_AES_BLOCK_SIZE * 3 - 1] < 2U) {
13136
        for (i = 1; i < lenSz; i++) {
13137
            if (++B[WC_AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
13138
        }
13139
    }
13140
    B[WC_AES_BLOCK_SIZE * 4 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 4 - 1] + 3U);
13141
    if (B[WC_AES_BLOCK_SIZE * 4 - 1] < 3U) {
13142
        for (i = 1; i < lenSz; i++) {
13143
            if (++B[WC_AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
13144
        }
13145
    }
13146
}
13147
13148
static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
13149
{
13150
    word32 i;
13151
13152
    B[WC_AES_BLOCK_SIZE - 1] = (byte)(B[WC_AES_BLOCK_SIZE - 1] + 4U);
13153
    if (B[WC_AES_BLOCK_SIZE - 1] < 4U) {
13154
        for (i = 1; i < lenSz; i++) {
13155
            if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) break;
13156
        }
13157
    }
13158
}
13159
#endif
13160
13161
/* Software AES - CCM Encrypt */
13162
/* return 0 on success */
13163
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
13164
                   const byte* nonce, word32 nonceSz,
13165
                   byte* authTag, word32 authTagSz,
13166
                   const byte* authIn, word32 authInSz)
13167
885
{
13168
#ifdef WOLFSSL_AESNI
13169
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
13170
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
13171
#else
13172
885
    byte A[WC_AES_BLOCK_SIZE];
13173
885
    byte B[WC_AES_BLOCK_SIZE];
13174
885
#endif
13175
885
    byte lenSz;
13176
885
    word32 i;
13177
885
    byte mask = 0xFF;
13178
885
    const word32 wordSz = (word32)sizeof(word32);
13179
885
    int ret;
13180
13181
    /* sanity check on arguments */
13182
885
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
13183
885
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
13184
885
            authTagSz > WC_AES_BLOCK_SIZE)
13185
0
        return BAD_FUNC_ARG;
13186
13187
    /* Sanity check on authIn to prevent segfault in xorbuf() where
13188
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
13189
885
    if (authIn == NULL && authInSz > 0)
13190
0
        return BAD_FUNC_ARG;
13191
13192
    /* sanity check on tag size */
13193
885
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
13194
0
        return BAD_FUNC_ARG;
13195
0
    }
13196
13197
885
#ifdef WOLF_CRYPTO_CB
13198
885
    #ifndef WOLF_CRYPTO_CB_FIND
13199
885
    if (aes->devId != INVALID_DEVID)
13200
0
    #endif
13201
0
    {
13202
0
        int crypto_cb_ret =
13203
0
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
13204
0
                                      authTag, authTagSz, authIn, authInSz);
13205
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13206
0
            return crypto_cb_ret;
13207
        /* fall-through when unavailable */
13208
0
    }
13209
885
#endif
13210
13211
885
    XMEMSET(A, 0, sizeof(A));
13212
885
    XMEMCPY(B+1, nonce, nonceSz);
13213
885
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
13214
885
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
13215
885
                  + (8 * (((byte)authTagSz - 2) / 2))
13216
885
                  + (lenSz - 1));
13217
3.54k
    for (i = 0; i < lenSz; i++) {
13218
2.65k
        if (mask && i >= wordSz)
13219
0
            mask = 0x00;
13220
2.65k
        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
13221
2.65k
    }
13222
13223
#ifdef WOLFSSL_CHECK_MEM_ZERO
13224
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
13225
#endif
13226
13227
885
    VECTOR_REGISTERS_PUSH;
13228
    /* note this wc_AesEncrypt() will perform cache prefetches if needed, so
13229
     * that the later encrypt ops don't need to.
13230
     */
13231
885
    ret = wc_AesEncrypt(aes, B, A);
13232
#ifdef WOLFSSL_CHECK_MEM_ZERO
13233
    if (ret == 0)
13234
        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
13235
#endif
13236
13237
885
    if ((ret == 0) && (authInSz > 0))
13238
885
        ret = roll_auth(aes, authIn, authInSz, A);
13239
13240
885
    if ((ret == 0) && (inSz > 0))
13241
885
        ret = roll_x(aes, in, inSz, A);
13242
13243
885
    if (ret == 0) {
13244
885
        XMEMCPY(authTag, A, authTagSz);
13245
13246
885
        B[0] = (byte)(lenSz - 1U);
13247
3.54k
        for (i = 0; i < lenSz; i++)
13248
2.65k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13249
885
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
13250
885
    }
13251
13252
885
    if (ret == 0) {
13253
885
        xorbuf(authTag, A, authTagSz);
13254
885
        B[15] = 1;
13255
885
    }
13256
#ifdef WOLFSSL_AESNI
13257
    if ((ret == 0) && aes->use_aesni) {
13258
        while (inSz >= WC_AES_BLOCK_SIZE * 4) {
13259
            AesCcmCtrIncSet4(B, lenSz);
13260
13261
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
13262
                            (int)aes->rounds);
13263
13264
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
13265
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE * 4);
13266
13267
            inSz -= WC_AES_BLOCK_SIZE * 4;
13268
            in += WC_AES_BLOCK_SIZE * 4;
13269
            out += WC_AES_BLOCK_SIZE * 4;
13270
13271
            AesCcmCtrInc4(B, lenSz);
13272
        }
13273
    }
13274
#endif
13275
885
    if (ret == 0) {
13276
43.5k
        while (inSz >= WC_AES_BLOCK_SIZE) {
13277
42.6k
            ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
13278
42.6k
            if (ret != 0)
13279
0
                break;
13280
42.6k
            xorbuf(A, in, WC_AES_BLOCK_SIZE);
13281
42.6k
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
13282
13283
42.6k
            AesCcmCtrInc(B, lenSz);
13284
42.6k
            inSz -= WC_AES_BLOCK_SIZE;
13285
42.6k
            in += WC_AES_BLOCK_SIZE;
13286
42.6k
            out += WC_AES_BLOCK_SIZE;
13287
42.6k
        }
13288
885
    }
13289
885
    if ((ret == 0) && (inSz > 0)) {
13290
802
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
13291
802
    }
13292
885
    if ((ret == 0) && (inSz > 0)) {
13293
802
        xorbuf(A, in, inSz);
13294
802
        XMEMCPY(out, A, inSz);
13295
802
    }
13296
13297
885
    ForceZero(A, sizeof(A));
13298
885
    ForceZero(B, sizeof(B));
13299
13300
#ifdef WOLFSSL_CHECK_MEM_ZERO
13301
    wc_MemZero_Check(A, sizeof(A));
13302
    wc_MemZero_Check(B, sizeof(B));
13303
#endif
13304
13305
885
    VECTOR_REGISTERS_POP;
13306
13307
885
    return ret;
13308
885
}
13309
13310
#ifdef HAVE_AES_DECRYPT
13311
/* Software AES - CCM Decrypt */
13312
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
13313
                   const byte* nonce, word32 nonceSz,
13314
                   const byte* authTag, word32 authTagSz,
13315
                   const byte* authIn, word32 authInSz)
13316
2.42k
{
13317
#ifdef WOLFSSL_AESNI
13318
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
13319
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
13320
#else
13321
2.42k
    byte A[WC_AES_BLOCK_SIZE];
13322
2.42k
    byte B[WC_AES_BLOCK_SIZE];
13323
2.42k
#endif
13324
2.42k
    byte* o;
13325
2.42k
    byte lenSz;
13326
2.42k
    word32 i, oSz;
13327
2.42k
    byte mask = 0xFF;
13328
2.42k
    const word32 wordSz = (word32)sizeof(word32);
13329
2.42k
    int ret = 0;
13330
2.42k
#ifdef WC_AES_HAVE_PREFETCH_ARG
13331
2.42k
    int did_prefetches = 0;
13332
2.42k
#endif
13333
13334
    /* sanity check on arguments */
13335
2.42k
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
13336
2.42k
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
13337
2.42k
        authTagSz > WC_AES_BLOCK_SIZE)
13338
0
        return BAD_FUNC_ARG;
13339
13340
    /* Sanity check on authIn to prevent segfault in xorbuf() where
13341
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
13342
2.42k
    if (authIn == NULL && authInSz > 0)
13343
0
        return BAD_FUNC_ARG;
13344
13345
    /* sanity check on tag size */
13346
2.42k
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
13347
0
        return BAD_FUNC_ARG;
13348
0
    }
13349
13350
2.42k
#ifdef WOLF_CRYPTO_CB
13351
2.42k
    #ifndef WOLF_CRYPTO_CB_FIND
13352
2.42k
    if (aes->devId != INVALID_DEVID)
13353
0
    #endif
13354
0
    {
13355
0
        int crypto_cb_ret =
13356
0
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
13357
0
            authTag, authTagSz, authIn, authInSz);
13358
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13359
0
            return crypto_cb_ret;
13360
        /* fall-through when unavailable */
13361
0
    }
13362
2.42k
#endif
13363
13364
2.42k
    o = out;
13365
2.42k
    oSz = inSz;
13366
2.42k
    XMEMSET(A, 0, sizeof A);
13367
2.42k
    XMEMCPY(B+1, nonce, nonceSz);
13368
2.42k
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
13369
13370
2.42k
    B[0] = (byte)(lenSz - 1U);
13371
9.69k
    for (i = 0; i < lenSz; i++)
13372
7.26k
        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13373
2.42k
    B[15] = 1;
13374
13375
#ifdef WOLFSSL_CHECK_MEM_ZERO
13376
    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
13377
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
13378
#endif
13379
13380
2.42k
    VECTOR_REGISTERS_PUSH;
13381
13382
#ifdef WOLFSSL_AESNI
13383
    if (aes->use_aesni) {
13384
        while (oSz >= WC_AES_BLOCK_SIZE * 4) {
13385
            AesCcmCtrIncSet4(B, lenSz);
13386
13387
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
13388
                            (int)aes->rounds);
13389
13390
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
13391
            XMEMCPY(o, A, WC_AES_BLOCK_SIZE * 4);
13392
13393
            oSz -= WC_AES_BLOCK_SIZE * 4;
13394
            in += WC_AES_BLOCK_SIZE * 4;
13395
            o += WC_AES_BLOCK_SIZE * 4;
13396
13397
            AesCcmCtrInc4(B, lenSz);
13398
        }
13399
    }
13400
#endif
13401
13402
12.9k
    while (oSz >= WC_AES_BLOCK_SIZE) {
13403
10.5k
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
13404
10.5k
        if (ret != 0)
13405
0
            break;
13406
10.5k
        xorbuf(A, in, WC_AES_BLOCK_SIZE);
13407
10.5k
        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
13408
10.5k
        AesCcmCtrInc(B, lenSz);
13409
10.5k
        oSz -= WC_AES_BLOCK_SIZE;
13410
10.5k
        in += WC_AES_BLOCK_SIZE;
13411
10.5k
        o += WC_AES_BLOCK_SIZE;
13412
10.5k
    }
13413
13414
2.42k
    if ((ret == 0) && (inSz > 0))
13415
2.41k
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
13416
13417
2.42k
    if ((ret == 0) && (inSz > 0)) {
13418
2.41k
        xorbuf(A, in, oSz);
13419
2.41k
        XMEMCPY(o, A, oSz);
13420
9.66k
        for (i = 0; i < lenSz; i++)
13421
7.25k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13422
2.41k
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
13423
2.41k
    }
13424
13425
2.42k
    if (ret == 0) {
13426
2.42k
        o = out;
13427
2.42k
        oSz = inSz;
13428
13429
2.42k
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
13430
2.42k
                      + (8 * (((byte)authTagSz - 2) / 2))
13431
2.42k
                      + (lenSz - 1));
13432
9.69k
        for (i = 0; i < lenSz; i++) {
13433
7.26k
            if (mask && i >= wordSz)
13434
0
                mask = 0x00;
13435
7.26k
            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
13436
7.26k
        }
13437
13438
2.42k
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
13439
2.42k
    }
13440
13441
2.42k
    if (ret == 0) {
13442
2.42k
        if (authInSz > 0)
13443
2.42k
            ret = roll_auth(aes, authIn, authInSz, A);
13444
2.42k
    }
13445
2.42k
    if ((ret == 0) && (inSz > 0))
13446
2.41k
        ret = roll_x(aes, o, oSz, A);
13447
13448
2.42k
    if (ret == 0) {
13449
2.42k
        B[0] = (byte)(lenSz - 1U);
13450
9.69k
        for (i = 0; i < lenSz; i++)
13451
7.26k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13452
2.42k
        ret = AesEncrypt_preFetchOpt(aes, B, B, &did_prefetches);
13453
2.42k
    }
13454
13455
2.42k
    if (ret == 0)
13456
2.42k
        xorbuf(A, B, authTagSz);
13457
13458
2.42k
    if (ret == 0) {
13459
2.42k
        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
13460
            /* If the authTag check fails, don't keep the decrypted data.
13461
             * Unfortunately, you need the decrypted data to calculate the
13462
             * check value. */
13463
            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
13464
                        defined(ACVP_VECTOR_TESTING)
13465
            WOLFSSL_MSG("Preserve output for vector responses");
13466
            #else
13467
2.42k
            if (inSz > 0)
13468
2.41k
                XMEMSET(out, 0, inSz);
13469
2.42k
            #endif
13470
2.42k
            ret = AES_CCM_AUTH_E;
13471
2.42k
        }
13472
2.42k
    }
13473
13474
2.42k
    ForceZero(A, sizeof(A));
13475
2.42k
    ForceZero(B, sizeof(B));
13476
2.42k
    o = NULL;
13477
13478
#ifdef WOLFSSL_CHECK_MEM_ZERO
13479
    wc_MemZero_Check(A, sizeof(A));
13480
    wc_MemZero_Check(B, sizeof(B));
13481
#endif
13482
13483
2.42k
    VECTOR_REGISTERS_POP;
13484
13485
2.42k
    return ret;
13486
2.42k
}
13487
13488
#endif /* HAVE_AES_DECRYPT */
13489
#endif /* software CCM */
13490
13491
/* abstract functions that call lower level AESCCM functions */
13492
#ifndef WC_NO_RNG
13493
13494
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
13495
857
{
13496
857
    int ret = 0;
13497
13498
857
    if (aes == NULL || nonce == NULL ||
13499
857
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
13500
13501
0
        ret = BAD_FUNC_ARG;
13502
0
    }
13503
13504
857
    if (ret == 0) {
13505
857
        XMEMCPY(aes->reg, nonce, nonceSz);
13506
857
        aes->nonceSz = nonceSz;
13507
13508
        /* Invocation counter should be 2^61 */
13509
857
        aes->invokeCtr[0] = 0;
13510
857
        aes->invokeCtr[1] = 0xE0000000;
13511
857
    }
13512
13513
857
    return ret;
13514
857
}
13515
13516
13517
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
13518
                        byte* ivOut, word32 ivOutSz,
13519
                        byte* authTag, word32 authTagSz,
13520
                        const byte* authIn, word32 authInSz)
13521
885
{
13522
885
    int ret = 0;
13523
13524
885
    if (aes == NULL || out == NULL ||
13525
885
        (in == NULL && sz != 0) ||
13526
885
        ivOut == NULL ||
13527
885
        (authIn == NULL && authInSz != 0) ||
13528
885
        (ivOutSz != aes->nonceSz)) {
13529
13530
0
        ret = BAD_FUNC_ARG;
13531
0
    }
13532
13533
885
    if (ret == 0) {
13534
885
        aes->invokeCtr[0]++;
13535
885
        if (aes->invokeCtr[0] == 0) {
13536
0
            aes->invokeCtr[1]++;
13537
0
            if (aes->invokeCtr[1] == 0)
13538
0
                ret = AES_CCM_OVERFLOW_E;
13539
0
        }
13540
885
    }
13541
13542
885
    if (ret == 0) {
13543
885
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
13544
885
                               (byte*)aes->reg, aes->nonceSz,
13545
885
                               authTag, authTagSz,
13546
885
                               authIn, authInSz);
13547
885
        if (ret == 0) {
13548
885
            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
13549
885
            IncCtr((byte*)aes->reg, aes->nonceSz);
13550
885
        }
13551
885
    }
13552
13553
885
    return ret;
13554
885
}
13555
13556
#endif /* WC_NO_RNG */
13557
13558
#endif /* HAVE_AESCCM */
13559
13560
#ifndef WC_NO_CONSTRUCTORS
13561
Aes* wc_AesNew(void* heap, int devId, int *result_code)
13562
0
{
13563
0
    int ret;
13564
0
    Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
13565
0
    if (aes == NULL) {
13566
0
        ret = MEMORY_E;
13567
0
    }
13568
0
    else {
13569
0
        ret = wc_AesInit(aes, heap, devId);
13570
0
        if (ret != 0) {
13571
0
            XFREE(aes, heap, DYNAMIC_TYPE_AES);
13572
0
            aes = NULL;
13573
0
        }
13574
0
    }
13575
13576
0
    if (result_code != NULL)
13577
0
        *result_code = ret;
13578
13579
0
    return aes;
13580
0
}
13581
13582
int wc_AesDelete(Aes *aes, Aes** aes_p)
13583
0
{
13584
0
    if (aes == NULL)
13585
0
        return BAD_FUNC_ARG;
13586
0
    wc_AesFree(aes);
13587
0
    XFREE(aes, aes->heap, DYNAMIC_TYPE_AES);
13588
0
    if (aes_p != NULL)
13589
0
        *aes_p = NULL;
13590
0
    return 0;
13591
0
}
13592
#endif /* !WC_NO_CONSTRUCTORS */
13593
13594
/* Initialize Aes */
13595
int wc_AesInit(Aes* aes, void* heap, int devId)
13596
7.19k
{
13597
7.19k
    int ret = 0;
13598
13599
7.19k
    if (aes == NULL)
13600
0
        return BAD_FUNC_ARG;
13601
13602
7.19k
    XMEMSET(aes, 0, sizeof(*aes));
13603
13604
7.19k
    aes->heap = heap;
13605
13606
7.19k
#if defined(WOLF_CRYPTO_CB) || defined(WOLFSSL_STM32U5_DHUK)
13607
7.19k
    aes->devId = devId;
13608
7.19k
    aes->devCtx = NULL;
13609
#else
13610
    (void)devId;
13611
#endif
13612
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
13613
    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
13614
                                                        aes->heap, devId);
13615
#endif /* WOLFSSL_ASYNC_CRYPT */
13616
13617
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
13618
    aes->alFd = WC_SOCK_NOTSET;
13619
    aes->rdFd = WC_SOCK_NOTSET;
13620
#endif
13621
#if defined(WOLFSSL_DEVCRYPTO) && \
13622
   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
13623
    aes->ctx.cfd = -1;
13624
#endif
13625
#if defined(WOLFSSL_IMXRT_DCP)
13626
    DCPAesInit(aes);
13627
#endif
13628
13629
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
13630
    ret = wc_psa_aes_init(aes);
13631
#endif
13632
13633
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
13634
    if (ret == 0)
13635
        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
13636
#endif
13637
13638
7.19k
    return ret;
13639
7.19k
}
13640
13641
#ifdef WOLF_PRIVATE_KEY_ID
13642
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
13643
0
{
13644
0
    int ret = 0;
13645
13646
0
    if (aes == NULL)
13647
0
        ret = BAD_FUNC_ARG;
13648
0
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
13649
0
        ret = BUFFER_E;
13650
13651
0
    if (ret == 0)
13652
0
        ret = wc_AesInit(aes, heap, devId);
13653
0
    if (ret == 0) {
13654
0
        XMEMCPY(aes->id, id, (size_t)len);
13655
0
        aes->idLen = len;
13656
0
        aes->labelLen = 0;
13657
0
    }
13658
13659
0
    return ret;
13660
0
}
13661
13662
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
13663
0
{
13664
0
    int ret = 0;
13665
0
    size_t labelLen = 0;
13666
13667
0
    if (aes == NULL || label == NULL)
13668
0
        ret = BAD_FUNC_ARG;
13669
0
    if (ret == 0) {
13670
0
        labelLen = XSTRLEN(label);
13671
0
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
13672
0
            ret = BUFFER_E;
13673
0
    }
13674
13675
0
    if (ret == 0)
13676
0
        ret = wc_AesInit(aes, heap, devId);
13677
0
    if (ret == 0) {
13678
0
        XMEMCPY(aes->label, label, labelLen);
13679
0
        aes->labelLen = (int)labelLen;
13680
0
        aes->idLen = 0;
13681
0
    }
13682
13683
0
    return ret;
13684
0
}
13685
#endif
13686
13687
/* Free Aes resources */
13688
void wc_AesFree(Aes* aes)
13689
371k
{
13690
371k
    if (aes == NULL) {
13691
364k
        return;
13692
364k
    }
13693
13694
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
13695
    #ifndef WOLF_CRYPTO_CB_FIND
13696
    if (aes->devId != INVALID_DEVID)
13697
    #endif
13698
    {
13699
        int ret = wc_CryptoCb_Free(aes->devId, WC_ALGO_TYPE_CIPHER,
13700
                                   WC_CIPHER_AES, 0, aes);
13701
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
13702
        aes->devCtx = NULL;  /* Clear device context handle */
13703
    #endif
13704
        /* If callback wants standard free, it can set devId to INVALID_DEVID.
13705
         * Otherwise assume the callback handled cleanup. */
13706
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13707
            return;
13708
        /* fall-through when unavailable */
13709
    }
13710
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
13711
13712
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
13713
    (void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
13714
#endif
13715
13716
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
13717
    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
13718
#endif /* WOLFSSL_ASYNC_CRYPT */
13719
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
13720
    if (aes->rdFd > 0) { /* negative is error case */
13721
        close(aes->rdFd);
13722
        aes->rdFd = WC_SOCK_NOTSET;
13723
    }
13724
    if (aes->alFd > 0) {
13725
        close(aes->alFd);
13726
        aes->alFd = WC_SOCK_NOTSET;
13727
    }
13728
#endif /* WOLFSSL_AFALG */
13729
#ifdef WOLFSSL_KCAPI_AES
13730
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
13731
    if (aes->init == 1) {
13732
        kcapi_cipher_destroy(aes->handle);
13733
    }
13734
    aes->init = 0;
13735
    aes->handle = NULL;
13736
#endif
13737
#if defined(WOLFSSL_DEVCRYPTO) && \
13738
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
13739
    wc_DevCryptoFree(&aes->ctx);
13740
#endif
13741
7.19k
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
13742
7.19k
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
13743
7.19k
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
13744
7.19k
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
13745
7.19k
#endif
13746
#if defined(WOLFSSL_IMXRT_DCP)
13747
    DCPAesFree(aes);
13748
#endif
13749
7.19k
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
13750
7.19k
    !defined(WOLFSSL_AESNI)
13751
7.19k
    if (aes->streamData != NULL) {
13752
980
        ForceZero(aes->streamData, aes->streamData_sz);
13753
980
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
13754
980
        aes->streamData = NULL;
13755
980
    }
13756
7.19k
#endif
13757
13758
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
13759
    if (aes->useSWCrypt == 0) {
13760
        se050_aes_free(aes);
13761
    }
13762
#endif
13763
13764
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
13765
    wc_psa_aes_free(aes);
13766
#endif
13767
13768
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
13769
    wc_MAXQ10XX_AesFree(aes);
13770
#endif
13771
13772
#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
13773
    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
13774
    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
13775
    wc_fspsm_Aesfree(aes);
13776
#endif
13777
13778
7.19k
    ForceZero(aes, sizeof(Aes));
13779
13780
#ifdef WOLFSSL_CHECK_MEM_ZERO
13781
    wc_MemZero_Check(aes, sizeof(Aes));
13782
#endif
13783
7.19k
}
13784
13785
int wc_AesGetKeySize(Aes* aes, word32* keySize)
13786
0
{
13787
0
    int ret = 0;
13788
13789
0
    if (aes == NULL || keySize == NULL) {
13790
0
        return BAD_FUNC_ARG;
13791
0
    }
13792
13793
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
13794
    return wc_psa_aes_get_key_size(aes, keySize);
13795
#endif
13796
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
13797
    *keySize = aes->ctx.key.keySize;
13798
    return ret;
13799
#endif
13800
0
    switch (aes->rounds) {
13801
0
#ifdef WOLFSSL_AES_128
13802
0
    case 10:
13803
0
        *keySize = 16;
13804
0
        break;
13805
0
#endif
13806
0
#ifdef WOLFSSL_AES_192
13807
0
    case 12:
13808
0
        *keySize = 24;
13809
0
        break;
13810
0
#endif
13811
0
#ifdef WOLFSSL_AES_256
13812
0
    case 14:
13813
0
        *keySize = 32;
13814
0
        break;
13815
0
#endif
13816
0
    default:
13817
0
        *keySize = 0;
13818
0
        ret = BAD_FUNC_ARG;
13819
0
    }
13820
13821
0
    return ret;
13822
0
}
13823
13824
#endif /* !WOLFSSL_TI_CRYPT */
13825
13826
/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
13827
 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
13828
 */
13829
#ifndef VECTOR_REGISTERS_PUSH
13830
    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
13831
#endif
13832
#ifndef VECTOR_REGISTERS_POP
13833
    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
13834
#endif
13835
13836
#ifdef HAVE_AES_ECB
13837
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
13838
        !defined(WOLFSSL_QNX_CAAM)
13839
    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
13840
13841
#elif defined(WOLFSSL_AFALG)
13842
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
13843
13844
#elif defined(WOLFSSL_DEVCRYPTO_AES)
13845
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
13846
13847
#elif defined(WOLFSSL_RISCV_ASM)
13848
    /* implemented in wolfcrypt/src/port/riscv/riscv-64-aes.c */
13849
13850
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
13851
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
13852
13853
#elif defined(MAX3266X_AES)
13854
13855
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13856
{
13857
    int status;
13858
    word32 keySize;
13859
13860
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13861
        return BAD_FUNC_ARG;
13862
13863
    status = wc_AesGetKeySize(aes, &keySize);
13864
    if (status != 0) {
13865
        return status;
13866
    }
13867
13868
    status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key,
13869
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
13870
13871
    return status;
13872
}
13873
13874
#ifdef HAVE_AES_DECRYPT
13875
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13876
{
13877
    int status;
13878
    word32 keySize;
13879
13880
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13881
        return BAD_FUNC_ARG;
13882
13883
    status = wc_AesGetKeySize(aes, &keySize);
13884
    if (status != 0) {
13885
        return status;
13886
    }
13887
13888
    status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key,
13889
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
13890
13891
    return status;
13892
}
13893
#endif /* HAVE_AES_DECRYPT */
13894
13895
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
13896
13897
/* Software AES - ECB */
13898
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13899
{
13900
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13901
        return BAD_FUNC_ARG;
13902
13903
    return AES_ECB_encrypt(aes, in, out, sz);
13904
}
13905
13906
13907
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13908
{
13909
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13910
        return BAD_FUNC_ARG;
13911
13912
    return AES_ECB_decrypt(aes, in, out, sz);
13913
}
13914
13915
#elif defined(WOLFSSL_PSOC6_CRYPTO)
13916
13917
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13918
{
13919
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13920
        return BAD_FUNC_ARG;
13921
13922
    return wc_Psoc6_Aes_EcbEncrypt(aes, out, in, sz);
13923
}
13924
13925
#define _AesEcbEncrypt(aes, out, in, sz) wc_AesEcbEncrypt(aes, out, in, sz)
13926
13927
#ifdef HAVE_AES_DECRYPT
13928
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
13929
{
13930
    if ((in == NULL) || (out == NULL) || (aes == NULL))
13931
        return BAD_FUNC_ARG;
13932
13933
    return wc_Psoc6_Aes_EcbDecrypt(aes, out, in, sz);
13934
}
13935
13936
#define _AesEcbDecrypt(aes, out, in, sz) wc_AesEcbDecrypt(aes, out, in, sz)
13937
#endif /* HAVE_AES_DECRYPT */
13938
13939
#else
13940
13941
/* Software AES - ECB */
13942
static WARN_UNUSED_RESULT int _AesEcbEncrypt(
13943
    Aes* aes, byte* out, const byte* in, word32 sz)
13944
1.17k
{
13945
1.17k
    int ret = 0;
13946
13947
1.17k
#ifdef WOLF_CRYPTO_CB
13948
1.17k
    #ifndef WOLF_CRYPTO_CB_FIND
13949
1.17k
    if (aes->devId != INVALID_DEVID)
13950
159
    #endif
13951
159
    {
13952
159
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
13953
159
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13954
0
            return ret;
13955
159
        ret = 0;
13956
        /* fall-through when unavailable */
13957
159
    }
13958
1.17k
#endif
13959
#ifdef WOLFSSL_IMXRT_DCP
13960
    if (aes->keylen == 16)
13961
        return DCPAesEcbEncrypt(aes, out, in, sz);
13962
#endif
13963
13964
1.17k
    VECTOR_REGISTERS_PUSH;
13965
13966
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
13967
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
13968
    AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
13969
#else
13970
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
13971
#endif
13972
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
13973
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13974
    if (aes->use_aes_hw_crypto) {
13975
        AES_encrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
13976
            (int)aes->rounds);
13977
    }
13978
    else
13979
#endif
13980
#if !defined(WOLFSSL_ARMASM_NO_NEON)
13981
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
13982
    if (sz >= 32)
13983
#endif
13984
    {
13985
        AES_ECB_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
13986
            aes->rounds);
13987
    }
13988
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
13989
    else
13990
#endif
13991
#endif
13992
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
13993
    {
13994
        AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key,
13995
            aes->rounds);
13996
    }
13997
#endif
13998
#else
13999
#ifdef WOLFSSL_AESNI
14000
    if (aes->use_aesni) {
14001
        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
14002
    }
14003
    else
14004
#endif
14005
1.17k
    {
14006
1.17k
#if defined(NEED_AES_TABLES)
14007
1.17k
        AesEncryptBlocks_C(aes, in, out, sz);
14008
#else
14009
        word32 i;
14010
#ifdef WC_AES_HAVE_PREFETCH_ARG
14011
        int did_prefetches = 0;
14012
#endif
14013
14014
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
14015
            ret = AesEncrypt_preFetchOpt(aes, in, out, &did_prefetches);
14016
            if (ret != 0)
14017
                break;
14018
            in += WC_AES_BLOCK_SIZE;
14019
            out += WC_AES_BLOCK_SIZE;
14020
        }
14021
#endif
14022
1.17k
    }
14023
1.17k
#endif
14024
14025
1.17k
    VECTOR_REGISTERS_POP;
14026
14027
1.17k
    return ret;
14028
1.17k
}
14029
14030
#ifdef HAVE_AES_DECRYPT
14031
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
14032
    Aes* aes, byte* out, const byte* in, word32 sz)
14033
279
{
14034
279
    int ret = 0;
14035
14036
279
#ifdef WOLF_CRYPTO_CB
14037
279
    #ifndef WOLF_CRYPTO_CB_FIND
14038
279
    if (aes->devId != INVALID_DEVID)
14039
234
    #endif
14040
234
    {
14041
234
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
14042
234
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
14043
0
            return ret;
14044
234
        ret = 0;
14045
        /* fall-through when unavailable */
14046
234
    }
14047
279
#endif
14048
#ifdef WOLFSSL_IMXRT_DCP
14049
    if (aes->keylen == 16)
14050
        return DCPAesEcbDecrypt(aes, out, in, sz);
14051
#endif
14052
14053
279
    VECTOR_REGISTERS_PUSH;
14054
14055
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
14056
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
14057
    AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
14058
#else
14059
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
14060
#endif
14061
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
14062
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14063
    if (aes->use_aes_hw_crypto) {
14064
        AES_decrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
14065
            (int)aes->rounds);
14066
    }
14067
    else
14068
#endif
14069
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
14070
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
14071
    if (sz >= 64)
14072
#endif
14073
    {
14074
        AES_ECB_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
14075
            aes->rounds);
14076
    }
14077
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
14078
    else
14079
#endif
14080
#endif
14081
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
14082
    {
14083
        AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key,
14084
            aes->rounds);
14085
    }
14086
#endif
14087
#else
14088
#ifdef WOLFSSL_AESNI
14089
    if (aes->use_aesni) {
14090
        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
14091
    }
14092
    else
14093
#endif
14094
279
    {
14095
279
#if defined(NEED_AES_TABLES)
14096
279
        AesDecryptBlocks_C(aes, in, out, sz);
14097
#else
14098
        word32 i;
14099
14100
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
14101
            ret = wc_AesDecryptDirect(aes, out, in);
14102
            if (ret != 0)
14103
                break;
14104
            in += WC_AES_BLOCK_SIZE;
14105
            out += WC_AES_BLOCK_SIZE;
14106
        }
14107
#endif
14108
279
    }
14109
279
#endif
14110
14111
279
    VECTOR_REGISTERS_POP;
14112
14113
279
    return ret;
14114
279
}
14115
#endif
14116
14117
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14118
1.01k
{
14119
1.01k
    if ((in == NULL) || (out == NULL) || (aes == NULL))
14120
0
      return BAD_FUNC_ARG;
14121
1.01k
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
14122
0
        return BAD_LENGTH_E;
14123
0
    }
14124
14125
1.01k
    return _AesEcbEncrypt(aes, out, in, sz);
14126
1.01k
}
14127
14128
#ifdef HAVE_AES_DECRYPT
14129
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14130
45
{
14131
45
    if ((in == NULL) || (out == NULL) || (aes == NULL))
14132
0
      return BAD_FUNC_ARG;
14133
45
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
14134
0
        return BAD_LENGTH_E;
14135
0
    }
14136
14137
45
    return _AesEcbDecrypt(aes, out, in, sz);
14138
45
}
14139
#endif /* HAVE_AES_DECRYPT */
14140
#endif
14141
#endif /* HAVE_AES_ECB */
14142
14143
#if defined(WOLFSSL_AES_CFB)
14144
14145
#if defined(WOLFSSL_PSOC6_CRYPTO)
14146
14147
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14148
{
14149
    return wc_Psoc6_Aes_CfbEncrypt(aes, out, in, sz);
14150
}
14151
14152
#ifdef HAVE_AES_DECRYPT
14153
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14154
{
14155
    return wc_Psoc6_Aes_CfbDecrypt(aes, out, in, sz);
14156
}
14157
#endif /* HAVE_AES_DECRYPT */
14158
14159
#else
14160
/* Feedback AES mode
14161
 *
14162
 * aes structure holding key to use for encryption
14163
 * out buffer to hold result of encryption (must be at least as large as input
14164
 *     buffer)
14165
 * in  buffer to encrypt
14166
 * sz  size of input buffer
14167
 * mode flag to specify AES mode
14168
 *
14169
 * returns 0 on success and negative error values on failure
14170
 */
14171
/* Software AES - CFB Encrypt */
14172
static WARN_UNUSED_RESULT int AesCfbEncrypt_C(Aes* aes, byte* out,
14173
    const byte* in, word32 sz)
14174
0
{
14175
0
    int ret = 0;
14176
0
    word32 processed;
14177
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
14178
0
    int did_prefetches = 0;
14179
0
#endif
14180
14181
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
14182
0
        return BAD_FUNC_ARG;
14183
0
    }
14184
0
    if (sz == 0) {
14185
0
        return 0;
14186
0
    }
14187
14188
0
    if (aes->left > 0) {
14189
        /* consume any unused bytes left in aes->tmp */
14190
0
        processed = min(aes->left, sz);
14191
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
14192
0
            processed);
14193
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out,
14194
0
            processed);
14195
0
        aes->left -= processed;
14196
0
        out += processed;
14197
0
        in += processed;
14198
0
        sz -= processed;
14199
0
    }
14200
14201
0
    VECTOR_REGISTERS_PUSH;
14202
14203
0
    while (sz >= WC_AES_BLOCK_SIZE) {
14204
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
14205
0
                                        &did_prefetches);
14206
0
        if (ret != 0) {
14207
0
            break;
14208
0
        }
14209
0
        xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
14210
0
        XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
14211
0
        out += WC_AES_BLOCK_SIZE;
14212
0
        in  += WC_AES_BLOCK_SIZE;
14213
0
        sz  -= WC_AES_BLOCK_SIZE;
14214
0
    }
14215
14216
    /* encrypt left over data */
14217
0
    if ((ret == 0) && sz) {
14218
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14219
0
                                     &did_prefetches);
14220
0
        if (ret == 0) {
14221
0
            xorbufout(out, in, aes->tmp, sz);
14222
0
            XMEMCPY(aes->reg, out, sz);
14223
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
14224
0
        }
14225
0
    }
14226
14227
0
    VECTOR_REGISTERS_POP;
14228
14229
0
    return ret;
14230
0
}
14231
14232
14233
#if defined(HAVE_AES_DECRYPT)
14234
/* CFB 128
14235
 *
14236
 * aes structure holding key to use for decryption
14237
 * out buffer to hold result of decryption (must be at least as large as input
14238
 *     buffer)
14239
 * in  buffer to decrypt
14240
 * sz  size of input buffer
14241
 *
14242
 * returns 0 on success and negative error values on failure
14243
 */
14244
/* Software AES - CFB Decrypt */
14245
static WARN_UNUSED_RESULT int AesCfbDecrypt_C(Aes* aes, byte* out,
14246
    const byte* in, word32 sz, byte mode)
14247
0
{
14248
0
    int ret = 0;
14249
0
    word32 processed;
14250
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
14251
0
    int did_prefetches = 0;
14252
0
#endif
14253
14254
0
    (void)mode;
14255
14256
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
14257
0
        return BAD_FUNC_ARG;
14258
0
    }
14259
0
    if (sz == 0) {
14260
0
        return 0;
14261
0
    }
14262
14263
0
    if (aes->left > 0) {
14264
        /* consume any unused bytes left in aes->tmp */
14265
0
        processed = min(aes->left, sz);
14266
        /* copy input over to aes->reg */
14267
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, processed);
14268
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
14269
0
            processed);
14270
0
        aes->left -= processed;
14271
0
        out += processed;
14272
0
        in += processed;
14273
0
        sz -= processed;
14274
0
    }
14275
14276
0
    VECTOR_REGISTERS_PUSH;
14277
14278
    #if !defined(WOLFSSL_SMALL_STACK) && defined(HAVE_AES_ECB) && \
14279
        !defined(WOLFSSL_PIC32MZ_CRYPT) && \
14280
        (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
14281
    {
14282
        ALIGN16 byte tmp[4 * WC_AES_BLOCK_SIZE];
14283
        while (sz >= 4 * WC_AES_BLOCK_SIZE) {
14284
            XMEMCPY(tmp, aes->reg, WC_AES_BLOCK_SIZE);
14285
            XMEMCPY(tmp + WC_AES_BLOCK_SIZE, in, 3 * WC_AES_BLOCK_SIZE);
14286
            XMEMCPY(aes->reg, in + 3 * WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
14287
            ret = wc_AesEcbEncrypt(aes, tmp, tmp, 4 * WC_AES_BLOCK_SIZE);
14288
            if (ret != 0) {
14289
                break;
14290
            }
14291
            xorbufout(out, in, tmp, 4 * WC_AES_BLOCK_SIZE);
14292
            out += 4 * WC_AES_BLOCK_SIZE;
14293
            in  += 4 * WC_AES_BLOCK_SIZE;
14294
            sz  -= 4 * WC_AES_BLOCK_SIZE;
14295
        }
14296
    }
14297
    #endif
14298
0
    while (sz >= WC_AES_BLOCK_SIZE) {
14299
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14300
0
                                        &did_prefetches);
14301
0
        if (ret != 0) {
14302
0
            break;
14303
0
        }
14304
0
        XMEMCPY((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
14305
0
        xorbufout(out, in, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
14306
0
        out += WC_AES_BLOCK_SIZE;
14307
0
        in  += WC_AES_BLOCK_SIZE;
14308
0
        sz  -= WC_AES_BLOCK_SIZE;
14309
0
    }
14310
14311
    /* decrypt left over data */
14312
0
    if ((ret == 0) && sz) {
14313
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14314
0
                                        &did_prefetches);
14315
0
        if (ret == 0) {
14316
0
            XMEMCPY(aes->reg, in, sz);
14317
0
            xorbufout(out, in, aes->tmp, sz);
14318
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
14319
0
        }
14320
0
    }
14321
14322
0
    VECTOR_REGISTERS_POP;
14323
14324
0
    return ret;
14325
0
}
14326
#endif /* HAVE_AES_DECRYPT */
14327
14328
/* CFB 128
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 - CFB Encrypt */
14339
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14340
0
{
14341
0
    return AesCfbEncrypt_C(aes, out, in, sz);
14342
0
}
14343
14344
14345
#ifdef HAVE_AES_DECRYPT
14346
/* CFB 128
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 - CFB Decrypt */
14357
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14358
0
{
14359
0
    return AesCfbDecrypt_C(aes, out, in, sz, AES_CFB_MODE);
14360
0
}
14361
#endif /* HAVE_AES_DECRYPT */
14362
#endif /* WOLFSSL_PSOC6_CRYPTO */
14363
14364
#ifndef WOLFSSL_NO_AES_CFB_1_8
14365
/* shift the whole WC_AES_BLOCK_SIZE array left by 8 or 1 bits */
14366
static void shiftLeftArray(byte* ary, byte shift)
14367
35.9k
{
14368
35.9k
    int i;
14369
14370
35.9k
    if (shift == WOLFSSL_BIT_SIZE) {
14371
        /* shifting over by 8 bits */
14372
65.1k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
14373
61.0k
            ary[i] = ary[i+1];
14374
61.0k
        }
14375
4.07k
        ary[i] = 0;
14376
4.07k
    }
14377
31.9k
    else {
14378
        /* shifting over by 7 or less bits */
14379
510k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
14380
478k
            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
14381
478k
            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
14382
478k
            ary[i] = (byte)((ary[i] << shift) + carry);
14383
478k
        }
14384
31.9k
        ary[i] = (byte)(ary[i] << shift);
14385
31.9k
    }
14386
35.9k
}
14387
14388
14389
/* returns 0 on success and negative values on failure */
14390
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
14391
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
14392
403
{
14393
403
    byte *pt;
14394
403
    int ret = 0;
14395
403
#ifdef WC_AES_HAVE_PREFETCH_ARG
14396
403
    int did_prefetches = 0;
14397
403
#endif
14398
14399
403
    if (aes == NULL || out == NULL || in == NULL) {
14400
0
        return BAD_FUNC_ARG;
14401
0
    }
14402
14403
403
    if (sz == 0) {
14404
0
        return 0;
14405
0
    }
14406
14407
403
    VECTOR_REGISTERS_PUSH;
14408
14409
4.47k
    while (sz > 0) {
14410
4.07k
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14411
4.07k
                                        &did_prefetches);
14412
4.07k
        if (ret != 0)
14413
0
            break;
14414
4.07k
        if (dir == AES_DECRYPTION) {
14415
2.32k
            pt = (byte*)aes->reg;
14416
14417
            /* LSB + CAT */
14418
2.32k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
14419
2.32k
            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
14420
2.32k
        }
14421
14422
        /* MSB + XOR */
14423
    #ifdef BIG_ENDIAN_ORDER
14424
        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
14425
    #endif
14426
4.07k
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
14427
4.07k
        if (dir == AES_ENCRYPTION) {
14428
1.74k
            pt = (byte*)aes->reg;
14429
14430
            /* LSB + CAT */
14431
1.74k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
14432
1.74k
            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
14433
1.74k
        }
14434
14435
4.07k
        out += 1;
14436
4.07k
        in  += 1;
14437
4.07k
        sz  -= 1;
14438
4.07k
    }
14439
14440
403
    VECTOR_REGISTERS_POP;
14441
14442
403
    return ret;
14443
403
}
14444
14445
14446
/* returns 0 on success and negative values on failure */
14447
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
14448
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
14449
387
{
14450
387
    byte tmp;
14451
387
    byte cur = 0; /* hold current work in order to handle inline in=out */
14452
387
    byte* pt;
14453
387
    int bit = 7;
14454
387
    int ret = 0;
14455
387
#ifdef WC_AES_HAVE_PREFETCH_ARG
14456
387
    int did_prefetches = 0;
14457
387
#endif
14458
14459
387
    if (aes == NULL || out == NULL || in == NULL) {
14460
0
        return BAD_FUNC_ARG;
14461
0
    }
14462
14463
387
    if (sz == 0) {
14464
0
        return 0;
14465
0
    }
14466
14467
387
    VECTOR_REGISTERS_PUSH;
14468
14469
32.2k
    while (sz > 0) {
14470
31.9k
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14471
31.9k
                                        &did_prefetches);
14472
31.9k
        if (ret != 0)
14473
0
            break;
14474
31.9k
        if (dir == AES_DECRYPTION) {
14475
15.3k
            pt = (byte*)aes->reg;
14476
14477
            /* LSB + CAT */
14478
15.3k
            tmp = (byte)((0X01U << bit) & in[0]);
14479
15.3k
            tmp = (byte)(tmp >> bit);
14480
15.3k
            tmp &= 0x01;
14481
15.3k
            shiftLeftArray((byte*)aes->reg, 1);
14482
15.3k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
14483
15.3k
        }
14484
14485
        /* MSB  + XOR */
14486
31.9k
        tmp = (byte)((0X01U << bit) & in[0]);
14487
31.9k
        pt = (byte*)aes->tmp;
14488
31.9k
        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
14489
31.9k
        tmp &= 0x01;
14490
31.9k
        cur = (byte)(cur | (tmp << bit));
14491
14492
14493
31.9k
        if (dir == AES_ENCRYPTION) {
14494
16.5k
            pt = (byte*)aes->reg;
14495
14496
            /* LSB + CAT */
14497
16.5k
            shiftLeftArray((byte*)aes->reg, 1);
14498
16.5k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
14499
16.5k
        }
14500
14501
31.9k
        bit--;
14502
31.9k
        if (bit < 0) {
14503
3.98k
            out[0] = cur;
14504
3.98k
            out += 1;
14505
3.98k
            in  += 1;
14506
3.98k
            sz  -= 1;
14507
3.98k
            bit = 7U;
14508
3.98k
            cur = 0;
14509
3.98k
        }
14510
27.9k
        else {
14511
27.9k
            sz -= 1;
14512
27.9k
        }
14513
31.9k
    }
14514
14515
387
    if (ret == 0) {
14516
387
        if (bit >= 0 && bit < 7) {
14517
0
            out[0] = cur;
14518
0
        }
14519
387
    }
14520
14521
387
    VECTOR_REGISTERS_POP;
14522
14523
387
    return ret;
14524
387
}
14525
14526
14527
/* CFB 1
14528
 *
14529
 * aes structure holding key to use for encryption
14530
 * out buffer to hold result of encryption (must be at least as large as input
14531
 *     buffer)
14532
 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
14533
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
14534
 *
14535
 * returns 0 on success and negative values on failure
14536
 */
14537
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14538
264
{
14539
264
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
14540
264
}
14541
14542
14543
/* CFB 8
14544
 *
14545
 * aes structure holding key to use for encryption
14546
 * out buffer to hold result of encryption (must be at least as large as input
14547
 *     buffer)
14548
 * in  buffer to encrypt
14549
 * sz  size of input buffer
14550
 *
14551
 * returns 0 on success and negative values on failure
14552
 */
14553
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14554
219
{
14555
219
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
14556
219
}
14557
#ifdef HAVE_AES_DECRYPT
14558
14559
/* CFB 1
14560
 *
14561
 * aes structure holding key to use for encryption
14562
 * out buffer to hold result of encryption (must be at least as large as input
14563
 *     buffer)
14564
 * in  buffer to encrypt
14565
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
14566
 *
14567
 * returns 0 on success and negative values on failure
14568
 */
14569
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14570
123
{
14571
123
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
14572
123
}
14573
14574
14575
/* CFB 8
14576
 *
14577
 * aes structure holding key to use for encryption
14578
 * out buffer to hold result of encryption (must be at least as large as input
14579
 *     buffer)
14580
 * in  buffer to encrypt
14581
 * sz  size of input buffer
14582
 *
14583
 * returns 0 on success and negative values on failure
14584
 */
14585
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14586
184
{
14587
184
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
14588
184
}
14589
#endif /* HAVE_AES_DECRYPT */
14590
#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
14591
#endif /* WOLFSSL_AES_CFB */
14592
14593
#ifdef WOLFSSL_AES_OFB
14594
/* OFB AES mode
14595
 *
14596
 * aes structure holding key to use for encryption
14597
 * out buffer to hold result of encryption (must be at least as large as input
14598
 *     buffer)
14599
 * in  buffer to encrypt
14600
 * sz  size of input buffer
14601
 *
14602
 * returns 0 on success and negative error values on failure
14603
 */
14604
/* Software AES - OFB Encrypt/Decrypt */
14605
static WARN_UNUSED_RESULT int AesOfbCrypt_C(Aes* aes, byte* out, const byte* in,
14606
    word32 sz)
14607
943
{
14608
943
    int ret = 0;
14609
943
    word32 processed;
14610
943
#ifdef WC_AES_HAVE_PREFETCH_ARG
14611
943
    int did_prefetches = 0;
14612
943
#endif
14613
14614
943
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
14615
0
        return BAD_FUNC_ARG;
14616
0
    }
14617
943
    if (sz == 0) {
14618
0
        return 0;
14619
0
    }
14620
14621
943
    if (aes->left > 0) {
14622
        /* consume any unused bytes left in aes->tmp */
14623
386
        processed = min(aes->left, sz);
14624
386
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
14625
386
            processed);
14626
386
        aes->left -= processed;
14627
386
        out += processed;
14628
386
        in += processed;
14629
386
        sz -= processed;
14630
386
    }
14631
14632
943
    VECTOR_REGISTERS_PUSH;
14633
14634
1.79k
    while (sz >= WC_AES_BLOCK_SIZE) {
14635
852
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
14636
852
                                        &did_prefetches);
14637
852
        if (ret != 0) {
14638
0
            break;
14639
0
        }
14640
852
        xorbufout(out, in, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
14641
852
        out += WC_AES_BLOCK_SIZE;
14642
852
        in  += WC_AES_BLOCK_SIZE;
14643
852
        sz  -= WC_AES_BLOCK_SIZE;
14644
852
    }
14645
14646
    /* encrypt left over data */
14647
943
    if ((ret == 0) && sz) {
14648
307
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14649
307
                                        &did_prefetches);
14650
307
        if (ret == 0) {
14651
307
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
14652
307
            xorbufout(out, in, aes->tmp, sz);
14653
307
            aes->left = WC_AES_BLOCK_SIZE - sz;
14654
307
        }
14655
307
    }
14656
14657
943
    VECTOR_REGISTERS_POP;
14658
14659
943
    return ret;
14660
943
}
14661
14662
/* OFB
14663
 *
14664
 * aes structure holding key to use for encryption
14665
 * out buffer to hold result of encryption (must be at least as large as input
14666
 *     buffer)
14667
 * in  buffer to encrypt
14668
 * sz  size of input buffer
14669
 *
14670
 * returns 0 on success and negative error values on failure
14671
 */
14672
/* Software AES - OFB Encrypt */
14673
int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14674
666
{
14675
666
    return AesOfbCrypt_C(aes, out, in, sz);
14676
666
}
14677
14678
14679
#ifdef HAVE_AES_DECRYPT
14680
/* OFB
14681
 *
14682
 * aes structure holding key to use for decryption
14683
 * out buffer to hold result of decryption (must be at least as large as input
14684
 *     buffer)
14685
 * in  buffer to decrypt
14686
 * sz  size of input buffer
14687
 *
14688
 * returns 0 on success and negative error values on failure
14689
 */
14690
/* Software AES - OFB Decrypt */
14691
int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14692
277
{
14693
277
    return AesOfbCrypt_C(aes, out, in, sz);
14694
277
}
14695
#endif /* HAVE_AES_DECRYPT */
14696
#endif /* WOLFSSL_AES_OFB */
14697
14698
14699
#ifdef HAVE_AES_KEYWRAP
14700
14701
/* Initialize key wrap counter with value */
14702
static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
14703
0
{
14704
0
    word32 i;
14705
0
    word32 bytes;
14706
14707
0
    bytes = sizeof(word32);
14708
0
    for (i = 0; i < sizeof(word32); i++) {
14709
0
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
14710
0
        bytes--;
14711
0
    }
14712
0
}
14713
14714
/* Increment key wrap counter */
14715
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
14716
0
{
14717
0
    int i;
14718
14719
    /* in network byte order so start at end and work back */
14720
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
14721
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
14722
0
            return;
14723
0
    }
14724
0
}
14725
14726
/* Decrement key wrap counter */
14727
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
14728
0
{
14729
0
    int i;
14730
14731
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
14732
0
        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
14733
0
            return;
14734
0
    }
14735
0
}
14736
14737
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
14738
        word32 outSz, const byte* iv)
14739
0
{
14740
0
    word32 i;
14741
0
    byte* r;
14742
0
    int j;
14743
0
    int ret = 0;
14744
14745
0
    byte t[KEYWRAP_BLOCK_SIZE];
14746
0
    byte tmp[WC_AES_BLOCK_SIZE];
14747
14748
    /* n must be at least 2 64-bit blocks, output size is (n + 1) 8 bytes (64-bit) */
14749
0
    if (aes == NULL || in  == NULL || inSz < 2*KEYWRAP_BLOCK_SIZE ||
14750
0
        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
14751
0
        return BAD_FUNC_ARG;
14752
14753
    /* input must be multiple of 64-bits */
14754
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
14755
0
        return BAD_FUNC_ARG;
14756
14757
0
    r = out + 8;
14758
0
    XMEMCPY(r, in, inSz);
14759
0
    XMEMSET(t, 0, sizeof(t));
14760
14761
    /* user IV is optional */
14762
0
    if (iv == NULL) {
14763
0
        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
14764
0
    } else {
14765
0
        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
14766
0
    }
14767
14768
0
    VECTOR_REGISTERS_PUSH;
14769
14770
0
    for (j = 0; j <= 5; j++) {
14771
0
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
14772
            /* load R[i] */
14773
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
14774
14775
0
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
14776
0
            if (ret != 0)
14777
0
                break;
14778
14779
            /* calculate new A */
14780
0
            IncrementKeyWrapCounter(t);
14781
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
14782
14783
            /* save R[i] */
14784
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
14785
0
            r += KEYWRAP_BLOCK_SIZE;
14786
0
        }
14787
0
        if (ret != 0)
14788
0
            break;
14789
0
        r = out + KEYWRAP_BLOCK_SIZE;
14790
0
    }
14791
14792
0
    VECTOR_REGISTERS_POP;
14793
14794
0
    if (ret != 0)
14795
0
        return ret;
14796
14797
    /* C[0] = A */
14798
0
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
14799
14800
0
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
14801
0
}
14802
14803
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
14804
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
14805
                  byte* out, word32 outSz, const byte* iv)
14806
0
{
14807
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
14808
0
    int ret;
14809
14810
0
    if (key == NULL)
14811
0
        return BAD_FUNC_ARG;
14812
14813
0
#ifdef WOLFSSL_SMALL_STACK
14814
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
14815
0
                              DYNAMIC_TYPE_AES)) == NULL)
14816
0
        return MEMORY_E;
14817
0
#endif
14818
14819
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14820
0
    if (ret != 0)
14821
0
        goto out;
14822
14823
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
14824
0
    if (ret != 0) {
14825
0
        wc_AesFree(aes);
14826
0
        goto out;
14827
0
    }
14828
14829
0
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
14830
14831
0
    wc_AesFree(aes);
14832
14833
0
  out:
14834
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
14835
14836
0
    return ret;
14837
0
}
14838
14839
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
14840
        word32 outSz, const byte* iv)
14841
0
{
14842
0
    byte* r;
14843
0
    word32 i, n;
14844
0
    int j;
14845
0
    int ret = 0;
14846
14847
0
    byte t[KEYWRAP_BLOCK_SIZE];
14848
0
    byte tmp[WC_AES_BLOCK_SIZE];
14849
14850
0
    const byte* expIv;
14851
0
    const byte defaultIV[] = {
14852
0
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
14853
0
    };
14854
14855
0
    if (aes == NULL || in == NULL || inSz < 3 * KEYWRAP_BLOCK_SIZE ||
14856
0
        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
14857
0
        return BAD_FUNC_ARG;
14858
14859
    /* input must be multiple of 64-bits */
14860
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
14861
0
        return BAD_FUNC_ARG;
14862
14863
    /* user IV optional */
14864
0
    if (iv != NULL)
14865
0
        expIv = iv;
14866
0
    else
14867
0
        expIv = defaultIV;
14868
14869
    /* A = C[0], R[i] = C[i] */
14870
0
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
14871
0
    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
14872
0
    XMEMSET(t, 0, sizeof(t));
14873
14874
0
    VECTOR_REGISTERS_PUSH;
14875
14876
    /* initialize counter to 6n */
14877
0
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
14878
0
    InitKeyWrapCounter(t, 6 * n);
14879
14880
0
    for (j = 5; j >= 0; j--) {
14881
0
        for (i = n; i >= 1; i--) {
14882
14883
            /* calculate A */
14884
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
14885
0
            DecrementKeyWrapCounter(t);
14886
14887
            /* load R[i], starting at end of R */
14888
0
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
14889
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
14890
0
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
14891
0
            if (ret != 0)
14892
0
                break;
14893
14894
            /* save R[i] */
14895
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
14896
0
        }
14897
0
        if (ret != 0)
14898
0
            break;
14899
0
    }
14900
14901
0
    VECTOR_REGISTERS_POP;
14902
14903
0
    if (ret != 0)
14904
0
        return ret;
14905
14906
    /* verify IV */
14907
0
    if (ConstantCompare(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
14908
0
        return BAD_KEYWRAP_IV_E;
14909
14910
0
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
14911
0
}
14912
14913
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
14914
                    byte* out, word32 outSz, const byte* iv)
14915
0
{
14916
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
14917
0
    int ret;
14918
14919
0
    (void)iv;
14920
14921
0
    if (key == NULL)
14922
0
        return BAD_FUNC_ARG;
14923
14924
0
#ifdef WOLFSSL_SMALL_STACK
14925
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
14926
0
                              DYNAMIC_TYPE_AES)) == NULL)
14927
0
        return MEMORY_E;
14928
0
#endif
14929
14930
14931
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14932
0
    if (ret != 0)
14933
0
        goto out;
14934
14935
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
14936
0
    if (ret != 0) {
14937
0
        wc_AesFree(aes);
14938
0
        goto out;
14939
0
    }
14940
14941
0
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
14942
14943
0
    wc_AesFree(aes);
14944
14945
0
  out:
14946
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
14947
14948
0
    return ret;
14949
0
}
14950
14951
#endif /* HAVE_AES_KEYWRAP */
14952
14953
#ifdef WOLFSSL_AES_XTS
14954
14955
/* Galois Field to use */
14956
926
#define GF_XTS 0x87
14957
14958
/* Set up keys for encryption and/or decryption.
14959
 *
14960
 * aes   buffer holding aes subkeys
14961
 * heap  heap hint to use for memory. Can be NULL
14962
 * devId id to use with async crypto. Can be 0
14963
 *
14964
 * return 0 on success
14965
 */
14966
int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
14967
492
{
14968
492
    int    ret = 0;
14969
14970
492
    if (aes == NULL) {
14971
0
        return BAD_FUNC_ARG;
14972
0
    }
14973
14974
492
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
14975
0
        return ret;
14976
0
    }
14977
492
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
14978
0
        (void)wc_AesFree(&aes->tweak);
14979
0
        return ret;
14980
0
    }
14981
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
14982
    if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) {
14983
        (void)wc_AesFree(&aes->tweak);
14984
        (void)wc_AesFree(&aes->aes);
14985
        return ret;
14986
    }
14987
#endif
14988
14989
492
    return 0;
14990
492
}
14991
14992
/* Set up keys for encryption and/or decryption.
14993
 *
14994
 * aes   buffer holding aes subkeys
14995
 * key   AES key for encrypt/decrypt and tweak process (concatenated)
14996
 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
14997
 *       32 for a 16 byte key.
14998
 * dir   direction: AES_ENCRYPTION, AES_DECRYPTION, or
14999
 *       AES_ENCRYPTION_AND_DECRYPTION
15000
 *
15001
 * return 0 on success
15002
 */
15003
int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
15004
459
{
15005
459
    word32 keySz;
15006
459
    int    ret = 0;
15007
15008
459
    if (aes == NULL || key == NULL) {
15009
0
        return BAD_FUNC_ARG;
15010
0
    }
15011
15012
459
    if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION)
15013
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15014
        && (dir != AES_ENCRYPTION_AND_DECRYPTION)
15015
#endif
15016
459
        )
15017
0
    {
15018
0
        return BAD_FUNC_ARG;
15019
0
    }
15020
15021
459
    if ((len != (AES_128_KEY_SIZE*2)) &&
15022
90
#ifndef HAVE_FIPS
15023
        /* XTS-384 not allowed by FIPS and can not be treated like
15024
         * RSA-4096 bit keys back in the day, can not vendor affirm
15025
         * the use of 2 concatenated 192-bit keys (XTS-384) */
15026
90
        (len != (AES_192_KEY_SIZE*2)) &&
15027
90
#endif
15028
90
        (len != (AES_256_KEY_SIZE*2)))
15029
0
    {
15030
0
        WOLFSSL_MSG("Unsupported key size");
15031
0
        return WC_KEY_SIZE_E;
15032
0
    }
15033
15034
459
    keySz = len/2;
15035
15036
#ifdef HAVE_FIPS
15037
    if (XMEMCMP(key, key + keySz, keySz) == 0) {
15038
        WOLFSSL_MSG("FIPS AES-XTS main and tweak keys must differ");
15039
        return BAD_FUNC_ARG;
15040
    }
15041
#endif
15042
15043
459
    if (dir == AES_ENCRYPTION
15044
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15045
        || dir == AES_ENCRYPTION_AND_DECRYPTION
15046
#endif
15047
459
        )
15048
222
    {
15049
222
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
15050
222
    }
15051
15052
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15053
    if ((ret == 0) && ((dir == AES_DECRYPTION)
15054
                       || (dir == AES_ENCRYPTION_AND_DECRYPTION)))
15055
        ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION);
15056
#else
15057
459
    if (dir == AES_DECRYPTION)
15058
237
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
15059
459
#endif
15060
15061
459
    if (ret == 0)
15062
459
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
15063
459
                AES_ENCRYPTION);
15064
15065
#ifdef WOLFSSL_AESNI
15066
    if (ret == 0) {
15067
        /* With WC_C_DYNAMIC_FALLBACK, the main and tweak keys could have
15068
         * conflicting _aesni status, but the AES-XTS asm implementations need
15069
         * them to all be AESNI.  If any aren't, disable AESNI on all.
15070
         */
15071
    #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15072
        if ((((dir == AES_ENCRYPTION) ||
15073
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
15074
             && (aes->aes.use_aesni != aes->tweak.use_aesni))
15075
            ||
15076
            (((dir == AES_DECRYPTION) ||
15077
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
15078
             && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)))
15079
        {
15080
        #ifdef WC_C_DYNAMIC_FALLBACK
15081
            aes->aes.use_aesni = 0;
15082
            aes->aes_decrypt.use_aesni = 0;
15083
            aes->tweak.use_aesni = 0;
15084
        #else
15085
            ret = SYSLIB_FAILED_E;
15086
        #endif
15087
        }
15088
    #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
15089
        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
15090
        #ifdef WC_C_DYNAMIC_FALLBACK
15091
            aes->aes.use_aesni = 0;
15092
            aes->tweak.use_aesni = 0;
15093
        #else
15094
            ret = SYSLIB_FAILED_E;
15095
        #endif
15096
        }
15097
    #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
15098
    }
15099
#endif /* WOLFSSL_AESNI */
15100
15101
459
    return ret;
15102
459
}
15103
15104
/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
15105
 *
15106
 * Note: is up to user to call wc_AesXtsFree when done.
15107
 *
15108
 * return 0 on success
15109
 */
15110
int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
15111
        void* heap, int devId)
15112
0
{
15113
0
    int    ret = 0;
15114
15115
0
    if (aes == NULL || key == NULL) {
15116
0
        return BAD_FUNC_ARG;
15117
0
    }
15118
15119
0
    ret = wc_AesXtsInit(aes, heap, devId);
15120
0
    if (ret != 0)
15121
0
        return ret;
15122
15123
0
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
15124
15125
0
    if (ret != 0)
15126
0
        wc_AesXtsFree(aes);
15127
15128
0
    return ret;
15129
0
}
15130
15131
15132
/* This is used to free up resources used by Aes structs
15133
 *
15134
 * aes AES keys to free
15135
 *
15136
 * return 0 on success
15137
 */
15138
int wc_AesXtsFree(XtsAes* aes)
15139
492
{
15140
492
    if (aes != NULL) {
15141
492
        wc_AesFree(&aes->aes);
15142
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15143
        wc_AesFree(&aes->aes_decrypt);
15144
#endif
15145
492
        wc_AesFree(&aes->tweak);
15146
492
    }
15147
15148
492
    return 0;
15149
492
}
15150
15151
15152
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
15153
 * instead of a byte array. This just converts the word64 to a byte array and
15154
 * calls wc_AesXtsEncrypt.
15155
 *
15156
 * aes    AES keys to use for block encrypt/decrypt
15157
 * out    output buffer to hold cipher text
15158
 * in     input plain text buffer to encrypt
15159
 * sz     size of both out and in buffers
15160
 * sector value to use for tweak
15161
 *
15162
 * returns 0 on success
15163
 */
15164
int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
15165
        word32 sz, word64 sector)
15166
0
{
15167
0
    byte* pt;
15168
0
    byte  i[WC_AES_BLOCK_SIZE];
15169
15170
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
15171
#ifdef BIG_ENDIAN_ORDER
15172
    sector = ByteReverseWord64(sector);
15173
#endif
15174
0
    pt = (byte*)&sector;
15175
0
    XMEMCPY(i, pt, sizeof(word64));
15176
15177
0
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
15178
0
}
15179
15180
#ifdef HAVE_AES_DECRYPT
15181
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
15182
 * instead of a byte array. This just converts the word64 to a byte array.
15183
 *
15184
 * aes    AES keys to use for block encrypt/decrypt
15185
 * out    output buffer to hold plain text
15186
 * in     input cipher text buffer to encrypt
15187
 * sz     size of both out and in buffers
15188
 * sector value to use for tweak
15189
 *
15190
 * returns 0 on success
15191
 */
15192
int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
15193
        word64 sector)
15194
0
{
15195
0
    byte* pt;
15196
0
    byte  i[WC_AES_BLOCK_SIZE];
15197
15198
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
15199
#ifdef BIG_ENDIAN_ORDER
15200
    sector = ByteReverseWord64(sector);
15201
#endif
15202
0
    pt = (byte*)&sector;
15203
0
    XMEMCPY(i, pt, sizeof(word64));
15204
15205
0
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
15206
0
}
15207
#endif
15208
15209
#ifdef WOLFSSL_AESNI
15210
15211
#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
15212
    #define USE_INTEL_SPEEDUP
15213
#endif
15214
15215
#if defined(USE_INTEL_SPEEDUP)
15216
    #define HAVE_INTEL_AVX1
15217
    #define HAVE_INTEL_AVX2
15218
#endif /* USE_INTEL_SPEEDUP */
15219
15220
void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
15221
                     const unsigned char* i, const unsigned char* key,
15222
                     const unsigned char* key2, int nr)
15223
                     XASM_LINK("AES_XTS_encrypt_aesni");
15224
#ifdef WOLFSSL_AESXTS_STREAM
15225
void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
15226
                     int tweak_nr)
15227
                     XASM_LINK("AES_XTS_init_aesni");
15228
void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
15229
                     const unsigned char* key, unsigned char *i, int nr)
15230
                     XASM_LINK("AES_XTS_encrypt_update_aesni");
15231
#endif
15232
#ifdef HAVE_INTEL_AVX1
15233
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
15234
                     word32 sz, const unsigned char* i,
15235
                     const unsigned char* key, const unsigned char* key2,
15236
                     int nr)
15237
                     XASM_LINK("AES_XTS_encrypt_avx1");
15238
#ifdef WOLFSSL_AESXTS_STREAM
15239
void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
15240
                     int tweak_nr)
15241
                     XASM_LINK("AES_XTS_init_avx1");
15242
void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
15243
                     const unsigned char* key, unsigned char *i, int nr)
15244
                     XASM_LINK("AES_XTS_encrypt_update_avx1");
15245
#endif
15246
#endif /* HAVE_INTEL_AVX1 */
15247
15248
#ifdef HAVE_AES_DECRYPT
15249
void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
15250
                     const unsigned char* i, const unsigned char* key,
15251
                     const unsigned char* key2, int nr)
15252
                     XASM_LINK("AES_XTS_decrypt_aesni");
15253
#ifdef WOLFSSL_AESXTS_STREAM
15254
void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
15255
                     const unsigned char* key, unsigned char *i, int nr)
15256
                     XASM_LINK("AES_XTS_decrypt_update_aesni");
15257
#endif
15258
#ifdef HAVE_INTEL_AVX1
15259
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
15260
                     word32 sz, const unsigned char* i,
15261
                     const unsigned char* key, const unsigned char* key2,
15262
                     int nr)
15263
                     XASM_LINK("AES_XTS_decrypt_avx1");
15264
#ifdef WOLFSSL_AESXTS_STREAM
15265
void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
15266
                     const unsigned char* key, unsigned char *i, int nr)
15267
                     XASM_LINK("AES_XTS_decrypt_update_avx1");
15268
#endif
15269
#endif /* HAVE_INTEL_AVX1 */
15270
#endif /* HAVE_AES_DECRYPT */
15271
15272
#endif /* WOLFSSL_AESNI */
15273
15274
#ifdef HAVE_AES_ECB
15275
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15276
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
15277
/* helper function for encrypting / decrypting full buffer at once */
15278
static WARN_UNUSED_RESULT int _AesXtsHelper(
15279
    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
15280
393
{
15281
393
    word32 outSz   = sz;
15282
393
    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
15283
393
    byte*  pt      = out;
15284
15285
393
    outSz -= WC_AES_BLOCK_SIZE;
15286
15287
989
    while (outSz > 0) {
15288
596
        word32 j;
15289
596
        byte carry = 0;
15290
15291
        /* multiply by shift left and propagate carry */
15292
9.65k
        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
15293
9.06k
            byte tmpC;
15294
15295
9.06k
            tmpC   = (pt[j] >> 7) & 0x01;
15296
9.06k
            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
15297
9.06k
            carry  = tmpC;
15298
9.06k
        }
15299
596
        if (carry) {
15300
339
            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
15301
339
        }
15302
15303
596
        pt += WC_AES_BLOCK_SIZE;
15304
596
    }
15305
15306
393
    xorbuf(out, in, totalSz);
15307
393
#ifndef WOLFSSL_RISCV_ASM
15308
393
    if (dir == AES_ENCRYPTION) {
15309
159
        return _AesEcbEncrypt(aes, out, out, totalSz);
15310
159
    }
15311
234
    else {
15312
234
        return _AesEcbDecrypt(aes, out, out, totalSz);
15313
234
    }
15314
#else
15315
    if (dir == AES_ENCRYPTION) {
15316
        return wc_AesEcbEncrypt(aes, out, out, totalSz);
15317
    }
15318
    else {
15319
        return wc_AesEcbDecrypt(aes, out, out, totalSz);
15320
    }
15321
#endif
15322
393
}
15323
#endif
15324
#endif /* HAVE_AES_ECB */
15325
15326
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
15327
 *
15328
 * xaes  AES keys to use for block encrypt/decrypt
15329
 * out   output buffer to hold cipher text
15330
 * in    input plain text buffer to encrypt
15331
 * sz    size of both out and in buffers
15332
 * i     value to use for tweak
15333
 *
15334
 * returns 0 on success
15335
 */
15336
/* Software AES - XTS Encrypt  */
15337
15338
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15339
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
15340
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15341
                                  word32 sz,
15342
                                  byte *i);
15343
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15344
        const byte* i)
15345
208
{
15346
208
    int ret;
15347
208
    byte tweak_block[WC_AES_BLOCK_SIZE];
15348
15349
208
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
15350
208
    if (ret != 0)
15351
0
        return ret;
15352
15353
208
    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
15354
208
}
15355
#endif
15356
15357
#ifdef WOLFSSL_AESXTS_STREAM
15358
15359
/* Block-streaming AES-XTS tweak setup.
15360
 *
15361
 * xaes  AES keys to use for block encrypt/decrypt
15362
 * i     readwrite value to use for tweak
15363
 *
15364
 * returns 0 on success
15365
 */
15366
static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
15367
    return wc_AesEncryptDirect(&xaes->tweak, i, i);
15368
}
15369
15370
#endif /* WOLFSSL_AESXTS_STREAM */
15371
15372
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15373
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || defined(WOLFSSL_AESXTS_STREAM)
15374
/* Block-streaming AES-XTS.
15375
 *
15376
 * Supply block-aligned input data with successive calls.  Final call need not
15377
 * be block aligned.
15378
 *
15379
 * xaes  AES keys to use for block encrypt/decrypt
15380
 * out   output buffer to hold cipher text
15381
 * in    input plain text buffer to encrypt
15382
 * sz    size of both out and in buffers
15383
 *
15384
 * returns 0 on success
15385
 */
15386
/* Software AES - XTS Encrypt  */
15387
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15388
                                  word32 sz,
15389
                                  byte *i)
15390
208
{
15391
208
    int ret = 0;
15392
208
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
15393
208
    Aes *aes = &xaes->aes;
15394
15395
208
#ifdef HAVE_AES_ECB
15396
    /* encrypt all of buffer at once when possible */
15397
208
    if (in != out) { /* can not handle inline */
15398
159
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
15399
159
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
15400
0
            return ret;
15401
159
    }
15402
208
#endif
15403
15404
711
    while (blocks > 0) {
15405
503
        word32 j;
15406
503
        byte carry = 0;
15407
15408
503
#ifdef HAVE_AES_ECB
15409
503
        if (in == out)
15410
134
#endif
15411
134
        { /* check for if inline */
15412
134
            byte buf[WC_AES_BLOCK_SIZE];
15413
15414
134
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
15415
134
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15416
134
            ret = wc_AesEncryptDirect(aes, out, buf);
15417
134
            if (ret != 0)
15418
0
                return ret;
15419
134
        }
15420
503
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
15421
15422
        /* multiply by shift left and propagate carry */
15423
8.55k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
15424
8.04k
            byte tmpC;
15425
15426
8.04k
            tmpC   = (i[j] >> 7) & 0x01;
15427
8.04k
            i[j] = (byte)((i[j] << 1) + carry);
15428
8.04k
            carry  = tmpC;
15429
8.04k
        }
15430
503
        if (carry) {
15431
283
            i[0] ^= GF_XTS;
15432
283
        }
15433
15434
503
        in  += WC_AES_BLOCK_SIZE;
15435
503
        out += WC_AES_BLOCK_SIZE;
15436
503
        sz  -= WC_AES_BLOCK_SIZE;
15437
503
        blocks--;
15438
503
    }
15439
15440
    /* stealing operation of XTS to handle left overs */
15441
208
    if (sz > 0) {
15442
35
        byte buf[WC_AES_BLOCK_SIZE];
15443
15444
35
        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
15445
35
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
15446
0
            return BUFFER_E;
15447
0
        }
15448
35
        if (in != out) {
15449
25
            XMEMCPY(out, buf, sz);
15450
25
            XMEMCPY(buf, in, sz);
15451
25
        }
15452
10
        else {
15453
10
            byte buf2[WC_AES_BLOCK_SIZE];
15454
15455
10
            XMEMCPY(buf2, buf, sz);
15456
10
            XMEMCPY(buf, in, sz);
15457
10
            XMEMCPY(out, buf2, sz);
15458
10
        }
15459
15460
35
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15461
35
        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
15462
35
        if (ret == 0)
15463
35
            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
15464
35
    }
15465
15466
208
    return ret;
15467
208
}
15468
#endif
15469
15470
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
15471
 *
15472
 * xaes  AES keys to use for block encrypt/decrypt
15473
 * out   output buffer to hold cipher text
15474
 * in    input plain text buffer to encrypt
15475
 * sz    size of both out and in buffers
15476
 * i     value to use for tweak
15477
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15478
 *       adds a sanity check on how the user calls the function.
15479
 *
15480
 * returns 0 on success
15481
 */
15482
int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15483
        const byte* i, word32 iSz)
15484
218
{
15485
218
    int ret;
15486
15487
218
    Aes *aes;
15488
15489
218
    if (xaes == NULL || out == NULL || in == NULL) {
15490
0
        return BAD_FUNC_ARG;
15491
0
    }
15492
15493
#if FIPS_VERSION3_GE(6,0,0)
15494
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
15495
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
15496
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
15497
     */
15498
    if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
15499
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
15500
        return BAD_FUNC_ARG;
15501
    }
15502
#endif
15503
15504
218
    aes = &xaes->aes;
15505
15506
218
    if (aes->keylen == 0) {
15507
0
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
15508
0
        return BAD_FUNC_ARG;
15509
0
    }
15510
15511
218
    if (iSz < WC_AES_BLOCK_SIZE) {
15512
0
        return BAD_FUNC_ARG;
15513
0
    }
15514
15515
218
    if (sz < WC_AES_BLOCK_SIZE) {
15516
10
        WOLFSSL_MSG("Plain text input too small for encryption");
15517
10
        return BAD_FUNC_ARG;
15518
10
    }
15519
15520
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
15521
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15522
    AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
15523
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15524
    ret = 0;
15525
#elif defined(WOLFSSL_AESNI)
15526
    if (aes->use_aesni) {
15527
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
15528
#if defined(HAVE_INTEL_AVX1)
15529
        if (IS_INTEL_AVX1(intel_flags)) {
15530
            AES_XTS_encrypt_avx1(in, out, sz, i,
15531
                                 (const byte*)aes->key,
15532
                                 (const byte*)xaes->tweak.key,
15533
                                 (int)aes->rounds);
15534
            ret = 0;
15535
        }
15536
        else
15537
#endif
15538
        {
15539
            AES_XTS_encrypt_aesni(in, out, sz, i,
15540
                                  (const byte*)aes->key,
15541
                                  (const byte*)xaes->tweak.key,
15542
                                  (int)aes->rounds);
15543
            ret = 0;
15544
        }
15545
        RESTORE_VECTOR_REGISTERS();
15546
    }
15547
    else {
15548
        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
15549
    }
15550
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15551
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15552
    if (aes->use_aes_hw_crypto) {
15553
        AES_XTS_encrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
15554
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15555
        ret = 0;
15556
    }
15557
    else
15558
#endif
15559
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
15560
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15561
    if (sz >= 32)
15562
#endif
15563
    {
15564
        AES_XTS_encrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
15565
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15566
        ret = 0;
15567
    }
15568
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15569
    else
15570
#endif
15571
#endif
15572
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15573
    {
15574
        AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
15575
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15576
        ret = 0;
15577
    }
15578
#endif
15579
#else
15580
208
    ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
15581
208
#endif
15582
15583
208
    return ret;
15584
218
}
15585
15586
#ifdef WOLFSSL_AESXTS_STREAM
15587
15588
/* Block-streaming AES-XTS.
15589
 *
15590
 * xaes  AES keys to use for block encrypt/decrypt
15591
 * i     readwrite value to use for tweak
15592
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15593
 *       adds a sanity check on how the user calls the function.
15594
 *
15595
 * returns 0 on success
15596
 */
15597
int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
15598
                         struct XtsAesStreamData *stream)
15599
{
15600
    int ret;
15601
15602
    Aes *aes;
15603
15604
    if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
15605
        return BAD_FUNC_ARG;
15606
    }
15607
15608
    if (iSz < WC_AES_BLOCK_SIZE) {
15609
        return BAD_FUNC_ARG;
15610
    }
15611
15612
    aes = &xaes->aes;
15613
15614
    if (aes->keylen == 0) {
15615
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
15616
        return BAD_FUNC_ARG;
15617
    }
15618
15619
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
15620
    stream->bytes_crypted_with_this_tweak = 0;
15621
15622
    {
15623
#ifdef WOLFSSL_AESNI
15624
        if (aes->use_aesni) {
15625
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15626
#if defined(HAVE_INTEL_AVX1)
15627
            if (IS_INTEL_AVX1(intel_flags)) {
15628
                AES_XTS_init_avx1(stream->tweak_block,
15629
                                  (const byte*)xaes->tweak.key,
15630
                                  (int)xaes->tweak.rounds);
15631
                ret = 0;
15632
            }
15633
            else
15634
#endif
15635
            {
15636
                AES_XTS_init_aesni(stream->tweak_block,
15637
                                   (const byte*)xaes->tweak.key,
15638
                                   (int)xaes->tweak.rounds);
15639
                ret = 0;
15640
            }
15641
            RESTORE_VECTOR_REGISTERS();
15642
        }
15643
        else
15644
#endif /* WOLFSSL_AESNI */
15645
        {
15646
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
15647
        }
15648
    }
15649
15650
    return ret;
15651
}
15652
15653
/* Block-streaming AES-XTS
15654
 *
15655
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
15656
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsEncryptUpdate().
15657
 * wc_AesXtsEncryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
15658
 *
15659
 * xaes  AES keys to use for block encrypt/decrypt
15660
 * out   output buffer to hold cipher text
15661
 * in    input plain text buffer to encrypt
15662
 * sz    size of both out and in buffers -- must be >= WC_AES_BLOCK_SIZE.
15663
 * i     value to use for tweak
15664
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15665
 *       adds a sanity check on how the user calls the function.
15666
 *
15667
 * returns 0 on success
15668
 */
15669
static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15670
                           struct XtsAesStreamData *stream)
15671
{
15672
    int ret;
15673
15674
#ifdef WOLFSSL_AESNI
15675
    Aes *aes;
15676
#endif
15677
15678
    if (xaes == NULL || out == NULL || in == NULL) {
15679
        return BAD_FUNC_ARG;
15680
    }
15681
15682
#ifdef WOLFSSL_AESNI
15683
    aes = &xaes->aes;
15684
#endif
15685
15686
    if (sz < WC_AES_BLOCK_SIZE) {
15687
        WOLFSSL_MSG("Plain text input too small for encryption");
15688
        return BAD_FUNC_ARG;
15689
    }
15690
15691
    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
15692
    {
15693
        WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
15694
        return BAD_FUNC_ARG;
15695
    }
15696
15697
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
15698
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
15699
                             stream->bytes_crypted_with_this_tweak))
15700
    {
15701
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
15702
                    "in AesXtsEncryptUpdate().");
15703
    }
15704
#endif
15705
#if FIPS_VERSION3_GE(6,0,0)
15706
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
15707
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
15708
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
15709
     */
15710
    if (stream->bytes_crypted_with_this_tweak >
15711
        FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
15712
    {
15713
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
15714
        return BAD_FUNC_ARG;
15715
    }
15716
#endif
15717
    {
15718
#ifdef WOLFSSL_AESNI
15719
        if (aes->use_aesni) {
15720
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15721
#if defined(HAVE_INTEL_AVX1)
15722
            if (IS_INTEL_AVX1(intel_flags)) {
15723
                AES_XTS_encrypt_update_avx1(in, out, sz,
15724
                                            (const byte*)aes->key,
15725
                                            stream->tweak_block,
15726
                                            (int)aes->rounds);
15727
                ret = 0;
15728
            }
15729
            else
15730
#endif
15731
            {
15732
                AES_XTS_encrypt_update_aesni(in, out, sz,
15733
                                            (const byte*)aes->key,
15734
                                            stream->tweak_block,
15735
                                            (int)aes->rounds);
15736
                ret = 0;
15737
            }
15738
            RESTORE_VECTOR_REGISTERS();
15739
        }
15740
        else
15741
#endif /* WOLFSSL_AESNI */
15742
        {
15743
            ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
15744
        }
15745
    }
15746
15747
    return ret;
15748
}
15749
15750
int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15751
                           struct XtsAesStreamData *stream)
15752
{
15753
    if (stream == NULL)
15754
        return BAD_FUNC_ARG;
15755
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
15756
        return BAD_FUNC_ARG;
15757
    return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
15758
}
15759
15760
int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15761
                           struct XtsAesStreamData *stream)
15762
{
15763
    int ret;
15764
    if (stream == NULL)
15765
        return BAD_FUNC_ARG;
15766
    if (sz > 0)
15767
        ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
15768
    else
15769
        ret = 0;
15770
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
15771
     * after finalization.
15772
     */
15773
    stream->bytes_crypted_with_this_tweak |= 1U;
15774
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
15775
#ifdef WOLFSSL_CHECK_MEM_ZERO
15776
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
15777
#endif
15778
    return ret;
15779
}
15780
15781
#endif /* WOLFSSL_AESXTS_STREAM */
15782
15783
#ifdef HAVE_AES_DECRYPT
15784
15785
/* Same process as encryption but use aes_decrypt key.
15786
 *
15787
 * xaes  AES keys to use for block encrypt/decrypt
15788
 * out   output buffer to hold plain text
15789
 * in    input cipher text buffer to decrypt
15790
 * sz    size of both out and in buffers
15791
 * i     value to use for tweak
15792
 *
15793
 * returns 0 on success
15794
 */
15795
/* Software AES - XTS Decrypt */
15796
15797
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15798
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
15799
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15800
                                  word32 sz, byte *i);
15801
15802
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15803
        const byte* i)
15804
234
{
15805
234
    int ret;
15806
234
    byte tweak_block[WC_AES_BLOCK_SIZE];
15807
15808
234
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
15809
234
    if (ret != 0)
15810
0
        return ret;
15811
15812
234
    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
15813
234
}
15814
#endif
15815
15816
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15817
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
15818
/* Block-streaming AES-XTS.
15819
 *
15820
 * Same process as encryption but use decrypt key.
15821
 *
15822
 * Supply block-aligned input data with successive calls.  Final call need not
15823
 * be block aligned.
15824
 *
15825
 * xaes  AES keys to use for block encrypt/decrypt
15826
 * out   output buffer to hold plain text
15827
 * in    input cipher text buffer to decrypt
15828
 * sz    size of both out and in buffers
15829
 * i     value to use for tweak
15830
 *
15831
 * returns 0 on success
15832
 */
15833
/* Software AES - XTS Decrypt */
15834
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15835
                                  word32 sz, byte *i)
15836
234
{
15837
234
    int ret = 0;
15838
234
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
15839
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15840
    Aes *aes = &xaes->aes_decrypt;
15841
#else
15842
234
    Aes *aes = &xaes->aes;
15843
234
#endif
15844
234
    word32 j;
15845
234
    byte carry = 0;
15846
234
    byte stl = (sz % WC_AES_BLOCK_SIZE);
15847
15848
    /* if Stealing then break out of loop one block early to handle special
15849
     * case */
15850
234
    if (stl > 0) {
15851
60
        blocks--;
15852
60
    }
15853
15854
234
#ifdef HAVE_AES_ECB
15855
    /* decrypt all of buffer at once when possible */
15856
234
    if (in != out) { /* can not handle inline */
15857
234
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
15858
234
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
15859
0
            return ret;
15860
234
    }
15861
234
#endif
15862
15863
709
    while (blocks > 0) {
15864
475
#ifdef HAVE_AES_ECB
15865
475
        if (in == out)
15866
0
#endif
15867
0
        { /* check for if inline */
15868
0
            byte buf[WC_AES_BLOCK_SIZE];
15869
15870
0
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
15871
0
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15872
0
            ret = wc_AesDecryptDirect(aes, out, buf);
15873
0
            if (ret != 0)
15874
0
                return ret;
15875
0
        }
15876
475
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
15877
15878
        /* multiply by shift left and propagate carry */
15879
8.07k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
15880
7.60k
            byte tmpC;
15881
15882
7.60k
            tmpC   = (i[j] >> 7) & 0x01;
15883
7.60k
            i[j] = (byte)((i[j] << 1) + carry);
15884
7.60k
            carry  = tmpC;
15885
7.60k
        }
15886
475
        if (carry) {
15887
269
            i[0] ^= GF_XTS;
15888
269
        }
15889
475
        carry = 0;
15890
15891
475
        in  += WC_AES_BLOCK_SIZE;
15892
475
        out += WC_AES_BLOCK_SIZE;
15893
475
        sz  -= WC_AES_BLOCK_SIZE;
15894
475
        blocks--;
15895
475
    }
15896
15897
    /* stealing operation of XTS to handle left overs */
15898
234
    if (sz >= WC_AES_BLOCK_SIZE) {
15899
60
        byte buf[WC_AES_BLOCK_SIZE];
15900
60
        byte tmp2[WC_AES_BLOCK_SIZE];
15901
15902
        /* multiply by shift left and propagate carry */
15903
1.02k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
15904
960
            byte tmpC;
15905
15906
960
            tmpC   = (i[j] >> 7) & 0x01;
15907
960
            tmp2[j] = (byte)((i[j] << 1) + carry);
15908
960
            carry  = tmpC;
15909
960
        }
15910
60
        if (carry) {
15911
35
            tmp2[0] ^= GF_XTS;
15912
35
        }
15913
15914
60
        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
15915
60
        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
15916
60
        ret = wc_AesDecryptDirect(aes, out, buf);
15917
60
        if (ret != 0)
15918
0
            return ret;
15919
60
        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
15920
15921
        /* tmp2 holds partial | last */
15922
60
        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
15923
60
        in  += WC_AES_BLOCK_SIZE;
15924
60
        out += WC_AES_BLOCK_SIZE;
15925
60
        sz  -= WC_AES_BLOCK_SIZE;
15926
15927
        /* Make buffer with end of cipher text | last */
15928
60
        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
15929
60
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
15930
0
            return BUFFER_E;
15931
0
        }
15932
60
        XMEMCPY(buf, in,   sz);
15933
60
        XMEMCPY(out, tmp2, sz);
15934
15935
60
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15936
60
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
15937
60
        if (ret != 0)
15938
0
            return ret;
15939
60
        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
15940
60
        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
15941
60
    }
15942
15943
234
    return ret;
15944
234
}
15945
#endif
15946
15947
/* Same process as encryption but Aes key is AES_DECRYPTION type.
15948
 *
15949
 * xaes  AES keys to use for block encrypt/decrypt
15950
 * out   output buffer to hold plain text
15951
 * in    input cipher text buffer to decrypt
15952
 * sz    size of both out and in buffers
15953
 * i     value to use for tweak
15954
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15955
 *       adds a sanity check on how the user calls the function.
15956
 *
15957
 * returns 0 on success
15958
 */
15959
int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15960
        const byte* i, word32 iSz)
15961
237
{
15962
237
    int ret;
15963
237
    Aes *aes;
15964
15965
237
    if (xaes == NULL || out == NULL || in == NULL) {
15966
0
        return BAD_FUNC_ARG;
15967
0
    }
15968
15969
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15970
    aes = &xaes->aes_decrypt;
15971
#else
15972
237
    aes = &xaes->aes;
15973
237
#endif
15974
15975
/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
15976
 * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
15977
 * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes or
15978
 * 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
15979
 * return whenever sz / WC_AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
15980
 * not a sequence of complete blocks.
15981
 */
15982
15983
237
    if (aes->keylen == 0) {
15984
0
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
15985
0
        return BAD_FUNC_ARG;
15986
0
    }
15987
15988
237
    if (iSz < WC_AES_BLOCK_SIZE) {
15989
0
        return BAD_FUNC_ARG;
15990
0
    }
15991
15992
237
    if (sz < WC_AES_BLOCK_SIZE) {
15993
3
        WOLFSSL_MSG("Cipher text input too small for decryption");
15994
3
        return BAD_FUNC_ARG;
15995
3
    }
15996
15997
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
15998
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15999
    AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
16000
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
16001
    ret = 0;
16002
#elif defined(WOLFSSL_AESNI)
16003
    if (aes->use_aesni) {
16004
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
16005
#if defined(HAVE_INTEL_AVX1)
16006
        if (IS_INTEL_AVX1(intel_flags)) {
16007
            AES_XTS_decrypt_avx1(in, out, sz, i,
16008
                                 (const byte*)aes->key,
16009
                                 (const byte*)xaes->tweak.key,
16010
                                 (int)aes->rounds);
16011
            ret = 0;
16012
        }
16013
        else
16014
#endif
16015
        {
16016
            AES_XTS_decrypt_aesni(in, out, sz, i,
16017
                                  (const byte*)aes->key,
16018
                                  (const byte*)xaes->tweak.key,
16019
                                  (int)aes->rounds);
16020
            ret = 0;
16021
        }
16022
        RESTORE_VECTOR_REGISTERS();
16023
    }
16024
    else {
16025
        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
16026
    }
16027
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16028
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16029
    if (aes->use_aes_hw_crypto) {
16030
        AES_XTS_decrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
16031
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
16032
        ret = 0;
16033
    }
16034
    else
16035
#endif
16036
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
16037
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16038
    if (sz >= 64)
16039
#endif
16040
    {
16041
        AES_XTS_decrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
16042
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
16043
        ret = 0;
16044
    }
16045
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16046
    else
16047
#endif
16048
#endif
16049
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16050
    {
16051
        AES_XTS_decrypt(in, out, sz, i, (byte*)xaes->aes.key,
16052
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
16053
        ret = 0;
16054
    }
16055
#endif
16056
#else
16057
234
    ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
16058
234
#endif
16059
16060
234
    return ret;
16061
237
}
16062
16063
#ifdef WOLFSSL_AESXTS_STREAM
16064
16065
/* Same process as encryption but Aes key is AES_DECRYPTION type.
16066
 *
16067
 * xaes  AES keys to use for block encrypt/decrypt
16068
 * i     readwrite value to use for tweak
16069
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
16070
 *       adds a sanity check on how the user calls the function.
16071
 *
16072
 * returns 0 on success
16073
 */
16074
int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
16075
                         struct XtsAesStreamData *stream)
16076
{
16077
    int ret;
16078
    Aes *aes;
16079
16080
    if (xaes == NULL) {
16081
        return BAD_FUNC_ARG;
16082
    }
16083
16084
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16085
    aes = &xaes->aes_decrypt;
16086
#else
16087
    aes = &xaes->aes;
16088
#endif
16089
16090
    if (aes->keylen == 0) {
16091
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
16092
        return BAD_FUNC_ARG;
16093
    }
16094
16095
    if (iSz < WC_AES_BLOCK_SIZE) {
16096
        return BAD_FUNC_ARG;
16097
    }
16098
16099
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
16100
    stream->bytes_crypted_with_this_tweak = 0;
16101
16102
    {
16103
#ifdef WOLFSSL_AESNI
16104
        if (aes->use_aesni) {
16105
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
16106
#if defined(HAVE_INTEL_AVX1)
16107
            if (IS_INTEL_AVX1(intel_flags)) {
16108
                AES_XTS_init_avx1(stream->tweak_block,
16109
                                  (const byte*)xaes->tweak.key,
16110
                                  (int)xaes->tweak.rounds);
16111
                ret = 0;
16112
            }
16113
            else
16114
#endif
16115
            {
16116
                AES_XTS_init_aesni(stream->tweak_block,
16117
                                   (const byte*)xaes->tweak.key,
16118
                                   (int)xaes->tweak.rounds);
16119
                ret = 0;
16120
            }
16121
            RESTORE_VECTOR_REGISTERS();
16122
        }
16123
        else
16124
#endif /* WOLFSSL_AESNI */
16125
        {
16126
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
16127
        }
16128
16129
    }
16130
16131
    return ret;
16132
}
16133
16134
/* Block-streaming AES-XTS
16135
 *
16136
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
16137
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsDecryptUpdate().
16138
 * wc_AesXtsDecryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
16139
 *
16140
 * xaes  AES keys to use for block encrypt/decrypt
16141
 * out   output buffer to hold plain text
16142
 * in    input cipher text buffer to decrypt
16143
 * sz    size of both out and in buffers
16144
 * i     tweak buffer of size WC_AES_BLOCK_SIZE.
16145
 *
16146
 * returns 0 on success
16147
 */
16148
static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16149
                           struct XtsAesStreamData *stream)
16150
{
16151
    int ret;
16152
#ifdef WOLFSSL_AESNI
16153
    Aes *aes;
16154
#endif
16155
16156
    if (xaes == NULL || out == NULL || in == NULL) {
16157
        return BAD_FUNC_ARG;
16158
    }
16159
16160
#ifdef WOLFSSL_AESNI
16161
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16162
    aes = &xaes->aes_decrypt;
16163
#else
16164
    aes = &xaes->aes;
16165
#endif
16166
#endif
16167
16168
    if (sz < WC_AES_BLOCK_SIZE) {
16169
        WOLFSSL_MSG("Cipher text input too small for decryption");
16170
        return BAD_FUNC_ARG;
16171
    }
16172
16173
    if (stream->bytes_crypted_with_this_tweak &
16174
        ((word32)WC_AES_BLOCK_SIZE - 1U))
16175
    {
16176
        WOLFSSL_MSG("AesXtsDecryptUpdate after previous finalizing call");
16177
        return BAD_FUNC_ARG;
16178
    }
16179
16180
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
16181
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
16182
                             stream->bytes_crypted_with_this_tweak))
16183
    {
16184
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
16185
                    "in AesXtsDecryptUpdate().");
16186
    }
16187
#endif
16188
16189
    {
16190
#ifdef WOLFSSL_AESNI
16191
        if (aes->use_aesni) {
16192
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
16193
#if defined(HAVE_INTEL_AVX1)
16194
            if (IS_INTEL_AVX1(intel_flags)) {
16195
                AES_XTS_decrypt_update_avx1(in, out, sz,
16196
                                            (const byte*)aes->key,
16197
                                            stream->tweak_block,
16198
                                            (int)aes->rounds);
16199
                ret = 0;
16200
            }
16201
            else
16202
#endif
16203
            {
16204
                AES_XTS_decrypt_update_aesni(in, out, sz,
16205
                                             (const byte*)aes->key,
16206
                                             stream->tweak_block,
16207
                                             (int)aes->rounds);
16208
                ret = 0;
16209
            }
16210
            RESTORE_VECTOR_REGISTERS();
16211
        }
16212
        else
16213
#endif /* WOLFSSL_AESNI */
16214
        {
16215
            ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
16216
                                         stream->tweak_block);
16217
        }
16218
    }
16219
16220
    return ret;
16221
}
16222
16223
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16224
                           struct XtsAesStreamData *stream)
16225
{
16226
    if (stream == NULL)
16227
        return BAD_FUNC_ARG;
16228
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
16229
        return BAD_FUNC_ARG;
16230
    return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
16231
}
16232
16233
int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16234
                           struct XtsAesStreamData *stream)
16235
{
16236
    int ret;
16237
    if (stream == NULL)
16238
        return BAD_FUNC_ARG;
16239
    if (sz > 0)
16240
        ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
16241
    else
16242
        ret = 0;
16243
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
16244
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
16245
     * after finalization.
16246
     */
16247
    stream->bytes_crypted_with_this_tweak |= 1U;
16248
#ifdef WOLFSSL_CHECK_MEM_ZERO
16249
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
16250
#endif
16251
    return ret;
16252
}
16253
16254
#endif /* WOLFSSL_AESXTS_STREAM */
16255
#endif /* HAVE_AES_DECRYPT */
16256
16257
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
16258
 * sectorSz bytes
16259
 *
16260
 * xaes     AES keys to use for block encrypt
16261
 * out      output buffer to hold cipher text
16262
 * in       input plain text buffer to encrypt
16263
 * sz       size of both out and in buffers
16264
 * sector   value to use for tweak
16265
 * sectorSz size of the sector
16266
 *
16267
 * returns 0 on success
16268
 */
16269
int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
16270
        word32 sz, word64 sector, word32 sectorSz)
16271
0
{
16272
0
    int ret  = 0;
16273
0
    word32 iter = 0;
16274
0
    word32 sectorCount;
16275
0
    word32 remainder;
16276
16277
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
16278
0
        return BAD_FUNC_ARG;
16279
0
    }
16280
16281
0
    if (sz < WC_AES_BLOCK_SIZE) {
16282
0
        WOLFSSL_MSG("Cipher text input too small for encryption");
16283
0
        return BAD_FUNC_ARG;
16284
0
    }
16285
16286
0
    sectorCount  = sz / sectorSz;
16287
0
    remainder = sz % sectorSz;
16288
16289
0
    while (sectorCount) {
16290
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
16291
0
                in + (iter * sectorSz), sectorSz, sector);
16292
0
        if (ret != 0)
16293
0
            break;
16294
16295
0
        sectorCount--;
16296
0
        iter++;
16297
0
        sector++;
16298
0
    }
16299
16300
0
    if (remainder && ret == 0)
16301
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
16302
0
                in + (iter * sectorSz), remainder, sector);
16303
16304
0
    return ret;
16305
0
}
16306
16307
#ifdef HAVE_AES_DECRYPT
16308
16309
/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
16310
 *
16311
 * xaes     AES keys to use for block decrypt
16312
 * out      output buffer to hold cipher text
16313
 * in       input plain text buffer to encrypt
16314
 * sz       size of both out and in buffers
16315
 * sector   value to use for tweak
16316
 * sectorSz size of the sector
16317
 *
16318
 * returns 0 on success
16319
 */
16320
int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
16321
        word32 sz, word64 sector, word32 sectorSz)
16322
0
{
16323
0
    int ret  = 0;
16324
0
    word32 iter = 0;
16325
0
    word32 sectorCount;
16326
0
    word32 remainder;
16327
16328
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
16329
0
        return BAD_FUNC_ARG;
16330
0
    }
16331
16332
0
    if (sz < WC_AES_BLOCK_SIZE) {
16333
0
        WOLFSSL_MSG("Cipher text input too small for decryption");
16334
0
        return BAD_FUNC_ARG;
16335
0
    }
16336
16337
0
    sectorCount  = sz / sectorSz;
16338
0
    remainder = sz % sectorSz;
16339
16340
0
    while (sectorCount) {
16341
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
16342
0
                in + (iter * sectorSz), sectorSz, sector);
16343
0
        if (ret != 0)
16344
0
            break;
16345
16346
0
        sectorCount--;
16347
0
        iter++;
16348
0
        sector++;
16349
0
    }
16350
16351
0
    if (remainder && ret == 0)
16352
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
16353
0
                in + (iter * sectorSz), remainder, sector);
16354
16355
0
    return ret;
16356
0
}
16357
#endif /* HAVE_AES_DECRYPT */
16358
#endif /* WOLFSSL_AES_XTS */
16359
16360
#ifdef WOLFSSL_CMAC
16361
16362
1.96k
int wc_local_CmacUpdateAes(struct Cmac *cmac, const byte* in, word32 inSz) {
16363
1.96k
    int ret = 0;
16364
1.96k
    Aes *aes = &cmac->aes;
16365
1.96k
#ifdef WC_AES_HAVE_PREFETCH_ARG
16366
1.96k
    int did_prefetches = 0;
16367
1.96k
#endif
16368
16369
1.96k
    VECTOR_REGISTERS_PUSH;
16370
16371
7.39k
    while ((ret == 0) && (inSz != 0)) {
16372
5.43k
        word32 add = min(inSz, WC_AES_BLOCK_SIZE - cmac->bufferSz);
16373
5.43k
        XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
16374
16375
5.43k
        cmac->bufferSz += add;
16376
5.43k
        inSz -= add;
16377
5.43k
        in += add;
16378
16379
5.43k
        if (cmac->bufferSz == WC_AES_BLOCK_SIZE && inSz != 0) {
16380
4.97k
            if (cmac->totalSz != 0) {
16381
4.87k
                xorbuf(cmac->buffer, cmac->digest, WC_AES_BLOCK_SIZE);
16382
4.87k
            }
16383
4.97k
            ret = AesEncrypt_preFetchOpt(aes, cmac->buffer,
16384
4.97k
                                            cmac->digest, &did_prefetches);
16385
4.97k
            if (ret == 0) {
16386
4.97k
                cmac->totalSz += WC_AES_BLOCK_SIZE;
16387
4.97k
                cmac->bufferSz = 0;
16388
4.97k
            }
16389
4.97k
        }
16390
5.43k
    }
16391
16392
1.96k
    VECTOR_REGISTERS_POP;
16393
16394
1.96k
    return ret;
16395
1.96k
}
16396
16397
#endif /* WOLFSSL_CMAC */
16398
16399
#ifdef WOLFSSL_AES_SIV
16400
16401
/*
16402
 * See RFC 5297 Section 2.4.
16403
 */
16404
static WARN_UNUSED_RESULT int S2V(
16405
    const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc,
16406
    const byte* nonce, word32 nonceSz, const byte* data,
16407
    word32 dataSz, byte* out)
16408
0
{
16409
0
#ifdef WOLFSSL_SMALL_STACK
16410
0
    byte* tmp[3] = {NULL, NULL, NULL};
16411
0
    int i;
16412
0
    Cmac* cmac;
16413
#else
16414
    byte tmp[3][WC_AES_BLOCK_SIZE];
16415
    Cmac cmac[1];
16416
#endif
16417
0
    word32 macSz = WC_AES_BLOCK_SIZE;
16418
0
    int ret = 0;
16419
0
    byte tmpi = 0;
16420
0
    word32 ai;
16421
0
    word32 zeroBytes;
16422
16423
0
#ifdef WOLFSSL_SMALL_STACK
16424
0
    for (i = 0; i < 3; ++i) {
16425
0
        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16426
0
        if (tmp[i] == NULL) {
16427
0
            ret = MEMORY_E;
16428
0
            break;
16429
0
        }
16430
0
    }
16431
0
    if (ret == 0)
16432
0
#endif
16433
16434
0
    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
16435
        /* See RFC 5297 Section 7. */
16436
0
        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
16437
0
                    " 126.");
16438
0
        ret = BAD_FUNC_ARG;
16439
0
    }
16440
16441
0
    if (ret == 0) {
16442
0
        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
16443
0
        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
16444
16445
0
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
16446
0
                                 key, keySz);
16447
0
    }
16448
16449
0
    if (ret == 0) {
16450
        /* Loop over authenticated associated data AD1..ADn */
16451
0
        for (ai = 0; ai < numAssoc; ++ai) {
16452
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
16453
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
16454
0
                                     assoc[ai].assocSz, key, keySz);
16455
0
            if (ret != 0)
16456
0
                break;
16457
0
            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
16458
0
            tmpi = (byte)(1 - tmpi);
16459
0
        }
16460
16461
        /* Add nonce as final AD. See RFC 5297 Section 3. */
16462
0
        if ((ret == 0) && (nonceSz > 0)) {
16463
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
16464
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
16465
0
                                     nonceSz, key, keySz);
16466
0
            if (ret == 0) {
16467
0
                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
16468
0
            }
16469
0
            tmpi = (byte)(1U - tmpi);
16470
0
        }
16471
16472
        /* For simplicity of the remaining code, make sure the "final" result
16473
           is always in tmp[0]. */
16474
0
        if (tmpi == 1) {
16475
0
            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
16476
0
        }
16477
0
    }
16478
16479
0
    if (ret == 0) {
16480
0
        if (dataSz >= WC_AES_BLOCK_SIZE) {
16481
16482
0
            WC_ALLOC_VAR_EX(cmac, Cmac, 1, NULL, DYNAMIC_TYPE_CMAC,
16483
0
                ret=MEMORY_E);
16484
0
            if (WC_VAR_OK(cmac))
16485
0
            {
16486
            #ifdef WOLFSSL_CHECK_MEM_ZERO
16487
                /* Aes part is checked by wc_AesFree. */
16488
                wc_MemZero_Add("wc_AesCmacGenerate cmac",
16489
                    ((unsigned char *)cmac) + sizeof(Aes),
16490
                    sizeof(Cmac) - sizeof(Aes));
16491
            #endif
16492
0
                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
16493
0
                       WC_AES_BLOCK_SIZE);
16494
0
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
16495
0
                if (ret == 0) {
16496
0
                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
16497
0
                }
16498
0
                if (ret == 0) {
16499
0
                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
16500
0
                }
16501
0
                if (ret == 0) {
16502
0
                    ret = wc_CmacFinal(cmac, out, &macSz);
16503
0
                }
16504
0
            }
16505
0
        #ifdef WOLFSSL_SMALL_STACK
16506
0
            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
16507
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
16508
            wc_MemZero_Check(cmac, sizeof(Cmac));
16509
        #endif
16510
0
        }
16511
0
        else {
16512
0
            XMEMCPY(tmp[2], data, dataSz);
16513
0
            tmp[2][dataSz] |= 0x80;
16514
0
            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
16515
0
            if (zeroBytes != 0) {
16516
0
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
16517
0
            }
16518
0
            ShiftAndXorRb(tmp[1], tmp[0]);
16519
0
            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
16520
0
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
16521
0
                                     keySz);
16522
0
        }
16523
0
    }
16524
16525
0
#ifdef WOLFSSL_SMALL_STACK
16526
0
    for (i = 0; i < 3; ++i) {
16527
0
        if (tmp[i] != NULL) {
16528
0
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
16529
0
        }
16530
0
    }
16531
0
#endif
16532
16533
0
    return ret;
16534
0
}
16535
16536
static WARN_UNUSED_RESULT int AesSivCipher(
16537
    const byte* key, word32 keySz, const AesSivAssoc* assoc,
16538
    word32 numAssoc, const byte* nonce, word32 nonceSz,
16539
    const byte* data, word32 dataSz, byte* siv, byte* out,
16540
    int enc)
16541
0
{
16542
0
    int ret = 0;
16543
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16544
0
    byte sivTmp[WC_AES_BLOCK_SIZE];
16545
16546
0
    if (key == NULL || siv == NULL || out == NULL) {
16547
0
        WOLFSSL_MSG("Bad parameter");
16548
0
        ret = BAD_FUNC_ARG;
16549
0
    }
16550
16551
0
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
16552
0
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
16553
0
        ret = BAD_FUNC_ARG;
16554
0
    }
16555
16556
0
    if (ret == 0) {
16557
0
        if (enc == 1) {
16558
0
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
16559
0
                      dataSz, sivTmp);
16560
0
            if (ret != 0) {
16561
0
                WOLFSSL_MSG("S2V failed.");
16562
0
            }
16563
0
            else {
16564
0
                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
16565
0
            }
16566
0
        }
16567
0
        else {
16568
0
            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
16569
0
        }
16570
0
    }
16571
16572
0
    if (ret == 0) {
16573
0
#ifdef WOLFSSL_SMALL_STACK
16574
0
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
16575
#else
16576
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16577
#endif
16578
0
        if (ret != 0) {
16579
0
            WOLFSSL_MSG("Failed to initialized AES object.");
16580
0
        }
16581
0
    }
16582
16583
0
    if (ret == 0 && dataSz > 0) {
16584
0
        sivTmp[12] &= 0x7f;
16585
0
        sivTmp[8] &= 0x7f;
16586
0
        ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
16587
0
                           AES_ENCRYPTION);
16588
0
        if (ret != 0) {
16589
0
            WOLFSSL_MSG("Failed to set key for AES-CTR.");
16590
0
        }
16591
0
        else {
16592
0
            ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
16593
0
            if (ret != 0) {
16594
0
                WOLFSSL_MSG("AES-CTR encryption failed.");
16595
0
            }
16596
0
        }
16597
0
    }
16598
16599
0
    if (ret == 0 && enc == 0) {
16600
0
        ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out, dataSz,
16601
0
                  sivTmp);
16602
0
        if (ret != 0) {
16603
0
            WOLFSSL_MSG("S2V failed.");
16604
0
        }
16605
16606
0
        if (ConstantCompare(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
16607
0
            WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
16608
0
            ret = AES_SIV_AUTH_E;
16609
0
        }
16610
0
    }
16611
16612
0
#ifdef WOLFSSL_SMALL_STACK
16613
0
    wc_AesDelete(aes, NULL);
16614
#else
16615
    wc_AesFree(aes);
16616
#endif
16617
16618
0
    ForceZero(sivTmp, sizeof(sivTmp));
16619
16620
0
    return ret;
16621
0
}
16622
16623
/*
16624
 * See RFC 5297 Section 2.6.
16625
 */
16626
int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
16627
                     word32 assocSz, const byte* nonce, word32 nonceSz,
16628
                     const byte* in, word32 inSz, byte* siv, byte* out)
16629
0
{
16630
0
    AesSivAssoc ad;
16631
0
    ad.assoc = assoc;
16632
0
    ad.assocSz = assocSz;
16633
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
16634
0
                        siv, out, 1);
16635
0
}
16636
16637
/*
16638
 * See RFC 5297 Section 2.7.
16639
 */
16640
int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
16641
                     word32 assocSz, const byte* nonce, word32 nonceSz,
16642
                     const byte* in, word32 inSz, byte* siv, byte* out)
16643
0
{
16644
0
    AesSivAssoc ad;
16645
0
    ad.assoc = assoc;
16646
0
    ad.assocSz = assocSz;
16647
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
16648
0
                        siv, out, 0);
16649
0
}
16650
16651
/*
16652
 * See RFC 5297 Section 2.6.
16653
 */
16654
int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
16655
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
16656
                        const byte* in, word32 inSz, byte* siv, byte* out)
16657
0
{
16658
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
16659
0
                        siv, out, 1);
16660
0
}
16661
16662
/*
16663
 * See RFC 5297 Section 2.7.
16664
 */
16665
int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
16666
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
16667
                        const byte* in, word32 inSz, byte* siv, byte* out)
16668
0
{
16669
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
16670
0
                        siv, out, 0);
16671
0
}
16672
16673
#endif /* WOLFSSL_AES_SIV */
16674
16675
#if defined(WOLFSSL_AES_EAX)
16676
16677
/*
16678
 * AES EAX one-shot API
16679
 * Encrypts input data and computes an auth tag over the input
16680
 * auth data and ciphertext
16681
 *
16682
 * Returns 0 on success
16683
 * Returns error code on failure
16684
 */
16685
int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
16686
                          const byte* in, word32 inSz,
16687
                          const byte* nonce, word32 nonceSz,
16688
                          /* output computed auth tag */
16689
                          byte* authTag, word32 authTagSz,
16690
                          /* input data to authenticate */
16691
                          const byte* authIn, word32 authInSz)
16692
{
16693
#if defined(WOLFSSL_SMALL_STACK)
16694
    AesEax *eax;
16695
#else
16696
    AesEax eax_mem;
16697
    AesEax *eax = &eax_mem;
16698
#endif
16699
    int ret;
16700
    int eaxInited = 0;
16701
16702
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
16703
                              || authTag == NULL || authIn == NULL) {
16704
        return BAD_FUNC_ARG;
16705
    }
16706
16707
#if defined(WOLFSSL_SMALL_STACK)
16708
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
16709
                                 NULL,
16710
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
16711
        return MEMORY_E;
16712
    }
16713
#endif
16714
16715
    if ((ret = wc_AesEaxInit(eax,
16716
                             key, keySz,
16717
                             nonce, nonceSz,
16718
                             authIn, authInSz)) != 0) {
16719
        goto cleanup;
16720
    }
16721
    eaxInited = 1;
16722
16723
    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
16724
        goto cleanup;
16725
    }
16726
16727
    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
16728
        goto cleanup;
16729
    }
16730
16731
cleanup:
16732
    if (eaxInited)
16733
        wc_AesEaxFree(eax);
16734
#if defined(WOLFSSL_SMALL_STACK)
16735
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
16736
#endif
16737
    return ret;
16738
}
16739
16740
16741
/*
16742
 * AES EAX one-shot API
16743
 * Decrypts and authenticates data against a supplied auth tag
16744
 *
16745
 * Returns 0 on success
16746
 * Returns error code on failure
16747
 */
16748
int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
16749
                          const byte* in, word32 inSz,
16750
                          const byte* nonce, word32 nonceSz,
16751
                          /* auth tag to verify against */
16752
                          const byte* authTag, word32 authTagSz,
16753
                          /* input data to authenticate */
16754
                          const byte* authIn, word32 authInSz)
16755
{
16756
#if defined(WOLFSSL_SMALL_STACK)
16757
    AesEax *eax;
16758
#else
16759
    AesEax eax_mem;
16760
    AesEax *eax = &eax_mem;
16761
#endif
16762
    int ret;
16763
    int eaxInited = 0;
16764
16765
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
16766
                              || authTag == NULL || authIn == NULL) {
16767
        return BAD_FUNC_ARG;
16768
    }
16769
16770
#if defined(WOLFSSL_SMALL_STACK)
16771
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
16772
                                 NULL,
16773
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
16774
        return MEMORY_E;
16775
    }
16776
#endif
16777
16778
    if ((ret = wc_AesEaxInit(eax,
16779
                             key, keySz,
16780
                             nonce, nonceSz,
16781
                             authIn, authInSz)) != 0) {
16782
16783
        goto cleanup;
16784
    }
16785
    eaxInited = 1;
16786
16787
    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
16788
        goto cleanup;
16789
    }
16790
16791
    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
16792
        goto cleanup;
16793
    }
16794
16795
cleanup:
16796
    if (eaxInited)
16797
        wc_AesEaxFree(eax);
16798
#if defined(WOLFSSL_SMALL_STACK)
16799
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
16800
#endif
16801
    return ret;
16802
}
16803
16804
16805
/*
16806
 * AES EAX Incremental API:
16807
 * Initializes an AES EAX encryption or decryption operation. This must be
16808
 * called before any other EAX APIs are used on the AesEax struct
16809
 *
16810
 * Returns 0 on success
16811
 * Returns error code on failure
16812
 */
16813
int  wc_AesEaxInit(AesEax* eax,
16814
                   const byte* key, word32 keySz,
16815
                   const byte* nonce, word32 nonceSz,
16816
                   const byte* authIn, word32 authInSz)
16817
{
16818
    int ret = 0;
16819
    word32 cmacSize;
16820
    int aesInited = 0;
16821
    int nonceCmacInited = 0;
16822
    int aadCmacInited = 0;
16823
16824
    if (eax == NULL || key == NULL ||  nonce == NULL) {
16825
        return BAD_FUNC_ARG;
16826
    }
16827
16828
    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
16829
16830
    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
16831
        goto out;
16832
    }
16833
    aesInited = 1;
16834
16835
    if ((ret = wc_AesSetKey(&eax->aes,
16836
                            key,
16837
                            keySz,
16838
                            NULL,
16839
                            AES_ENCRYPTION)) != 0) {
16840
        goto out;
16841
    }
16842
16843
    /*
16844
    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
16845
    *   N' = OMAC^0_K(N)
16846
    */
16847
    if ((ret = wc_InitCmac(&eax->nonceCmac,
16848
                           key,
16849
                           keySz,
16850
                           WC_CMAC_AES,
16851
                           NULL)) != 0) {
16852
        return ret;
16853
    }
16854
    nonceCmacInited = 1;
16855
16856
    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
16857
                             eax->prefixBuf,
16858
                             sizeof(eax->prefixBuf))) != 0) {
16859
        goto out;
16860
    }
16861
16862
    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
16863
        goto out;
16864
    }
16865
16866
    cmacSize = WC_AES_BLOCK_SIZE;
16867
    if ((ret = wc_CmacFinal(&eax->nonceCmac,
16868
                            eax->nonceCmacFinal,
16869
                            &cmacSize)) != 0) {
16870
        goto out;
16871
    }
16872
16873
    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
16874
        goto out;
16875
    }
16876
16877
    /*
16878
     * start the OMAC used to build the auth tag chunk for the AD .
16879
     * This CMAC is continued in subsequent update calls when more auth data is
16880
     * provided
16881
     *   H' = OMAC^1_K(H)
16882
     */
16883
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 1;
16884
    if ((ret = wc_InitCmac(&eax->aadCmac,
16885
                           key,
16886
                           keySz,
16887
                           WC_CMAC_AES,
16888
                           NULL)) != 0) {
16889
        goto out;
16890
    }
16891
    aadCmacInited = 1;
16892
16893
    if ((ret = wc_CmacUpdate(&eax->aadCmac,
16894
                             eax->prefixBuf,
16895
                             sizeof(eax->prefixBuf))) != 0) {
16896
        goto out;
16897
    }
16898
16899
    if (authIn != NULL) {
16900
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
16901
            goto out;
16902
        }
16903
    }
16904
16905
    /*
16906
     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
16907
     * updated in subsequent calls to encrypt/decrypt
16908
     *  C' = OMAC^2_K(C)
16909
     */
16910
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 2;
16911
    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
16912
                           key,
16913
                           keySz,
16914
                           WC_CMAC_AES,
16915
                           NULL)) != 0) {
16916
        goto out;
16917
    }
16918
16919
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
16920
                             eax->prefixBuf,
16921
                             sizeof(eax->prefixBuf))) != 0) {
16922
        goto out;
16923
    }
16924
16925
out:
16926
16927
    if (ret != 0) {
16928
        if (aesInited)
16929
            wc_AesFree(&eax->aes);
16930
        if (nonceCmacInited)
16931
            wc_CmacFree(&eax->nonceCmac);
16932
        if (aadCmacInited)
16933
            wc_CmacFree(&eax->aadCmac);
16934
    }
16935
16936
    return ret;
16937
}
16938
16939
16940
/*
16941
 * AES EAX Incremental API:
16942
 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
16943
 * the authentication stream
16944
 *
16945
 * Returns 0 on success
16946
 * Returns error code on failure
16947
 */
16948
int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
16949
                            const byte* in, word32 inSz,
16950
                            const byte* authIn, word32 authInSz)
16951
{
16952
    int ret;
16953
16954
    if (eax == NULL || out == NULL ||  in == NULL) {
16955
        return BAD_FUNC_ARG;
16956
    }
16957
16958
    /*
16959
     * Encrypt the plaintext using AES CTR
16960
     *  C = CTR(M)
16961
     */
16962
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
16963
        return ret;
16964
    }
16965
16966
    /*
16967
     * update OMAC with new ciphertext
16968
     *  C' = OMAC^2_K(C)
16969
     */
16970
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
16971
        return ret;
16972
    }
16973
16974
    /* If there exists new auth data, update the OMAC for that as well */
16975
    if (authIn != NULL) {
16976
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
16977
            return ret;
16978
        }
16979
    }
16980
16981
    return 0;
16982
}
16983
16984
16985
/*
16986
 * AES EAX Incremental API:
16987
 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
16988
 * the authentication stream
16989
 *
16990
 * Returns 0 on success
16991
 * Returns error code on failure
16992
 */
16993
int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
16994
                            const byte* in, word32 inSz,
16995
                            const byte* authIn, word32 authInSz)
16996
{
16997
    int ret;
16998
16999
    if (eax == NULL || out == NULL ||  in == NULL) {
17000
        return BAD_FUNC_ARG;
17001
    }
17002
17003
    /*
17004
     * Decrypt the plaintext using AES CTR
17005
     *  C = CTR(M)
17006
     */
17007
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
17008
        return ret;
17009
    }
17010
17011
    /*
17012
     * update OMAC with new ciphertext
17013
     *  C' = OMAC^2_K(C)
17014
     */
17015
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
17016
        return ret;
17017
    }
17018
17019
    /* If there exists new auth data, update the OMAC for that as well */
17020
    if (authIn != NULL) {
17021
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
17022
            return ret;
17023
        }
17024
    }
17025
17026
    return 0;
17027
}
17028
17029
17030
/*
17031
 * AES EAX Incremental API:
17032
 * Provides additional auth data information to the authentication
17033
 * stream for an authenticated encryption or decryption operation
17034
 *
17035
 * Returns 0 on success
17036
 * Returns error code on failure
17037
 */
17038
int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
17039
{
17040
    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
17041
}
17042
17043
17044
/*
17045
 * AES EAX Incremental API:
17046
 * Finalizes the authenticated encryption operation, computing the auth tag
17047
 * over previously supplied auth data and computed ciphertext
17048
 *
17049
 * Returns 0 on success
17050
 * Returns error code on failure
17051
 */
17052
int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
17053
{
17054
    word32 cmacSize;
17055
    int ret;
17056
    word32 i;
17057
17058
    if (eax == NULL || authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE) {
17059
        return BAD_FUNC_ARG;
17060
    }
17061
17062
    /* Complete the OMAC for the ciphertext */
17063
    cmacSize = WC_AES_BLOCK_SIZE;
17064
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
17065
                                  eax->ciphertextCmacFinal,
17066
                                  &cmacSize)) != 0) {
17067
        return ret;
17068
    }
17069
17070
    /* Complete the OMAC for auth data */
17071
    cmacSize = WC_AES_BLOCK_SIZE;
17072
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
17073
                                  eax->aadCmacFinal,
17074
                                  &cmacSize)) != 0) {
17075
        return ret;
17076
    }
17077
17078
    /*
17079
     * Concatenate all three auth tag chunks into the final tag, truncating
17080
     * at the specified tag length
17081
     *   T = Tag [first authTagSz bytes]
17082
     */
17083
    for (i = 0; i < authTagSz; i++) {
17084
        authTag[i] = eax->nonceCmacFinal[i]
17085
                    ^ eax->aadCmacFinal[i]
17086
                    ^ eax->ciphertextCmacFinal[i];
17087
    }
17088
17089
    return 0;
17090
}
17091
17092
17093
/*
17094
 * AES EAX Incremental API:
17095
 * Finalizes the authenticated decryption operation, computing the auth tag
17096
 * for the previously supplied auth data and cipher text and validating it
17097
 * against a provided auth tag
17098
 *
17099
 * Returns 0 on success
17100
 * Return error code for failure
17101
 */
17102
int wc_AesEaxDecryptFinal(AesEax* eax,
17103
                          const byte* authIn, word32 authInSz)
17104
{
17105
    int ret;
17106
    word32 i;
17107
    word32 cmacSize;
17108
17109
#if defined(WOLFSSL_SMALL_STACK)
17110
    byte *authTag;
17111
#else
17112
    byte authTag[WC_AES_BLOCK_SIZE];
17113
#endif
17114
17115
    if (eax == NULL || authIn == NULL || authInSz > WC_AES_BLOCK_SIZE) {
17116
        return BAD_FUNC_ARG;
17117
    }
17118
17119
    /* Complete the OMAC for the ciphertext */
17120
    cmacSize = WC_AES_BLOCK_SIZE;
17121
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
17122
                                  eax->ciphertextCmacFinal,
17123
                                  &cmacSize)) != 0) {
17124
        return ret;
17125
    }
17126
17127
    /* Complete the OMAC for auth data */
17128
    cmacSize = WC_AES_BLOCK_SIZE;
17129
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
17130
                                  eax->aadCmacFinal,
17131
                                  &cmacSize)) != 0) {
17132
        return ret;
17133
    }
17134
17135
#if defined(WOLFSSL_SMALL_STACK)
17136
    authTag = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17137
    if (authTag == NULL) {
17138
        return MEMORY_E;
17139
    }
17140
#endif
17141
17142
    /*
17143
     * Concatenate all three auth tag chunks into the final tag, truncating
17144
     * at the specified tag length
17145
     *   T = Tag [first authInSz bytes]
17146
     */
17147
    for (i = 0; i < authInSz; i++) {
17148
        authTag[i] = eax->nonceCmacFinal[i]
17149
                    ^ eax->aadCmacFinal[i]
17150
                    ^ eax->ciphertextCmacFinal[i];
17151
    }
17152
17153
    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
17154
        ret = AES_EAX_AUTH_E;
17155
    }
17156
    else {
17157
        ret = 0;
17158
    }
17159
17160
#if defined(WOLFSSL_SMALL_STACK)
17161
    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17162
#endif
17163
17164
    return ret;
17165
}
17166
17167
/*
17168
 * Frees the underlying CMAC and AES contexts. Must be called when done using
17169
 * the AES EAX context structure.
17170
 *
17171
 * Returns 0 on success
17172
 * Returns error code on failure
17173
 */
17174
int wc_AesEaxFree(AesEax* eax)
17175
{
17176
    if (eax == NULL) {
17177
        return BAD_FUNC_ARG;
17178
    }
17179
17180
    (void)wc_CmacFree(&eax->ciphertextCmac);
17181
    (void)wc_CmacFree(&eax->aadCmac);
17182
    wc_AesFree(&eax->aes);
17183
17184
    return 0;
17185
}
17186
17187
#endif /* WOLFSSL_AES_EAX */
17188
17189
#ifdef WOLFSSL_AES_CTS
17190
17191
17192
/* One-shot API */
17193
int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out,
17194
                     const byte* in, word32 inSz,
17195
                     const byte* iv)
17196
{
17197
    WC_DECLARE_VAR(aes, Aes, 1, 0);
17198
    int ret = 0;
17199
    word32 outSz = inSz;
17200
17201
    if (key == NULL || out == NULL || in == NULL || iv == NULL)
17202
        return BAD_FUNC_ARG;
17203
17204
#ifdef WOLFSSL_SMALL_STACK
17205
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
17206
#else
17207
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17208
#endif
17209
    if (ret == 0)
17210
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
17211
    if (ret == 0)
17212
        ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz);
17213
    if (ret == 0) {
17214
        out += outSz;
17215
        outSz = inSz - outSz;
17216
        ret = wc_AesCtsEncryptFinal(aes, out, &outSz);
17217
    }
17218
17219
#ifdef WOLFSSL_SMALL_STACK
17220
    wc_AesDelete(aes, NULL);
17221
#else
17222
    wc_AesFree(aes);
17223
#endif
17224
    return ret;
17225
}
17226
17227
int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out,
17228
                     const byte* in, word32 inSz,
17229
                     const byte* iv)
17230
{
17231
    WC_DECLARE_VAR(aes, Aes, 1, 0);
17232
    int ret = 0;
17233
    word32 outSz = inSz;
17234
17235
    if (key == NULL || out == NULL || in == NULL || iv == NULL) {
17236
        return BAD_FUNC_ARG;
17237
    }
17238
17239
#ifdef WOLFSSL_SMALL_STACK
17240
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
17241
#else
17242
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17243
#endif
17244
    if (ret == 0)
17245
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
17246
    if (ret == 0)
17247
        ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz);
17248
    if (ret == 0) {
17249
        out += outSz;
17250
        outSz = inSz - outSz;
17251
        ret = wc_AesCtsDecryptFinal(aes, out, &outSz);
17252
    }
17253
17254
#ifdef WOLFSSL_SMALL_STACK
17255
    wc_AesDelete(aes, NULL);
17256
#else
17257
    wc_AesFree(aes);
17258
#endif
17259
    return ret;
17260
}
17261
17262
static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz,
17263
                        const byte* in, word32 inSz, int enc)
17264
{
17265
    word32 blocks = 0;
17266
    int ret = 0;
17267
    word32 writtenSz = 0;
17268
    word32 tmpOutSz;
17269
17270
    if (aes == NULL || out == NULL || in == NULL || outSz == NULL)
17271
        return BAD_FUNC_ARG;
17272
17273
    /* Error out early for easy sanity check */
17274
    if (*outSz < inSz)
17275
        return BUFFER_E;
17276
    tmpOutSz = *outSz;
17277
17278
    /* We need to store last two blocks of plaintext */
17279
    if (aes->left > 0) {
17280
        word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left);
17281
        XMEMCPY(aes->ctsBlock + aes->left, in, copySz);
17282
        aes->left += copySz;
17283
        in += copySz;
17284
        inSz -= copySz;
17285
17286
        if (aes->left == WC_AES_BLOCK_SIZE * 2) {
17287
            if (inSz > WC_AES_BLOCK_SIZE) {
17288
                if (tmpOutSz < WC_AES_BLOCK_SIZE * 2)
17289
                    return BUFFER_E;
17290
                if (enc) {
17291
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
17292
                                           WC_AES_BLOCK_SIZE * 2);
17293
                }
17294
                else {
17295
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
17296
                                           WC_AES_BLOCK_SIZE * 2);
17297
                }
17298
                if (ret != 0)
17299
                    return ret;
17300
                out += WC_AES_BLOCK_SIZE * 2;
17301
                writtenSz += WC_AES_BLOCK_SIZE * 2;
17302
                tmpOutSz -= WC_AES_BLOCK_SIZE * 2;
17303
                aes->left = 0;
17304
            }
17305
            else if (inSz > 0) {
17306
                if (tmpOutSz < WC_AES_BLOCK_SIZE)
17307
                    return BUFFER_E;
17308
                if (enc) {
17309
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
17310
                                           WC_AES_BLOCK_SIZE);
17311
                }
17312
                else {
17313
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
17314
                                           WC_AES_BLOCK_SIZE);
17315
                }
17316
                if (ret != 0)
17317
                    return ret;
17318
                out += WC_AES_BLOCK_SIZE;
17319
                writtenSz += WC_AES_BLOCK_SIZE;
17320
                tmpOutSz -= WC_AES_BLOCK_SIZE;
17321
                /* Move the last block in ctsBlock to the beginning for
17322
                 * next operation */
17323
                XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE,
17324
                        WC_AES_BLOCK_SIZE);
17325
                XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz);
17326
                aes->left = WC_AES_BLOCK_SIZE + inSz;
17327
                *outSz = writtenSz;
17328
                return ret; /* Return the result of encryption */
17329
            }
17330
            else {
17331
                /* Can't output data as we need > 1 block for Final call */
17332
                *outSz = writtenSz;
17333
                return 0;
17334
            }
17335
        }
17336
        else {
17337
            /* All input has been absorbed into aes->ctsBlock */
17338
            *outSz = 0;
17339
            return 0;
17340
        }
17341
    }
17342
    if (inSz > WC_AES_BLOCK_SIZE) {
17343
        /* We need to store the last two full or partial blocks */
17344
        blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE;
17345
        blocks -= 2;
17346
    }
17347
    if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE)
17348
        return BUFFER_E;
17349
    if (enc)
17350
        ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
17351
    else
17352
        ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
17353
    in += blocks * WC_AES_BLOCK_SIZE;
17354
    inSz -= blocks * WC_AES_BLOCK_SIZE;
17355
    XMEMCPY(aes->ctsBlock, in, inSz);
17356
    aes->left = inSz;
17357
    writtenSz += blocks * WC_AES_BLOCK_SIZE;
17358
    *outSz = writtenSz;
17359
    return ret;
17360
}
17361
17362
/* Incremental API */
17363
int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz,
17364
                           const byte* in, word32 inSz)
17365
{
17366
    return AesCtsUpdate(aes, out, outSz, in, inSz, 1);
17367
}
17368
17369
int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz)
17370
{
17371
    int ret = 0;
17372
17373
    if (aes == NULL || out == NULL || outSz == NULL)
17374
        return BAD_FUNC_ARG;
17375
    if (*outSz < aes->left)
17376
        return BUFFER_E;
17377
17378
    /* Input must be at least two complete or partial blocks */
17379
    if (aes->left <= WC_AES_BLOCK_SIZE)
17380
        return BAD_FUNC_ARG;
17381
17382
    /* Zero padding */
17383
    XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left);
17384
17385
    ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock,
17386
                           WC_AES_BLOCK_SIZE * 2);
17387
    if (ret != 0)
17388
        return ret;
17389
17390
    XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
17391
    XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock,
17392
            aes->left - WC_AES_BLOCK_SIZE);
17393
    *outSz = aes->left;
17394
    return ret;
17395
}
17396
17397
int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz,
17398
                           const byte* in, word32 inSz)
17399
{
17400
    return AesCtsUpdate(aes, out, outSz, in, inSz, 0);
17401
}
17402
17403
int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz)
17404
{
17405
    int ret = 0;
17406
    byte iv[WC_AES_BLOCK_SIZE];
17407
    byte tmp[WC_AES_BLOCK_SIZE];
17408
    word32 partialSz;
17409
    word32 padSz;
17410
17411
    if (aes == NULL || out == NULL || outSz == NULL)
17412
        return BAD_FUNC_ARG;
17413
    if (*outSz < aes->left)
17414
        return BUFFER_E;
17415
17416
    /* Input must be at least two complete or partial blocks */
17417
    if (aes->left <= WC_AES_BLOCK_SIZE)
17418
        return BAD_FUNC_ARG;
17419
17420
    partialSz = aes->left - WC_AES_BLOCK_SIZE;
17421
    padSz = 2 * WC_AES_BLOCK_SIZE - aes->left;
17422
    /* Zero pad */
17423
    XMEMSET(aes->ctsBlock + aes->left, 0, padSz);
17424
17425
    /* Store IV */
17426
    XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE);
17427
    /* Load IV */
17428
    XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
17429
17430
    ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE);
17431
    if (ret != 0)
17432
        return ret;
17433
17434
    /* Write out partial block */
17435
    XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz);
17436
    /* Retrieve the padding */
17437
    XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz);
17438
    /* Restore IV */
17439
    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
17440
17441
    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE,
17442
                           WC_AES_BLOCK_SIZE);
17443
    if (ret != 0)
17444
        return ret;
17445
17446
    *outSz = aes->left;
17447
    return ret;
17448
}
17449
17450
#endif /* WOLFSSL_AES_CTS */
17451
17452
#endif /* !NO_AES */