Coverage Report

Created: 2026-07-16 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/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_AESGCM_SIV:      Enable AES-GCM-SIV (RFC 8452) mode    default: off
55
 * WOLFSSL_AES_EAX:         Enable AES-EAX AEAD mode              default: off
56
 * WOLFSSL_CMAC:            Enable AES-CMAC (RFC 4493)            default: off
57
 * HAVE_AESCCM:             Enable AES-CCM mode                   default: off
58
 * HAVE_AES_KEYWRAP:        Enable AES key wrap (RFC 3394)        default: off
59
 * WOLFSSL_AES_CBC_LENGTH_CHECKS: Validate CBC input length       default: off
60
 *
61
 * AES-GCM:
62
 * HAVE_AESGCM:             Enable AES-GCM mode                   default: off
63
 * HAVE_AESGCM_DECRYPT:     Enable AES-GCM decryption             default: on
64
 *                           (when HAVE_AESGCM is enabled)
65
 * WOLFSSL_AESGCM_STREAM:   Enable streaming AES-GCM API          default: off
66
 * WC_AES_GCM_DEC_AUTH_EARLY: Authenticate tag before decryption  default: off
67
 * GCM_SMALL:               Small GCM table, saves memory         default: off
68
 * GCM_TABLE:               Full 4-bit GCM lookup table, faster   default: off
69
 * GCM_TABLE_4BIT:          Explicit 4-bit GCM table mode         default: off
70
 * GCM_WORD32:              Use 32-bit word GCM implementation    default: off
71
 * GCM_GMULT_LEN:           GCM GMULT length optimization         default: off
72
 *
73
 * AES-XTS Stream:
74
 * WOLFSSL_AESXTS_STREAM:   Enable streaming AES-XTS API          default: off
75
 * WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING:
76
 *                           Disable XTS stream request accounting default: off
77
 * WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS:
78
 *                           Support both encrypt and decrypt keys default: off
79
 *                           simultaneously in XTS context
80
 *
81
 * Performance / Side-Channel:
82
 * WOLFSSL_AESNI:           Enable Intel AES-NI instructions      default: off
83
 * WOLFSSL_AESNI_BY4:       AES-NI 4-block parallel processing    default: off
84
 * WOLFSSL_AESNI_BY6:       AES-NI 6-block parallel processing    default: off
85
 * USE_INTEL_SPEEDUP:       Intel AVX/AVX2 for AES acceleration   default: off
86
 * USE_INTEL_SPEEDUP_FOR_AES:
87
                            Same as USE_INTEL_SPEEDUP, but scoped
88
                              to AES.                             default: off
89
 * WOLFSSL_AES_SMALL_TABLES: Use smaller AES S-box tables         default: off
90
 * WOLFSSL_AES_NO_UNROLL:   Disable AES round loop unrolling      default: off
91
 * WOLFSSL_AES_TOUCH_LINES: Touch all cache lines for             default: off
92
 *                           side-channel resistance
93
 * WC_AES_BITSLICED:        Use bitsliced AES implementation      default: off
94
 * AES_GCM_GMULT_NCT:       GCM GMULT non-constant-time          default: off
95
 * NO_WOLFSSL_ALLOC_ALIGN:  Disable aligned memory allocation     default: off
96
 *
97
 * Hardware Acceleration (AES-specific):
98
 * WC_ASYNC_ENABLE_AES:     Enable async AES operations           default: off
99
 * WOLFSSL_CRYPTOCELL_AES:  CryptoCell AES acceleration           default: off
100
 * WOLFSSL_DEVCRYPTO_AES:   /dev/crypto AES acceleration          default: off
101
 * WOLFSSL_DEVCRYPTO_CBC:   /dev/crypto AES-CBC acceleration      default: off
102
 * WOLFSSL_KCAPI_AES:       Linux kernel crypto API for AES       default: off
103
 * WOLFSSL_NO_KCAPI_AES_CBC: Disable KCAPI AES-CBC                default: off
104
 * WOLFSSL_NRF51_AES:       nRF51 hardware AES                    default: off
105
 * WOLFSSL_PSA_NO_AES:      Disable PSA AES                       default: off
106
 * WOLFSSL_SCE_NO_AES:      Disable Renesas SCE AES               default: off
107
 * NO_IMX6_CAAM_AES:        Disable i.MX6 CAAM AES               default: off
108
 * WOLFSSL_AFALG_XILINX_AES: AF_ALG Xilinx AES acceleration      default: off
109
 * NO_WOLFSSL_ESP32_CRYPT_AES: Disable ESP32 AES acceleration     default: off
110
 * STM32_CRYPTO_AES_ONLY:   STM32 AES-only crypto mode            default: off
111
 *
112
 * Debug:
113
 * WC_DEBUG_CIPHER_LIFECYCLE: Debug cipher init/free lifecycle     default: off
114
 * WOLFSSL_HW_METRICS:      Track hardware acceleration usage     default: off
115
 */
116
117
#define _WC_BUILDING_AES_C
118
119
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
120
121
#if !defined(NO_AES)
122
123
/* Tip: Locate the software cipher modes by searching for "Software AES" */
124
125
#if FIPS_VERSION3_GE(2,0,0)
126
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
127
    #define FIPS_NO_WRAPPERS
128
129
    #ifdef USE_WINDOWS_API
130
        #pragma code_seg(".fipsA$b")
131
        #pragma const_seg(".fipsB$b")
132
    #endif
133
#endif
134
135
#include <wolfssl/wolfcrypt/aes.h>
136
137
#ifdef WOLFSSL_AESNI
138
#include <wmmintrin.h>
139
#include <emmintrin.h>
140
#include <smmintrin.h>
141
#endif /* WOLFSSL_AESNI */
142
143
#include <wolfssl/wolfcrypt/cpuid.h>
144
145
#ifdef WOLF_CRYPTO_CB
146
    #include <wolfssl/wolfcrypt/cryptocb.h>
147
#endif
148
149
#ifdef WOLFSSL_NXP_HASHCRYPT_AES
150
    #include <wolfssl/wolfcrypt/port/nxp/hashcrypt_port.h>
151
#endif
152
153
#ifdef WOLFSSL_SECO_CAAM
154
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
155
#endif
156
157
#ifdef WOLFSSL_IMXRT_DCP
158
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
159
#endif
160
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
161
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
162
#endif
163
#ifdef WOLFSSL_MICROCHIP_TA100
164
    #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
165
#endif
166
#ifdef WOLFSSL_CMAC
167
    #include <wolfssl/wolfcrypt/cmac.h>
168
#endif
169
170
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
171
    #include <wolfssl/wolfcrypt/port/psa/psa.h>
172
#endif
173
174
#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
175
    #include <wolfssl/wolfcrypt/port/maxim/max3266x.h>
176
#ifdef MAX3266X_CB
177
    /* Revert back to SW so HW CB works */
178
    /* HW only works for AES: ECB, CBC, and partial via ECB for other modes */
179
    #include <wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h>
180
    /* Turn off MAX3266X_AES in the context of this file when using CB */
181
    #undef MAX3266X_AES
182
#endif
183
#endif
184
185
#if defined(WOLFSSL_TI_CRYPT)
186
    #include <wolfcrypt/src/port/ti/ti-aes.c>
187
188
    #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
189
        wc_AesEncryptDirect(aes, outBlock, inBlock)
190
    #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
191
        wc_AesDecryptDirect(aes, outBlock, inBlock)
192
#else
193
194
195
#if defined(WOLFSSL_PSOC6_CRYPTO)
196
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
197
#endif /* WOLFSSL_PSOC6_CRYPTO */
198
199
#ifdef NO_INLINE
200
    #include <wolfssl/wolfcrypt/misc.h>
201
#else
202
    #define WOLFSSL_MISC_INCLUDED
203
    #include <wolfcrypt/src/misc.c>
204
#endif
205
206
#if !defined(WOLFSSL_RISCV_ASM)
207
208
#ifdef WOLFSSL_IMX6_CAAM_BLOB
209
    /* case of possibly not using hardware acceleration for AES but using key
210
       blobs */
211
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
212
#endif
213
214
#ifdef DEBUG_AESNI
215
    #include <stdio.h>
216
#endif
217
218
#ifdef _MSC_VER
219
    /* 4127 warning constant while(1)  */
220
    #pragma warning(disable: 4127)
221
#endif
222
223
#if (!defined(WOLFSSL_ARMASM) && FIPS_VERSION3_GE(6,0,0)) || \
224
    FIPS_VERSION3_GE(7,0,0)
225
    const unsigned int wolfCrypt_FIPS_aes_ro_sanity[2] =
226
                                                     { 0x1a2b3c4d, 0x00000002 };
227
    int wolfCrypt_FIPS_AES_sanity(void)
228
    {
229
        return 0;
230
    }
231
#endif
232
233
/* Define AES implementation includes and functions */
234
#if defined(STM32_CRYPTO) && !defined(WOLF_CRYPTO_CB_ONLY_AES)
235
     /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
236
237
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
238
239
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
240
        Aes* aes, const byte* inBlock, byte* outBlock)
241
    {
242
    #ifdef WOLFSSL_STM32_BARE
243
        /* Bare-metal driver handles mutex, clock and key/IV internally.
244
         * DHUK is routed via the crypto-callback framework, not here. */
245
        return wc_Stm32_Aes_Ecb(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE, 1);
246
    #else
247
        int ret = 0;
248
    #ifdef WOLFSSL_STM32_CUBEMX
249
        CRYP_HandleTypeDef hcryp;
250
    #else
251
        CRYP_InitTypeDef cryptInit;
252
        CRYP_KeyInitTypeDef keyInit;
253
    #endif
254
255
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
256
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
257
        if (ret < 0)
258
            return ret;
259
#endif
260
261
    #if defined(WOLFSSL_STM32_CUBEMX)
262
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
263
        if (ret != 0)
264
            return ret;
265
266
        ret = wolfSSL_CryptHwMutexLock();
267
        if (ret != 0)
268
            return ret;
269
270
    #if defined(STM32_HAL_V2)
271
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
272
    #elif defined(STM32_CRYPTO_AES_ONLY)
273
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
274
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
275
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
276
    #endif
277
        if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
278
            ret = BAD_FUNC_ARG;
279
        }
280
281
        if (ret == 0) {
282
        #if defined(STM32_HAL_V2)
283
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
284
                (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
285
        #elif defined(STM32_CRYPTO_AES_ONLY)
286
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
287
                outBlock, STM32_HAL_TIMEOUT);
288
        #else
289
            ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
290
                outBlock, STM32_HAL_TIMEOUT);
291
        #endif
292
            if (ret != HAL_OK) {
293
                ret = WC_TIMEOUT_E;
294
            }
295
            HAL_CRYP_DeInit(&hcryp);
296
        }
297
298
    #else /* Standard Peripheral Library */
299
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
300
        if (ret != 0)
301
            return ret;
302
303
        ret = wolfSSL_CryptHwMutexLock();
304
        if (ret != 0)
305
            return ret;
306
307
        /* reset registers to their default values */
308
        CRYP_DeInit();
309
310
        /* setup key */
311
        CRYP_KeyInit(&keyInit);
312
313
        /* set direction and mode */
314
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
315
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
316
        CRYP_Init(&cryptInit);
317
318
        /* enable crypto processor */
319
        CRYP_Cmd(ENABLE);
320
321
        /* flush IN/OUT FIFOs */
322
        CRYP_FIFOFlush();
323
324
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
325
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
326
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
327
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
328
329
        /* wait until the complete message has been processed */
330
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
331
332
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
333
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
334
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
335
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
336
337
        /* disable crypto processor */
338
        CRYP_Cmd(DISABLE);
339
    #endif /* WOLFSSL_STM32_CUBEMX */
340
        wolfSSL_CryptHwMutexUnLock();
341
        wc_Stm32_Aes_Cleanup();
342
343
        return ret;
344
    #endif /* !WOLFSSL_STM32_BARE */
345
    }
346
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
347
348
#ifdef HAVE_AES_DECRYPT
349
    #if defined(WOLFSSL_AES_DIRECT)
350
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
351
        Aes* aes, const byte* inBlock, byte* outBlock)
352
    {
353
    #ifdef WOLFSSL_STM32_BARE
354
        /* DHUK is routed via the crypto-callback framework, not here. */
355
        return wc_Stm32_Aes_Ecb(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE, 0);
356
    #else
357
        int ret = 0;
358
    #ifdef WOLFSSL_STM32_CUBEMX
359
        CRYP_HandleTypeDef hcryp;
360
    #else
361
        CRYP_InitTypeDef cryptInit;
362
        CRYP_KeyInitTypeDef keyInit;
363
    #endif
364
365
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
366
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
367
        if (ret < 0)
368
            return ret;
369
#endif
370
371
    #if defined(WOLFSSL_STM32_CUBEMX)
372
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
373
        if (ret != 0)
374
            return ret;
375
376
        ret = wolfSSL_CryptHwMutexLock();
377
        if (ret != 0)
378
            return ret;
379
380
    #if defined(STM32_HAL_V2)
381
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
382
    #elif defined(STM32_CRYPTO_AES_ONLY)
383
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
384
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
385
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
386
    #endif
387
        HAL_CRYP_Init(&hcryp);
388
389
    #if defined(STM32_HAL_V2)
390
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
391
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
392
    #elif defined(STM32_CRYPTO_AES_ONLY)
393
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
394
            outBlock, STM32_HAL_TIMEOUT);
395
    #else
396
        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
397
            outBlock, STM32_HAL_TIMEOUT);
398
    #endif
399
        if (ret != HAL_OK) {
400
            ret = WC_TIMEOUT_E;
401
        }
402
        HAL_CRYP_DeInit(&hcryp);
403
404
    #else /* Standard Peripheral Library */
405
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
406
        if (ret != 0)
407
            return ret;
408
409
        ret = wolfSSL_CryptHwMutexLock();
410
        if (ret != 0)
411
            return ret;
412
413
        /* reset registers to their default values */
414
        CRYP_DeInit();
415
416
        /* set direction and key */
417
        CRYP_KeyInit(&keyInit);
418
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
419
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
420
        CRYP_Init(&cryptInit);
421
422
        /* enable crypto processor */
423
        CRYP_Cmd(ENABLE);
424
425
        /* wait until decrypt key has been initialized */
426
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
427
428
        /* set direction and mode */
429
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
430
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
431
        CRYP_Init(&cryptInit);
432
433
        /* enable crypto processor */
434
        CRYP_Cmd(ENABLE);
435
436
        /* flush IN/OUT FIFOs */
437
        CRYP_FIFOFlush();
438
439
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
440
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
441
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
442
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
443
444
        /* wait until the complete message has been processed */
445
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
446
447
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
448
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
449
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
450
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
451
452
        /* disable crypto processor */
453
        CRYP_Cmd(DISABLE);
454
    #endif /* WOLFSSL_STM32_CUBEMX */
455
        wolfSSL_CryptHwMutexUnLock();
456
        wc_Stm32_Aes_Cleanup();
457
458
        return ret;
459
    #endif /* !WOLFSSL_STM32_BARE */
460
    }
461
    #endif /* WOLFSSL_AES_DIRECT */
462
#endif /* HAVE_AES_DECRYPT */
463
464
#elif defined(HAVE_COLDFIRE_SEC)
465
    /* Freescale Coldfire SEC support for CBC mode.
466
     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
467
    #include "sec.h"
468
    #include "mcf5475_sec.h"
469
    #include "mcf5475_siu.h"
470
#elif defined(FREESCALE_LTC)
471
    #include "fsl_ltc.h"
472
    #if defined(FREESCALE_LTC_AES_GCM)
473
        #undef NEED_AES_TABLES
474
        #undef GCM_TABLE
475
    #endif
476
477
        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
478
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
479
            Aes* aes, const byte* inBlock, byte* outBlock)
480
        {
481
            word32 keySize = 0;
482
            byte* key = (byte*)aes->key;
483
            int ret = wc_AesGetKeySize(aes, &keySize);
484
            if (ret != 0)
485
                return ret;
486
487
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
488
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
489
            if (ret < 0)
490
                return ret;
491
#endif
492
493
            if (wolfSSL_CryptHwMutexLock() == 0) {
494
                LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
495
                    key, keySize);
496
                wolfSSL_CryptHwMutexUnLock();
497
            }
498
            return 0;
499
        }
500
        #ifdef HAVE_AES_DECRYPT
501
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
502
            Aes* aes, const byte* inBlock, byte* outBlock)
503
        {
504
            word32 keySize = 0;
505
            byte* key = (byte*)aes->key;
506
            int ret = wc_AesGetKeySize(aes, &keySize);
507
            if (ret != 0)
508
                return ret;
509
510
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
511
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
512
            if (ret < 0)
513
                return ret;
514
#endif
515
516
            if (wolfSSL_CryptHwMutexLock() == 0) {
517
                LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
518
                    key, keySize, kLTC_EncryptKey);
519
                wolfSSL_CryptHwMutexUnLock();
520
            }
521
            return 0;
522
        }
523
        #endif
524
525
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
526
527
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
528
529
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
530
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
531
        Aes* aes, const byte* inBlock, byte* outBlock)
532
    {
533
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
534
        {
535
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
536
            if (ret < 0)
537
                return ret;
538
        }
539
#endif
540
        /* Thread mutex protection handled in Pic32Crypto */
541
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
542
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
543
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
544
    }
545
    #endif
546
547
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
548
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
549
        Aes* aes, const byte* inBlock, byte* outBlock)
550
    {
551
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
552
        {
553
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
554
            if (ret < 0)
555
                return ret;
556
        }
557
#endif
558
        /* Thread mutex protection handled in Pic32Crypto */
559
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
560
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
561
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
562
    }
563
    #endif
564
565
#elif defined(WOLFSSL_NRF51_AES)
566
    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
567
    #include "wolfssl/wolfcrypt/port/nrf51.h"
568
569
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
570
        Aes* aes, const byte* inBlock, byte* outBlock)
571
    {
572
        int 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
        ret = wolfSSL_CryptHwMutexLock();
581
        if (ret == 0) {
582
            ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds,
583
                                    outBlock);
584
            wolfSSL_CryptHwMutexUnLock();
585
        }
586
        return ret;
587
    }
588
589
    #ifdef HAVE_AES_DECRYPT
590
        #error nRF51 AES Hardware does not support decrypt
591
    #endif /* HAVE_AES_DECRYPT */
592
593
#elif defined(WOLFSSL_ESP32_CRYPT) && \
594
     !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
595
    #include <esp_log.h>
596
    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
597
    #define TAG "aes"
598
599
    /* We'll use SW for fallback:
600
     *   unsupported key lengths. (e.g. ESP32-S3)
601
     *   chipsets not implemented.
602
     *   hardware busy. */
603
    #define NEED_AES_TABLES
604
    #define NEED_AES_HW_FALLBACK
605
    #define NEED_SOFTWARE_AES_SETKEY
606
    #undef  WOLFSSL_AES_DIRECT
607
    #define WOLFSSL_AES_DIRECT
608
609
    /* Encrypt: If we choose to never have a fallback to SW: */
610
    #if !defined(NEED_AES_HW_FALLBACK) && \
611
        (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
612
    /* calling this one when NO_AES_192 is defined */
613
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
614
        Aes* aes, const byte* inBlock, byte* outBlock)
615
    {
616
        int ret;
617
618
    #ifdef WC_DEBUG_CIPHER_LIFECYCLE
619
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
620
        if (ret < 0)
621
            return ret;
622
    #endif
623
624
        /* Thread mutex protection handled in esp_aes_hw_InUse */
625
    #ifdef NEED_AES_HW_FALLBACK
626
        if (wc_esp32AesSupportedKeyLen(aes)) {
627
            ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
628
        }
629
    #else
630
        ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
631
    #endif
632
        return ret;
633
    }
634
    #endif
635
636
    /* Decrypt: If we choose to never have a fallback to SW: */
637
    #if !defined(NEED_AES_HW_FALLBACK) && \
638
        (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
639
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
640
        Aes* aes, const byte* inBlock, byte* outBlock)
641
    {
642
        int ret = 0;
643
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
644
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
645
        if (ret < 0)
646
            return ret;
647
#endif
648
        /* Thread mutex protection handled in esp_aes_hw_InUse */
649
    #ifdef NEED_AES_HW_FALLBACK
650
        if (wc_esp32AesSupportedKeyLen(aes)) {
651
            ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
652
        }
653
        else {
654
            ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
655
        }
656
    #else
657
        /* if we don't need fallback, always use HW */
658
        ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
659
    #endif
660
        return ret;
661
    }
662
    #endif
663
664
#elif defined(WOLFSSL_AESNI)
665
666
    #define NEED_AES_TABLES
667
668
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
669
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
670
     */
671
672
    #ifndef AESNI_ALIGN
673
        #define AESNI_ALIGN 16
674
    #endif
675
676
    /* Accessed with the wolfSSL atomic APIs so the one-time detection is free of
677
     * data races.  Writes are also idempotent (all callers compute the same
678
     * value), so a benign concurrent double-write is harmless. */
679
    static wolfSSL_Atomic_Uint checkedAESNI = WOLFSSL_ATOMIC_INITIALIZER(0);
680
    static wolfSSL_Atomic_Uint haveAESNI = WOLFSSL_ATOMIC_INITIALIZER(0);
681
    static cpuid_flags_atomic_t intel_flags = WC_CPUID_ATOMIC_INITIALIZER;
682
683
    static WARN_UNUSED_RESULT int Check_CPU_support_AES(void)
684
    {
685
        cpuid_get_flags_atomic(&intel_flags);
686
687
        return IS_INTEL_AESNI(intel_flags) != 0;
688
    }
689
690
691
    /* tell C compiler these are asm functions in case any mix up of ABI underscore
692
       prefix between clang/gcc/llvm etc */
693
    #ifdef HAVE_AES_CBC
694
        void AES_CBC_encrypt_AESNI(const unsigned char* in, unsigned char* out,
695
                             unsigned char* ivec, unsigned long length,
696
                             const unsigned char* KS, int nr)
697
                             XASM_LINK("AES_CBC_encrypt_AESNI");
698
699
        #ifdef HAVE_AES_DECRYPT
700
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
701
                void AES_CBC_decrypt_AESNI_by4(const unsigned char* in, unsigned char* out,
702
                                         unsigned char* ivec, unsigned long length,
703
                                         const unsigned char* KS, int nr)
704
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by4");
705
            #elif defined(WOLFSSL_AESNI_BY6)
706
                void AES_CBC_decrypt_AESNI_by6(const unsigned char* in, unsigned char* out,
707
                                         unsigned char* ivec, unsigned long length,
708
                                         const unsigned char* KS, int nr)
709
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by6");
710
            #else /* WOLFSSL_AESNI_BYx */
711
                void AES_CBC_decrypt_AESNI_by8(const unsigned char* in, unsigned char* out,
712
                                         unsigned char* ivec, unsigned long length,
713
                                         const unsigned char* KS, int nr)
714
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by8");
715
            #endif /* WOLFSSL_AESNI_BYx */
716
        #endif /* HAVE_AES_DECRYPT */
717
    #endif /* HAVE_AES_CBC */
718
719
    void AES_ECB_encrypt_AESNI(const unsigned char* in, unsigned char* out,
720
                         unsigned long length, const unsigned char* KS, int nr)
721
                         XASM_LINK("AES_ECB_encrypt_AESNI");
722
723
    #ifdef HAVE_AES_DECRYPT
724
        void AES_ECB_decrypt_AESNI(const unsigned char* in, unsigned char* out,
725
                             unsigned long length, const unsigned char* KS, int nr)
726
                             XASM_LINK("AES_ECB_decrypt_AESNI");
727
    #endif
728
729
    void AES_128_Key_Expansion_AESNI(const unsigned char* userkey,
730
                               unsigned char* key_schedule)
731
                               XASM_LINK("AES_128_Key_Expansion_AESNI");
732
733
    void AES_192_Key_Expansion_AESNI(const unsigned char* userkey,
734
                               unsigned char* key_schedule)
735
                               XASM_LINK("AES_192_Key_Expansion_AESNI");
736
737
    void AES_256_Key_Expansion_AESNI(const unsigned char* userkey,
738
                               unsigned char* key_schedule)
739
                               XASM_LINK("AES_256_Key_Expansion_AESNI");
740
741
#ifdef WOLFSSL_X86_64_BUILD
742
    #if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
743
        #define USE_INTEL_SPEEDUP
744
    #endif
745
746
    /* Wide ECB / CBC / CTR variants for x86_64.  They share the AES-NI key
747
     * schedule declared above and are selected at runtime from intel_flags.
748
     * AES_CBC_decrypt_AESNI is the single max-width path (the by4/by6/by8
749
     * variants are only used by the 32-bit x86 build). */
750
    #if defined(USE_INTEL_SPEEDUP)
751
        #ifndef HAVE_INTEL_AVX1
752
            #define HAVE_INTEL_AVX1
753
        #endif
754
        #if !defined(NO_AVX2_SUPPORT) && !defined(HAVE_INTEL_AVX2)
755
            #define HAVE_INTEL_AVX2
756
        #endif
757
        #if !defined(NO_VAES_SUPPORT) && !defined(HAVE_INTEL_VAES)
758
            #define HAVE_INTEL_VAES
759
        #endif
760
        #if !defined(NO_AVX512_SUPPORT) && !defined(HAVE_INTEL_AVX512)
761
            #define HAVE_INTEL_AVX512
762
        #endif
763
764
        /* Below this threshold the narrower path (AVX1 / AES-NI) is faster on
765
         * Zen 4 than the wide VAES/AVX512 path.  Verify and tune
766
         * per-microarchecture.
767
         */
768
        #ifndef WC_VAES_MIN_BLOCKS
769
            #define WC_VAES_MIN_BLOCKS 8
770
        #elif WC_VAES_MIN_BLOCKS < 1
771
            #error Invalid WC_VAES_MIN_BLOCKS
772
        #endif
773
        /* ECB/CBC/CTR/XTS: the wide ladder handles 2+ blocks in parallel and
774
         * only caches round keys once it pays off (>= 32B), so the wide path
775
         * beats the single-block AES-NI fallback from 2 blocks up; a lone block
776
         * stays on AES-NI. (Measured +8..+58% at 2-6 blocks on Zen5.) */
777
        #ifndef WC_VAES_ECB_MIN_BLOCKS
778
            #define WC_VAES_ECB_MIN_BLOCKS 2
779
        #elif WC_VAES_ECB_MIN_BLOCKS < 1
780
            #error Invalid WC_VAES_ECB_MIN_BLOCKS
781
        #endif
782
        /* GCM one-shot: AVX2 faster than wide below this (layout/setup, not
783
         * amortization); pure GMAC (sz==0) routes to AVX2 by construction.
784
         */
785
        #ifndef WC_VAES_GCM_MIN_BLOCKS
786
            #define WC_VAES_GCM_MIN_BLOCKS WC_VAES_MIN_BLOCKS
787
        #elif WC_VAES_GCM_MIN_BLOCKS < 1
788
            #error Invalid WC_VAES_GCM_MIN_BLOCKS
789
        #endif
790
    #endif
791
792
    void AES_CTR_encrypt_AESNI(const unsigned char* in, unsigned char* out,
793
        unsigned long length, const unsigned char* KS, int nr,
794
        unsigned char* ctr) XASM_LINK("AES_CTR_encrypt_AESNI");
795
    #ifdef HAVE_AES_DECRYPT
796
    void AES_CBC_decrypt_AESNI(const unsigned char* in, unsigned char* out,
797
        unsigned char* ivec, unsigned long length, const unsigned char* KS,
798
        int nr) XASM_LINK("AES_CBC_decrypt_AESNI");
799
    #endif
800
801
    #define AES_DECL_VARIANT(suff)                                            \
802
        void AES_ECB_encrypt_##suff(const unsigned char* in,                  \
803
            unsigned char* out, unsigned long length,                         \
804
            const unsigned char* KS, int nr)                                  \
805
            XASM_LINK("AES_ECB_encrypt_" #suff);                              \
806
        void AES_CBC_encrypt_##suff(const unsigned char* in,                  \
807
            unsigned char* out, unsigned char* ivec, unsigned long length,    \
808
            const unsigned char* KS, int nr)                                  \
809
            XASM_LINK("AES_CBC_encrypt_" #suff);                              \
810
        void AES_CTR_encrypt_##suff(const unsigned char* in,                  \
811
            unsigned char* out, unsigned long length,                         \
812
            const unsigned char* KS, int nr, unsigned char* ctr)              \
813
            XASM_LINK("AES_CTR_encrypt_" #suff)
814
    #ifdef HAVE_AES_DECRYPT
815
        #define AES_DECL_VARIANT_DEC(suff)                                    \
816
            void AES_ECB_decrypt_##suff(const unsigned char* in,              \
817
                unsigned char* out, unsigned long length,                     \
818
                const unsigned char* KS, int nr)                              \
819
                XASM_LINK("AES_ECB_decrypt_" #suff);                          \
820
            void AES_CBC_decrypt_##suff(const unsigned char* in,              \
821
                unsigned char* out, unsigned char* ivec,                      \
822
                unsigned long length, const unsigned char* KS, int nr)        \
823
                XASM_LINK("AES_CBC_decrypt_" #suff)
824
    #else
825
        #define AES_DECL_VARIANT_DEC(suff) /* no decrypt */
826
    #endif
827
828
    #ifdef HAVE_INTEL_AVX1
829
        AES_DECL_VARIANT(avx1);
830
        AES_DECL_VARIANT_DEC(avx1);
831
    #endif
832
    #ifdef HAVE_INTEL_VAES
833
        AES_DECL_VARIANT(vaes);
834
        AES_DECL_VARIANT_DEC(vaes);
835
    #endif
836
    #ifdef HAVE_INTEL_AVX512
837
        AES_DECL_VARIANT(avx512);
838
        AES_DECL_VARIANT_DEC(avx512);
839
    #endif
840
841
    /* Pick the widest available implementation at runtime.  Callers must
842
     * already be inside a VECTOR_REGISTERS_PUSH / SAVE_VECTOR_REGISTERS
843
     * region (all bulk AES-NI call sites are). */
844
    #ifdef HAVE_AES_ECB
845
    static WC_INLINE void AesEcbEncryptBlocks(const unsigned char* in,
846
        unsigned char* out, word32 sz, const unsigned char* key, int nr)
847
    {
848
    #ifdef HAVE_INTEL_AVX512
849
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
850
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
851
            AES_ECB_encrypt_avx512(in, out, sz, key, nr);
852
        }
853
        else
854
    #endif
855
    #ifdef HAVE_INTEL_VAES
856
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
857
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
858
            AES_ECB_encrypt_vaes(in, out, sz, key, nr);
859
        }
860
        else
861
    #endif
862
    #ifdef HAVE_INTEL_AVX1
863
        if (IS_INTEL_AVX1(intel_flags)) {
864
            AES_ECB_encrypt_avx1(in, out, sz, key, nr);
865
        }
866
        else
867
    #endif
868
        {
869
            AES_ECB_encrypt_AESNI(in, out, sz, key, nr);
870
        }
871
    }
872
    #endif /* HAVE_AES_ECB */
873
874
    #if defined(HAVE_AES_ECB) && defined(HAVE_AES_DECRYPT)
875
    static WC_INLINE void AesEcbDecryptBlocks(const unsigned char* in,
876
        unsigned char* out, word32 sz, const unsigned char* key, int nr)
877
    {
878
    #ifdef HAVE_INTEL_AVX512
879
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
880
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
881
            AES_ECB_decrypt_avx512(in, out, sz, key, nr);
882
        }
883
        else
884
    #endif
885
    #ifdef HAVE_INTEL_VAES
886
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
887
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
888
            AES_ECB_decrypt_vaes(in, out, sz, key, nr);
889
        }
890
        else
891
    #endif
892
    #ifdef HAVE_INTEL_AVX1
893
        if (IS_INTEL_AVX1(intel_flags)) {
894
            AES_ECB_decrypt_avx1(in, out, sz, key, nr);
895
        }
896
        else
897
    #endif
898
        {
899
            AES_ECB_decrypt_AESNI(in, out, sz, key, nr);
900
        }
901
    }
902
    #endif /* HAVE_AES_ECB && HAVE_AES_DECRYPT */
903
904
    #ifdef HAVE_AES_CBC
905
    static WC_MAYBE_UNUSED WC_INLINE void AesCbcEncryptBlocks(const unsigned char* in,
906
        unsigned char* out, unsigned char* iv, word32 sz,
907
        const unsigned char* key, int nr)
908
    {
909
    #ifdef HAVE_INTEL_AVX512
910
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
911
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
912
            AES_CBC_encrypt_avx512(in, out, iv, sz, key, nr);
913
        }
914
        else
915
    #endif
916
    #ifdef HAVE_INTEL_VAES
917
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
918
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
919
            AES_CBC_encrypt_vaes(in, out, iv, sz, key, nr);
920
        }
921
        else
922
    #endif
923
    #ifdef HAVE_INTEL_AVX1
924
        if (IS_INTEL_AVX1(intel_flags)) {
925
            AES_CBC_encrypt_avx1(in, out, iv, sz, key, nr);
926
        }
927
        else
928
    #endif
929
        {
930
            AES_CBC_encrypt_AESNI(in, out, iv, sz, key, nr);
931
        }
932
    }
933
    #endif /* HAVE_AES_CBC */
934
935
    #ifdef HAVE_AES_DECRYPT
936
    static WC_MAYBE_UNUSED WC_INLINE void AesCbcDecryptBlocks(const unsigned char* in,
937
        unsigned char* out, unsigned char* iv, word32 sz,
938
        const unsigned char* key, int nr)
939
    {
940
    #ifdef HAVE_INTEL_AVX512
941
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
942
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
943
            AES_CBC_decrypt_avx512(in, out, iv, sz, key, nr);
944
        }
945
        else
946
    #endif
947
    #ifdef HAVE_INTEL_VAES
948
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
949
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
950
            AES_CBC_decrypt_vaes(in, out, iv, sz, key, nr);
951
        }
952
        else
953
    #endif
954
    #ifdef HAVE_INTEL_AVX1
955
        if (IS_INTEL_AVX1(intel_flags)) {
956
            AES_CBC_decrypt_avx1(in, out, iv, sz, key, nr);
957
        }
958
        else
959
    #endif
960
        {
961
            AES_CBC_decrypt_AESNI(in, out, iv, sz, key, nr);
962
        }
963
    }
964
    #endif /* HAVE_AES_DECRYPT */
965
966
    #ifdef WOLFSSL_AES_COUNTER
967
    static WC_INLINE void AesCtrEncryptBlocks(const unsigned char* in,
968
        unsigned char* out, word32 sz, const unsigned char* key, int nr,
969
        unsigned char* ctr)
970
    {
971
    #ifdef HAVE_INTEL_AVX512
972
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
973
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
974
            AES_CTR_encrypt_avx512(in, out, sz, key, nr, ctr);
975
        }
976
        else
977
    #endif
978
    #ifdef HAVE_INTEL_VAES
979
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
980
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
981
            AES_CTR_encrypt_vaes(in, out, sz, key, nr, ctr);
982
        }
983
        else
984
    #endif
985
    #ifdef HAVE_INTEL_AVX1
986
        if (IS_INTEL_AVX1(intel_flags)) {
987
            AES_CTR_encrypt_avx1(in, out, sz, key, nr, ctr);
988
        }
989
        else
990
    #endif
991
        {
992
            AES_CTR_encrypt_AESNI(in, out, sz, key, nr, ctr);
993
        }
994
    }
995
    #endif /* WOLFSSL_AES_COUNTER */
996
#endif /* WOLFSSL_X86_64_BUILD */
997
998
999
    static WARN_UNUSED_RESULT int AES_set_encrypt_key_AESNI(
1000
        const unsigned char *userKey, const int bits, Aes* aes)
1001
    {
1002
        int ret;
1003
1004
        ASSERT_SAVED_VECTOR_REGISTERS();
1005
1006
        if (!userKey || !aes)
1007
            return BAD_FUNC_ARG;
1008
1009
        switch (bits) {
1010
            case 128:
1011
               AES_128_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 10;
1012
               return 0;
1013
            case 192:
1014
               AES_192_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 12;
1015
               return 0;
1016
            case 256:
1017
               AES_256_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 14;
1018
               return 0;
1019
            default:
1020
                ret = BAD_FUNC_ARG;
1021
        }
1022
1023
        return ret;
1024
    }
1025
1026
    #ifdef HAVE_AES_DECRYPT
1027
        static WARN_UNUSED_RESULT int AES_set_decrypt_key_AESNI(
1028
            const unsigned char* userKey, const int bits, Aes* aes)
1029
        {
1030
            word32 nr;
1031
            WC_DECLARE_VAR(temp_key, Aes, 1, 0);
1032
            __m128i *Key_Schedule;
1033
            __m128i *Temp_Key_Schedule;
1034
1035
            ASSERT_SAVED_VECTOR_REGISTERS();
1036
1037
            if (!userKey || !aes)
1038
                return BAD_FUNC_ARG;
1039
1040
#ifdef WOLFSSL_SMALL_STACK
1041
            if ((temp_key = (Aes *)XMALLOC(sizeof *aes, aes->heap,
1042
                                           DYNAMIC_TYPE_AES)) == NULL)
1043
                return MEMORY_E;
1044
#endif
1045
1046
            if (AES_set_encrypt_key_AESNI(userKey,bits,temp_key)
1047
                == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
1048
                WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
1049
                return BAD_FUNC_ARG;
1050
            }
1051
1052
            Key_Schedule = (__m128i*)aes->key;
1053
            Temp_Key_Schedule = (__m128i*)temp_key->key;
1054
1055
            nr = temp_key->rounds;
1056
            aes->rounds = nr;
1057
1058
            Key_Schedule[nr] = Temp_Key_Schedule[0];
1059
            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
1060
            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
1061
            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
1062
            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
1063
            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
1064
            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
1065
            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
1066
            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
1067
            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
1068
1069
            if (nr>10) {
1070
                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
1071
                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
1072
            }
1073
1074
            if (nr>12) {
1075
                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
1076
                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
1077
            }
1078
1079
            Key_Schedule[0] = Temp_Key_Schedule[nr];
1080
1081
            WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
1082
1083
            return 0;
1084
        }
1085
    #endif /* HAVE_AES_DECRYPT */
1086
1087
#elif defined(WOLFSSL_ARMASM)
1088
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1089
static cpuid_flags_atomic_t cpuid_flags = WC_CPUID_ATOMIC_INITIALIZER;
1090
1091
static void Check_CPU_support_HwCrypto(Aes* aes)
1092
{
1093
    cpuid_get_flags_atomic(&cpuid_flags);
1094
    aes->use_aes_hw_crypto = IS_AARCH64_AES(cpuid_flags);
1095
#ifdef HAVE_AESGCM
1096
    aes->use_pmull_hw_crypto = IS_AARCH64_PMULL(cpuid_flags);
1097
    aes->use_sha3_hw_crypto = IS_AARCH64_SHA3(cpuid_flags);
1098
#endif
1099
}
1100
#endif /* __aarch64__ && !WOLFSSL_ARMASM_NO_HW_CRYPTO */
1101
1102
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
1103
    defined(WOLFSSL_AESGCM_STREAM) || defined(WOLFSSL_AESGCM_SIV)
1104
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
1105
    byte* outBlock)
1106
{
1107
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
1108
#if !defined(__aarch64__)
1109
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1110
#else
1111
    if (aes->use_aes_hw_crypto) {
1112
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
1113
           (int)aes->rounds);
1114
    }
1115
    else
1116
#endif /* !__aarch64__ */
1117
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
1118
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
1119
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
1120
    {
1121
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
1122
            (const unsigned char*)aes->key, aes->rounds);
1123
    }
1124
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1125
    {
1126
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1127
            (int)aes->rounds);
1128
    }
1129
#endif
1130
1131
    return 0;
1132
}
1133
#endif
1134
1135
#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1136
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
1137
    byte* outBlock)
1138
{
1139
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
1140
#if !defined(__aarch64__)
1141
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1142
#else
1143
    if (aes->use_aes_hw_crypto) {
1144
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
1145
            (int)aes->rounds);
1146
    }
1147
    else
1148
#endif /* !__aarch64__ */
1149
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
1150
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
1151
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
1152
    {
1153
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
1154
            (byte*)aes->key, (int)aes->rounds);
1155
    }
1156
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1157
    {
1158
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1159
            (int)aes->rounds);
1160
    }
1161
#endif
1162
    return 0;
1163
}
1164
#endif /* HAVE_AES_DECRYPT && WOLFSSL_AES_DIRECT */
1165
1166
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
1167
1168
#if defined(WOLFSSL_PPC64_ASM) && defined(WOLFSSL_PPC64_ASM_CRYPTO)
1169
/* POWER8+ has vector AES (vcipher/vncipher...) instructions.  When built in,
1170
 * select the "_crypto" implementations at run time if the CPU supports them.
1171
 *
1172
 * A run-time flag with direct calls is used rather than a function pointer: an
1173
 * indirect call would require an ELFv1 function descriptor, whereas direct
1174
 * calls work under both the ELFv1 and ELFv2 ABIs.  The dispatch is expressed as
1175
 * self-referential macros - the base name inside each macro is not re-expanded
1176
 * (C99 6.10.3.4), so it names the real base function.  In a PPC build the ARM
1177
 * branches that also call these names are #if'd out, so only the live PPC call
1178
 * sites are redirected. */
1179
1180
/* Resolved dispatch decision (0 = base, 1 = vector-crypto), accessed with the
1181
 * wolfSSL atomic APIs so the one-time detection is free of data races.  The
1182
 * master cpuid flags read by cpuid_get_flags() are themselves atomic; the write
1183
 * here is idempotent so a benign concurrent double-write is harmless. */
1184
static wolfSSL_Atomic_Uint aes_ppc64_use_crypto = WOLFSSL_ATOMIC_INITIALIZER(0);
1185
1186
/* True when the CPU supports the vector-crypto instructions. */
1187
#define AES_PPC64_USE_CRYPTO()   (WOLFSSL_ATOMIC_LOAD(aes_ppc64_use_crypto) != 0)
1188
1189
/* Check and set the decision together (as Check_CPU_support_AES/HwCrypto do);
1190
 * called from the key-setup path before any AES_*_crypto use. */
1191
static void Aes_SetCrypto(void)
1192
{
1193
    WOLFSSL_ATOMIC_STORE(aes_ppc64_use_crypto,
1194
        (unsigned int)(IS_PPC64_VEC_CRYPTO(cpuid_get_flags()) != 0));
1195
}
1196
1197
#define AES_set_encrypt_key(key, len, ks)                                     \
1198
    (AES_PPC64_USE_CRYPTO() ?                                               \
1199
        AES_set_encrypt_key_crypto((key), (len), (ks)) :                      \
1200
        AES_set_encrypt_key((key), (len), (ks)))
1201
#define AES_invert_key(ks, rounds)                                            \
1202
    (AES_PPC64_USE_CRYPTO() ?                                               \
1203
        AES_invert_key_crypto((ks), (rounds)) :                              \
1204
        AES_invert_key((ks), (rounds)))
1205
#define AES_ECB_encrypt(in, out, len, ks, nr)                                 \
1206
    (AES_PPC64_USE_CRYPTO() ?                                               \
1207
        AES_ECB_encrypt_crypto((in), (out), (len), (ks), (nr)) :              \
1208
        AES_ECB_encrypt((in), (out), (len), (ks), (nr)))
1209
#define AES_ECB_decrypt(in, out, len, ks, nr)                                 \
1210
    (AES_PPC64_USE_CRYPTO() ?                                               \
1211
        AES_ECB_decrypt_crypto((in), (out), (len), (ks), (nr)) :              \
1212
        AES_ECB_decrypt((in), (out), (len), (ks), (nr)))
1213
#define AES_CBC_encrypt(in, out, len, ks, nr, iv)                             \
1214
    (AES_PPC64_USE_CRYPTO() ?                                               \
1215
        AES_CBC_encrypt_crypto((in), (out), (len), (ks), (nr), (iv)) :        \
1216
        AES_CBC_encrypt((in), (out), (len), (ks), (nr), (iv)))
1217
#define AES_CBC_decrypt(in, out, len, ks, nr, iv)                             \
1218
    (AES_PPC64_USE_CRYPTO() ?                                               \
1219
        AES_CBC_decrypt_crypto((in), (out), (len), (ks), (nr), (iv)) :        \
1220
        AES_CBC_decrypt((in), (out), (len), (ks), (nr), (iv)))
1221
#define AES_CTR_encrypt(in, out, len, ks, nr, ctr)                            \
1222
    (AES_PPC64_USE_CRYPTO() ?                                               \
1223
        AES_CTR_encrypt_crypto((in), (out), (len), (ks), (nr), (ctr)) :       \
1224
        AES_CTR_encrypt((in), (out), (len), (ks), (nr), (ctr)))
1225
#define AES_GCM_encrypt(in, out, len, ks, nr, ctr)                            \
1226
    (AES_PPC64_USE_CRYPTO() ?                                               \
1227
        AES_GCM_encrypt_crypto((in), (out), (len), (ks), (nr), (ctr)) :       \
1228
        AES_GCM_encrypt((in), (out), (len), (ks), (nr), (ctr)))
1229
#if defined(WOLFSSL_AES_XTS)
1230
#define AES_XTS_encrypt(in, out, sz, i, key, key2, tmp, nr)                   \
1231
    (AES_PPC64_USE_CRYPTO() ?                                               \
1232
        AES_XTS_encrypt_crypto((in), (out), (sz), (i), (key), (key2), (tmp),  \
1233
            (nr)) :                                                           \
1234
        AES_XTS_encrypt((in), (out), (sz), (i), (key), (key2), (tmp), (nr)))
1235
#define AES_XTS_decrypt(in, out, sz, i, key, key2, tmp, nr)                   \
1236
    (AES_PPC64_USE_CRYPTO() ?                                               \
1237
        AES_XTS_decrypt_crypto((in), (out), (sz), (i), (key), (key2), (tmp),  \
1238
            (nr)) :                                                           \
1239
        AES_XTS_decrypt((in), (out), (sz), (i), (key), (key2), (tmp), (nr)))
1240
#endif /* WOLFSSL_AES_XTS */
1241
#else
1242
#define Aes_SetCrypto()                 WC_DO_NOTHING
1243
#endif /* WOLFSSL_PPC64_ASM && WOLFSSL_PPC64_ASM_CRYPTO */
1244
1245
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
1246
    defined(WOLFSSL_AESGCM_STREAM) || defined(HAVE_AESGCM)
1247
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
1248
    byte* outBlock)
1249
{
1250
    AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1251
        (int)aes->rounds);
1252
1253
    return 0;
1254
}
1255
#endif
1256
1257
#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1258
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
1259
    byte* outBlock)
1260
{
1261
    AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1262
        (int)aes->rounds);
1263
    return 0;
1264
}
1265
#endif /* HAVE_AES_DECRYPT && WOLFSSL_AES_DIRECT */
1266
1267
#elif defined(FREESCALE_MMCAU)
1268
    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
1269
     * through the CAU/mmCAU library. Documentation located in
1270
     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
1271
     * Guide (See note in README). */
1272
    #ifdef FREESCALE_MMCAU_CLASSIC
1273
        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
1274
        #include "cau_api.h"
1275
    #else
1276
        #include "fsl_mmcau.h"
1277
    #endif
1278
1279
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1280
        Aes* aes, const byte* inBlock, byte* outBlock)
1281
    {
1282
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1283
        {
1284
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1285
            if (ret < 0)
1286
                return ret;
1287
        }
1288
#endif
1289
1290
        if (wolfSSL_CryptHwMutexLock() == 0) {
1291
        #ifdef FREESCALE_MMCAU_CLASSIC
1292
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1293
                WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
1294
                return BAD_ALIGN_E;
1295
            }
1296
            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1297
        #else
1298
            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1299
                                 outBlock);
1300
        #endif
1301
            wolfSSL_CryptHwMutexUnLock();
1302
        }
1303
        return 0;
1304
    }
1305
    #ifdef HAVE_AES_DECRYPT
1306
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1307
        Aes* aes, const byte* inBlock, byte* outBlock)
1308
    {
1309
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1310
        {
1311
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1312
            if (ret < 0)
1313
                return ret;
1314
        }
1315
#endif
1316
        if (wolfSSL_CryptHwMutexLock() == 0) {
1317
        #ifdef FREESCALE_MMCAU_CLASSIC
1318
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1319
                WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
1320
                return BAD_ALIGN_E;
1321
            }
1322
            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1323
        #else
1324
            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1325
                                 outBlock);
1326
        #endif
1327
            wolfSSL_CryptHwMutexUnLock();
1328
        }
1329
        return 0;
1330
    }
1331
    #endif /* HAVE_AES_DECRYPT */
1332
1333
#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
1334
        && !defined(WOLFSSL_QNX_CAAM)) || \
1335
      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
1336
        defined(HAVE_AESCCM))
1337
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1338
            Aes* aes, const byte* inBlock, byte* outBlock)
1339
        {
1340
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1341
            {
1342
                int ret =
1343
                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1344
                if (ret < 0)
1345
                    return ret;
1346
            }
1347
#endif
1348
            return wc_AesEncryptDirect(aes, outBlock, inBlock);
1349
        }
1350
1351
#elif defined(WOLFSSL_AFALG)
1352
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
1353
1354
#elif defined(WOLFSSL_DEVCRYPTO_AES)
1355
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
1356
1357
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
1358
    #include "hal_data.h"
1359
1360
    #ifndef WOLFSSL_SCE_AES256_HANDLE
1361
        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
1362
    #endif
1363
1364
    #ifndef WOLFSSL_SCE_AES192_HANDLE
1365
        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
1366
    #endif
1367
1368
    #ifndef WOLFSSL_SCE_AES128_HANDLE
1369
        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
1370
    #endif
1371
1372
    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
1373
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1374
    {
1375
        word32 ret;
1376
1377
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1378
                CRYPTO_WORD_ENDIAN_BIG) {
1379
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1380
        }
1381
1382
        switch (aes->keylen) {
1383
        #ifdef WOLFSSL_AES_128
1384
            case AES_128_KEY_SIZE:
1385
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
1386
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
1387
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1388
                        (word32*)outBlock);
1389
                break;
1390
        #endif
1391
        #ifdef WOLFSSL_AES_192
1392
            case AES_192_KEY_SIZE:
1393
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
1394
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
1395
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1396
                        (word32*)outBlock);
1397
                break;
1398
        #endif
1399
        #ifdef WOLFSSL_AES_256
1400
            case AES_256_KEY_SIZE:
1401
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
1402
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
1403
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1404
                        (word32*)outBlock);
1405
                break;
1406
        #endif
1407
            default:
1408
                WOLFSSL_MSG("Unknown key size");
1409
                return BAD_FUNC_ARG;
1410
        }
1411
1412
        if (ret != SSP_SUCCESS) {
1413
            /* revert input */
1414
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1415
            return WC_HW_E;
1416
        }
1417
1418
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1419
                CRYPTO_WORD_ENDIAN_BIG) {
1420
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1421
            if (inBlock != outBlock) {
1422
                /* revert input */
1423
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1424
            }
1425
        }
1426
        return 0;
1427
    }
1428
1429
    #if defined(HAVE_AES_DECRYPT)
1430
    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
1431
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1432
    {
1433
        word32 ret;
1434
1435
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1436
                CRYPTO_WORD_ENDIAN_BIG) {
1437
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1438
        }
1439
1440
        switch (aes->keylen) {
1441
        #ifdef WOLFSSL_AES_128
1442
            case AES_128_KEY_SIZE:
1443
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
1444
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
1445
                        (sz / sizeof(word32)), (word32*)inBlock,
1446
                        (word32*)outBlock);
1447
                break;
1448
        #endif
1449
        #ifdef WOLFSSL_AES_192
1450
            case AES_192_KEY_SIZE:
1451
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
1452
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
1453
                        (sz / sizeof(word32)), (word32*)inBlock,
1454
                        (word32*)outBlock);
1455
                break;
1456
        #endif
1457
        #ifdef WOLFSSL_AES_256
1458
            case AES_256_KEY_SIZE:
1459
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
1460
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
1461
                        (sz / sizeof(word32)), (word32*)inBlock,
1462
                        (word32*)outBlock);
1463
                break;
1464
        #endif
1465
            default:
1466
                WOLFSSL_MSG("Unknown key size");
1467
                return BAD_FUNC_ARG;
1468
        }
1469
        if (ret != SSP_SUCCESS) {
1470
            return WC_HW_E;
1471
        }
1472
1473
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1474
                CRYPTO_WORD_ENDIAN_BIG) {
1475
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1476
            if (inBlock != outBlock) {
1477
                /* revert input */
1478
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1479
            }
1480
        }
1481
1482
        return 0;
1483
    }
1484
    #endif /* HAVE_AES_DECRYPT */
1485
1486
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
1487
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1488
        Aes* aes, const byte* inBlock, byte* outBlock)
1489
    {
1490
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1491
        {
1492
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1493
            if (ret < 0)
1494
                return ret;
1495
        }
1496
#endif
1497
        return AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1498
    }
1499
    #endif
1500
1501
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1502
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1503
        Aes* aes, const byte* inBlock, byte* outBlock)
1504
    {
1505
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1506
        {
1507
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1508
            if (ret < 0)
1509
                return ret;
1510
        }
1511
#endif
1512
        return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1513
    }
1514
    #endif
1515
1516
#elif defined(WOLFSSL_KCAPI_AES)
1517
    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
1518
    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
1519
        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1520
        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
1521
        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
1522
        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
1523
1524
        #define NEED_AES_TABLES
1525
    #endif
1526
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
1527
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
1528
1529
#elif defined(WOLFSSL_RISCV_ASM)
1530
/* implemented in wolfcrypt/src/port/riscv/riscv-64-aes.c */
1531
1532
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1533
/* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
1534
1535
#elif defined(WOLFSSL_PSOC6_CRYPTO)
1536
1537
    #if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
1538
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1539
            Aes* aes, const byte* inBlock, byte* outBlock)
1540
        {
1541
            return wc_Psoc6_Aes_Encrypt(aes, inBlock, outBlock);
1542
        }
1543
    #endif
1544
1545
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1546
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
1547
            Aes* aes, const byte* inBlock, byte* outBlock)
1548
        {
1549
            return wc_Psoc6_Aes_Decrypt(aes, inBlock, outBlock);
1550
        }
1551
1552
    #endif
1553
#elif defined(WOLF_CRYPTO_CB_ONLY_AES)
1554
    /* No software implementation AES T-tables, S-box, Rcon and the C key
1555
     * schedule are stripped. */
1556
#else
1557
1558
    /* using wolfCrypt software implementation */
1559
    #define NEED_AES_TABLES
1560
#endif
1561
1562
1563
1564
#if defined(WC_AES_BITSLICED) && !defined(HAVE_AES_ECB)
1565
    #error "When WC_AES_BITSLICED is defined, HAVE_AES_ECB is needed."
1566
#endif
1567
1568
#ifdef NEED_AES_TABLES
1569
1570
#ifndef WC_AES_BITSLICED
1571
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1572
#if !defined(WOLFSSL_ESP32_CRYPT) || \
1573
    (defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
1574
     defined(NEED_AES_HW_FALLBACK))
1575
#ifndef WOLFSSL_PPC64_ASM
1576
static const FLASH_QUALIFIER word32 rcon[] = {
1577
    0x01000000, 0x02000000, 0x04000000, 0x08000000,
1578
    0x10000000, 0x20000000, 0x40000000, 0x80000000,
1579
    0x1B000000, 0x36000000,
1580
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1581
};
1582
#endif
1583
#endif /* ESP32 */
1584
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1585
1586
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
1587
      defined(HAVE_AESCCM)
1588
#ifndef WOLFSSL_AES_SMALL_TABLES
1589
static const FLASH_QUALIFIER word32 Te[4][256] = {
1590
{
1591
    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1592
    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1593
    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1594
    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1595
    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1596
    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1597
    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1598
    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1599
    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1600
    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1601
    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1602
    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1603
    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1604
    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1605
    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1606
    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1607
    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1608
    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1609
    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1610
    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1611
    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1612
    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1613
    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1614
    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1615
    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1616
    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1617
    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1618
    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1619
    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1620
    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1621
    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1622
    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1623
    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1624
    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1625
    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1626
    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1627
    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1628
    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1629
    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1630
    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1631
    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1632
    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1633
    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1634
    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1635
    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1636
    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1637
    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1638
    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1639
    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1640
    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1641
    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1642
    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1643
    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1644
    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1645
    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1646
    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1647
    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1648
    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1649
    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1650
    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1651
    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1652
    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1653
    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1654
    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1655
},
1656
{
1657
    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1658
    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1659
    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1660
    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1661
    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1662
    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1663
    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1664
    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1665
    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1666
    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1667
    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1668
    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1669
    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1670
    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1671
    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1672
    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1673
    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1674
    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1675
    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1676
    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1677
    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1678
    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1679
    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1680
    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1681
    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1682
    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1683
    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1684
    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1685
    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1686
    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1687
    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1688
    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1689
    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1690
    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1691
    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1692
    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1693
    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1694
    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1695
    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1696
    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1697
    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1698
    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1699
    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1700
    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1701
    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1702
    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1703
    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1704
    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1705
    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1706
    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1707
    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1708
    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1709
    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1710
    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1711
    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1712
    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1713
    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1714
    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1715
    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1716
    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1717
    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1718
    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1719
    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1720
    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1721
},
1722
{
1723
    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1724
    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1725
    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1726
    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1727
    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1728
    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1729
    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1730
    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1731
    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1732
    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1733
    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1734
    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1735
    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1736
    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1737
    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1738
    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1739
    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1740
    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1741
    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1742
    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1743
    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1744
    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1745
    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1746
    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1747
    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1748
    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1749
    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1750
    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1751
    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1752
    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1753
    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1754
    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1755
    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1756
    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1757
    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1758
    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1759
    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1760
    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1761
    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1762
    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1763
    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1764
    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1765
    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1766
    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1767
    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1768
    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1769
    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1770
    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1771
    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1772
    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1773
    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1774
    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1775
    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1776
    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1777
    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1778
    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1779
    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1780
    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1781
    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1782
    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1783
    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1784
    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1785
    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1786
    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1787
},
1788
{
1789
    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1790
    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1791
    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1792
    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1793
    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1794
    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1795
    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1796
    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1797
    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1798
    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1799
    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1800
    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1801
    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1802
    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1803
    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1804
    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1805
    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1806
    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1807
    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1808
    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1809
    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1810
    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1811
    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1812
    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1813
    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1814
    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1815
    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1816
    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1817
    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1818
    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1819
    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1820
    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1821
    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1822
    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1823
    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1824
    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1825
    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1826
    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1827
    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1828
    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1829
    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1830
    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1831
    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1832
    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1833
    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1834
    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1835
    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1836
    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1837
    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1838
    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1839
    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1840
    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1841
    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1842
    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1843
    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1844
    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1845
    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1846
    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1847
    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1848
    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1849
    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1850
    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1851
    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1852
    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1853
}
1854
};
1855
1856
#ifdef HAVE_AES_DECRYPT
1857
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1858
static const FLASH_QUALIFIER word32 Td[4][256] = {
1859
{
1860
    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1861
    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1862
    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1863
    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1864
    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1865
    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1866
    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1867
    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1868
    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1869
    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1870
    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1871
    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1872
    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1873
    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1874
    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1875
    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1876
    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1877
    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1878
    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1879
    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1880
    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1881
    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1882
    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1883
    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1884
    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1885
    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1886
    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1887
    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1888
    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1889
    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1890
    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1891
    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1892
    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1893
    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1894
    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1895
    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1896
    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1897
    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1898
    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1899
    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1900
    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1901
    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1902
    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1903
    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1904
    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1905
    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1906
    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1907
    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1908
    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1909
    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1910
    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1911
    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1912
    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1913
    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1914
    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1915
    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1916
    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1917
    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1918
    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1919
    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1920
    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1921
    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1922
    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1923
    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1924
},
1925
{
1926
    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
1927
    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
1928
    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
1929
    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
1930
    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
1931
    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
1932
    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
1933
    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
1934
    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
1935
    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
1936
    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
1937
    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
1938
    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
1939
    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
1940
    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
1941
    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
1942
    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
1943
    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
1944
    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
1945
    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
1946
    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
1947
    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
1948
    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
1949
    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
1950
    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
1951
    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
1952
    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
1953
    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
1954
    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
1955
    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
1956
    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
1957
    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
1958
    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
1959
    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
1960
    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
1961
    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
1962
    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
1963
    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
1964
    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
1965
    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
1966
    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
1967
    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
1968
    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
1969
    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
1970
    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
1971
    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
1972
    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
1973
    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
1974
    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
1975
    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
1976
    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
1977
    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
1978
    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
1979
    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
1980
    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
1981
    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
1982
    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
1983
    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
1984
    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
1985
    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
1986
    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
1987
    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
1988
    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
1989
    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
1990
},
1991
{
1992
    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
1993
    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
1994
    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
1995
    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
1996
    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
1997
    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
1998
    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
1999
    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
2000
    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
2001
    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
2002
    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
2003
    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
2004
    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
2005
    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
2006
    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
2007
    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
2008
    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
2009
    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
2010
    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
2011
    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
2012
2013
    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
2014
    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
2015
    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
2016
    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
2017
    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
2018
    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
2019
    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
2020
    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
2021
    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
2022
    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
2023
    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
2024
    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
2025
    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
2026
    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
2027
    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
2028
    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
2029
    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
2030
    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
2031
    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
2032
    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
2033
    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
2034
    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
2035
    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
2036
    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
2037
    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
2038
    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
2039
    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
2040
    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
2041
    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
2042
    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
2043
    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
2044
    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
2045
    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
2046
    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
2047
    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
2048
    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
2049
    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
2050
    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
2051
    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
2052
    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
2053
    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
2054
    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
2055
    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
2056
    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
2057
},
2058
{
2059
    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
2060
    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
2061
    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
2062
    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
2063
    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
2064
    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
2065
    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
2066
    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
2067
    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
2068
    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
2069
    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
2070
    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
2071
    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
2072
    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
2073
    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
2074
    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
2075
    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
2076
    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
2077
    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
2078
    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
2079
    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
2080
    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
2081
    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
2082
    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
2083
    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
2084
    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
2085
    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
2086
    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
2087
    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
2088
    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
2089
    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
2090
    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
2091
    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
2092
    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
2093
    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
2094
    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
2095
    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
2096
    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
2097
    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
2098
    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
2099
    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
2100
    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
2101
    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
2102
    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
2103
    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
2104
    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
2105
    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
2106
    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
2107
    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
2108
    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
2109
    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
2110
    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
2111
    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
2112
    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
2113
    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
2114
    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
2115
    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
2116
    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
2117
    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
2118
    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
2119
    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
2120
    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
2121
    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
2122
    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
2123
}
2124
};
2125
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
2126
#endif /* HAVE_AES_DECRYPT */
2127
#endif /* WOLFSSL_AES_SMALL_TABLES */
2128
2129
#ifdef HAVE_AES_DECRYPT
2130
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
2131
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)
2132
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
2133
static const FLASH_QUALIFIER byte Td4[256] =
2134
{
2135
    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
2136
    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
2137
    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
2138
    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
2139
    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
2140
    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
2141
    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
2142
    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
2143
    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
2144
    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
2145
    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
2146
    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
2147
    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
2148
    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
2149
    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
2150
    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
2151
    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
2152
    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
2153
    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
2154
    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
2155
    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
2156
    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
2157
    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
2158
    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
2159
    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
2160
    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
2161
    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
2162
    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
2163
    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
2164
    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
2165
    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
2166
    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
2167
};
2168
#endif
2169
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
2170
#endif /* HAVE_AES_DECRYPT */
2171
2172
#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
2173
2174
#ifdef WOLFSSL_AES_SMALL_TABLES
2175
static const byte Tsbox[256] = {
2176
    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
2177
    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
2178
    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
2179
    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
2180
    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
2181
    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
2182
    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
2183
    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
2184
    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
2185
    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
2186
    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
2187
    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
2188
    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
2189
    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
2190
    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
2191
    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
2192
    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
2193
    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
2194
    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
2195
    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
2196
    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
2197
    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
2198
    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
2199
    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
2200
    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
2201
    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
2202
    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
2203
    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
2204
    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
2205
    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
2206
    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
2207
    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
2208
};
2209
2210
#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
2211
2212
static WARN_UNUSED_RESULT word32 col_mul(
2213
    word32 t, int i2, int i3, int ia, int ib)
2214
{
2215
    byte t3 = GETBYTE(t, i3);
2216
    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
2217
2218
    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
2219
}
2220
2221
#if defined(HAVE_AES_DECRYPT) && \
2222
    (defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
2223
     defined(WOLFSSL_AES_DIRECT))
2224
static WARN_UNUSED_RESULT word32 inv_col_mul(
2225
    word32 t, int i9, int ib, int id, int ie)
2226
{
2227
    byte t9 = GETBYTE(t, i9);
2228
    byte tb = GETBYTE(t, ib);
2229
    byte td = GETBYTE(t, id);
2230
    byte te = GETBYTE(t, ie);
2231
    byte t0 = t9 ^ tb ^ td;
2232
    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
2233
}
2234
#endif /* HAVE_AES_DECRYPT && (HAVE_AES_CBC || HAVE_AES_ECB || WOLFSSL_AES_DIRECT) */
2235
#endif /* WOLFSSL_AES_SMALL_TABLES */
2236
#endif
2237
#endif
2238
2239
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
2240
                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
2241
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
2242
      defined(HAVE_AESCCM)
2243
2244
2245
#ifndef WC_AES_BITSLICED
2246
2247
#ifndef WC_CACHE_LINE_SZ
2248
    #if defined(__x86_64__) || defined(_M_X64) || \
2249
       (defined(__ILP32__) && (__ILP32__ >= 1))
2250
0
        #define WC_CACHE_LINE_SZ 64
2251
    #else
2252
        /* default cache line size */
2253
        #define WC_CACHE_LINE_SZ 32
2254
    #endif
2255
#endif
2256
2257
#ifndef WC_NO_CACHE_RESISTANT
2258
2259
#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
2260
    #define WOLFSSL_AES_TOUCH_LINES
2261
#endif
2262
2263
#ifndef WOLFSSL_AES_SMALL_TABLES
2264
/* load 4 Te Tables into cache by cache line stride */
2265
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
2266
0
{
2267
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2268
0
    volatile word32 x = 0;
2269
0
    int i;
2270
0
    int j;
2271
2272
0
    for (i = 0; i < 4; i++) {
2273
        /* 256 elements, each one is 4 bytes */
2274
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
2275
0
            x &= Te[i][j];
2276
0
        }
2277
0
    }
2278
2279
0
    return x;
2280
#else
2281
    return 0;
2282
#endif
2283
0
}
2284
#else
2285
/* load sbox into cache by cache line stride */
2286
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
2287
{
2288
#ifndef WOLFSSL_AES_TOUCH_LINES
2289
    volatile word32 x = 0;
2290
    int i;
2291
2292
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
2293
        x &= Tsbox[i];
2294
    }
2295
2296
    return x;
2297
#else
2298
    return 0;
2299
#endif
2300
}
2301
#endif
2302
#endif
2303
2304
#ifdef WOLFSSL_AES_TOUCH_LINES
2305
#if WC_CACHE_LINE_SZ == 128
2306
    #define WC_CACHE_LINE_BITS      5
2307
    #define WC_CACHE_LINE_MASK_HI   0xe0
2308
    #define WC_CACHE_LINE_MASK_LO   0x1f
2309
    #define WC_CACHE_LINE_ADD       0x20
2310
#elif WC_CACHE_LINE_SZ == 64
2311
    #define WC_CACHE_LINE_BITS      4
2312
    #define WC_CACHE_LINE_MASK_HI   0xf0
2313
    #define WC_CACHE_LINE_MASK_LO   0x0f
2314
    #define WC_CACHE_LINE_ADD       0x10
2315
#elif WC_CACHE_LINE_SZ == 32
2316
    #define WC_CACHE_LINE_BITS      3
2317
    #define WC_CACHE_LINE_MASK_HI   0xf8
2318
    #define WC_CACHE_LINE_MASK_LO   0x07
2319
    #define WC_CACHE_LINE_ADD       0x08
2320
#elif WC_CACHE_LINE_SZ == 16
2321
    #define WC_CACHE_LINE_BITS      2
2322
    #define WC_CACHE_LINE_MASK_HI   0xfc
2323
    #define WC_CACHE_LINE_MASK_LO   0x03
2324
    #define WC_CACHE_LINE_ADD       0x04
2325
#else
2326
    #error Cache line size not supported
2327
#endif
2328
2329
#ifndef WOLFSSL_AES_SMALL_TABLES
2330
static word32 GetTable(const word32* t, byte o)
2331
{
2332
#if WC_CACHE_LINE_SZ == 64
2333
    word32 e;
2334
    byte hi = o & 0xf0;
2335
    byte lo = o & 0x0f;
2336
2337
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2338
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2339
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2340
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2341
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2342
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2343
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2344
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2345
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2346
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2347
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2348
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2349
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2350
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2351
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2352
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2353
2354
    return e;
2355
#else
2356
    word32 e = 0;
2357
    int i;
2358
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2359
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2360
2361
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2362
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2363
        hi -= WC_CACHE_LINE_ADD;
2364
    }
2365
2366
    return e;
2367
#endif
2368
}
2369
#endif
2370
2371
#ifdef WOLFSSL_AES_SMALL_TABLES
2372
static byte GetTable8(const byte* t, byte o)
2373
{
2374
#if WC_CACHE_LINE_SZ == 64
2375
    byte e;
2376
    byte hi = o & 0xf0;
2377
    byte lo = o & 0x0f;
2378
2379
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2380
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2381
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2382
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2383
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2384
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2385
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2386
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2387
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2388
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2389
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2390
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2391
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2392
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2393
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2394
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2395
2396
    return e;
2397
#else
2398
    byte e = 0;
2399
    int i;
2400
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2401
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2402
2403
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2404
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2405
        hi -= WC_CACHE_LINE_ADD;
2406
    }
2407
2408
    return e;
2409
#endif
2410
}
2411
#endif
2412
2413
#ifndef WOLFSSL_AES_SMALL_TABLES
2414
static void GetTable_Multi(const word32* t, word32* t0, byte o0,
2415
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2416
{
2417
    word32 e0 = 0;
2418
    word32 e1 = 0;
2419
    word32 e2 = 0;
2420
    word32 e3 = 0;
2421
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2422
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2423
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2424
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2425
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2426
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2427
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2428
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2429
    int i;
2430
2431
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2432
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2433
        hi0 -= WC_CACHE_LINE_ADD;
2434
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2435
        hi1 -= WC_CACHE_LINE_ADD;
2436
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2437
        hi2 -= WC_CACHE_LINE_ADD;
2438
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2439
        hi3 -= WC_CACHE_LINE_ADD;
2440
    }
2441
    *t0 = e0;
2442
    *t1 = e1;
2443
    *t2 = e2;
2444
    *t3 = e3;
2445
}
2446
static void XorTable_Multi(const word32* t, word32* t0, byte o0,
2447
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2448
{
2449
    word32 e0 = 0;
2450
    word32 e1 = 0;
2451
    word32 e2 = 0;
2452
    word32 e3 = 0;
2453
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2454
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2455
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2456
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2457
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2458
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2459
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2460
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2461
    int i;
2462
2463
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2464
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2465
        hi0 -= WC_CACHE_LINE_ADD;
2466
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2467
        hi1 -= WC_CACHE_LINE_ADD;
2468
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2469
        hi2 -= WC_CACHE_LINE_ADD;
2470
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2471
        hi3 -= WC_CACHE_LINE_ADD;
2472
    }
2473
    *t0 ^= e0;
2474
    *t1 ^= e1;
2475
    *t2 ^= e2;
2476
    *t3 ^= e3;
2477
}
2478
static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
2479
{
2480
    word32 e = 0;
2481
    int i;
2482
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2483
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2484
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2485
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2486
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2487
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2488
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2489
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2490
2491
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2492
        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
2493
             << 24;
2494
        hi0 -= WC_CACHE_LINE_ADD;
2495
        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
2496
             << 16;
2497
        hi1 -= WC_CACHE_LINE_ADD;
2498
        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
2499
             <<  8;
2500
        hi2 -= WC_CACHE_LINE_ADD;
2501
        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
2502
             <<  0;
2503
        hi3 -= WC_CACHE_LINE_ADD;
2504
    }
2505
2506
    return e;
2507
}
2508
#endif
2509
#else
2510
2511
0
#define GetTable(t, o)  t[o]
2512
#define GetTable8(t, o) t[o]
2513
#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2514
    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
2515
#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2516
    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
2517
#define GetTable8_4(t, o0, o1, o2, o3) \
2518
0
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
2519
0
     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
2520
#endif
2521
2522
#ifndef HAVE_CUDA
2523
/* Encrypt a block using AES.
2524
 *
2525
 * @param [in]  aes       AES object.
2526
 * @param [in]  inBlock   Block to encrypt.
2527
 * @param [out] outBlock  Encrypted block.
2528
 * @param [in]  r         Rounds divided by 2.
2529
 */
2530
#define WC_AES_HAVE_PREFETCH_ARG
2531
static int always_prefetch = 0;
2532
WC_MAYBE_UNUSED static int never_prefetch = 1;
2533
WC_ARGS_NOT_NULL((1, 2, 3, 5))
2534
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2535
        word32 r, int *prefetch_ptr)
2536
0
{
2537
0
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
2538
0
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
2539
0
    const word32* rk;
2540
2541
#ifdef WC_C_DYNAMIC_FALLBACK
2542
    rk = aes->key_C_fallback;
2543
#else
2544
0
    rk = aes->key;
2545
0
#endif
2546
2547
    /*
2548
     * map byte array block to cipher state
2549
     * and add initial round key:
2550
     */
2551
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
2552
0
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
2553
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
2554
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
2555
2556
0
#ifdef LITTLE_ENDIAN_ORDER
2557
0
    s0 = ByteReverseWord32(s0);
2558
0
    s1 = ByteReverseWord32(s1);
2559
0
    s2 = ByteReverseWord32(s2);
2560
0
    s3 = ByteReverseWord32(s3);
2561
0
#endif
2562
2563
    /* AddRoundKey */
2564
0
    s0 ^= rk[0];
2565
0
    s1 ^= rk[1];
2566
0
    s2 ^= rk[2];
2567
0
    s3 ^= rk[3];
2568
2569
0
#ifndef WOLFSSL_AES_SMALL_TABLES
2570
2571
0
#ifndef WC_NO_CACHE_RESISTANT
2572
0
    if (*prefetch_ptr == 0) {
2573
0
        s0 |= PreFetchTe();
2574
0
        if (prefetch_ptr != &always_prefetch)
2575
0
            *prefetch_ptr = 1;
2576
0
    }
2577
#else
2578
    (void)prefetch_ptr;
2579
#endif
2580
2581
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2582
0
#define ENC_ROUND_T_S(o)                                                       \
2583
0
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
2584
0
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
2585
0
         rk[(o)+4];                                                            \
2586
0
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
2587
0
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
2588
0
         rk[(o)+5];                                                            \
2589
0
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
2590
0
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
2591
0
         rk[(o)+6];                                                            \
2592
0
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
2593
0
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
2594
0
         rk[(o)+7]
2595
0
#define ENC_ROUND_S_T(o)                                                       \
2596
0
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
2597
0
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
2598
0
         rk[(o)+0];                                                            \
2599
0
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
2600
0
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
2601
0
         rk[(o)+1];                                                            \
2602
0
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
2603
0
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
2604
0
         rk[(o)+2];                                                            \
2605
0
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
2606
0
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
2607
0
         rk[(o)+3]
2608
#else
2609
#define ENC_ROUND_T_S(o)                                                       \
2610
    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
2611
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
2612
    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
2613
                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
2614
    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
2615
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
2616
    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
2617
                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
2618
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
2619
2620
#define ENC_ROUND_S_T(o)                                                       \
2621
    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
2622
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
2623
    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
2624
                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
2625
    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
2626
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2627
    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
2628
                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
2629
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2630
#endif
2631
2632
0
#ifndef WOLFSSL_AES_NO_UNROLL
2633
/* Unroll the loop. */
2634
0
                       ENC_ROUND_T_S( 0);
2635
0
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2636
0
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2637
0
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2638
0
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2639
0
    if (r > 5) {
2640
0
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2641
0
        if (r > 6) {
2642
0
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2643
0
        }
2644
0
    }
2645
0
    rk += r * 8;
2646
#else
2647
    /*
2648
     * Nr - 1 full rounds:
2649
     */
2650
2651
    for (;;) {
2652
        ENC_ROUND_T_S(0);
2653
2654
        rk += 8;
2655
        if (--r == 0) {
2656
            break;
2657
        }
2658
2659
        ENC_ROUND_S_T(0);
2660
    }
2661
#endif
2662
2663
    /*
2664
     * apply last round and
2665
     * map cipher state to byte array block:
2666
     */
2667
2668
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2669
0
    s0 =
2670
0
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2671
0
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2672
0
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2673
0
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2674
0
        rk[0];
2675
0
    s1 =
2676
0
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2677
0
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2678
0
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2679
0
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2680
0
        rk[1];
2681
0
    s2 =
2682
0
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2683
0
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2684
0
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2685
0
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2686
0
        rk[2];
2687
0
    s3 =
2688
0
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2689
0
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2690
0
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2691
0
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2692
0
        rk[3];
2693
#else
2694
{
2695
    word32 u0;
2696
    word32 u1;
2697
    word32 u2;
2698
    word32 u3;
2699
2700
    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
2701
    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
2702
                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
2703
    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
2704
    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
2705
    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
2706
                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
2707
    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
2708
    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
2709
    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
2710
                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
2711
    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
2712
    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
2713
    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
2714
                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
2715
    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
2716
    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
2717
}
2718
#endif
2719
2720
#else /* WOLFSSL_AES_SMALL_TABLES */
2721
2722
#ifndef WC_NO_CACHE_RESISTANT
2723
    if (*prefetch_ptr == 0) {
2724
        s0 |= PreFetchSBox();
2725
        if (prefetch_ptr != &always_prefetch)
2726
            *prefetch_ptr = 1;
2727
    }
2728
#else
2729
    (void)prefetch_ptr;
2730
#endif
2731
2732
    r *= 2;
2733
    /* Two rounds at a time */
2734
    for (rk += 4; r > 1; r--, rk += 4) {
2735
        t0 =
2736
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2737
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2738
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2739
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2740
        t1 =
2741
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2742
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2743
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2744
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2745
        t2 =
2746
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2747
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2748
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2749
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2750
        t3 =
2751
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2752
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2753
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2754
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2755
2756
        s0 =
2757
            (col_mul(t0, 3, 2, 0, 1) << 24) ^
2758
            (col_mul(t0, 2, 1, 0, 3) << 16) ^
2759
            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
2760
            (col_mul(t0, 0, 3, 2, 1)      ) ^
2761
            rk[0];
2762
        s1 =
2763
            (col_mul(t1, 3, 2, 0, 1) << 24) ^
2764
            (col_mul(t1, 2, 1, 0, 3) << 16) ^
2765
            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
2766
            (col_mul(t1, 0, 3, 2, 1)      ) ^
2767
            rk[1];
2768
        s2 =
2769
            (col_mul(t2, 3, 2, 0, 1) << 24) ^
2770
            (col_mul(t2, 2, 1, 0, 3) << 16) ^
2771
            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
2772
            (col_mul(t2, 0, 3, 2, 1)      ) ^
2773
            rk[2];
2774
        s3 =
2775
            (col_mul(t3, 3, 2, 0, 1) << 24) ^
2776
            (col_mul(t3, 2, 1, 0, 3) << 16) ^
2777
            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
2778
            (col_mul(t3, 0, 3, 2, 1)      ) ^
2779
            rk[3];
2780
    }
2781
2782
    t0 =
2783
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2784
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2785
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2786
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2787
    t1 =
2788
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2789
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2790
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2791
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2792
    t2 =
2793
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2794
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2795
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2796
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2797
    t3 =
2798
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2799
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2800
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2801
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2802
    s0 = t0 ^ rk[0];
2803
    s1 = t1 ^ rk[1];
2804
    s2 = t2 ^ rk[2];
2805
    s3 = t3 ^ rk[3];
2806
2807
#endif /* WOLFSSL_AES_SMALL_TABLES */
2808
2809
    /* write out */
2810
0
#ifdef LITTLE_ENDIAN_ORDER
2811
0
    s0 = ByteReverseWord32(s0);
2812
0
    s1 = ByteReverseWord32(s1);
2813
0
    s2 = ByteReverseWord32(s2);
2814
0
    s3 = ByteReverseWord32(s3);
2815
0
#endif
2816
2817
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2818
0
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2819
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2820
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2821
0
}
2822
2823
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2824
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
2825
    !defined(MAX3266X_AES)
2826
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
2827
/* Encrypt a number of blocks using AES.
2828
 *
2829
 * @param [in]  aes  AES object.
2830
 * @param [in]  in   Block to encrypt.
2831
 * @param [out] out  Encrypted block.
2832
 * @param [in]  sz   Number of blocks to encrypt.
2833
 */
2834
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2835
{
2836
    word32 i;
2837
    int did_prefetches = 0;
2838
2839
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
2840
        AesEncrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
2841
        in += WC_AES_BLOCK_SIZE;
2842
        out += WC_AES_BLOCK_SIZE;
2843
    }
2844
}
2845
#endif
2846
#endif
2847
#else
2848
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2849
        word32 r);
2850
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2851
#endif /* HAVE_CUDA */
2852
2853
#else
2854
2855
/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
2856
 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
2857
 */
2858
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
2859
static void bs_sub_bytes(bs_word u[8])
2860
{
2861
    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
2862
    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
2863
    bs_word y20, y21;
2864
    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
2865
    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
2866
    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
2867
    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
2868
    bs_word t40, t41, t42, t43, t44, t45;
2869
    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
2870
    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
2871
    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
2872
    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
2873
    bs_word tc20, tc21, tc26;
2874
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
2875
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
2876
2877
    U0 = u[7];
2878
    U1 = u[6];
2879
    U2 = u[5];
2880
    U3 = u[4];
2881
    U4 = u[3];
2882
    U5 = u[2];
2883
    U6 = u[1];
2884
    U7 = u[0];
2885
2886
    y14 = U3 ^ U5;
2887
    y13 = U0 ^ U6;
2888
    y9 = U0 ^ U3;
2889
    y8 = U0 ^ U5;
2890
    t0 = U1 ^ U2;
2891
    y1 = t0 ^ U7;
2892
    y4 = y1 ^ U3;
2893
    y12 = y13 ^ y14;
2894
    y2 = y1 ^ U0;
2895
    y5 = y1 ^ U6;
2896
    y3 = y5 ^ y8;
2897
    t1 = U4 ^ y12;
2898
    y15 = t1 ^ U5;
2899
    y20 = t1 ^ U1;
2900
    y6 = y15 ^ U7;
2901
    y10 = y15 ^ t0;
2902
    y11 = y20 ^ y9;
2903
    y7 = U7 ^ y11;
2904
    y17 = y10 ^ y11;
2905
    y19 = y10 ^ y8;
2906
    y16 = t0 ^ y11;
2907
    y21 = y13 ^ y16;
2908
    y18 = U0 ^ y16;
2909
    t2 = y12 & y15;
2910
    t3 = y3 & y6;
2911
    t4 = t3 ^ t2;
2912
    t5 = y4 & U7;
2913
    t6 = t5 ^ t2;
2914
    t7 = y13 & y16;
2915
    t8 = y5 & y1;
2916
    t9 = t8 ^ t7;
2917
    t10 = y2 & y7;
2918
    t11 = t10 ^ t7;
2919
    t12 = y9 & y11;
2920
    t13 = y14 & y17;
2921
    t14 = t13 ^ t12;
2922
    t15 = y8 & y10;
2923
    t16 = t15 ^ t12;
2924
    t17 = t4 ^ y20;
2925
    t18 = t6 ^ t16;
2926
    t19 = t9 ^ t14;
2927
    t20 = t11 ^ t16;
2928
    t21 = t17 ^ t14;
2929
    t22 = t18 ^ y19;
2930
    t23 = t19 ^ y21;
2931
    t24 = t20 ^ y18;
2932
    t25 = t21 ^ t22;
2933
    t26 = t21 & t23;
2934
    t27 = t24 ^ t26;
2935
    t28 = t25 & t27;
2936
    t29 = t28 ^ t22;
2937
    t30 = t23 ^ t24;
2938
    t31 = t22 ^ t26;
2939
    t32 = t31 & t30;
2940
    t33 = t32 ^ t24;
2941
    t34 = t23 ^ t33;
2942
    t35 = t27 ^ t33;
2943
    t36 = t24 & t35;
2944
    t37 = t36 ^ t34;
2945
    t38 = t27 ^ t36;
2946
    t39 = t29 & t38;
2947
    t40 = t25 ^ t39;
2948
    t41 = t40 ^ t37;
2949
    t42 = t29 ^ t33;
2950
    t43 = t29 ^ t40;
2951
    t44 = t33 ^ t37;
2952
    t45 = t42 ^ t41;
2953
    z0 = t44 & y15;
2954
    z1 = t37 & y6;
2955
    z2 = t33 & U7;
2956
    z3 = t43 & y16;
2957
    z4 = t40 & y1;
2958
    z5 = t29 & y7;
2959
    z6 = t42 & y11;
2960
    z7 = t45 & y17;
2961
    z8 = t41 & y10;
2962
    z9 = t44 & y12;
2963
    z10 = t37 & y3;
2964
    z11 = t33 & y4;
2965
    z12 = t43 & y13;
2966
    z13 = t40 & y5;
2967
    z14 = t29 & y2;
2968
    z15 = t42 & y9;
2969
    z16 = t45 & y14;
2970
    z17 = t41 & y8;
2971
    tc1 = z15 ^ z16;
2972
    tc2 = z10 ^ tc1;
2973
    tc3 = z9 ^ tc2;
2974
    tc4 = z0 ^ z2;
2975
    tc5 = z1 ^ z0;
2976
    tc6 = z3 ^ z4;
2977
    tc7 = z12 ^ tc4;
2978
    tc8 = z7 ^ tc6;
2979
    tc9 = z8 ^ tc7;
2980
    tc10 = tc8 ^ tc9;
2981
    tc11 = tc6 ^ tc5;
2982
    tc12 = z3 ^ z5;
2983
    tc13 = z13 ^ tc1;
2984
    tc14 = tc4 ^ tc12;
2985
    S3 = tc3 ^ tc11;
2986
    tc16 = z6 ^ tc8;
2987
    tc17 = z14 ^ tc10;
2988
    tc18 = tc13 ^ tc14;
2989
    S7 = ~(z12 ^ tc18);
2990
    tc20 = z15 ^ tc16;
2991
    tc21 = tc2 ^ z11;
2992
    S0 = tc3 ^ tc16;
2993
    S6 = ~(tc10 ^ tc18);
2994
    S4 = tc14 ^ S3;
2995
    S1 = ~(S3 ^ tc16);
2996
    tc26 = tc17 ^ tc20;
2997
    S2 = ~(tc26 ^ z17);
2998
    S5 = tc21 ^ tc17;
2999
3000
    u[0] = S7;
3001
    u[1] = S6;
3002
    u[2] = S5;
3003
    u[3] = S4;
3004
    u[4] = S3;
3005
    u[5] = S2;
3006
    u[6] = S1;
3007
    u[7] = S0;
3008
}
3009
3010
#define BS_MASK_BIT_SET(w, j, bmask) \
3011
    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
3012
3013
#define BS_TRANS_8(t, o, w, bmask, s)                   \
3014
    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
3015
    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
3016
    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
3017
    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
3018
    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
3019
    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
3020
    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
3021
    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
3022
3023
static void bs_transpose(bs_word* t, bs_word* blocks)
3024
{
3025
    bs_word bmask = 1;
3026
    int i;
3027
3028
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
3029
3030
    for (i = 0; i < BS_WORD_SIZE; i++) {
3031
        int j;
3032
        int o = 0;
3033
        for (j = 0; j < BS_BLOCK_WORDS; j++) {
3034
        #ifdef LITTLE_ENDIAN_ORDER
3035
            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
3036
        #else
3037
            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
3038
        #endif
3039
    #ifdef WOLFSSL_AES_NO_UNROLL
3040
            int k;
3041
            for (k = 0; k < BS_WORD_SIZE; k++) {
3042
                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
3043
            }
3044
    #else
3045
            BS_TRANS_8(t, o, w, bmask,  0);
3046
        #if BS_WORD_SIZE >= 16
3047
            BS_TRANS_8(t, o, w, bmask,  8);
3048
        #endif
3049
        #if BS_WORD_SIZE >= 32
3050
            BS_TRANS_8(t, o, w, bmask, 16);
3051
            BS_TRANS_8(t, o, w, bmask, 24);
3052
        #endif
3053
        #if BS_WORD_SIZE >= 64
3054
            BS_TRANS_8(t, o, w, bmask, 32);
3055
            BS_TRANS_8(t, o, w, bmask, 40);
3056
            BS_TRANS_8(t, o, w, bmask, 48);
3057
            BS_TRANS_8(t, o, w, bmask, 56);
3058
        #endif
3059
    #endif
3060
            o += BS_WORD_SIZE;
3061
        }
3062
        bmask <<= 1;
3063
    }
3064
}
3065
3066
#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
3067
    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
3068
    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
3069
    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
3070
    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
3071
    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
3072
    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
3073
    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
3074
    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
3075
3076
static void bs_inv_transpose(bs_word* t, bs_word* blocks)
3077
{
3078
    int o;
3079
3080
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
3081
3082
    for (o = 0; o < BS_BLOCK_WORDS; o++) {
3083
        int i;
3084
        for (i = 0; i < BS_WORD_SIZE; i++) {
3085
        #ifdef LITTLE_ENDIAN_ORDER
3086
            bs_word bmask = (bs_word)1 << i;
3087
        #else
3088
            bs_word bmask = bs_bswap((bs_word)1 << i);
3089
        #endif
3090
            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
3091
    #ifdef WOLFSSL_AES_NO_UNROLL
3092
            int j;
3093
            for (j = 0; j < BS_WORD_SIZE; j++) {
3094
                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
3095
            }
3096
    #else
3097
            BS_INV_TRANS_8(t, o, w, bmask, 0);
3098
        #if BS_WORD_SIZE >= 16
3099
            BS_INV_TRANS_8(t, o, w, bmask, 8);
3100
        #endif
3101
        #if BS_WORD_SIZE >= 32
3102
            BS_INV_TRANS_8(t, o, w, bmask, 16);
3103
            BS_INV_TRANS_8(t, o, w, bmask, 24);
3104
        #endif
3105
        #if BS_WORD_SIZE >= 64
3106
            BS_INV_TRANS_8(t, o, w, bmask, 32);
3107
            BS_INV_TRANS_8(t, o, w, bmask, 40);
3108
            BS_INV_TRANS_8(t, o, w, bmask, 48);
3109
            BS_INV_TRANS_8(t, o, w, bmask, 56);
3110
        #endif
3111
    #endif
3112
        }
3113
    }
3114
}
3115
3116
#define BS_ROW_OFF_0    0
3117
#define BS_ROW_OFF_1    32
3118
#define BS_ROW_OFF_2    64
3119
#define BS_ROW_OFF_3    96
3120
3121
#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
3122
#define BS_IDX_MASK     0x7f
3123
3124
#define BS_ASSIGN_8(d, od, s, os)   \
3125
    d[(od) + 0] = s[(os) + 0];      \
3126
    d[(od) + 1] = s[(os) + 1];      \
3127
    d[(od) + 2] = s[(os) + 2];      \
3128
    d[(od) + 3] = s[(os) + 3];      \
3129
    d[(od) + 4] = s[(os) + 4];      \
3130
    d[(od) + 5] = s[(os) + 5];      \
3131
    d[(od) + 6] = s[(os) + 6];      \
3132
    d[(od) + 7] = s[(os) + 7]
3133
3134
static void bs_shift_rows(bs_word* t, bs_word* b)
3135
{
3136
    int i;
3137
3138
    for (i = 0; i < 128; i += 32) {
3139
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
3140
        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
3141
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
3142
        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
3143
    }
3144
}
3145
3146
#define BS_SHIFT_OFF_0  0
3147
#define BS_SHIFT_OFF_1  8
3148
#define BS_SHIFT_OFF_2  16
3149
#define BS_SHIFT_OFF_3  24
3150
3151
/* Shift rows and mix columns.
3152
 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
3153
 */
3154
3155
#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
3156
        of      = br0[7] ^ br1[7];                                  \
3157
        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
3158
        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
3159
        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
3160
        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
3161
        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
3162
        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
3163
        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
3164
        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
3165
3166
static void bs_shift_mix(bs_word* t, bs_word* b)
3167
{
3168
    int i;
3169
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
3170
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
3171
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
3172
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
3173
3174
    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
3175
        bs_word* br0 = b + or0;
3176
        bs_word* br1 = b + or1;
3177
        bs_word* br2 = b + or2;
3178
        bs_word* br3 = b + or3;
3179
        bs_word of;
3180
3181
        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
3182
        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
3183
        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
3184
        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
3185
3186
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3187
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3188
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3189
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3190
    }
3191
}
3192
3193
static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
3194
{
3195
    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
3196
}
3197
3198
static void bs_sub_bytes_blocks(bs_word* b)
3199
{
3200
    int i;
3201
3202
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
3203
        bs_sub_bytes(b + i);
3204
    }
3205
}
3206
3207
static const FLASH_QUALIFIER byte bs_rcon[] = {
3208
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
3209
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
3210
};
3211
3212
static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
3213
    bs_word block[AES_BLOCK_BITS];
3214
    bs_word trans[AES_BLOCK_BITS];
3215
3216
    XMEMSET(block, 0, sizeof(block));
3217
    XMEMCPY(block, in, 4);
3218
3219
    bs_transpose(trans, block);
3220
    bs_sub_bytes_blocks(trans);
3221
    bs_inv_transpose(block, trans);
3222
3223
    XMEMCPY(out, block, 4);
3224
}
3225
3226
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
3227
    /* Rotate the input 8 bits to the left */
3228
#ifdef LITTLE_ENDIAN_ORDER
3229
    *(word32*)out = rotrFixed(*(word32*)in, 8);
3230
#else
3231
    *(word32*)out = rotlFixed(*(word32*)in, 8);
3232
#endif
3233
    bs_ke_sub_bytes(out, out);
3234
    /* On just the first byte, add 2^i to the byte */
3235
    out[0] ^= bs_rcon[i];
3236
}
3237
3238
static void bs_expand_key(unsigned char *in, word32 sz) {
3239
    unsigned char t[4];
3240
    word32 o;
3241
    word8 i = 0;
3242
3243
    if (sz == 176) {
3244
        /* Total of 11 rounds - AES-128. */
3245
        for (o = 16; o < sz; o += 16) {
3246
            bs_ke_transform(t, in + o - 4, i);
3247
            i++;
3248
            *(word32*)(in + o +  0) = *(word32*)(in + o - 16) ^
3249
                                      *(word32*) t;
3250
            *(word32*)(in + o +  4) = *(word32*)(in + o - 12) ^
3251
                                      *(word32*)(in + o +  0);
3252
            *(word32*)(in + o +  8) = *(word32*)(in + o -  8) ^
3253
                                      *(word32*)(in + o +  4);
3254
            *(word32*)(in + o + 12) = *(word32*)(in + o -  4) ^
3255
                                      *(word32*)(in + o +  8);
3256
        }
3257
    }
3258
    else if (sz == 208) {
3259
        /* Total of 13 rounds - AES-192. */
3260
        for (o = 24; o < sz; o += 24) {
3261
            bs_ke_transform(t, in + o - 4, i);
3262
            i++;
3263
            *(word32*)(in + o +  0) = *(word32*)(in + o - 24) ^
3264
                                      *(word32*) t;
3265
            *(word32*)(in + o +  4) = *(word32*)(in + o - 20) ^
3266
                                      *(word32*)(in + o +  0);
3267
            *(word32*)(in + o +  8) = *(word32*)(in + o - 16) ^
3268
                                      *(word32*)(in + o +  4);
3269
            *(word32*)(in + o + 12) = *(word32*)(in + o - 12) ^
3270
                                      *(word32*)(in + o +  8);
3271
            *(word32*)(in + o + 16) = *(word32*)(in + o -  8) ^
3272
                                      *(word32*)(in + o + 12);
3273
            *(word32*)(in + o + 20) = *(word32*)(in + o -  4) ^
3274
                                      *(word32*)(in + o + 16);
3275
        }
3276
    }
3277
    else if (sz == 240) {
3278
        /* Total of 15 rounds - AES-256. */
3279
        for (o = 32; o < sz; o += 16) {
3280
            if ((o & 0x1f) == 0) {
3281
                bs_ke_transform(t, in + o - 4, i);
3282
                i++;
3283
            }
3284
            else {
3285
                bs_ke_sub_bytes(t, in + o - 4);
3286
            }
3287
            *(word32*)(in + o +  0) = *(word32*)(in + o - 32) ^
3288
                                      *(word32*) t;
3289
            *(word32*)(in + o +  4) = *(word32*)(in + o - 28) ^
3290
                                      *(word32*)(in + o +  0);
3291
            *(word32*)(in + o +  8) = *(word32*)(in + o - 24) ^
3292
                                      *(word32*)(in + o +  4);
3293
            *(word32*)(in + o + 12) = *(word32*)(in + o - 20) ^
3294
                                      *(word32*)(in + o +  8);
3295
        }
3296
    }
3297
}
3298
3299
static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
3300
    word32 rounds)
3301
{
3302
    int i;
3303
    byte bs_key[15 * WC_AES_BLOCK_SIZE];
3304
    int ksSz = (rounds + 1) * WC_AES_BLOCK_SIZE;
3305
    bs_word block[AES_BLOCK_BITS];
3306
3307
    /* Fist round. */
3308
    XMEMCPY(bs_key, key, keyLen);
3309
    bs_expand_key(bs_key, ksSz);
3310
3311
    for (i = 0; i < ksSz; i += WC_AES_BLOCK_SIZE) {
3312
        int k;
3313
3314
        XMEMCPY(block, bs_key + i, WC_AES_BLOCK_SIZE);
3315
        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
3316
            int l;
3317
            for (l = 0; l < BS_BLOCK_WORDS; l++) {
3318
                block[k + l] = block[l];
3319
            }
3320
        }
3321
        bs_transpose(rk, block);
3322
        rk += AES_BLOCK_BITS;
3323
    }
3324
}
3325
3326
static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
3327
{
3328
    word32 i;
3329
    bs_word trans[AES_BLOCK_BITS];
3330
3331
    bs_transpose(trans, state);
3332
3333
    bs_add_round_key(trans, trans, rk);
3334
    for (i = 1; i < r; i++) {
3335
        bs_sub_bytes_blocks(trans);
3336
        bs_shift_mix(state, trans);
3337
        rk += AES_BLOCK_BITS;
3338
        bs_add_round_key(trans, state, rk);
3339
    }
3340
    bs_sub_bytes_blocks(trans);
3341
    bs_shift_rows(state, trans);
3342
    rk += AES_BLOCK_BITS;
3343
    bs_add_round_key(trans, state, rk);
3344
    bs_inv_transpose(state, trans);
3345
}
3346
3347
#ifndef HAVE_CUDA
3348
/* Encrypt a block using AES.
3349
 *
3350
 * @param [in]  aes       AES object.
3351
 * @param [in]  inBlock   Block to encrypt.
3352
 * @param [out] outBlock  Encrypted block.
3353
 * @param [in]  r         Rounds divided by 2.
3354
 */
3355
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3356
        word32 r)
3357
{
3358
    bs_word state[AES_BLOCK_BITS];
3359
3360
    (void)r;
3361
3362
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
3363
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
3364
3365
    bs_encrypt(state, aes->bs_key, aes->rounds);
3366
3367
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
3368
}
3369
3370
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3371
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3372
/* Encrypt a number of blocks using AES.
3373
 *
3374
 * @param [in]  aes  AES object.
3375
 * @param [in]  in   Block to encrypt.
3376
 * @param [out] out  Encrypted block.
3377
 * @param [in]  sz   Number of blocks to encrypt.
3378
 */
3379
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3380
{
3381
    bs_word state[AES_BLOCK_BITS];
3382
3383
    while (sz >= BS_BLOCK_SIZE) {
3384
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3385
        bs_encrypt(state, aes->bs_key, aes->rounds);
3386
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3387
        sz  -= BS_BLOCK_SIZE;
3388
        in  += BS_BLOCK_SIZE;
3389
        out += BS_BLOCK_SIZE;
3390
    }
3391
    if (sz > 0) {
3392
        XMEMCPY(state, in, sz);
3393
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3394
        bs_encrypt(state, aes->bs_key, aes->rounds);
3395
        XMEMCPY(out, state, sz);
3396
    }
3397
}
3398
#endif
3399
#else
3400
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3401
        word32 r);
3402
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
3403
#endif /* HAVE_CUDA */
3404
3405
#endif /* !WC_AES_BITSLICED */
3406
3407
#ifdef WC_AES_HAVE_PREFETCH_ARG
3408
#define wc_AesEncrypt(aes, inBlock, outBlock) \
3409
0
    AesEncrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
3410
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesEncrypt_preFetchOpt(
3411
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
3412
#else
3413
#define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
3414
    wc_AesEncrypt(aes, inBlock, outBlock)
3415
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesEncrypt(
3416
    Aes* aes, const byte* inBlock, byte* outBlock)
3417
#endif
3418
0
{
3419
#if defined(MAX3266X_AES)
3420
    word32 keySize;
3421
#endif
3422
#if defined(MAX3266X_CB)
3423
    int ret_cb;
3424
#endif
3425
0
    word32 r;
3426
3427
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3428
    {
3429
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3430
        if (ret < 0)
3431
            return ret;
3432
    }
3433
#endif
3434
3435
0
    r = aes->rounds >> 1;
3436
3437
0
    if (r > 7 || r == 0) {
3438
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3439
0
        return KEYUSAGE_E;
3440
0
    }
3441
3442
#ifdef WOLFSSL_AESNI
3443
    if (aes->use_aesni) {
3444
        ASSERT_SAVED_VECTOR_REGISTERS();
3445
3446
        #ifdef DEBUG_AESNI
3447
            printf("about to aes encrypt\n");
3448
            printf("in  = %p\n", inBlock);
3449
            printf("out = %p\n", outBlock);
3450
            printf("aes->key = %p\n", aes->key);
3451
            printf("aes->rounds = %d\n", aes->rounds);
3452
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
3453
        #endif
3454
3455
        /* check alignment, decrypt doesn't need alignment */
3456
        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
3457
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
3458
            byte* tmp = (byte*)XMALLOC(WC_AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
3459
                                                      DYNAMIC_TYPE_TMP_BUFFER);
3460
            byte* tmp_align;
3461
            if (tmp == NULL)
3462
                return MEMORY_E;
3463
3464
            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
3465
3466
            XMEMCPY(tmp_align, inBlock, WC_AES_BLOCK_SIZE);
3467
            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, WC_AES_BLOCK_SIZE,
3468
                    (byte*)aes->key, (int)aes->rounds);
3469
            XMEMCPY(outBlock, tmp_align, WC_AES_BLOCK_SIZE);
3470
            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3471
            return 0;
3472
        #else
3473
            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
3474
            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
3475
            return BAD_ALIGN_E;
3476
        #endif
3477
        }
3478
3479
        AES_ECB_encrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3480
                        (int)aes->rounds);
3481
3482
        return 0;
3483
    }
3484
    else {
3485
        #ifdef DEBUG_AESNI
3486
            printf("Skipping AES-NI\n");
3487
        #endif
3488
    }
3489
#elif defined(WOLFSSL_ARMASM)
3490
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
3491
#if !defined(__aarch64__)
3492
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
3493
#else
3494
    if (aes->use_aes_hw_crypto) {
3495
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3496
            (int)aes->rounds);
3497
    }
3498
    else
3499
#endif /* !__aarch64__ */
3500
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
3501
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
3502
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
3503
    {
3504
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3505
            (const unsigned char*)aes->key, aes->rounds);
3506
    }
3507
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
3508
    {
3509
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3510
            (const unsigned char*)aes->key, aes->rounds);
3511
    }
3512
#endif
3513
    return 0;
3514
#endif /* WOLFSSL_AESNI */
3515
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3516
    AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3517
    return 0;
3518
#endif
3519
3520
#if defined(WOLFSSL_IMXRT_DCP)
3521
    if (aes->keylen == 16) {
3522
        DCPAesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3523
        return 0;
3524
    }
3525
#endif
3526
3527
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3528
    if (aes->useSWCrypt == 0) {
3529
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3530
                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
3531
    }
3532
#endif
3533
3534
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3535
    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
3536
    if (wc_esp32AesSupportedKeyLen(aes)) {
3537
        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
3538
    }
3539
    else {
3540
        /* For example, the ESP32-S3 does not support HW for len = 24,
3541
         * so fall back to SW */
3542
    #ifdef DEBUG_WOLFSSL
3543
        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
3544
                      aes->keylen);
3545
    #endif
3546
    }
3547
#endif
3548
3549
#if defined(MAX3266X_AES)
3550
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3551
        return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3552
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3553
                                    outBlock, (unsigned int)keySize);
3554
    }
3555
#endif
3556
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3557
    #ifndef WOLF_CRYPTO_CB_FIND
3558
    if (aes->devId != INVALID_DEVID)
3559
    #endif
3560
    {
3561
        ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock,
3562
                                            WC_AES_BLOCK_SIZE);
3563
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3564
            return ret_cb;
3565
        /* fall-through when unavailable */
3566
    }
3567
#endif
3568
3569
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
3570
0
    AesEncrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
3571
#else
3572
    AesEncrypt_C(aes, inBlock, outBlock, r);
3573
#endif
3574
3575
0
    return 0;
3576
0
} /* wc_AesEncrypt */
3577
#endif
3578
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
3579
3580
#if defined(HAVE_AES_DECRYPT)
3581
#if ((defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3582
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)) && \
3583
    (defined(__aarch64__) || !defined(WOLFSSL_ARMASM))
3584
3585
#ifndef WC_AES_BITSLICED
3586
#ifndef WC_NO_CACHE_RESISTANT
3587
#ifndef WOLFSSL_AES_SMALL_TABLES
3588
/* load 4 Td Tables into cache by cache line stride */
3589
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
3590
0
{
3591
0
    volatile word32 x = 0;
3592
0
    int i;
3593
0
    int j;
3594
3595
0
    for (i = 0; i < 4; i++) {
3596
        /* 256 elements, each one is 4 bytes */
3597
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
3598
0
            x &= Td[i][j];
3599
0
        }
3600
0
    }
3601
3602
0
    return x;
3603
0
}
3604
#endif /* !WOLFSSL_AES_SMALL_TABLES */
3605
3606
/* load Td Table4 into cache by cache line stride */
3607
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
3608
0
{
3609
0
#ifndef WOLFSSL_AES_TOUCH_LINES
3610
0
    volatile word32 x = 0;
3611
0
    int i;
3612
3613
0
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
3614
0
        x &= (word32)Td4[i];
3615
0
    }
3616
3617
0
    return x;
3618
#else
3619
    return 0;
3620
#endif
3621
0
}
3622
#endif /* !WC_NO_CACHE_RESISTANT */
3623
3624
/* Decrypt a block using AES.
3625
 *
3626
 * @param [in]  aes       AES object.
3627
 * @param [in]  inBlock   Block to encrypt.
3628
 * @param [out] outBlock  Encrypted block.
3629
 * @param [in]  r         Rounds divided by 2.
3630
 */
3631
#ifndef WC_AES_HAVE_PREFETCH_ARG
3632
    #define WC_AES_HAVE_PREFETCH_ARG
3633
    static int always_prefetch = 0;
3634
    WC_MAYBE_UNUSED static int never_prefetch = 1;
3635
#endif
3636
WC_ARGS_NOT_NULL((1, 2, 3, 5))
3637
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3638
    word32 r, int *prefetch_ptr)
3639
0
{
3640
0
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
3641
0
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
3642
0
    const word32* rk;
3643
3644
#ifdef WC_C_DYNAMIC_FALLBACK
3645
    rk = aes->key_C_fallback;
3646
#else
3647
0
    rk = aes->key;
3648
0
#endif
3649
3650
    /*
3651
     * map byte array block to cipher state
3652
     * and add initial round key:
3653
     */
3654
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
3655
0
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
3656
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
3657
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
3658
3659
0
#ifdef LITTLE_ENDIAN_ORDER
3660
0
    s0 = ByteReverseWord32(s0);
3661
0
    s1 = ByteReverseWord32(s1);
3662
0
    s2 = ByteReverseWord32(s2);
3663
0
    s3 = ByteReverseWord32(s3);
3664
0
#endif
3665
3666
0
    s0 ^= rk[0];
3667
0
    s1 ^= rk[1];
3668
0
    s2 ^= rk[2];
3669
0
    s3 ^= rk[3];
3670
3671
0
#ifndef WOLFSSL_AES_SMALL_TABLES
3672
3673
0
#ifndef WC_NO_CACHE_RESISTANT
3674
0
    if (*prefetch_ptr == 0) {
3675
0
        s0 |= PreFetchTd();
3676
        /* don't set the prefetched flag here -- PreFetchTd4() is called
3677
         * below.
3678
         */
3679
0
    }
3680
#else
3681
    (void)prefetch_ptr;
3682
#endif
3683
3684
0
#ifndef WOLFSSL_AES_TOUCH_LINES
3685
/* Unroll the loop. */
3686
0
#define DEC_ROUND_T_S(o)                                            \
3687
0
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
3688
0
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
3689
0
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
3690
0
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
3691
0
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
3692
0
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
3693
0
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
3694
0
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
3695
0
#define DEC_ROUND_S_T(o)                                            \
3696
0
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
3697
0
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
3698
0
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
3699
0
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
3700
0
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
3701
0
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
3702
0
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
3703
0
         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
3704
#else
3705
#define DEC_ROUND_T_S(o)                                                       \
3706
    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
3707
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
3708
    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
3709
                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
3710
    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
3711
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
3712
    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
3713
                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
3714
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
3715
3716
#define DEC_ROUND_S_T(o)                                                       \
3717
    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
3718
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
3719
    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
3720
                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
3721
    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
3722
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
3723
    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
3724
                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
3725
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
3726
#endif
3727
3728
0
#ifndef WOLFSSL_AES_NO_UNROLL
3729
0
                       DEC_ROUND_T_S( 0);
3730
0
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3731
0
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3732
0
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3733
0
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3734
0
    if (r > 5) {
3735
0
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3736
0
        if (r > 6) {
3737
0
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3738
0
        }
3739
0
    }
3740
0
    rk += r * 8;
3741
#else
3742
3743
    /*
3744
     * Nr - 1 full rounds:
3745
     */
3746
3747
    for (;;) {
3748
        DEC_ROUND_T_S(0);
3749
3750
        rk += 8;
3751
        if (--r == 0) {
3752
            break;
3753
        }
3754
3755
        DEC_ROUND_S_T(0);
3756
    }
3757
#endif
3758
    /*
3759
     * apply last round and
3760
     * map cipher state to byte array block:
3761
     */
3762
3763
0
#ifndef WC_NO_CACHE_RESISTANT
3764
0
    if (*prefetch_ptr == 0) {
3765
0
        t0 |= PreFetchTd4();
3766
0
        if (prefetch_ptr != &always_prefetch)
3767
0
            *prefetch_ptr = 1;
3768
0
    }
3769
#else
3770
    (void)prefetch_ptr;
3771
#endif
3772
3773
0
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3774
0
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3775
0
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3776
0
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3777
0
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3778
0
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3779
0
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3780
0
                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
3781
3782
#else /* WOLFSSL_AES_SMALL_TABLES */
3783
3784
#ifndef WC_NO_CACHE_RESISTANT
3785
    if (*prefetch_ptr == 0) {
3786
        s0 |= PreFetchTd4();
3787
        if (prefetch_ptr != &always_prefetch)
3788
            *prefetch_ptr = 1;
3789
    }
3790
#else
3791
    (void)prefetch_ptr;
3792
#endif
3793
3794
    r *= 2;
3795
    for (rk += 4; r > 1; r--, rk += 4) {
3796
        t0 =
3797
            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3798
            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3799
            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3800
            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
3801
            rk[0];
3802
        t1 =
3803
            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3804
            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3805
            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3806
            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
3807
            rk[1];
3808
        t2 =
3809
            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3810
            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3811
            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3812
            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
3813
            rk[2];
3814
        t3 =
3815
            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3816
            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3817
            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3818
            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
3819
            rk[3];
3820
3821
        s0 =
3822
            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
3823
            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
3824
            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
3825
            (inv_col_mul(t0, 1, 3, 2, 0)      );
3826
        s1 =
3827
            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
3828
            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
3829
            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
3830
            (inv_col_mul(t1, 1, 3, 2, 0)      );
3831
        s2 =
3832
            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
3833
            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
3834
            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
3835
            (inv_col_mul(t2, 1, 3, 2, 0)      );
3836
        s3 =
3837
            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
3838
            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
3839
            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
3840
            (inv_col_mul(t3, 1, 3, 2, 0)      );
3841
    }
3842
3843
    t0 =
3844
        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3845
        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3846
        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3847
        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
3848
    t1 =
3849
        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3850
        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3851
        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3852
        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
3853
    t2 =
3854
        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3855
        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3856
        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3857
        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
3858
    t3 =
3859
        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3860
        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3861
        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3862
        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
3863
    s0 = t0 ^ rk[0];
3864
    s1 = t1 ^ rk[1];
3865
    s2 = t2 ^ rk[2];
3866
    s3 = t3 ^ rk[3];
3867
3868
#endif /* WOLFSSL_AES_SMALL_TABLES */
3869
3870
    /* write out */
3871
0
#ifdef LITTLE_ENDIAN_ORDER
3872
0
    s0 = ByteReverseWord32(s0);
3873
0
    s1 = ByteReverseWord32(s1);
3874
0
    s2 = ByteReverseWord32(s2);
3875
0
    s3 = ByteReverseWord32(s3);
3876
0
#endif
3877
3878
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
3879
0
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
3880
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
3881
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
3882
3883
0
}
3884
3885
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3886
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
3887
    !defined(MAX3266X_AES)
3888
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
3889
/* Decrypt a number of blocks using AES.
3890
 *
3891
 * @param [in]  aes  AES object.
3892
 * @param [in]  in   Block to encrypt.
3893
 * @param [out] out  Encrypted block.
3894
 * @param [in]  sz   Number of blocks to encrypt.
3895
 */
3896
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3897
{
3898
    word32 i;
3899
    int did_prefetches = 0;
3900
3901
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
3902
        AesDecrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
3903
        in += WC_AES_BLOCK_SIZE;
3904
        out += WC_AES_BLOCK_SIZE;
3905
    }
3906
}
3907
#endif
3908
#endif
3909
3910
#else /* WC_AES_BITSLICED */
3911
3912
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
3913
static void bs_inv_sub_bytes(bs_word u[8])
3914
{
3915
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
3916
    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
3917
    bs_word RTL0, RTL1, RTL2;
3918
    bs_word sa0, sa1;
3919
    bs_word sb0, sb1;
3920
    bs_word ab0, ab1, ab2, ab3;
3921
    bs_word ab20, ab21, ab22, ab23;
3922
    bs_word al, ah, aa, bl, bh, bb;
3923
    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
3924
    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
3925
    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
3926
    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
3927
    bs_word rr1, rr2;
3928
    bs_word r10, r11;
3929
    bs_word cp1, cp2, cp3, cp4;
3930
    bs_word vr1, vr2, vr3;
3931
    bs_word pr1, pr2, pr3;
3932
    bs_word wr1, wr2, wr3;
3933
    bs_word qr1, qr2, qr3;
3934
    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
3935
    bs_word tinv10, tinv11, tinv12, tinv13;
3936
    bs_word t01, t02;
3937
    bs_word d0, d1, d2, d3;
3938
    bs_word dl, dd, dh;
3939
    bs_word sd0, sd1;
3940
    bs_word p0, p1, p2, p3, p4, p6, p7;
3941
    bs_word X11, X13, X14, X16, X18, X19;
3942
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
3943
3944
    U0 = u[7];
3945
    U1 = u[6];
3946
    U2 = u[5];
3947
    U3 = u[4];
3948
    U4 = u[3];
3949
    U5 = u[2];
3950
    U6 = u[1];
3951
    U7 = u[0];
3952
3953
    Y0 = U0 ^ U3;
3954
    Y2 = ~(U1 ^ U3);
3955
    Y4 = U0 ^ Y2;
3956
    RTL0 = U6 ^ U7;
3957
    Y1 = Y2 ^ RTL0;
3958
    Y7 = ~(U2 ^ Y1);
3959
    RTL1 = U3 ^ U4;
3960
    Y6 = ~(U7 ^ RTL1);
3961
    Y3 = Y1 ^ RTL1;
3962
    RTL2 = ~(U0 ^ U2);
3963
    Y5 = U5 ^ RTL2;
3964
    sa1 = Y0 ^ Y2;
3965
    sa0 = Y1 ^ Y3;
3966
    sb1 = Y4 ^ Y6;
3967
    sb0 = Y5 ^ Y7;
3968
    ah = Y0 ^ Y1;
3969
    al = Y2 ^ Y3;
3970
    aa = sa0 ^ sa1;
3971
    bh = Y4 ^ Y5;
3972
    bl = Y6 ^ Y7;
3973
    bb = sb0 ^ sb1;
3974
    ab20 = sa0 ^ sb0;
3975
    ab22 = al ^ bl;
3976
    ab23 = Y3 ^ Y7;
3977
    ab21 = sa1 ^ sb1;
3978
    abcd1 = ah & bh;
3979
    rr1 = Y0 & Y4;
3980
    ph11 = ab20 ^ abcd1;
3981
    t01 = Y1 & Y5;
3982
    ph01 = t01 ^ abcd1;
3983
    abcd2 = al & bl;
3984
    r1 = Y2 & Y6;
3985
    pl11 = ab22 ^ abcd2;
3986
    r2 = Y3 & Y7;
3987
    pl01 = r2 ^ abcd2;
3988
    r3 = sa0 & sb0;
3989
    vr1 = aa & bb;
3990
    pr1 = vr1 ^ r3;
3991
    wr1 = sa1 & sb1;
3992
    qr1 = wr1 ^ r3;
3993
    ab0 = ph11 ^ rr1;
3994
    ab1 = ph01 ^ ab21;
3995
    ab2 = pl11 ^ r1;
3996
    ab3 = pl01 ^ qr1;
3997
    cp1 = ab0 ^ pr1;
3998
    cp2 = ab1 ^ qr1;
3999
    cp3 = ab2 ^ pr1;
4000
    cp4 = ab3 ^ ab23;
4001
    tinv1 = cp3 ^ cp4;
4002
    tinv2 = cp3 & cp1;
4003
    tinv3 = cp2 ^ tinv2;
4004
    tinv4 = cp1 ^ cp2;
4005
    tinv5 = cp4 ^ tinv2;
4006
    tinv6 = tinv5 & tinv4;
4007
    tinv7 = tinv3 & tinv1;
4008
    d2 = cp4 ^ tinv7;
4009
    d0 = cp2 ^ tinv6;
4010
    tinv8 = cp1 & cp4;
4011
    tinv9 = tinv4 & tinv8;
4012
    tinv10 = tinv4 ^ tinv2;
4013
    d1 = tinv9 ^ tinv10;
4014
    tinv11 = cp2 & cp3;
4015
    tinv12 = tinv1 & tinv11;
4016
    tinv13 = tinv1 ^ tinv2;
4017
    d3 = tinv12 ^ tinv13;
4018
    sd1 = d1 ^ d3;
4019
    sd0 = d0 ^ d2;
4020
    dl = d0 ^ d1;
4021
    dh = d2 ^ d3;
4022
    dd = sd0 ^ sd1;
4023
    abcd3 = dh & bh;
4024
    rr2 = d3 & Y4;
4025
    t02 = d2 & Y5;
4026
    abcd4 = dl & bl;
4027
    r4 = d1 & Y6;
4028
    r5 = d0 & Y7;
4029
    r6 = sd0 & sb0;
4030
    vr2 = dd & bb;
4031
    wr2 = sd1 & sb1;
4032
    abcd5 = dh & ah;
4033
    r7 = d3 & Y0;
4034
    r8 = d2 & Y1;
4035
    abcd6 = dl & al;
4036
    r9 = d1 & Y2;
4037
    r10 = d0 & Y3;
4038
    r11 = sd0 & sa0;
4039
    vr3 = dd & aa;
4040
    wr3 = sd1 & sa1;
4041
    ph12 = rr2 ^ abcd3;
4042
    ph02 = t02 ^ abcd3;
4043
    pl12 = r4 ^ abcd4;
4044
    pl02 = r5 ^ abcd4;
4045
    pr2 = vr2 ^ r6;
4046
    qr2 = wr2 ^ r6;
4047
    p0 = ph12 ^ pr2;
4048
    p1 = ph02 ^ qr2;
4049
    p2 = pl12 ^ pr2;
4050
    p3 = pl02 ^ qr2;
4051
    ph13 = r7 ^ abcd5;
4052
    ph03 = r8 ^ abcd5;
4053
    pl13 = r9 ^ abcd6;
4054
    pl03 = r10 ^ abcd6;
4055
    pr3 = vr3 ^ r11;
4056
    qr3 = wr3 ^ r11;
4057
    p4 = ph13 ^ pr3;
4058
    S7 = ph03 ^ qr3;
4059
    p6 = pl13 ^ pr3;
4060
    p7 = pl03 ^ qr3;
4061
    S3 = p1 ^ p6;
4062
    S6 = p2 ^ p6;
4063
    S0 = p3 ^ p6;
4064
    X11 = p0 ^ p2;
4065
    S5 = S0 ^ X11;
4066
    X13 = p4 ^ p7;
4067
    X14 = X11 ^ X13;
4068
    S1 = S3 ^ X14;
4069
    X16 = p1 ^ S7;
4070
    S2 = X14 ^ X16;
4071
    X18 = p0 ^ p4;
4072
    X19 = S5 ^ X16;
4073
    S4 = X18 ^ X19;
4074
4075
    u[0] = S7;
4076
    u[1] = S6;
4077
    u[2] = S5;
4078
    u[3] = S4;
4079
    u[4] = S3;
4080
    u[5] = S2;
4081
    u[6] = S1;
4082
    u[7] = S0;
4083
}
4084
4085
static void bs_inv_shift_rows(bs_word* b)
4086
{
4087
    bs_word t[AES_BLOCK_BITS];
4088
    int i;
4089
4090
    for (i = 0; i < 128; i += 32) {
4091
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
4092
        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
4093
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
4094
        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
4095
    }
4096
4097
    XMEMCPY(b, t, sizeof(t));
4098
}
4099
4100
#define O0  0
4101
#define O1  8
4102
#define O2  16
4103
#define O3  24
4104
4105
#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
4106
    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
4107
          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
4108
    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
4109
          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
4110
    of2 =                     b[O0+7] ^             b[O1+7] ^               \
4111
                    b[O2+7] ^ b[O3+7];                                      \
4112
                                                                            \
4113
    br[0] =                                                   b[O1+0] ^     \
4114
            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
4115
    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
4116
            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
4117
    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
4118
            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
4119
    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
4120
            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
4121
    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
4122
            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
4123
    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
4124
            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
4125
    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
4126
            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
4127
    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
4128
            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
4129
4130
/* Inverse mix columns and shift rows. */
4131
static void bs_inv_mix_shift(bs_word* t, bs_word* b)
4132
{
4133
    bs_word* bp = b;
4134
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
4135
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
4136
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
4137
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
4138
    int i;
4139
4140
    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
4141
        bs_word* br;
4142
        bs_word of0;
4143
        bs_word of1;
4144
        bs_word of2;
4145
4146
        br = t + or0;
4147
        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
4148
        br = t + or1;
4149
        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
4150
        br = t + or2;
4151
        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
4152
        br = t + or3;
4153
        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
4154
4155
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4156
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4157
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4158
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4159
4160
        bp += AES_BLOCK_BITS / 4;
4161
    }
4162
}
4163
4164
static void bs_inv_sub_bytes_blocks(bs_word* b)
4165
{
4166
    int i;
4167
4168
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
4169
        bs_inv_sub_bytes(b + i);
4170
    }
4171
}
4172
4173
static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
4174
{
4175
    int i;
4176
    bs_word trans[AES_BLOCK_BITS];
4177
4178
    bs_transpose(trans, state);
4179
4180
    rk += r * AES_BLOCK_BITS;
4181
    bs_add_round_key(trans, trans, rk);
4182
    bs_inv_shift_rows(trans);
4183
    bs_inv_sub_bytes_blocks(trans);
4184
    rk -= AES_BLOCK_BITS;
4185
    bs_add_round_key(trans, trans, rk);
4186
    for (i = (int)r - 2; i >= 0; i--) {
4187
        bs_inv_mix_shift(state, trans);
4188
        bs_inv_sub_bytes_blocks(state);
4189
        rk -= AES_BLOCK_BITS;
4190
        bs_add_round_key(trans, state, rk);
4191
    }
4192
4193
    bs_inv_transpose(state, trans);
4194
}
4195
4196
#ifdef WOLFSSL_AES_DIRECT
4197
/* Decrypt a block using AES.
4198
 *
4199
 * @param [in]  aes       AES object.
4200
 * @param [in]  inBlock   Block to encrypt.
4201
 * @param [out] outBlock  Encrypted block.
4202
 * @param [in]  r         Rounds divided by 2.
4203
 */
4204
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
4205
    word32 r)
4206
{
4207
    bs_word state[AES_BLOCK_BITS];
4208
4209
    (void)r;
4210
4211
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
4212
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
4213
4214
    bs_decrypt(state, aes->bs_key, aes->rounds);
4215
4216
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
4217
}
4218
#endif
4219
4220
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
4221
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
4222
/* Decrypt a number of blocks using AES.
4223
 *
4224
 * @param [in]  aes  AES object.
4225
 * @param [in]  in   Block to encrypt.
4226
 * @param [out] out  Encrypted block.
4227
 * @param [in]  sz   Number of blocks to encrypt.
4228
 */
4229
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
4230
{
4231
    bs_word state[AES_BLOCK_BITS];
4232
4233
    while (sz >= BS_BLOCK_SIZE) {
4234
        XMEMCPY(state, in, BS_BLOCK_SIZE);
4235
        bs_decrypt(state, aes->bs_key, aes->rounds);
4236
        XMEMCPY(out, state, BS_BLOCK_SIZE);
4237
        sz  -= BS_BLOCK_SIZE;
4238
        in  += BS_BLOCK_SIZE;
4239
        out += BS_BLOCK_SIZE;
4240
    }
4241
    if (sz > 0) {
4242
        XMEMCPY(state, in, sz);
4243
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
4244
        bs_decrypt(state, aes->bs_key, aes->rounds);
4245
        XMEMCPY(out, state, sz);
4246
    }
4247
}
4248
#endif
4249
4250
#endif /* !WC_AES_BITSLICED */
4251
#endif
4252
4253
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
4254
    defined(WOLFSSL_AES_DIRECT)
4255
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
4256
#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
4257
/* Software AES - ECB Decrypt */
4258
4259
#ifdef WC_AES_HAVE_PREFETCH_ARG
4260
#define wc_AesDecrypt(aes, inBlock, outBlock) \
4261
    AesDecrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
4262
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesDecrypt_preFetchOpt(
4263
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
4264
#else
4265
#define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
4266
    wc_AesDecrypt(aes, inBlock, outBlock)
4267
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
4268
    Aes* aes, const byte* inBlock, byte* outBlock)
4269
#endif
4270
0
{
4271
#if defined(MAX3266X_AES)
4272
    word32 keySize;
4273
#endif
4274
#if defined(MAX3266X_CB)
4275
    int ret_cb;
4276
#endif
4277
0
    word32 r;
4278
4279
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4280
    {
4281
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4282
        if (ret < 0)
4283
            return ret;
4284
    }
4285
#endif
4286
4287
0
    r = aes->rounds >> 1;
4288
4289
0
    if (r > 7 || r == 0) {
4290
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
4291
0
        return KEYUSAGE_E;
4292
0
    }
4293
4294
#ifdef WOLFSSL_AESNI
4295
    if (aes->use_aesni) {
4296
        ASSERT_SAVED_VECTOR_REGISTERS();
4297
4298
        #ifdef DEBUG_AESNI
4299
            printf("about to aes decrypt\n");
4300
            printf("in  = %p\n", inBlock);
4301
            printf("out = %p\n", outBlock);
4302
            printf("aes->key = %p\n", aes->key);
4303
            printf("aes->rounds = %d\n", aes->rounds);
4304
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
4305
        #endif
4306
4307
        /* if input and output same will overwrite input iv */
4308
        if ((const byte*)aes->tmp != inBlock)
4309
            XMEMCPY(aes->tmp, inBlock, WC_AES_BLOCK_SIZE);
4310
        AES_ECB_decrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
4311
                        (int)aes->rounds);
4312
        return 0;
4313
    }
4314
    else {
4315
        #ifdef DEBUG_AESNI
4316
            printf("Skipping AES-NI\n");
4317
        #endif
4318
    }
4319
#elif defined(WOLFSSL_ARMASM)
4320
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4321
#if !defined(__aarch64__)
4322
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
4323
#else
4324
    if (aes->use_aes_hw_crypto) {
4325
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
4326
            (int)aes->rounds);
4327
    }
4328
    else
4329
#endif /* !__aarch64__ */
4330
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
4331
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
4332
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
4333
    {
4334
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4335
            (const unsigned char*)aes->key, aes->rounds);
4336
    }
4337
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
4338
    {
4339
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4340
            (const unsigned char*)aes->key, aes->rounds);
4341
    }
4342
#endif
4343
    return 0;
4344
#endif /* WOLFSSL_AESNI */
4345
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
4346
    return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
4347
#endif
4348
#if defined(WOLFSSL_IMXRT_DCP)
4349
    if (aes->keylen == 16) {
4350
        DCPAesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4351
        return 0;
4352
    }
4353
#endif
4354
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
4355
    if (aes->useSWCrypt == 0) {
4356
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
4357
                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
4358
    }
4359
#endif
4360
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
4361
    if (wc_esp32AesSupportedKeyLen(aes)) {
4362
        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
4363
    }
4364
    else {
4365
        /* For example, the ESP32-S3 does not support HW for len = 24,
4366
         * so fall back to SW */
4367
    #ifdef DEBUG_WOLFSSL
4368
        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
4369
                        "unsupported keylen = %d", aes->keylen);
4370
    #endif
4371
    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
4372
#endif
4373
4374
#if defined(MAX3266X_AES)
4375
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
4376
        return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
4377
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
4378
                                    outBlock, (unsigned int)keySize);
4379
    }
4380
#endif
4381
4382
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
4383
    #ifndef WOLF_CRYPTO_CB_FIND
4384
    if (aes->devId != INVALID_DEVID)
4385
    #endif
4386
    {
4387
        ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock,
4388
                                            WC_AES_BLOCK_SIZE);
4389
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4390
            return ret_cb;
4391
        /* fall-through when unavailable */
4392
    }
4393
#endif
4394
4395
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
4396
0
    AesDecrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
4397
#else
4398
    AesDecrypt_C(aes, inBlock, outBlock, r);
4399
#endif
4400
4401
0
    return 0;
4402
0
} /* wc_AesDecrypt[_SW]() */
4403
#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
4404
#endif
4405
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
4406
#endif /* HAVE_AES_DECRYPT */
4407
4408
#endif /* NEED_AES_TABLES */
4409
4410
#ifdef WOLF_CRYPTO_CB_ONLY_AES
4411
/* Under WOLF_CRYPTO_CB_ONLY_AES the per-block primitive is a thin shim over
4412
 * the cryptocb ECB callback. When the callback returns CRYPTOCB_UNAVAILABLE
4413
 * there is no software fallback, so the operation fails with NO_VALID_DEVID. */
4414
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
4415
    byte* outBlock)
4416
{
4417
    int ret;
4418
4419
    if (aes == NULL || inBlock == NULL || outBlock == NULL)
4420
        return BAD_FUNC_ARG;
4421
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4422
    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4423
    if (ret < 0)
4424
        return ret;
4425
#endif
4426
4427
    ret = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4428
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4429
        return ret;
4430
    return NO_VALID_DEVID;
4431
}
4432
4433
#ifdef HAVE_AES_DECRYPT
4434
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
4435
    byte* outBlock)
4436
{
4437
    int ret;
4438
4439
    if (aes == NULL || inBlock == NULL || outBlock == NULL)
4440
        return BAD_FUNC_ARG;
4441
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4442
    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4443
    if (ret < 0)
4444
        return ret;
4445
#endif
4446
4447
    ret = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4448
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4449
        return ret;
4450
    return NO_VALID_DEVID;
4451
}
4452
#endif /* HAVE_AES_DECRYPT */
4453
#endif /* WOLF_CRYPTO_CB_ONLY_AES */
4454
4455
#ifndef WC_AES_HAVE_PREFETCH_ARG
4456
    #ifndef AesEncrypt_preFetchOpt
4457
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4458
            wc_AesEncrypt(aes, inBlock, outBlock)
4459
    #endif
4460
    #ifndef AesDecrypt_preFetchOpt
4461
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4462
            wc_AesDecrypt(aes, inBlock, outBlock)
4463
    #endif
4464
#endif
4465
4466
/* wc_AesSetKey */
4467
#if defined(STM32_CRYPTO)
4468
4469
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4470
            const byte* iv, int dir)
4471
    {
4472
        word32 *rk;
4473
4474
        (void)dir;
4475
4476
        if (aes == NULL || (keylen != 16 &&
4477
        #ifdef WOLFSSL_AES_192
4478
            keylen != 24 &&
4479
        #endif
4480
            keylen != 32)) {
4481
            return BAD_FUNC_ARG;
4482
        }
4483
4484
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4485
        {
4486
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4487
            if (ret < 0)
4488
                return ret;
4489
        }
4490
#endif
4491
4492
        rk = aes->key;
4493
        aes->keylen = keylen;
4494
        aes->rounds = keylen/4 + 6;
4495
        XMEMCPY(rk, userKey, keylen);
4496
    #ifdef WOLF_CRYPTO_CB
4497
        /* Keep a raw (non-reversed) copy for crypto-callback offload, e.g. the
4498
         * DHUK device reads the seed from devKey. Mirrors the generic
4499
         * wc_AesSetKey cryptocb path. */
4500
        if (keylen <= sizeof(aes->devKey)) {
4501
            XMEMCPY(aes->devKey, userKey, keylen);
4502
        }
4503
    #endif
4504
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
4505
        ByteReverseWords(rk, rk, keylen);
4506
    #endif
4507
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4508
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4509
        defined(WOLFSSL_AES_CTS)
4510
        aes->left = 0;
4511
    #endif
4512
        return wc_AesSetIV(aes, iv);
4513
    }
4514
    #if defined(WOLFSSL_AES_DIRECT)
4515
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4516
                            const byte* iv, int dir)
4517
        {
4518
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4519
        }
4520
    #endif
4521
4522
#elif defined(HAVE_COLDFIRE_SEC)
4523
    #if defined (HAVE_THREADX)
4524
        #include "memory_pools.h"
4525
        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
4526
    #endif
4527
4528
    #define AES_BUFFER_SIZE (WC_AES_BLOCK_SIZE * 64)
4529
    static unsigned char *AESBuffIn = NULL;
4530
    static unsigned char *AESBuffOut = NULL;
4531
    static byte *secReg;
4532
    static byte *secKey;
4533
    static volatile SECdescriptorType *secDesc;
4534
4535
    static wolfSSL_Mutex Mutex_AesSEC;
4536
4537
    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
4538
    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
4539
4540
    extern volatile unsigned char __MBAR[];
4541
4542
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4543
        const byte* iv, int dir)
4544
    {
4545
        if (AESBuffIn == NULL) {
4546
        #if defined (HAVE_THREADX)
4547
            int s1, s2, s3, s4, s5;
4548
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
4549
                                  sizeof(SECdescriptorType), TX_NO_WAIT);
4550
            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
4551
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4552
            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
4553
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4554
            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
4555
                                  WC_AES_BLOCK_SIZE*2, TX_NO_WAIT);
4556
            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
4557
                                  WC_AES_BLOCK_SIZE, TX_NO_WAIT);
4558
4559
            if (s1 || s2 || s3 || s4 || s5)
4560
                return BAD_FUNC_ARG;
4561
        #else
4562
            #warning "Allocate non-Cache buffers"
4563
        #endif
4564
4565
            wc_InitMutex(&Mutex_AesSEC);
4566
        }
4567
4568
        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4569
            return BAD_FUNC_ARG;
4570
4571
        if (aes == NULL)
4572
            return BAD_FUNC_ARG;
4573
4574
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4575
        {
4576
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4577
            if (ret < 0)
4578
                return ret;
4579
        }
4580
#endif
4581
4582
        aes->keylen = keylen;
4583
        aes->rounds = keylen/4 + 6;
4584
        XMEMCPY(aes->key, userKey, keylen);
4585
4586
        if (iv)
4587
            XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4588
4589
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4590
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4591
        defined(WOLFSSL_AES_CTS)
4592
        aes->left = 0;
4593
    #endif
4594
4595
        return 0;
4596
    }
4597
#elif defined(FREESCALE_LTC)
4598
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
4599
        const byte* iv, int dir, int checkKeyLen)
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
        (void)dir;
4617
4618
        aes->rounds = keylen/4 + 6;
4619
        XMEMCPY(aes->key, userKey, keylen);
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
        return wc_AesSetIV(aes, iv);
4628
    }
4629
4630
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4631
        const byte* iv, int dir)
4632
    {
4633
        if (aes == NULL || userKey == NULL) {
4634
            return BAD_FUNC_ARG;
4635
        }
4636
        if (keylen > sizeof(aes->key)) {
4637
            return BAD_FUNC_ARG;
4638
        }
4639
4640
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4641
    }
4642
4643
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4644
                        const byte* iv, int dir)
4645
    {
4646
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4647
    }
4648
#elif defined(WOLFSSL_NRF51_AES)
4649
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4650
        const byte* iv, int dir)
4651
    {
4652
        int ret;
4653
4654
        (void)dir;
4655
        (void)iv;
4656
4657
        if (aes == NULL || keylen != 16)
4658
            return BAD_FUNC_ARG;
4659
4660
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4661
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4662
        if (ret < 0)
4663
            return ret;
4664
#endif
4665
4666
        aes->keylen = keylen;
4667
        aes->rounds = keylen/4 + 6;
4668
        XMEMCPY(aes->key, userKey, keylen);
4669
        ret = nrf51_aes_set_key(userKey);
4670
4671
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4672
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4673
        defined(WOLFSSL_AES_CTS)
4674
        aes->left = 0;
4675
    #endif
4676
4677
        return ret;
4678
    }
4679
4680
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4681
                        const byte* iv, int dir)
4682
    {
4683
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4684
    }
4685
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4686
    /* This is the only definition for HW only.
4687
     * but needs to be renamed when fallback needed.
4688
     * See call in wc_AesSetKey() */
4689
    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
4690
        const byte* iv, int dir)
4691
    {
4692
        (void)dir;
4693
        (void)iv;
4694
        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
4695
        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
4696
            return BAD_FUNC_ARG;
4697
        }
4698
4699
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4700
        {
4701
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4702
            if (ret < 0)
4703
                return ret;
4704
        }
4705
#endif
4706
4707
    #if !defined(WOLFSSL_AES_128)
4708
        if (keylen == 16) {
4709
            return BAD_FUNC_ARG;
4710
        }
4711
    #endif
4712
4713
    #if !defined(WOLFSSL_AES_192)
4714
        if (keylen == 24) {
4715
            return BAD_FUNC_ARG;
4716
        }
4717
    #endif
4718
4719
    #if !defined(WOLFSSL_AES_256)
4720
        if (keylen == 32) {
4721
            return BAD_FUNC_ARG;
4722
        }
4723
    #endif
4724
4725
        aes->keylen = keylen;
4726
        aes->rounds = keylen/4 + 6;
4727
4728
        XMEMCPY(aes->key, userKey, keylen);
4729
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4730
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4731
            defined(WOLFSSL_AES_CTS)
4732
            aes->left = 0;
4733
        #endif
4734
        return wc_AesSetIV(aes, iv);
4735
    } /* wc_AesSetKey */
4736
4737
    /* end #elif ESP32 */
4738
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
4739
4740
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
4741
                    int dir)
4742
    {
4743
        SaSiError_t ret = SASI_OK;
4744
        SaSiAesIv_t iv_aes;
4745
4746
        if (aes == NULL ||
4747
           (keylen != AES_128_KEY_SIZE &&
4748
            keylen != AES_192_KEY_SIZE &&
4749
            keylen != AES_256_KEY_SIZE)) {
4750
            return BAD_FUNC_ARG;
4751
        }
4752
4753
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4754
        {
4755
            int ret2 =
4756
                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4757
            if (ret2 < 0)
4758
                return ret2;
4759
        }
4760
#endif
4761
4762
    #if defined(AES_MAX_KEY_SIZE)
4763
        if (keylen > (AES_MAX_KEY_SIZE/8)) {
4764
            return BAD_FUNC_ARG;
4765
        }
4766
    #endif
4767
        if (dir != AES_ENCRYPTION &&
4768
            dir != AES_DECRYPTION) {
4769
            return BAD_FUNC_ARG;
4770
        }
4771
4772
        if (dir == AES_ENCRYPTION) {
4773
            aes->ctx.mode = SASI_AES_ENCRYPT;
4774
            SaSi_AesInit(&aes->ctx.user_ctx,
4775
                         SASI_AES_ENCRYPT,
4776
                         SASI_AES_MODE_CBC,
4777
                         SASI_AES_PADDING_NONE);
4778
        }
4779
        else {
4780
            aes->ctx.mode = SASI_AES_DECRYPT;
4781
            SaSi_AesInit(&aes->ctx.user_ctx,
4782
                         SASI_AES_DECRYPT,
4783
                         SASI_AES_MODE_CBC,
4784
                         SASI_AES_PADDING_NONE);
4785
        }
4786
4787
        aes->keylen = keylen;
4788
        aes->rounds = keylen/4 + 6;
4789
        XMEMCPY(aes->key, userKey, keylen);
4790
4791
        aes->ctx.key.pKey = (byte*)aes->key;
4792
        aes->ctx.key.keySize= keylen;
4793
4794
        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
4795
                             SASI_AES_USER_KEY,
4796
                             &aes->ctx.key,
4797
                             sizeof(aes->ctx.key));
4798
        if (ret != SASI_OK) {
4799
            return BAD_FUNC_ARG;
4800
        }
4801
4802
        ret = wc_AesSetIV(aes, iv);
4803
4804
        if (iv)
4805
            XMEMCPY(iv_aes, iv, WC_AES_BLOCK_SIZE);
4806
        else
4807
            XMEMSET(iv_aes,  0, WC_AES_BLOCK_SIZE);
4808
4809
4810
        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
4811
        if (ret != SASI_OK) {
4812
            return ret;
4813
        }
4814
       return ret;
4815
    }
4816
    #if defined(WOLFSSL_AES_DIRECT)
4817
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4818
                            const byte* iv, int dir)
4819
        {
4820
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4821
        }
4822
    #endif
4823
4824
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
4825
    && !defined(WOLFSSL_QNX_CAAM)
4826
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4827
4828
#elif defined(WOLFSSL_AFALG)
4829
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4830
4831
#elif defined(WOLFSSL_DEVCRYPTO_AES)
4832
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
4833
4834
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4835
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
4836
4837
#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
4838
     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
4839
    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
4840
4841
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
4842
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4843
            const byte* iv, int dir)
4844
    {
4845
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4846
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4847
        defined(WOLFSSL_AES_CTS)
4848
        aes->left = 0;
4849
    #endif
4850
4851
        aes->keylen = (int)keylen;
4852
        aes->rounds = (keylen/4) + 6;
4853
4854
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4855
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
4856
#else
4857
        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
4858
4859
    #ifdef HAVE_AES_DECRYPT
4860
        if (dir == AES_DECRYPTION) {
4861
            AES_invert_key((byte*)aes->key, aes->rounds);
4862
        }
4863
    #else
4864
        (void)dir;
4865
    #endif
4866
#endif
4867
        return wc_AesSetIV(aes, iv);
4868
    }
4869
4870
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4871
            const byte* iv, int dir)
4872
    {
4873
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
4874
        int cbRet;
4875
#endif
4876
        if ((aes == NULL) || (userKey == NULL)) {
4877
            return BAD_FUNC_ARG;
4878
        }
4879
4880
        switch (keylen) {
4881
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4882
        defined(WOLFSSL_AES_128)
4883
        case 16:
4884
    #endif
4885
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4886
        defined(WOLFSSL_AES_192)
4887
        case 24:
4888
    #endif
4889
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4890
        defined(WOLFSSL_AES_256)
4891
        case 32:
4892
    #endif
4893
            break;
4894
        default:
4895
            return BAD_FUNC_ARG;
4896
        }
4897
4898
    #ifdef WOLF_CRYPTO_CB
4899
        if (aes->devId != INVALID_DEVID) {
4900
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
4901
            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
4902
            if (ret == 0) {
4903
                /* Callback succeeded - SE owns the key */
4904
                aes->keylen = (int)keylen;
4905
                if (iv != NULL)
4906
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4907
                else
4908
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
4909
                return 0;
4910
            }
4911
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
4912
                aes->devCtx = NULL;
4913
                return ret;
4914
            }
4915
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
4916
        #endif
4917
        #ifdef WOLF_CRYPTO_CB_SETKEY
4918
            cbRet = wc_CryptoCb_SetKey(aes->devId,
4919
                WC_SETKEY_AES, aes, (void*)userKey, keylen,
4920
                (void*)iv,
4921
                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
4922
            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4923
                return cbRet;
4924
            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
4925
        #endif /* WOLF_CRYPTO_CB_SETKEY */
4926
            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
4927
            if (keylen > sizeof(aes->devKey)) {
4928
                return BAD_FUNC_ARG;
4929
            }
4930
            XMEMCPY(aes->devKey, userKey, keylen);
4931
        }
4932
    #endif
4933
4934
        return AesSetKey(aes, userKey, keylen, iv, dir);
4935
    }
4936
4937
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
4938
        /* AES-CTR and AES-DIRECT need to use this for key setup */
4939
        /* This function allows key sizes that are not 128/192/256 bits */
4940
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4941
                           const byte* iv, int dir)
4942
    {
4943
        if (aes == NULL) {
4944
            return BAD_FUNC_ARG;
4945
        }
4946
        if (keylen > sizeof(aes->key)) {
4947
            return BAD_FUNC_ARG;
4948
        }
4949
4950
        return AesSetKey(aes, userKey, keylen, iv, dir);
4951
    }
4952
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
4953
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
4954
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4955
            const byte* iv, int dir)
4956
    {
4957
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4958
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4959
        defined(WOLFSSL_AES_CTS)
4960
        aes->left = 0;
4961
    #endif
4962
4963
        aes->keylen = (int)keylen;
4964
        aes->rounds = (keylen/4) + 6;
4965
4966
        /* Determine base vs vector-crypto before the (dispatched) key setup so
4967
         * the schedule matches the mode functions that later consume it. */
4968
        Aes_SetCrypto();
4969
        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
4970
4971
    #ifdef HAVE_AES_DECRYPT
4972
        if (dir == AES_DECRYPTION) {
4973
            AES_invert_key((byte*)aes->key, aes->rounds);
4974
        }
4975
    #else
4976
        (void)dir;
4977
    #endif
4978
        return wc_AesSetIV(aes, iv);
4979
    }
4980
4981
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4982
            const byte* iv, int dir)
4983
    {
4984
        if ((aes == NULL) || (userKey == NULL)) {
4985
            return BAD_FUNC_ARG;
4986
        }
4987
4988
        switch (keylen) {
4989
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4990
        defined(WOLFSSL_AES_128)
4991
        case 16:
4992
    #endif
4993
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4994
        defined(WOLFSSL_AES_192)
4995
        case 24:
4996
    #endif
4997
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4998
        defined(WOLFSSL_AES_256)
4999
        case 32:
5000
    #endif
5001
            break;
5002
        default:
5003
            return BAD_FUNC_ARG;
5004
        }
5005
5006
    #ifdef WOLF_CRYPTO_CB
5007
        if (aes->devId != INVALID_DEVID) {
5008
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5009
            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5010
            if (ret == 0) {
5011
                /* Callback succeeded - SE owns the key */
5012
                aes->keylen = (int)keylen;
5013
                if (iv != NULL)
5014
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5015
                else
5016
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5017
                return 0;
5018
            }
5019
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5020
                aes->devCtx = NULL;
5021
                return ret;
5022
            }
5023
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5024
        #endif
5025
            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
5026
            if (keylen > sizeof(aes->devKey)) {
5027
                return BAD_FUNC_ARG;
5028
            }
5029
            XMEMCPY(aes->devKey, userKey, keylen);
5030
        }
5031
    #endif
5032
5033
        return AesSetKey(aes, userKey, keylen, iv, dir);
5034
    }
5035
5036
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5037
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5038
        /* This function allows key sizes that are not 128/192/256 bits */
5039
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5040
                           const byte* iv, int dir)
5041
    {
5042
        if (aes == NULL) {
5043
            return BAD_FUNC_ARG;
5044
        }
5045
        if (keylen > sizeof(aes->key)) {
5046
            return BAD_FUNC_ARG;
5047
        }
5048
5049
        return AesSetKey(aes, userKey, keylen, iv, dir);
5050
    }
5051
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5052
#elif defined(FREESCALE_MMCAU)
5053
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
5054
        const byte* iv, int dir, int checkKeyLen)
5055
    {
5056
        int ret;
5057
        byte* rk;
5058
        byte* tmpKey = (byte*)userKey;
5059
        int tmpKeyDynamic = 0;
5060
        word32 alignOffset = 0;
5061
5062
        (void)dir;
5063
5064
        if (aes == NULL)
5065
            return BAD_FUNC_ARG;
5066
5067
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5068
        {
5069
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5070
            if (ret < 0)
5071
                return ret;
5072
        }
5073
#endif
5074
5075
        if (checkKeyLen) {
5076
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
5077
                return BAD_FUNC_ARG;
5078
        }
5079
5080
        rk = (byte*)aes->key;
5081
        if (rk == NULL)
5082
            return BAD_FUNC_ARG;
5083
5084
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5085
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5086
        defined(WOLFSSL_AES_CTS)
5087
        aes->left = 0;
5088
    #endif
5089
5090
        aes->rounds = keylen/4 + 6;
5091
5092
    #ifdef FREESCALE_MMCAU_CLASSIC
5093
        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
5094
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
5095
            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
5096
                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5097
            if (tmp == NULL) {
5098
                return MEMORY_E;
5099
            }
5100
            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
5101
                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
5102
            tmpKey = tmp + alignOffset;
5103
            XMEMCPY(tmpKey, userKey, keylen);
5104
            tmpKeyDynamic = 1;
5105
        #else
5106
            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
5107
            return BAD_ALIGN_E;
5108
        #endif
5109
        }
5110
    #endif
5111
5112
        ret = wolfSSL_CryptHwMutexLock();
5113
        if(ret == 0) {
5114
        #ifdef FREESCALE_MMCAU_CLASSIC
5115
            cau_aes_set_key(tmpKey, keylen*8, rk);
5116
        #else
5117
            MMCAU_AES_SetKey(tmpKey, keylen, rk);
5118
        #endif
5119
            wolfSSL_CryptHwMutexUnLock();
5120
5121
            ret = wc_AesSetIV(aes, iv);
5122
        }
5123
5124
        if (tmpKeyDynamic == 1) {
5125
            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5126
        }
5127
5128
        return ret;
5129
    }
5130
5131
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5132
        const byte* iv, int dir)
5133
    {
5134
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
5135
    }
5136
5137
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5138
                        const byte* iv, int dir)
5139
    {
5140
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
5141
    }
5142
5143
#elif defined(WOLFSSL_PSOC6_CRYPTO)
5144
5145
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5146
        const byte* iv, int dir)
5147
    {
5148
        return wc_Psoc6_Aes_SetKey(aes, userKey, keylen, iv, dir);
5149
    }
5150
5151
    #if defined(WOLFSSL_AES_DIRECT)
5152
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5153
                            const byte* iv, int dir)
5154
        {
5155
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
5156
        }
5157
    #endif /* WOLFSSL_AES_DIRECT */
5158
#else
5159
    #define NEED_SOFTWARE_AES_SETKEY
5160
#endif
5161
5162
/* Either we fell though with no HW support at all,
5163
 * or perhaps there's HW support for *some* keylengths
5164
 * and we need both HW and SW. */
5165
#ifdef NEED_SOFTWARE_AES_SETKEY
5166
5167
#ifdef NEED_AES_TABLES
5168
5169
#ifndef WC_AES_BITSLICED
5170
#if !defined(WOLFSSL_ARMASM)
5171
/* Set the AES key and expand.
5172
 *
5173
 * @param [in]  aes    AES object.
5174
 * @param [in]  key    Block to encrypt.
5175
 * @param [in]  keySz  Number of bytes in key.
5176
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
5177
 */
5178
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
5179
0
{
5180
#ifdef WC_C_DYNAMIC_FALLBACK
5181
    word32* rk = aes->key_C_fallback;
5182
#else
5183
0
    word32* rk = aes->key;
5184
0
#endif
5185
0
    word32 temp;
5186
0
    unsigned int i = 0;
5187
5188
0
    XMEMCPY(rk, key, keySz);
5189
0
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
5190
0
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
5191
0
    !defined(MAX3266X_AES)
5192
    /* Always reverse words when using only SW */
5193
0
    {
5194
0
        ByteReverseWords(rk, rk, keySz);
5195
0
    }
5196
#else
5197
    /* Sometimes reverse words when using supported HW */
5198
    #if defined(WOLFSSL_ESPIDF)
5199
        /* Some platforms may need SW fallback (e.g. AES192) */
5200
        #if defined(NEED_AES_HW_FALLBACK)
5201
        {
5202
            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
5203
            if (wc_esp32AesSupportedKeyLen(aes)) {
5204
                /* don't reverse for HW supported key lengths */
5205
            }
5206
            else {
5207
                ByteReverseWords(rk, rk, keySz);
5208
            }
5209
        }
5210
        #else
5211
            /* If we don't need SW fallback, don't need to reverse words. */
5212
        #endif /* NEED_AES_HW_FALLBACK */
5213
    #endif /* WOLFSSL_ESPIDF */
5214
#endif /* LITTLE_ENDIAN_ORDER, etc */
5215
5216
0
    switch (keySz) {
5217
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
5218
0
        defined(WOLFSSL_AES_128)
5219
0
    case 16:
5220
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5221
        temp = (word32)-1;
5222
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5223
    #endif
5224
0
        while (1)
5225
0
        {
5226
0
            temp  = rk[3];
5227
0
            rk[4] = rk[0] ^
5228
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5229
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5230
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5231
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5232
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5233
        #else
5234
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5235
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5236
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5237
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5238
        #endif
5239
0
                rcon[i];
5240
0
            rk[5] = rk[1] ^ rk[4];
5241
0
            rk[6] = rk[2] ^ rk[5];
5242
0
            rk[7] = rk[3] ^ rk[6];
5243
0
            if (++i == 10)
5244
0
                break;
5245
0
            rk += 4;
5246
0
        }
5247
0
        break;
5248
0
#endif /* 128 */
5249
5250
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
5251
0
        defined(WOLFSSL_AES_192)
5252
0
    case 24:
5253
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5254
        temp = (word32)-1;
5255
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5256
    #endif
5257
        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
5258
0
        while (1)
5259
0
        {
5260
0
            temp = rk[ 5];
5261
0
            rk[ 6] = rk[ 0] ^
5262
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5263
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5264
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5265
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5266
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5267
        #else
5268
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5269
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5270
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5271
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5272
        #endif
5273
0
                rcon[i];
5274
0
            rk[ 7] = rk[ 1] ^ rk[ 6];
5275
0
            rk[ 8] = rk[ 2] ^ rk[ 7];
5276
0
            rk[ 9] = rk[ 3] ^ rk[ 8];
5277
0
            if (++i == 8)
5278
0
                break;
5279
0
            rk[10] = rk[ 4] ^ rk[ 9];
5280
0
            rk[11] = rk[ 5] ^ rk[10];
5281
0
            rk += 6;
5282
0
        }
5283
0
        break;
5284
0
#endif /* 192 */
5285
5286
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
5287
0
        defined(WOLFSSL_AES_256)
5288
0
    case 32:
5289
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5290
        temp = (word32)-1;
5291
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5292
    #endif
5293
0
        while (1)
5294
0
        {
5295
0
            temp = rk[ 7];
5296
0
            rk[ 8] = rk[ 0] ^
5297
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5298
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5299
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5300
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5301
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5302
        #else
5303
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5304
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5305
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5306
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5307
        #endif
5308
0
                rcon[i];
5309
0
            rk[ 9] = rk[ 1] ^ rk[ 8];
5310
0
            rk[10] = rk[ 2] ^ rk[ 9];
5311
0
            rk[11] = rk[ 3] ^ rk[10];
5312
0
            if (++i == 7)
5313
0
                break;
5314
0
            temp = rk[11];
5315
0
            rk[12] = rk[ 4] ^
5316
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5317
0
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
5318
0
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
5319
0
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
5320
0
                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
5321
        #else
5322
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
5323
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
5324
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
5325
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
5326
        #endif
5327
0
            rk[13] = rk[ 5] ^ rk[12];
5328
0
            rk[14] = rk[ 6] ^ rk[13];
5329
0
            rk[15] = rk[ 7] ^ rk[14];
5330
5331
0
            rk += 8;
5332
0
        }
5333
0
        break;
5334
0
#endif /* 256 */
5335
0
    } /* switch */
5336
0
    ForceZero(&temp, sizeof(temp));
5337
5338
0
#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
5339
0
    if (dir == AES_DECRYPTION) {
5340
0
        unsigned int j;
5341
5342
#ifdef WC_C_DYNAMIC_FALLBACK
5343
        rk = aes->key_C_fallback;
5344
#else
5345
0
        rk = aes->key;
5346
0
#endif
5347
5348
        /* invert the order of the round keys: */
5349
0
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
5350
0
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
5351
0
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
5352
0
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
5353
0
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
5354
0
        }
5355
0
        ForceZero(&temp, sizeof(temp));
5356
0
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
5357
        /* apply the inverse MixColumn transform to all round keys but the
5358
           first and the last: */
5359
0
        for (i = 1; i < aes->rounds; i++) {
5360
0
            rk += 4;
5361
0
            rk[0] =
5362
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
5363
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
5364
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
5365
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
5366
0
            rk[1] =
5367
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
5368
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
5369
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
5370
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
5371
0
            rk[2] =
5372
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
5373
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
5374
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
5375
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
5376
0
            rk[3] =
5377
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
5378
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
5379
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
5380
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
5381
0
        }
5382
0
    #endif
5383
0
    }
5384
#else
5385
    (void)dir;
5386
#endif /* HAVE_AES_DECRYPT */
5387
5388
#ifdef WOLFSSL_CHECK_MEM_ZERO
5389
    wc_MemZero_Check(&temp, sizeof(temp));
5390
#else
5391
0
    (void)temp;
5392
0
#endif
5393
0
}
5394
#endif
5395
#else /* WC_AES_BITSLICED */
5396
/* Set the AES key and expand.
5397
 *
5398
 * @param [in]  aes    AES object.
5399
 * @param [in]  key    Block to encrypt.
5400
 * @param [in]  keySz  Number of bytes in key.
5401
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
5402
 */
5403
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
5404
{
5405
    /* No need to invert when decrypting. */
5406
    (void)dir;
5407
5408
    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
5409
}
5410
#endif /* WC_AES_BITSLICED */
5411
5412
#endif /* NEED_AES_TABLES */
5413
5414
#ifndef WOLFSSL_RISCV_ASM
5415
    /* Software AES - SetKey */
5416
    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
5417
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
5418
        int checkKeyLen)
5419
0
    {
5420
0
        int ret;
5421
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
5422
        int cbRet;
5423
#endif
5424
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5425
        byte   local[32];
5426
        word32 localSz = 32;
5427
    #endif
5428
5429
0
        if (aes == NULL)
5430
0
            return BAD_FUNC_ARG;
5431
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5432
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5433
        if (ret < 0)
5434
            return ret;
5435
#endif
5436
5437
0
        switch (keylen) {
5438
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5439
0
        defined(WOLFSSL_AES_128)
5440
0
        case 16:
5441
0
    #endif
5442
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5443
0
        defined(WOLFSSL_AES_192)
5444
0
        case 24:
5445
0
    #endif
5446
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5447
0
        defined(WOLFSSL_AES_256)
5448
0
        case 32:
5449
0
    #endif
5450
0
            break;
5451
0
        default:
5452
0
            return BAD_FUNC_ARG;
5453
0
        }
5454
5455
    #ifdef WOLF_CRYPTO_CB
5456
        #ifndef WOLF_CRYPTO_CB_FIND
5457
        if (aes->devId != INVALID_DEVID)
5458
        #endif
5459
        {
5460
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5461
            ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5462
            if (ret == 0) {
5463
                /* Callback succeeded - SE owns the key */
5464
                aes->keylen = (int)keylen;
5465
                if (iv != NULL)
5466
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5467
                else
5468
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5469
                return 0;
5470
            }
5471
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5472
                aes->devCtx = NULL;
5473
                return ret;
5474
            }
5475
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5476
        #endif
5477
        #ifdef WOLF_CRYPTO_CB_SETKEY
5478
            cbRet = wc_CryptoCb_SetKey(aes->devId,
5479
                WC_SETKEY_AES, aes, (void*)userKey, keylen,
5480
                (void*)iv,
5481
                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
5482
            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5483
                return cbRet;
5484
            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
5485
        #endif /* WOLF_CRYPTO_CB_SETKEY */
5486
            /* Standard CryptoCB path - copy key to devKey */
5487
            if (keylen > sizeof(aes->devKey)) {
5488
                return BAD_FUNC_ARG;
5489
            }
5490
            XMEMCPY(aes->devKey, userKey, keylen);
5491
        }
5492
    #endif
5493
5494
    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
5495
        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
5496
            return WC_HW_E;
5497
        }
5498
    #endif
5499
5500
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5501
        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
5502
            keylen == (24 + WC_CAAM_BLOB_SZ) ||
5503
            keylen == (32 + WC_CAAM_BLOB_SZ)) {
5504
            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
5505
                return BAD_FUNC_ARG;
5506
            }
5507
5508
            /* set local values */
5509
            userKey = local;
5510
            keylen = localSz;
5511
        }
5512
    #endif
5513
5514
    #ifdef WOLFSSL_SECO_CAAM
5515
        /* if set to use hardware than import the key */
5516
        if (aes->devId == WOLFSSL_SECO_DEVID) {
5517
            int keyGroup = 1; /* group one was chosen arbitrarily */
5518
            unsigned int keyIdOut;
5519
            byte importiv[GCM_NONCE_MID_SZ];
5520
            int importivSz = GCM_NONCE_MID_SZ;
5521
            int keyType = 0;
5522
            WC_RNG rng;
5523
5524
            if (wc_InitRng(&rng) != 0) {
5525
                WOLFSSL_MSG("RNG init for IV failed");
5526
                return WC_HW_E;
5527
            }
5528
5529
            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
5530
                WOLFSSL_MSG("Generate IV failed");
5531
                wc_FreeRng(&rng);
5532
                return WC_HW_E;
5533
            }
5534
            wc_FreeRng(&rng);
5535
5536
            if (iv)
5537
                XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5538
            else
5539
                XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5540
5541
            switch (keylen) {
5542
                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
5543
                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
5544
                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
5545
            }
5546
5547
            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
5548
                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
5549
            if (keyIdOut == 0) {
5550
                return WC_HW_E;
5551
            }
5552
            aes->blackKey = keyIdOut;
5553
            return 0;
5554
        }
5555
    #endif
5556
5557
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
5558
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
5559
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) || \
5560
        defined(WOLFSSL_NXP_HASHCRYPT_AES)
5561
        #ifdef WOLF_CRYPTO_CB
5562
        #ifndef WOLF_CRYPTO_CB_FIND
5563
        if (aes->devId != INVALID_DEVID)
5564
        #endif
5565
        #endif
5566
        {
5567
            if (keylen > sizeof(aes->devKey)) {
5568
                return BAD_FUNC_ARG;
5569
            }
5570
            XMEMCPY(aes->devKey, userKey, keylen);
5571
        }
5572
    #endif
5573
5574
    #ifdef WOLF_CRYPTO_CB_ONLY_AES
5575
        /* No software AES schedule under CB_ONLY: aes->key[] (round keys) are
5576
         * unused because the static wc_AesEncrypt/wc_AesDecrypt are cryptocb-
5577
         * ECB shims. aes->rounds is still populated because wc_AesGetKeySize()
5578
         * reads it as the source of truth for the configured key size. */
5579
        aes->keylen = (int)keylen;
5580
        aes->rounds = (keylen / 4) + 6;
5581
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5582
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5583
            defined(WOLFSSL_AES_CTS)
5584
        aes->left = 0;
5585
        #endif
5586
        (void)dir;
5587
        return wc_AesSetIV(aes, iv);
5588
    #endif
5589
5590
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
5591
        if (checkKeyLen) {
5592
            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
5593
             * all key sizes. Otherwise this condition is never true. */
5594
            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
5595
                return BAD_FUNC_ARG;
5596
            }
5597
        }
5598
    #else
5599
0
        (void) checkKeyLen;
5600
0
    #endif
5601
5602
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5603
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5604
        defined(WOLFSSL_AES_CTS)
5605
        aes->left = 0;
5606
    #endif
5607
5608
0
        aes->keylen = (int)keylen;
5609
0
        aes->rounds = (keylen/4) + 6;
5610
0
        ret = wc_AesSetIV(aes, iv);
5611
0
        if (ret != 0)
5612
0
            return ret;
5613
5614
#ifdef WC_C_DYNAMIC_FALLBACK
5615
#ifdef NEED_AES_TABLES
5616
        AesSetKey_C(aes, userKey, keylen, dir);
5617
#endif /* NEED_AES_TABLES */
5618
#endif /* WC_C_DYNAMIC_FALLBACK */
5619
5620
    #ifdef WOLFSSL_AESNI
5621
5622
       /* The dynamics for determining whether AES-NI will be used are tricky.
5623
        *
5624
        * First, we check for CPU support and cache the result -- if AES-NI is
5625
        * missing, we always shortcut to the AesSetKey_C() path.
5626
        *
5627
        * Second, if the CPU supports AES-NI, we confirm on a per-call basis
5628
        * that it's safe to use in the caller context, using
5629
        * SAVE_VECTOR_REGISTERS2().  This is an always-true no-op in user-space
5630
        * builds, but has substantive logic behind it in kernel module builds.
5631
        *
5632
        * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on
5633
        * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with
5634
        * success but with AES-NI disabled (the earlier AesSetKey_C() allows
5635
        * future encrypt/decrypt calls to succeed), otherwise we fail.
5636
        *
5637
        * Upon successful return, aes->use_aesni will have a zero value if
5638
        * AES-NI is disabled, and a nonzero value if it's enabled.
5639
        *
5640
        * An additional, optional semantic is available via
5641
        * WC_FLAG_DONT_USE_VECTOR_OPS, and is used in some kernel module builds
5642
        * to let the caller inhibit AES-NI.  When this macro is defined,
5643
        * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of
5644
        * uninitialized data in aes->use_aesni.  That's why support for
5645
        * WC_FLAG_DONT_USE_VECTOR_OPS must remain optional -- wc_AesInit() was
5646
        * only added in release 3.11.0, so legacy applications inevitably call
5647
        * wc_AesSetKey() on uninitialized Aes contexts.  This must continue to
5648
        * function correctly with default build settings.
5649
        */
5650
5651
        if (WOLFSSL_ATOMIC_LOAD(checkedAESNI) == 0) {
5652
            WOLFSSL_ATOMIC_STORE(haveAESNI, Check_CPU_support_AES());
5653
            WOLFSSL_ATOMIC_STORE(checkedAESNI, 1);
5654
        }
5655
        if (WOLFSSL_ATOMIC_LOAD(haveAESNI)
5656
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS) && !defined(WC_C_DYNAMIC_FALLBACK)
5657
            && (aes->use_aesni != WC_FLAG_DONT_USE_VECTOR_OPS)
5658
#endif
5659
            )
5660
        {
5661
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS)
5662
            if (aes->use_aesni == WC_FLAG_DONT_USE_VECTOR_OPS) {
5663
                aes->use_aesni = 0;
5664
                return 0;
5665
            }
5666
#endif
5667
            aes->use_aesni = 0;
5668
            #ifdef WOLFSSL_KERNEL_MODE
5669
            /* runtime alignment check */
5670
            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
5671
                ret = BAD_ALIGN_E;
5672
            }
5673
            else
5674
            #endif /* WOLFSSL_KERNEL_MODE */
5675
            {
5676
                ret = SAVE_VECTOR_REGISTERS2();
5677
            }
5678
            if (ret == 0) {
5679
                if (dir == AES_ENCRYPTION)
5680
                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5681
#ifdef HAVE_AES_DECRYPT
5682
                else
5683
                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5684
#endif
5685
5686
                RESTORE_VECTOR_REGISTERS();
5687
5688
                if (ret == 0)
5689
                    aes->use_aesni = 1;
5690
                else {
5691
#ifdef WC_C_DYNAMIC_FALLBACK
5692
                    ret = 0;
5693
#endif
5694
                }
5695
                return ret;
5696
            } else {
5697
#ifdef WC_C_DYNAMIC_FALLBACK
5698
                return 0;
5699
#else
5700
                return ret;
5701
#endif
5702
            }
5703
        }
5704
        else {
5705
            aes->use_aesni = 0;
5706
#ifdef WC_C_DYNAMIC_FALLBACK
5707
            /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C()
5708
             * above.
5709
             */
5710
            return 0;
5711
#endif
5712
        }
5713
    #endif /* WOLFSSL_AESNI */
5714
5715
0
#ifndef WC_C_DYNAMIC_FALLBACK
5716
5717
#if defined(WOLFSSL_ARMASM)
5718
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5719
    #ifndef __aarch64__
5720
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5721
    #else
5722
        Check_CPU_support_HwCrypto(aes);
5723
        if (aes->use_aes_hw_crypto) {
5724
            AES_set_key_AARCH64(userKey, keylen, (byte*)aes->key, dir);
5725
        }
5726
        else
5727
    #endif /* __aarch64__ */
5728
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
5729
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
5730
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
5731
        {
5732
            AES_set_encrypt_key_NEON(userKey, keylen * 8, (byte*)aes->key);
5733
        #ifdef HAVE_AES_DECRYPT
5734
            if (dir == AES_DECRYPTION) {
5735
                AES_invert_key_NEON((byte*)aes->key, aes->rounds);
5736
            }
5737
        #else
5738
            (void)dir;
5739
        #endif
5740
        }
5741
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5742
        {
5743
            AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5744
        #ifdef HAVE_AES_DECRYPT
5745
            if (dir == AES_DECRYPTION) {
5746
                AES_invert_key((byte*)aes->key, aes->rounds);
5747
            }
5748
        #else
5749
            (void)dir;
5750
        #endif
5751
        }
5752
    #endif
5753
        return 0;
5754
#else
5755
5756
    #ifdef WOLFSSL_KCAPI_AES
5757
        XMEMCPY(aes->devKey, userKey, keylen);
5758
        if (aes->init != 0) {
5759
            kcapi_cipher_destroy(aes->handle);
5760
            aes->handle = NULL;
5761
            aes->init = 0;
5762
        }
5763
        (void)dir;
5764
    #endif
5765
5766
0
        if (keylen > sizeof(aes->key)) {
5767
0
            return BAD_FUNC_ARG;
5768
0
        }
5769
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
5770
        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
5771
                                  ((psa_algorithm_t)0), dir);
5772
#endif
5773
5774
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
5775
        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
5776
         * instead of SE05x crypto by setting useSWCrypt */
5777
        if (aes->useSWCrypt == 0) {
5778
            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
5779
            if (ret == 0) {
5780
                ret = wc_AesSetIV(aes, iv);
5781
            }
5782
            return ret;
5783
        }
5784
#endif
5785
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
5786
        if (keylen == TA_KEY_TYPE_AES128_SIZE) {
5787
            ret = wc_Microchip_aes_set_key(aes, userKey, keylen, iv, dir);
5788
            if (ret != 0) {
5789
                return ret;
5790
            }
5791
            ret = wc_AesSetIV(aes, iv);
5792
            if (ret != 0) {
5793
                return ret;
5794
            }
5795
        }
5796
#endif
5797
0
        XMEMCPY(aes->key, userKey, keylen);
5798
5799
0
#ifndef WC_AES_BITSLICED
5800
0
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
5801
0
        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
5802
0
        && !defined(MAX3266X_AES)
5803
5804
        /* software */
5805
0
        ByteReverseWords(aes->key, aes->key, keylen);
5806
5807
    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
5808
        if (wc_esp32AesSupportedKeyLen(aes)) {
5809
            /* supported lengths don't get reversed */
5810
            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
5811
        }
5812
        else {
5813
            word32* rk = aes->key;
5814
5815
            /* For example, the ESP32-S3 does not support HW for len = 24,
5816
             * so fall back to SW */
5817
        #ifdef DEBUG_WOLFSSL
5818
            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
5819
        #endif
5820
            XMEMCPY(rk, userKey, keylen);
5821
            /* When not ESP32 HW, we need to reverse endianness */
5822
            ByteReverseWords(rk, rk, keylen);
5823
        }
5824
    #endif
5825
5826
    #ifdef WOLFSSL_IMXRT_DCP
5827
        {
5828
            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
5829
            word32 temp = 0;
5830
            if (keylen == 16)
5831
                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
5832
            if (temp != 0)
5833
                return WC_HW_E;
5834
        }
5835
    #endif
5836
0
#endif /* !WC_AES_BITSLICED */
5837
5838
0
#ifdef NEED_AES_TABLES
5839
0
        AesSetKey_C(aes, userKey, keylen, dir);
5840
0
#endif /* NEED_AES_TABLES */
5841
5842
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
5843
        XMEMCPY((byte*)aes->key, userKey, keylen);
5844
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
5845
            ByteReverseWords(aes->key, aes->key, 32);
5846
        }
5847
#endif
5848
5849
    #if defined(WOLFSSL_DEVCRYPTO) && \
5850
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
5851
        aes->ctx.cfd = -1;
5852
    #endif
5853
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5854
        ForceZero(local, sizeof(local));
5855
    #endif
5856
0
        return ret;
5857
0
#endif
5858
5859
0
#endif /* !WC_C_DYNAMIC_FALLBACK */
5860
5861
0
    } /* wc_AesSetKeyLocal */
5862
5863
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5864
            const byte* iv, int dir)
5865
0
    {
5866
0
        if (aes == NULL) {
5867
0
            return BAD_FUNC_ARG;
5868
0
        }
5869
0
        if (keylen > sizeof(aes->key)) {
5870
0
            return BAD_FUNC_ARG;
5871
0
        }
5872
5873
    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
5874
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
5875
        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
5876
        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
5877
            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
5878
            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
5879
        }
5880
        else {
5881
        #if  defined(WOLFSSL_HW_METRICS)
5882
            /* It is interesting to know how many times we could not complete
5883
             * AES in hardware due to unsupported lengths. */
5884
            wc_esp32AesUnupportedLengthCountAdd();
5885
        #endif
5886
        #ifdef DEBUG_WOLFSSL
5887
            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
5888
                           keylen);
5889
        #endif
5890
        }
5891
    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
5892
5893
0
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
5894
5895
0
    } /* wc_AesSetKey() */
5896
#endif
5897
5898
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5899
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5900
        /* This function allows key sizes that are not 128/192/256 bits */
5901
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5902
                           const byte* iv, int dir)
5903
    {
5904
        if (aes == NULL) {
5905
            return BAD_FUNC_ARG;
5906
        }
5907
        if (keylen > sizeof(aes->key)) {
5908
            return BAD_FUNC_ARG;
5909
        }
5910
5911
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
5912
    }
5913
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5914
#endif /* wc_AesSetKey block */
5915
5916
5917
/* wc_AesSetIV is shared between software and hardware */
5918
int wc_AesSetIV(Aes* aes, const byte* iv)
5919
0
{
5920
0
    if (aes == NULL)
5921
0
        return BAD_FUNC_ARG;
5922
5923
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5924
    {
5925
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5926
        if (ret < 0)
5927
            return ret;
5928
    }
5929
#endif
5930
5931
0
    if (iv)
5932
0
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5933
0
    else
5934
0
        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
5935
5936
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5937
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5938
    defined(WOLFSSL_AES_CTS)
5939
    /* Clear any unused bytes from last cipher op. */
5940
    aes->left = 0;
5941
#endif
5942
5943
0
    return 0;
5944
0
}
5945
5946
#ifdef WOLFSSL_AESNI
5947
5948
#ifdef WC_C_DYNAMIC_FALLBACK
5949
5950
#define VECTOR_REGISTERS_PUSH {                                      \
5951
        int orig_use_aesni = aes->use_aesni;                         \
5952
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
5953
            aes->use_aesni = 0;                                      \
5954
        }                                                            \
5955
        WC_DO_NOTHING
5956
5957
#define VECTOR_REGISTERS_PUSH2(fail_clause) {                        \
5958
        int orig_use_aesni = aes->use_aesni;                         \
5959
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
5960
            aes->use_aesni = 0;                                      \
5961
        }                                                            \
5962
        WC_DO_NOTHING
5963
5964
5965
#define VECTOR_REGISTERS_POP                                         \
5966
        if (aes->use_aesni)                                          \
5967
            RESTORE_VECTOR_REGISTERS();                              \
5968
        else                                                         \
5969
            aes->use_aesni = orig_use_aesni;                         \
5970
    }                                                                \
5971
    WC_DO_NOTHING
5972
5973
#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
5974
5975
#define VECTOR_REGISTERS_PUSH { \
5976
        WC_DO_NOTHING
5977
5978
#define VECTOR_REGISTERS_PUSH2(fail_clause) { \
5979
        WC_DO_NOTHING
5980
5981
#define VECTOR_REGISTERS_POP                                         \
5982
    }                                                                \
5983
    WC_DO_NOTHING
5984
5985
#else
5986
5987
#define VECTOR_REGISTERS_PUSH {                                          \
5988
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
5989
            return ret;                                                  \
5990
        }                                                                \
5991
        WC_DO_NOTHING
5992
5993
#define VECTOR_REGISTERS_PUSH2(fail_clause) {                            \
5994
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
5995
            { fail_clause }                                              \
5996
            return ret;                                                  \
5997
        }                                                                \
5998
        WC_DO_NOTHING
5999
6000
#define VECTOR_REGISTERS_POP \
6001
        if (aes->use_aesni) {                                            \
6002
            RESTORE_VECTOR_REGISTERS();                                  \
6003
        }                                                                \
6004
    }                                                                    \
6005
    WC_DO_NOTHING
6006
6007
#endif
6008
6009
#else /* !WOLFSSL_AESNI */
6010
6011
0
#define VECTOR_REGISTERS_PUSH WC_DO_NOTHING
6012
#define VECTOR_REGISTERS_PUSH2(fail_clause) WC_DO_NOTHING
6013
0
#define VECTOR_REGISTERS_POP WC_DO_NOTHING
6014
6015
#endif /* !WOLFSSL_AESNI */
6016
6017
6018
/* AES-DIRECT */
6019
#if defined(WOLFSSL_AES_DIRECT)
6020
    #if defined(HAVE_COLDFIRE_SEC)
6021
        #error "Coldfire SEC doesn't yet support AES direct"
6022
6023
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6024
        !defined(WOLFSSL_QNX_CAAM)
6025
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6026
6027
    #elif defined(WOLFSSL_AFALG)
6028
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6029
6030
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
6031
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6032
6033
    #else
6034
6035
        /* Allow direct access to one block encrypt */
6036
        /* Note, the in and out args are swapped compared to wc_AesEncrypt(). */
6037
        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
6038
        {
6039
            int ret;
6040
6041
            if (aes == NULL || out == NULL || in == NULL)
6042
                return BAD_FUNC_ARG;
6043
            VECTOR_REGISTERS_PUSH;
6044
            ret = wc_AesEncrypt(aes, in, out);
6045
            VECTOR_REGISTERS_POP;
6046
            return ret;
6047
        }
6048
6049
        /* vector reg save/restore is explicit in all below calls to
6050
         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
6051
         * macro.
6052
         */
6053
        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
6054
6055
        #ifdef HAVE_AES_DECRYPT
6056
        /* Allow direct access to one block decrypt */
6057
        /* Note, the in and out args are swapped compared to wc_AesDecrypt(). */
6058
        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
6059
        {
6060
            int ret;
6061
6062
            if (aes == NULL)
6063
                return BAD_FUNC_ARG;
6064
            VECTOR_REGISTERS_PUSH;
6065
            ret = wc_AesDecrypt(aes, in, out);
6066
            VECTOR_REGISTERS_POP;
6067
            return ret;
6068
        }
6069
6070
        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
6071
6072
        #endif /* HAVE_AES_DECRYPT */
6073
    #endif /* AES direct block */
6074
#endif /* WOLFSSL_AES_DIRECT */
6075
6076
6077
/* AES-CBC */
6078
#ifdef HAVE_AES_CBC
6079
#if defined(STM32_CRYPTO)
6080
6081
#ifdef WOLFSSL_STM32_BARE
6082
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6083
    {
6084
    #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6085
        if (sz % WC_AES_BLOCK_SIZE) {
6086
            return BAD_LENGTH_E;
6087
        }
6088
    #endif
6089
        if (sz == 0) {
6090
            return 0;
6091
        }
6092
    #ifdef WOLF_CRYPTO_CB
6093
        #ifndef WOLF_CRYPTO_CB_FIND
6094
        if (aes->devId != INVALID_DEVID)
6095
        #endif
6096
        {
6097
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6098
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6099
                return crypto_cb_ret;
6100
            /* fall-through when unavailable (normal-keyed Aes) */
6101
        }
6102
    #endif
6103
        /* DHUK / any crypto-callback device is routed above. wc_Stm32_Aes_Cbc
6104
         * processes whole blocks and ignores any sub-block remainder, matching
6105
         * the SW / CUBEMX CBC backends; define WOLFSSL_AES_CBC_LENGTH_CHECKS
6106
         * (above) to reject a non-block-multiple length with BAD_LENGTH_E. */
6107
        return wc_Stm32_Aes_Cbc(aes, out, in, sz, 1);
6108
    }
6109
    #ifdef HAVE_AES_DECRYPT
6110
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6111
    {
6112
    #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6113
        if (sz % WC_AES_BLOCK_SIZE) {
6114
            return BAD_LENGTH_E;
6115
        }
6116
    #endif
6117
        if (sz == 0) {
6118
            return 0;
6119
        }
6120
    #ifdef WOLF_CRYPTO_CB
6121
        #ifndef WOLF_CRYPTO_CB_FIND
6122
        if (aes->devId != INVALID_DEVID)
6123
        #endif
6124
        {
6125
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6126
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6127
                return crypto_cb_ret;
6128
            /* fall-through when unavailable (normal-keyed Aes) */
6129
        }
6130
    #endif
6131
        /* DHUK / any crypto-callback device is routed above. */
6132
        return wc_Stm32_Aes_Cbc(aes, out, in, sz, 0);
6133
    }
6134
    #endif /* HAVE_AES_DECRYPT */
6135
#elif defined(WOLFSSL_STM32_CUBEMX)
6136
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6137
    {
6138
        int ret = 0;
6139
        CRYP_HandleTypeDef hcryp;
6140
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6141
6142
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6143
        if (sz % WC_AES_BLOCK_SIZE) {
6144
            return BAD_LENGTH_E;
6145
        }
6146
#endif
6147
        if (blocks == 0)
6148
            return 0;
6149
6150
    #ifdef WOLF_CRYPTO_CB
6151
        #ifndef WOLF_CRYPTO_CB_FIND
6152
        if (aes->devId != INVALID_DEVID)
6153
        #endif
6154
        {
6155
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6156
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6157
                return crypto_cb_ret;
6158
            /* fall-through when unavailable (normal-keyed Aes) */
6159
        }
6160
    #endif
6161
6162
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6163
        if (ret != 0)
6164
            return ret;
6165
6166
        ret = wolfSSL_CryptHwMutexLock();
6167
        if (ret != 0) {
6168
            return ret;
6169
        }
6170
6171
    #if defined(STM32_HAL_V2)
6172
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
6173
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
6174
    #elif defined(STM32_CRYPTO_AES_ONLY)
6175
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
6176
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
6177
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6178
    #endif
6179
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6180
        ret = HAL_CRYP_Init(&hcryp);
6181
6182
        if (ret == HAL_OK) {
6183
        #if defined(STM32_HAL_V2)
6184
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
6185
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6186
        #elif defined(STM32_CRYPTO_AES_ONLY)
6187
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
6188
                out, STM32_HAL_TIMEOUT);
6189
        #else
6190
            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
6191
                                        blocks * WC_AES_BLOCK_SIZE,
6192
                                        out, STM32_HAL_TIMEOUT);
6193
        #endif
6194
        }
6195
        if (ret != HAL_OK) {
6196
            ret = WC_TIMEOUT_E;
6197
        }
6198
6199
        /* store iv for next call */
6200
        XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6201
6202
        HAL_CRYP_DeInit(&hcryp);
6203
6204
        wolfSSL_CryptHwMutexUnLock();
6205
        wc_Stm32_Aes_Cleanup();
6206
6207
        return ret;
6208
    }
6209
    #ifdef HAVE_AES_DECRYPT
6210
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6211
    {
6212
        int ret = 0;
6213
        CRYP_HandleTypeDef hcryp;
6214
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6215
6216
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6217
        if (sz % WC_AES_BLOCK_SIZE) {
6218
            return BAD_LENGTH_E;
6219
        }
6220
#endif
6221
        if (blocks == 0)
6222
            return 0;
6223
6224
    #ifdef WOLF_CRYPTO_CB
6225
        #ifndef WOLF_CRYPTO_CB_FIND
6226
        if (aes->devId != INVALID_DEVID)
6227
        #endif
6228
        {
6229
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6230
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6231
                return crypto_cb_ret;
6232
            /* fall-through when unavailable (normal-keyed Aes) */
6233
        }
6234
    #endif
6235
6236
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6237
        if (ret != 0)
6238
            return ret;
6239
6240
        ret = wolfSSL_CryptHwMutexLock();
6241
        if (ret != 0) {
6242
            return ret;
6243
        }
6244
6245
        /* if input and output same will overwrite input iv */
6246
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6247
6248
    #if defined(STM32_HAL_V2)
6249
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
6250
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
6251
    #elif defined(STM32_CRYPTO_AES_ONLY)
6252
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
6253
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
6254
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6255
    #endif
6256
6257
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6258
        ret = HAL_CRYP_Init(&hcryp);
6259
6260
        if (ret == HAL_OK) {
6261
        #if defined(STM32_HAL_V2)
6262
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
6263
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6264
        #elif defined(STM32_CRYPTO_AES_ONLY)
6265
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
6266
                out, STM32_HAL_TIMEOUT);
6267
        #else
6268
            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
6269
                                        blocks * WC_AES_BLOCK_SIZE,
6270
                out, STM32_HAL_TIMEOUT);
6271
        #endif
6272
        }
6273
        if (ret != HAL_OK) {
6274
            ret = WC_TIMEOUT_E;
6275
        }
6276
6277
        /* store iv for next call */
6278
        XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6279
6280
        HAL_CRYP_DeInit(&hcryp);
6281
        wolfSSL_CryptHwMutexUnLock();
6282
        wc_Stm32_Aes_Cleanup();
6283
6284
        return ret;
6285
    }
6286
    #endif /* HAVE_AES_DECRYPT */
6287
6288
#else /* Standard Peripheral Library */
6289
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6290
    {
6291
        int ret;
6292
        word32 *iv;
6293
        CRYP_InitTypeDef cryptInit;
6294
        CRYP_KeyInitTypeDef keyInit;
6295
        CRYP_IVInitTypeDef ivInit;
6296
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6297
6298
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6299
        if (sz % WC_AES_BLOCK_SIZE) {
6300
            return BAD_LENGTH_E;
6301
        }
6302
#endif
6303
        if (blocks == 0)
6304
            return 0;
6305
6306
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6307
        if (ret != 0)
6308
            return ret;
6309
6310
        ret = wolfSSL_CryptHwMutexLock();
6311
        if (ret != 0) {
6312
            return ret;
6313
        }
6314
6315
        /* reset registers to their default values */
6316
        CRYP_DeInit();
6317
6318
        /* set key */
6319
        CRYP_KeyInit(&keyInit);
6320
6321
        /* set iv */
6322
        iv = aes->reg;
6323
        CRYP_IVStructInit(&ivInit);
6324
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
6325
        ivInit.CRYP_IV0Left  = iv[0];
6326
        ivInit.CRYP_IV0Right = iv[1];
6327
        ivInit.CRYP_IV1Left  = iv[2];
6328
        ivInit.CRYP_IV1Right = iv[3];
6329
        CRYP_IVInit(&ivInit);
6330
6331
        /* set direction and mode */
6332
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
6333
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
6334
        CRYP_Init(&cryptInit);
6335
6336
        /* enable crypto processor */
6337
        CRYP_Cmd(ENABLE);
6338
6339
        while (blocks--) {
6340
            /* flush IN/OUT FIFOs */
6341
            CRYP_FIFOFlush();
6342
6343
            CRYP_DataIn(*(uint32_t*)&in[0]);
6344
            CRYP_DataIn(*(uint32_t*)&in[4]);
6345
            CRYP_DataIn(*(uint32_t*)&in[8]);
6346
            CRYP_DataIn(*(uint32_t*)&in[12]);
6347
6348
            /* wait until the complete message has been processed */
6349
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6350
6351
            *(uint32_t*)&out[0]  = CRYP_DataOut();
6352
            *(uint32_t*)&out[4]  = CRYP_DataOut();
6353
            *(uint32_t*)&out[8]  = CRYP_DataOut();
6354
            *(uint32_t*)&out[12] = CRYP_DataOut();
6355
6356
            /* store iv for next call */
6357
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6358
6359
            sz  -= WC_AES_BLOCK_SIZE;
6360
            in  += WC_AES_BLOCK_SIZE;
6361
            out += WC_AES_BLOCK_SIZE;
6362
        }
6363
6364
        /* disable crypto processor */
6365
        CRYP_Cmd(DISABLE);
6366
        wolfSSL_CryptHwMutexUnLock();
6367
        wc_Stm32_Aes_Cleanup();
6368
6369
        return ret;
6370
    }
6371
6372
    #ifdef HAVE_AES_DECRYPT
6373
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6374
    {
6375
        int ret;
6376
        word32 *iv;
6377
        CRYP_InitTypeDef cryptInit;
6378
        CRYP_KeyInitTypeDef keyInit;
6379
        CRYP_IVInitTypeDef ivInit;
6380
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6381
6382
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6383
        if (sz % WC_AES_BLOCK_SIZE) {
6384
            return BAD_LENGTH_E;
6385
        }
6386
#endif
6387
        if (blocks == 0)
6388
            return 0;
6389
6390
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6391
        if (ret != 0)
6392
            return ret;
6393
6394
        ret = wolfSSL_CryptHwMutexLock();
6395
        if (ret != 0) {
6396
            return ret;
6397
        }
6398
6399
        /* if input and output same will overwrite input iv */
6400
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6401
6402
        /* reset registers to their default values */
6403
        CRYP_DeInit();
6404
6405
        /* set direction and key */
6406
        CRYP_KeyInit(&keyInit);
6407
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
6408
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
6409
        CRYP_Init(&cryptInit);
6410
6411
        /* enable crypto processor */
6412
        CRYP_Cmd(ENABLE);
6413
6414
        /* wait until key has been prepared */
6415
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6416
6417
        /* set direction and mode */
6418
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
6419
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
6420
        CRYP_Init(&cryptInit);
6421
6422
        /* set iv */
6423
        iv = aes->reg;
6424
        CRYP_IVStructInit(&ivInit);
6425
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
6426
        ivInit.CRYP_IV0Left  = iv[0];
6427
        ivInit.CRYP_IV0Right = iv[1];
6428
        ivInit.CRYP_IV1Left  = iv[2];
6429
        ivInit.CRYP_IV1Right = iv[3];
6430
        CRYP_IVInit(&ivInit);
6431
6432
        /* enable crypto processor */
6433
        CRYP_Cmd(ENABLE);
6434
6435
        while (blocks--) {
6436
            /* flush IN/OUT FIFOs */
6437
            CRYP_FIFOFlush();
6438
6439
            CRYP_DataIn(*(uint32_t*)&in[0]);
6440
            CRYP_DataIn(*(uint32_t*)&in[4]);
6441
            CRYP_DataIn(*(uint32_t*)&in[8]);
6442
            CRYP_DataIn(*(uint32_t*)&in[12]);
6443
6444
            /* wait until the complete message has been processed */
6445
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6446
6447
            *(uint32_t*)&out[0]  = CRYP_DataOut();
6448
            *(uint32_t*)&out[4]  = CRYP_DataOut();
6449
            *(uint32_t*)&out[8]  = CRYP_DataOut();
6450
            *(uint32_t*)&out[12] = CRYP_DataOut();
6451
6452
            /* store iv for next call */
6453
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6454
6455
            in  += WC_AES_BLOCK_SIZE;
6456
            out += WC_AES_BLOCK_SIZE;
6457
        }
6458
6459
        /* disable crypto processor */
6460
        CRYP_Cmd(DISABLE);
6461
        wolfSSL_CryptHwMutexUnLock();
6462
        wc_Stm32_Aes_Cleanup();
6463
6464
        return ret;
6465
    }
6466
    #endif /* HAVE_AES_DECRYPT */
6467
#endif /* WOLFSSL_STM32_CUBEMX */
6468
6469
#elif defined(HAVE_COLDFIRE_SEC)
6470
    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
6471
        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
6472
    {
6473
        #ifdef DEBUG_WOLFSSL
6474
            int i; int stat1, stat2; int ret;
6475
        #endif
6476
6477
        int size;
6478
        volatile int v;
6479
6480
        if ((pi == NULL) || (po == NULL))
6481
            return BAD_FUNC_ARG;    /*wrong pointer*/
6482
6483
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6484
        if (sz % WC_AES_BLOCK_SIZE) {
6485
            return BAD_LENGTH_E;
6486
        }
6487
#endif
6488
6489
        wc_LockMutex(&Mutex_AesSEC);
6490
6491
        /* Set descriptor for SEC */
6492
        secDesc->length1 = 0x0;
6493
        secDesc->pointer1 = NULL;
6494
6495
        secDesc->length2 = WC_AES_BLOCK_SIZE;
6496
        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
6497
6498
        switch(aes->rounds) {
6499
            case 10: secDesc->length3 = 16; break;
6500
            case 12: secDesc->length3 = 24; break;
6501
            case 14: secDesc->length3 = 32; break;
6502
        }
6503
        XMEMCPY(secKey, aes->key, secDesc->length3);
6504
6505
        secDesc->pointer3 = (byte *)secKey;
6506
        secDesc->pointer4 = AESBuffIn;
6507
        secDesc->pointer5 = AESBuffOut;
6508
        secDesc->length6 = 0x0;
6509
        secDesc->pointer6 = NULL;
6510
        secDesc->length7 = 0x0;
6511
        secDesc->pointer7 = NULL;
6512
        secDesc->nextDescriptorPtr = NULL;
6513
6514
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6515
        size = AES_BUFFER_SIZE;
6516
#endif
6517
        while (sz) {
6518
            secDesc->header = descHeader;
6519
            XMEMCPY(secReg, aes->reg, WC_AES_BLOCK_SIZE);
6520
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6521
            sz -= AES_BUFFER_SIZE;
6522
#else
6523
            if (sz < AES_BUFFER_SIZE) {
6524
                size = sz;
6525
                sz = 0;
6526
            } else {
6527
                size = AES_BUFFER_SIZE;
6528
                sz -= AES_BUFFER_SIZE;
6529
            }
6530
#endif
6531
6532
            secDesc->length4 = size;
6533
            secDesc->length5 = size;
6534
6535
            XMEMCPY(AESBuffIn, pi, size);
6536
            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
6537
                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-WC_AES_BLOCK_SIZE]),
6538
                        WC_AES_BLOCK_SIZE);
6539
            }
6540
6541
            /* Point SEC to the location of the descriptor */
6542
            MCF_SEC_FR0 = (uint32)secDesc;
6543
            /* Initialize SEC and wait for encryption to complete */
6544
            MCF_SEC_CCCR0 = 0x0000001a;
6545
            /* poll SISR to determine when channel is complete */
6546
            v=0;
6547
6548
            while ((secDesc->header>> 24) != 0xff) v++;
6549
6550
            #ifdef DEBUG_WOLFSSL
6551
                ret = MCF_SEC_SISRH;
6552
                stat1 = MCF_SEC_AESSR;
6553
                stat2 = MCF_SEC_AESISR;
6554
                if (ret & 0xe0000000) {
6555
                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
6556
                              "AESISR=%08x\n", i, ret, stat1, stat2);
6557
                }
6558
            #endif
6559
6560
            XMEMCPY(po, AESBuffOut, size);
6561
6562
            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
6563
                XMEMCPY((void*)aes->reg, (void*)&(po[size-WC_AES_BLOCK_SIZE]),
6564
                        WC_AES_BLOCK_SIZE);
6565
            } else {
6566
                XMEMCPY((void*)aes->reg, (void*)aes->tmp, WC_AES_BLOCK_SIZE);
6567
            }
6568
6569
            pi += size;
6570
            po += size;
6571
        }
6572
6573
        wc_UnLockMutex(&Mutex_AesSEC);
6574
        return 0;
6575
    }
6576
6577
    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6578
    {
6579
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
6580
    }
6581
6582
    #ifdef HAVE_AES_DECRYPT
6583
    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6584
    {
6585
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
6586
    }
6587
    #endif /* HAVE_AES_DECRYPT */
6588
6589
#elif defined(FREESCALE_LTC)
6590
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6591
    {
6592
        word32 keySize;
6593
        status_t status;
6594
        byte *iv, *enc_key;
6595
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6596
6597
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6598
        if (sz % WC_AES_BLOCK_SIZE) {
6599
            return BAD_LENGTH_E;
6600
        }
6601
#endif
6602
        if (blocks == 0)
6603
            return 0;
6604
6605
        iv      = (byte*)aes->reg;
6606
        enc_key = (byte*)aes->key;
6607
6608
        status = wc_AesGetKeySize(aes, &keySize);
6609
        if (status != 0) {
6610
            return status;
6611
        }
6612
6613
        status = wolfSSL_CryptHwMutexLock();
6614
        if (status != 0)
6615
            return status;
6616
        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6617
            iv, enc_key, keySize);
6618
        wolfSSL_CryptHwMutexUnLock();
6619
6620
        /* store iv for next call */
6621
        if (status == kStatus_Success) {
6622
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6623
        }
6624
6625
        return (status == kStatus_Success) ? 0 : -1;
6626
    }
6627
6628
    #ifdef HAVE_AES_DECRYPT
6629
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6630
    {
6631
        word32 keySize;
6632
        status_t status;
6633
        byte* iv, *dec_key;
6634
        byte temp_block[WC_AES_BLOCK_SIZE];
6635
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6636
6637
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6638
        if (sz % WC_AES_BLOCK_SIZE) {
6639
            return BAD_LENGTH_E;
6640
        }
6641
#endif
6642
        if (blocks == 0)
6643
            return 0;
6644
6645
        iv      = (byte*)aes->reg;
6646
        dec_key = (byte*)aes->key;
6647
6648
        status = wc_AesGetKeySize(aes, &keySize);
6649
        if (status != 0) {
6650
            return status;
6651
        }
6652
6653
        /* get IV for next call */
6654
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6655
6656
        status = wolfSSL_CryptHwMutexLock();
6657
        if (status != 0)
6658
            return status;
6659
        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6660
            iv, dec_key, keySize, kLTC_EncryptKey);
6661
        wolfSSL_CryptHwMutexUnLock();
6662
6663
        /* store IV for next call */
6664
        if (status == kStatus_Success) {
6665
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6666
        }
6667
6668
        return (status == kStatus_Success) ? 0 : -1;
6669
    }
6670
    #endif /* HAVE_AES_DECRYPT */
6671
6672
#elif defined(FREESCALE_MMCAU) && !defined(WOLFSSL_ARMASM)
6673
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6674
    {
6675
        int offset = 0;
6676
        byte *iv;
6677
        byte temp_block[WC_AES_BLOCK_SIZE];
6678
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6679
        int ret;
6680
6681
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6682
        if (sz % WC_AES_BLOCK_SIZE) {
6683
            return BAD_LENGTH_E;
6684
        }
6685
#endif
6686
        if (blocks == 0)
6687
            return 0;
6688
6689
        iv = (byte*)aes->reg;
6690
6691
        while (blocks--) {
6692
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
6693
6694
            /* XOR block with IV for CBC */
6695
            xorbuf(temp_block, iv, WC_AES_BLOCK_SIZE);
6696
6697
            ret = wc_AesEncrypt(aes, temp_block, out + offset);
6698
            if (ret != 0)
6699
                return ret;
6700
6701
            offset += WC_AES_BLOCK_SIZE;
6702
6703
            /* store IV for next block */
6704
            XMEMCPY(iv, out + offset - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6705
        }
6706
6707
        return 0;
6708
    }
6709
    #ifdef HAVE_AES_DECRYPT
6710
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6711
    {
6712
        int ret;
6713
        int offset = 0;
6714
        byte* iv;
6715
        byte temp_block[WC_AES_BLOCK_SIZE];
6716
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6717
6718
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6719
        if (sz % WC_AES_BLOCK_SIZE) {
6720
            return BAD_LENGTH_E;
6721
        }
6722
#endif
6723
        if (blocks == 0)
6724
            return 0;
6725
6726
        iv = (byte*)aes->reg;
6727
6728
        while (blocks--) {
6729
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
6730
6731
            ret = wc_AesDecrypt(aes, in + offset, out + offset);
6732
            if (ret != 0)
6733
                return ret;
6734
6735
            /* XOR block with IV for CBC */
6736
            xorbuf(out + offset, iv, WC_AES_BLOCK_SIZE);
6737
6738
            /* store IV for next block */
6739
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6740
6741
            offset += WC_AES_BLOCK_SIZE;
6742
        }
6743
        return 0;
6744
    }
6745
    #endif /* HAVE_AES_DECRYPT */
6746
6747
#elif defined(MAX3266X_AES)
6748
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6749
    {
6750
        word32 keySize;
6751
        int status;
6752
        byte *iv;
6753
6754
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
6755
            return BAD_FUNC_ARG;
6756
        }
6757
6758
        /* Always enforce a length check */
6759
        if (sz % WC_AES_BLOCK_SIZE) {
6760
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6761
            return BAD_LENGTH_E;
6762
        #else
6763
            return BAD_FUNC_ARG;
6764
        #endif
6765
        }
6766
        if (sz == 0) {
6767
            return 0;
6768
        }
6769
6770
        iv = (byte*)aes->reg;
6771
        status = wc_AesGetKeySize(aes, &keySize);
6772
        if (status != 0) {
6773
            return status;
6774
        }
6775
6776
        status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
6777
                                        MXC_TPU_MODE_CBC, sz, out,
6778
                                        (unsigned int)keySize);
6779
        /* store iv for next call */
6780
        if (status == 0) {
6781
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6782
        }
6783
        return (status == 0) ? 0 : -1;
6784
    }
6785
6786
    #ifdef HAVE_AES_DECRYPT
6787
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6788
    {
6789
        word32 keySize;
6790
        int status;
6791
        byte *iv;
6792
        byte temp_block[WC_AES_BLOCK_SIZE];
6793
6794
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
6795
            return BAD_FUNC_ARG;
6796
        }
6797
6798
        /* Always enforce a length check */
6799
        if (sz % WC_AES_BLOCK_SIZE) {
6800
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6801
            return BAD_LENGTH_E;
6802
        #else
6803
            return BAD_FUNC_ARG;
6804
        #endif
6805
        }
6806
        if (sz == 0) {
6807
            return 0;
6808
        }
6809
6810
        iv = (byte*)aes->reg;
6811
        status = wc_AesGetKeySize(aes, &keySize);
6812
        if (status != 0) {
6813
            return status;
6814
        }
6815
6816
        /* get IV for next call */
6817
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6818
        status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
6819
                                        MXC_TPU_MODE_CBC, sz, out,
6820
                                        keySize);
6821
6822
        /* store iv for next call */
6823
        if (status == 0) {
6824
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6825
        }
6826
        return (status == 0) ? 0 : -1;
6827
    }
6828
    #endif /* HAVE_AES_DECRYPT */
6829
6830
6831
6832
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
6833
6834
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6835
    {
6836
        int ret;
6837
6838
        if (sz == 0)
6839
            return 0;
6840
6841
        /* hardware fails on input that is not a multiple of AES block size */
6842
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6843
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6844
            return BAD_LENGTH_E;
6845
#else
6846
            return BAD_FUNC_ARG;
6847
#endif
6848
        }
6849
6850
        ret = wc_Pic32AesCrypt(
6851
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6852
            out, in, sz, PIC32_ENCRYPTION,
6853
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6854
6855
        /* store iv for next call */
6856
        if (ret == 0) {
6857
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6858
        }
6859
6860
        return ret;
6861
    }
6862
    #ifdef HAVE_AES_DECRYPT
6863
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6864
    {
6865
        int ret;
6866
        byte scratch[WC_AES_BLOCK_SIZE];
6867
6868
        if (sz == 0)
6869
            return 0;
6870
6871
        /* hardware fails on input that is not a multiple of AES block size */
6872
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6873
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6874
            return BAD_LENGTH_E;
6875
#else
6876
            return BAD_FUNC_ARG;
6877
#endif
6878
        }
6879
        XMEMCPY(scratch, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6880
6881
        ret = wc_Pic32AesCrypt(
6882
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6883
            out, in, sz, PIC32_DECRYPTION,
6884
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6885
6886
        /* store iv for next call */
6887
        if (ret == 0) {
6888
            XMEMCPY((byte*)aes->reg, scratch, WC_AES_BLOCK_SIZE);
6889
        }
6890
6891
        return ret;
6892
    }
6893
    #endif /* HAVE_AES_DECRYPT */
6894
#elif defined(WOLFSSL_ESP32_CRYPT) && \
6895
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6896
6897
    /* We'll use SW for fall back:
6898
     *   unsupported key lengths
6899
     *   hardware busy */
6900
    #define NEED_SW_AESCBC
6901
    #define NEED_AESCBC_HW_FALLBACK
6902
6903
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
6904
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6905
    {
6906
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6907
    }
6908
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6909
    {
6910
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6911
    }
6912
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6913
        !defined(WOLFSSL_QNX_CAAM)
6914
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6915
6916
#elif defined(WOLFSSL_AFALG)
6917
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6918
6919
#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
6920
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
6921
6922
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
6923
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6924
6925
#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
6926
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
6927
6928
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
6929
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
6930
6931
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6932
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
6933
6934
#elif defined(WOLFSSL_PSOC6_CRYPTO)
6935
6936
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6937
    {
6938
        return wc_Psoc6_Aes_CbcEncrypt(aes, out, in, sz);
6939
    }
6940
6941
    #if defined(HAVE_AES_DECRYPT)
6942
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6943
    {
6944
        return wc_Psoc6_Aes_CbcDecrypt(aes, out, in, sz);
6945
    }
6946
    #endif /* HAVE_AES_DECRYPT */
6947
6948
#else
6949
    /* Reminder: Some HW implementations may also define this as needed.
6950
     * (e.g. for unsupported key length fallback)  */
6951
    #define NEED_SW_AESCBC
6952
#endif
6953
6954
#ifdef NEED_SW_AESCBC
6955
    /* Software AES - CBC Encrypt */
6956
6957
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6958
0
    {
6959
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
6960
0
        word32 blocks;
6961
0
        int ret;
6962
0
#endif
6963
6964
0
        if (aes == NULL || out == NULL || in == NULL) {
6965
0
            return BAD_FUNC_ARG;
6966
0
        }
6967
6968
0
        if (sz == 0) {
6969
0
            return 0;
6970
0
        }
6971
6972
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
6973
0
        blocks = sz / WC_AES_BLOCK_SIZE;
6974
0
#endif
6975
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6976
        if (sz % WC_AES_BLOCK_SIZE) {
6977
            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
6978
            return BAD_LENGTH_E;
6979
        }
6980
#endif
6981
6982
    #ifdef WOLFSSL_IMXRT_DCP
6983
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
6984
        if (aes->keylen == 16)
6985
            return DCPAesCbcEncrypt(aes, out, in, sz);
6986
    #endif
6987
6988
    #ifdef WOLF_CRYPTO_CB
6989
        #ifndef WOLF_CRYPTO_CB_FIND
6990
        if (aes->devId != INVALID_DEVID)
6991
        #endif
6992
        {
6993
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6994
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6995
                return crypto_cb_ret;
6996
            /* fall-through when unavailable */
6997
        }
6998
    #endif
6999
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
7000
        /* if async and byte count above threshold */
7001
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
7002
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
7003
        #if defined(HAVE_CAVIUM)
7004
            return NitroxAesCbcEncrypt(aes, out, in, sz);
7005
        #elif defined(HAVE_INTEL_QA)
7006
            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
7007
                (const byte*)aes->devKey, aes->keylen,
7008
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7009
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
7010
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
7011
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
7012
                sw->aes.aes = aes;
7013
                sw->aes.out = out;
7014
                sw->aes.in = in;
7015
                sw->aes.sz = sz;
7016
                return WC_PENDING_E;
7017
            }
7018
        #endif
7019
        }
7020
    #endif /* WOLFSSL_ASYNC_CRYPT */
7021
7022
#if defined(WOLFSSL_ARMASM)
7023
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7024
    #if !defined(__aarch64__)
7025
        AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7026
            (int)aes->rounds);
7027
    #else
7028
        if (aes->use_aes_hw_crypto) {
7029
            AES_CBC_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7030
                (byte*)aes->key, (int)aes->rounds);
7031
        }
7032
        else
7033
    #endif /* __aarch64__ */
7034
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7035
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
7036
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7037
        {
7038
            AES_CBC_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
7039
                aes->rounds, (unsigned char*)aes->reg);
7040
        }
7041
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7042
        {
7043
            AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
7044
                aes->rounds, (unsigned char*)aes->reg);
7045
        }
7046
    #endif
7047
        return 0;
7048
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7049
        AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
7050
            aes->rounds, (unsigned char*)aes->reg);
7051
        return 0;
7052
#else
7053
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
7054
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
7055
        if (aes->useSWCrypt == 0) {
7056
            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
7057
                                   kAlgorithm_SSS_AES_CBC);
7058
        }
7059
        else
7060
    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
7061
        if (wc_esp32AesSupportedKeyLen(aes)) {
7062
            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
7063
            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
7064
        }
7065
        else {
7066
            /* For example, the ESP32-S3 does not support HW for len = 24,
7067
             * so fall back to SW */
7068
        #ifdef DEBUG_WOLFSSL
7069
            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
7070
                          "unsupported keylen = %d", aes->keylen);
7071
        #endif
7072
        }
7073
    #elif defined(WOLFSSL_AESNI)
7074
        VECTOR_REGISTERS_PUSH;
7075
        if (aes->use_aesni) {
7076
            #ifdef DEBUG_AESNI
7077
                printf("about to aes cbc encrypt\n");
7078
                printf("in  = %p\n", in);
7079
                printf("out = %p\n", out);
7080
                printf("aes->key = %p\n", aes->key);
7081
                printf("aes->reg = %p\n", aes->reg);
7082
                printf("aes->rounds = %d\n", aes->rounds);
7083
                printf("sz = %d\n", sz);
7084
            #endif
7085
7086
            /* check alignment, decrypt doesn't need alignment */
7087
            if ((wc_ptr_t)in % AESNI_ALIGN) {
7088
            #ifndef NO_WOLFSSL_ALLOC_ALIGN
7089
                byte* tmp = (byte*)XMALLOC(sz + WC_AES_BLOCK_SIZE + AESNI_ALIGN,
7090
                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
7091
                byte* tmp_align;
7092
                if (tmp == NULL)
7093
                    ret = MEMORY_E;
7094
                else {
7095
                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
7096
                    XMEMCPY(tmp_align, in, sz);
7097
                #ifdef WOLFSSL_X86_64_BUILD
7098
                    AesCbcEncryptBlocks(tmp_align, tmp_align, (byte*)aes->reg, sz,
7099
                                        (byte*)aes->key, (int)aes->rounds);
7100
                #else
7101
                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
7102
                                          (byte*)aes->key, (int)aes->rounds);
7103
                #endif
7104
                    /* store iv for next call */
7105
                    XMEMCPY(aes->reg, tmp_align + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7106
7107
                    XMEMCPY(out, tmp_align, sz);
7108
                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
7109
                    ret = 0;
7110
                }
7111
            #else
7112
                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
7113
                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
7114
                ret = BAD_ALIGN_E;
7115
            #endif
7116
            } else {
7117
            #ifdef WOLFSSL_X86_64_BUILD
7118
                AesCbcEncryptBlocks(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7119
                                    (int)aes->rounds);
7120
            #else
7121
                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7122
                                      (int)aes->rounds);
7123
            #endif
7124
                /* store iv for next call */
7125
                XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7126
7127
                ret = 0;
7128
            }
7129
        }
7130
        else
7131
    #endif
7132
0
        {
7133
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
7134
0
            int did_prefetches = 0;
7135
0
#endif
7136
0
            ret = 0;
7137
0
            while (blocks--) {
7138
0
                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
7139
0
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7140
0
                                                (byte*)aes->reg,
7141
0
                                                &did_prefetches);
7142
0
                if (ret != 0)
7143
0
                    break;
7144
0
                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
7145
7146
0
                out += WC_AES_BLOCK_SIZE;
7147
0
                in  += WC_AES_BLOCK_SIZE;
7148
0
            }
7149
0
        }
7150
7151
    #ifdef WOLFSSL_AESNI
7152
        VECTOR_REGISTERS_POP;
7153
    #endif
7154
7155
0
        return ret;
7156
0
#endif
7157
0
    } /* wc_AesCbcEncrypt */
7158
7159
#ifdef HAVE_AES_DECRYPT
7160
    /* Software AES - CBC Decrypt */
7161
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7162
0
    {
7163
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7164
0
        word32 blocks;
7165
0
        int ret;
7166
0
#endif
7167
7168
0
        if (aes == NULL || out == NULL || in == NULL) {
7169
0
            return BAD_FUNC_ARG;
7170
0
        }
7171
7172
0
        if (sz == 0) {
7173
0
            return 0;
7174
0
        }
7175
7176
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
7177
        if (wc_esp32AesSupportedKeyLen(aes)) {
7178
            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
7179
            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
7180
        }
7181
        else {
7182
            /* For example, the ESP32-S3 does not support HW for len = 24,
7183
             * so fall back to SW */
7184
        #ifdef DEBUG_WOLFSSL
7185
            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
7186
                          "unsupported keylen = %d", aes->keylen);
7187
        #endif
7188
        }
7189
    #endif
7190
7191
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7192
0
        blocks = sz / WC_AES_BLOCK_SIZE;
7193
0
#endif
7194
0
        if (sz % WC_AES_BLOCK_SIZE) {
7195
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7196
            return BAD_LENGTH_E;
7197
#else
7198
0
            return BAD_FUNC_ARG;
7199
0
#endif
7200
0
        }
7201
7202
    #ifdef WOLFSSL_IMXRT_DCP
7203
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
7204
        if (aes->keylen == 16)
7205
            return DCPAesCbcDecrypt(aes, out, in, sz);
7206
    #endif
7207
7208
    #ifdef WOLF_CRYPTO_CB
7209
        #ifndef WOLF_CRYPTO_CB_FIND
7210
        if (aes->devId != INVALID_DEVID)
7211
        #endif
7212
        {
7213
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
7214
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7215
                return crypto_cb_ret;
7216
            /* fall-through when unavailable */
7217
        }
7218
    #endif
7219
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
7220
        /* if async and byte count above threshold */
7221
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
7222
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
7223
        #if defined(HAVE_CAVIUM)
7224
            return NitroxAesCbcDecrypt(aes, out, in, sz);
7225
        #elif defined(HAVE_INTEL_QA)
7226
            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
7227
                (const byte*)aes->devKey, aes->keylen,
7228
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7229
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
7230
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
7231
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
7232
                sw->aes.aes = aes;
7233
                sw->aes.out = out;
7234
                sw->aes.in = in;
7235
                sw->aes.sz = sz;
7236
                return WC_PENDING_E;
7237
            }
7238
        #endif
7239
        }
7240
    #endif
7241
7242
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
7243
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
7244
        if (aes->useSWCrypt == 0) {
7245
            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
7246
                                   kAlgorithm_SSS_AES_CBC);
7247
        }
7248
    #endif
7249
7250
#if defined(WOLFSSL_ARMASM)
7251
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7252
    #if !defined(__aarch64__)
7253
        AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7254
            (int)aes->rounds);
7255
    #else
7256
        if (aes->use_aes_hw_crypto) {
7257
            AES_CBC_decrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7258
                (byte*)aes->key, (int)aes->rounds);
7259
        }
7260
        else
7261
    #endif /* !__aarch64__ */
7262
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7263
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
7264
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7265
        if (sz >= 64)
7266
    #endif
7267
        {
7268
            AES_CBC_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
7269
                aes->rounds, (unsigned char*)aes->reg);
7270
        }
7271
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7272
        else
7273
    #endif
7274
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
7275
    #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7276
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7277
        {
7278
            AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
7279
                aes->rounds, (unsigned char*)aes->reg);
7280
        }
7281
    #endif
7282
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
7283
        return 0;
7284
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7285
        AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
7286
            aes->rounds, (unsigned char*)aes->reg);
7287
        return 0;
7288
#else
7289
0
        VECTOR_REGISTERS_PUSH;
7290
7291
    #ifdef WOLFSSL_AESNI
7292
        if (aes->use_aesni) {
7293
            #ifdef DEBUG_AESNI
7294
                printf("about to aes cbc decrypt\n");
7295
                printf("in  = %p\n", in);
7296
                printf("out = %p\n", out);
7297
                printf("aes->key = %p\n", aes->key);
7298
                printf("aes->reg = %p\n", aes->reg);
7299
                printf("aes->rounds = %d\n", aes->rounds);
7300
                printf("sz = %d\n", sz);
7301
            #endif
7302
7303
            /* if input and output same will overwrite input iv */
7304
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7305
            #if defined(WOLFSSL_X86_64_BUILD)
7306
            AesCbcDecryptBlocks(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7307
                            (int)aes->rounds);
7308
            #elif defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
7309
            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7310
                            aes->rounds);
7311
            #elif defined(WOLFSSL_AESNI_BY6)
7312
            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7313
                            aes->rounds);
7314
            #else /* WOLFSSL_AESNI_BYx */
7315
            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7316
                            (int)aes->rounds);
7317
            #endif /* WOLFSSL_AESNI_BYx */
7318
            /* store iv for next call */
7319
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7320
            ret = 0;
7321
        }
7322
        else
7323
    #endif
7324
0
        {
7325
0
            ret = 0;
7326
#ifdef WC_AES_BITSLICED
7327
            if (in != out) {
7328
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
7329
7330
                while (blocks > BS_WORD_SIZE) {
7331
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
7332
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7333
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
7334
                              WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
7335
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
7336
                            WC_AES_BLOCK_SIZE);
7337
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7338
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7339
                    blocks -= BS_WORD_SIZE;
7340
                }
7341
                if (blocks > 0) {
7342
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
7343
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7344
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
7345
                              WC_AES_BLOCK_SIZE * (blocks - 1));
7346
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (blocks - 1)),
7347
                            WC_AES_BLOCK_SIZE);
7348
                    blocks = 0;
7349
                }
7350
            }
7351
            else {
7352
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
7353
                int i;
7354
7355
                while (blocks > BS_WORD_SIZE) {
7356
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
7357
                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * WC_AES_BLOCK_SIZE,
7358
                            WC_AES_BLOCK_SIZE);
7359
                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
7360
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
7361
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
7362
                                  WC_AES_BLOCK_SIZE);
7363
                    }
7364
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7365
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7366
7367
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7368
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7369
                    blocks -= BS_WORD_SIZE;
7370
                }
7371
                if (blocks > 0) {
7372
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
7373
                    XMEMCPY(aes->tmp, in + (blocks - 1) * WC_AES_BLOCK_SIZE,
7374
                            WC_AES_BLOCK_SIZE);
7375
                    for (i = blocks-1; i >= 1; i--) {
7376
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
7377
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
7378
                                  WC_AES_BLOCK_SIZE);
7379
                    }
7380
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7381
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7382
7383
                    blocks = 0;
7384
                }
7385
            }
7386
#else
7387
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
7388
0
            {
7389
0
            int did_prefetches = 0;
7390
0
#endif
7391
0
            while (blocks--) {
7392
0
                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
7393
0
                ret = AesDecrypt_preFetchOpt(aes, in, out, &did_prefetches);
7394
0
                if (ret != 0)
7395
0
                    return ret;
7396
0
                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7397
                /* store iv for next call */
7398
0
                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7399
7400
0
                out += WC_AES_BLOCK_SIZE;
7401
0
                in  += WC_AES_BLOCK_SIZE;
7402
0
            }
7403
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
7404
0
            }
7405
0
#endif
7406
0
#endif
7407
0
        }
7408
7409
0
        VECTOR_REGISTERS_POP;
7410
7411
0
        return ret;
7412
0
#endif
7413
0
    }
7414
#endif /* HAVE_AES_DECRYPT */
7415
7416
#endif /* AES-CBC block */
7417
#endif /* HAVE_AES_CBC */
7418
7419
/* AES-CTR */
7420
#if defined(WOLFSSL_AES_COUNTER)
7421
7422
    #ifdef STM32_CRYPTO
7423
        #define NEED_AES_CTR_SOFT
7424
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
7425
7426
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
7427
        {
7428
        #ifdef WOLFSSL_STM32_BARE
7429
            /* CTR per-block transform: produce out = in XOR AES_ECB(counter).
7430
             * ECB-encrypt the counter aes->reg into a keystream block, then XOR
7431
             * with the plaintext 'in'. The caller (XTRANSFORM_AESCTRBLOCK loop)
7432
             * does not XOR and increments aes->reg after this returns. */
7433
            byte ks[WC_AES_BLOCK_SIZE];
7434
            int  ret = wc_Stm32_Aes_Ecb(aes, ks, (const byte*)aes->reg,
7435
                                        WC_AES_BLOCK_SIZE, 1);
7436
            if (ret == 0) {
7437
                xorbufout(out, in, ks, WC_AES_BLOCK_SIZE);
7438
            }
7439
            else {
7440
                /* The CTR loop breaks on this non-zero return; zero the block
7441
                 * so a failed HW ECB does not leave stale/prior plaintext in
7442
                 * the output. */
7443
                ForceZero(out, WC_AES_BLOCK_SIZE);
7444
            }
7445
            ForceZero(ks, sizeof(ks));
7446
            return ret;
7447
        #else
7448
            int ret = 0;
7449
        #ifdef WOLFSSL_STM32_CUBEMX
7450
            CRYP_HandleTypeDef hcryp;
7451
            #ifdef STM32_HAL_V2
7452
            word32 iv[WC_AES_BLOCK_SIZE/sizeof(word32)];
7453
            #endif
7454
        #else
7455
            word32 *iv;
7456
            CRYP_InitTypeDef cryptInit;
7457
            CRYP_KeyInitTypeDef keyInit;
7458
            CRYP_IVInitTypeDef ivInit;
7459
        #endif
7460
7461
        #ifdef WOLFSSL_STM32_CUBEMX
7462
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
7463
            if (ret != 0) {
7464
                return ret;
7465
            }
7466
7467
            ret = wolfSSL_CryptHwMutexLock();
7468
            if (ret != 0) {
7469
                return ret;
7470
            }
7471
7472
        #if defined(STM32_HAL_V2)
7473
            hcryp.Init.Algorithm  = CRYP_AES_CTR;
7474
            ByteReverseWords(iv, aes->reg, WC_AES_BLOCK_SIZE);
7475
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
7476
        #elif defined(STM32_CRYPTO_AES_ONLY)
7477
            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
7478
            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
7479
            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
7480
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
7481
        #else
7482
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
7483
        #endif
7484
            HAL_CRYP_Init(&hcryp);
7485
7486
        #if defined(STM32_HAL_V2)
7487
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, WC_AES_BLOCK_SIZE,
7488
                (uint32_t*)out, STM32_HAL_TIMEOUT);
7489
        #elif defined(STM32_CRYPTO_AES_ONLY)
7490
            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
7491
                out, STM32_HAL_TIMEOUT);
7492
        #else
7493
            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
7494
                out, STM32_HAL_TIMEOUT);
7495
        #endif
7496
            if (ret != HAL_OK) {
7497
                ret = WC_TIMEOUT_E;
7498
            }
7499
            HAL_CRYP_DeInit(&hcryp);
7500
7501
        #else /* Standard Peripheral Library */
7502
            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
7503
            if (ret != 0) {
7504
                return ret;
7505
            }
7506
7507
            ret = wolfSSL_CryptHwMutexLock();
7508
            if (ret != 0) {
7509
                return ret;
7510
            }
7511
7512
            /* reset registers to their default values */
7513
            CRYP_DeInit();
7514
7515
            /* set key */
7516
            CRYP_KeyInit(&keyInit);
7517
7518
            /* set iv */
7519
            iv = aes->reg;
7520
            CRYP_IVStructInit(&ivInit);
7521
            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
7522
            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
7523
            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
7524
            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
7525
            CRYP_IVInit(&ivInit);
7526
7527
            /* set direction and mode */
7528
            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
7529
            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
7530
            CRYP_Init(&cryptInit);
7531
7532
            /* enable crypto processor */
7533
            CRYP_Cmd(ENABLE);
7534
7535
            /* flush IN/OUT FIFOs */
7536
            CRYP_FIFOFlush();
7537
7538
            CRYP_DataIn(*(uint32_t*)&in[0]);
7539
            CRYP_DataIn(*(uint32_t*)&in[4]);
7540
            CRYP_DataIn(*(uint32_t*)&in[8]);
7541
            CRYP_DataIn(*(uint32_t*)&in[12]);
7542
7543
            /* wait until the complete message has been processed */
7544
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
7545
7546
            *(uint32_t*)&out[0]  = CRYP_DataOut();
7547
            *(uint32_t*)&out[4]  = CRYP_DataOut();
7548
            *(uint32_t*)&out[8]  = CRYP_DataOut();
7549
            *(uint32_t*)&out[12] = CRYP_DataOut();
7550
7551
            /* disable crypto processor */
7552
            CRYP_Cmd(DISABLE);
7553
        #endif /* WOLFSSL_STM32_CUBEMX */
7554
7555
            wolfSSL_CryptHwMutexUnLock();
7556
            wc_Stm32_Aes_Cleanup();
7557
            return ret;
7558
        #endif /* !WOLFSSL_STM32_BARE */
7559
        }
7560
7561
7562
    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
7563
7564
        #define NEED_AES_CTR_SOFT
7565
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
7566
7567
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
7568
        {
7569
            word32 tmpIv[WC_AES_BLOCK_SIZE / sizeof(word32)];
7570
            XMEMCPY(tmpIv, aes->reg, WC_AES_BLOCK_SIZE);
7571
            return wc_Pic32AesCrypt(
7572
                aes->key, aes->keylen, tmpIv, WC_AES_BLOCK_SIZE,
7573
                out, in, WC_AES_BLOCK_SIZE,
7574
                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
7575
        }
7576
7577
    #elif defined(HAVE_COLDFIRE_SEC)
7578
        #error "Coldfire SEC doesn't currently support AES-CTR mode"
7579
7580
    #elif defined(FREESCALE_LTC)
7581
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7582
        {
7583
            int ret = 0;
7584
            word32 keySize;
7585
            byte *iv, *enc_key;
7586
            byte* tmp;
7587
7588
            if (aes == NULL || out == NULL || in == NULL) {
7589
                return BAD_FUNC_ARG;
7590
            }
7591
7592
            /* consume any unused bytes left in aes->tmp */
7593
            tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7594
            while (aes->left && sz) {
7595
                *(out++) = *(in++) ^ *(tmp++);
7596
                aes->left--;
7597
                sz--;
7598
            }
7599
7600
            if (sz) {
7601
                iv      = (byte*)aes->reg;
7602
                enc_key = (byte*)aes->key;
7603
7604
                ret = wc_AesGetKeySize(aes, &keySize);
7605
                if (ret != 0)
7606
                    return ret;
7607
7608
                ret = wolfSSL_CryptHwMutexLock();
7609
                if (ret != 0)
7610
                    return ret;
7611
                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
7612
                    iv, enc_key, keySize, (byte*)aes->tmp,
7613
                    (uint32_t*)&aes->left);
7614
                wolfSSL_CryptHwMutexUnLock();
7615
            }
7616
7617
            return ret;
7618
        }
7619
7620
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
7621
        !defined(WOLFSSL_QNX_CAAM)
7622
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
7623
7624
    #elif defined(WOLFSSL_AFALG)
7625
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
7626
7627
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
7628
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
7629
7630
    #elif defined(WOLFSSL_ESP32_CRYPT) && \
7631
        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
7632
        /* esp32 doesn't support CRT mode by hw.     */
7633
        /* use aes ecnryption plus sw implementation */
7634
        #define NEED_AES_CTR_SOFT
7635
7636
    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
7637
        /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
7638
7639
    #elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
7640
        /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
7641
7642
    #else
7643
7644
        /* Use software based AES counter */
7645
        #define NEED_AES_CTR_SOFT
7646
    #endif
7647
7648
    #ifdef NEED_AES_CTR_SOFT
7649
        #ifndef WOLFSSL_ARMASM
7650
        /* Increment AES counter */
7651
        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
7652
        {
7653
            /* in network byte order so start at end and work back */
7654
            int i;
7655
            for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
7656
                if (++inOutCtr[i])  /* we're done unless we overflow */
7657
                    return;
7658
            }
7659
        }
7660
        #endif
7661
7662
        /* Software AES - CTR Encrypt */
7663
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7664
        {
7665
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
7666
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7667
            byte scratch[WC_AES_BLOCK_SIZE];
7668
    #endif
7669
    #if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7670
            int ret = 0;
7671
    #endif
7672
            word32 processed;
7673
#ifdef WC_AES_HAVE_PREFETCH_ARG
7674
            int did_prefetches = 0;
7675
#endif
7676
7677
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
7678
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7679
            XMEMSET(scratch, 0, sizeof(scratch));
7680
    #endif
7681
7682
            if (aes == NULL || out == NULL || in == NULL) {
7683
                return BAD_FUNC_ARG;
7684
            }
7685
7686
        #ifdef WOLF_CRYPTO_CB
7687
            #ifndef WOLF_CRYPTO_CB_FIND
7688
            if (aes->devId != INVALID_DEVID)
7689
            #endif
7690
            {
7691
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
7692
                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7693
                    return crypto_cb_ret;
7694
                /* fall-through when unavailable */
7695
            }
7696
        #endif
7697
7698
            /* consume any unused bytes left in aes->tmp */
7699
            processed = min(aes->left, sz);
7700
            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
7701
                      processed);
7702
            out += processed;
7703
            in += processed;
7704
            aes->left -= processed;
7705
            sz -= processed;
7706
7707
    #if defined(WOLFSSL_ARMASM)
7708
        #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7709
            #ifndef __aarch64__
7710
            AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
7711
                (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
7712
            #else
7713
            if (aes->use_aes_hw_crypto) {
7714
                AES_CTR_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7715
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
7716
                return 0;
7717
            }
7718
            else
7719
            #endif /* !__aarch64__ */
7720
        #endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7721
        #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7722
            {
7723
                word32 numBlocks;
7724
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7725
                /* consume any unused bytes left in aes->tmp */
7726
                while ((aes->left != 0) && (sz != 0)) {
7727
                   *(out++) = *(in++) ^ *(tmp++);
7728
                   aes->left--;
7729
                   sz--;
7730
                }
7731
7732
                /* do as many block size ops as possible */
7733
                numBlocks = sz / WC_AES_BLOCK_SIZE;
7734
                if (numBlocks > 0) {
7735
                #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
7736
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7737
                    if (sz >= 32)
7738
                #endif
7739
                    {
7740
                        AES_CTR_encrypt_NEON(in, out,
7741
                            numBlocks * WC_AES_BLOCK_SIZE, (byte*)aes->key,
7742
                            aes->rounds, (byte*)aes->reg);
7743
                    }
7744
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7745
                    else
7746
                #endif
7747
                #endif
7748
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7749
                    {
7750
                        AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
7751
                            (byte*)aes->key, aes->rounds, (byte*)aes->reg);
7752
                    }
7753
                #endif
7754
7755
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
7756
                    out += numBlocks * WC_AES_BLOCK_SIZE;
7757
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
7758
                }
7759
7760
                /* handle non block size remaining */
7761
                if (sz) {
7762
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
7763
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
7764
7765
                #if defined(__aarch64__) && \
7766
                    !defined(WOLFSSL_ARMASM_NO_NEON) && \
7767
                    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7768
                    {
7769
                        AES_CTR_encrypt_NEON(zeros, (byte*)aes->tmp,
7770
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7771
                            (byte*)aes->reg);
7772
                    }
7773
                #else
7774
                    {
7775
                        AES_CTR_encrypt(zeros, (byte*)aes->tmp,
7776
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7777
                            (byte*)aes->reg);
7778
                    }
7779
                #endif
7780
7781
                    aes->left = WC_AES_BLOCK_SIZE;
7782
                    tmp = (byte*)aes->tmp;
7783
7784
                    while (sz--) {
7785
                        *(out++) = *(in++) ^ *(tmp++);
7786
                        aes->left--;
7787
                    }
7788
                }
7789
            }
7790
        #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
7791
            return 0;
7792
    #elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7793
            {
7794
                word32 numBlocks;
7795
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7796
                /* consume any unused bytes left in aes->tmp */
7797
                while ((aes->left != 0) && (sz != 0)) {
7798
                   *(out++) = *(in++) ^ *(tmp++);
7799
                   aes->left--;
7800
                   sz--;
7801
                }
7802
7803
                /* do as many block size ops as possible */
7804
                numBlocks = sz / WC_AES_BLOCK_SIZE;
7805
                if (numBlocks > 0) {
7806
                    AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
7807
                        (byte*)aes->key, aes->rounds, (byte*)aes->reg);
7808
7809
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
7810
                    out += numBlocks * WC_AES_BLOCK_SIZE;
7811
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
7812
                }
7813
7814
                /* handle non block size remaining */
7815
                if (sz) {
7816
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
7817
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
7818
7819
                    AES_CTR_encrypt(zeros, (byte*)aes->tmp,
7820
                        WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7821
                        (byte*)aes->reg);
7822
7823
                    aes->left = WC_AES_BLOCK_SIZE;
7824
                    tmp = (byte*)aes->tmp;
7825
7826
                    while (sz--) {
7827
                        *(out++) = *(in++) ^ *(tmp++);
7828
                        aes->left--;
7829
                    }
7830
                }
7831
            }
7832
            return 0;
7833
    #else
7834
            VECTOR_REGISTERS_PUSH;
7835
7836
        #if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
7837
            if (aes->use_aesni && sz >= WC_AES_BLOCK_SIZE) {
7838
                word32 ctrBlocks = sz / WC_AES_BLOCK_SIZE;
7839
                word32 ctrBytes  = ctrBlocks * WC_AES_BLOCK_SIZE;
7840
                AesCtrEncryptBlocks(in, out, ctrBytes, (byte*)aes->key,
7841
                                    (int)aes->rounds, (byte*)aes->reg);
7842
                in  += ctrBytes;
7843
                out += ctrBytes;
7844
                sz  -= ctrBytes;
7845
                aes->left = 0;
7846
            }
7847
        #endif
7848
7849
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
7850
            !defined(XTRANSFORM_AESCTRBLOCK)
7851
            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
7852
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
7853
                byte* counter = (byte*)aes->reg;
7854
                byte* c = out;
7855
                while (blocks--) {
7856
                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
7857
                    c += WC_AES_BLOCK_SIZE;
7858
                    IncrementAesCounter(counter);
7859
                }
7860
7861
                /* reset number of blocks and then do encryption */
7862
                blocks = sz / WC_AES_BLOCK_SIZE;
7863
                wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
7864
                xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
7865
                in += WC_AES_BLOCK_SIZE * blocks;
7866
                out += WC_AES_BLOCK_SIZE * blocks;
7867
                sz -= blocks * WC_AES_BLOCK_SIZE;
7868
            }
7869
            else
7870
        #endif
7871
            {
7872
            #ifdef WOLFSSL_CHECK_MEM_ZERO
7873
                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
7874
                    WC_AES_BLOCK_SIZE);
7875
            #endif
7876
                /* do as many block size ops as possible */
7877
                while (sz >= WC_AES_BLOCK_SIZE) {
7878
                #ifdef XTRANSFORM_AESCTRBLOCK
7879
                    ret = XTRANSFORM_AESCTRBLOCK(aes, out, in);
7880
                    if (ret != 0)
7881
                        break;
7882
                #else
7883
                    ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7884
                                                    scratch,
7885
                                                    &did_prefetches);
7886
                    if (ret != 0)
7887
                        break;
7888
                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
7889
                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
7890
                #endif
7891
                    IncrementAesCounter((byte*)aes->reg);
7892
7893
                    out += WC_AES_BLOCK_SIZE;
7894
                    in  += WC_AES_BLOCK_SIZE;
7895
                    sz  -= WC_AES_BLOCK_SIZE;
7896
                    aes->left = 0;
7897
                }
7898
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
7899
            }
7900
7901
            /* handle non block size remaining and store unused byte count in left */
7902
            if ((ret == 0) && sz) {
7903
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7904
                                                (byte*)aes->tmp,
7905
                                                &did_prefetches);
7906
                if (ret == 0) {
7907
                    IncrementAesCounter((byte*)aes->reg);
7908
                    aes->left = WC_AES_BLOCK_SIZE - sz;
7909
                    xorbufout(out, in, aes->tmp, sz);
7910
                }
7911
            }
7912
7913
            if (ret < 0)
7914
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
7915
7916
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7917
            wc_MemZero_Check(scratch, WC_AES_BLOCK_SIZE);
7918
        #endif
7919
7920
            VECTOR_REGISTERS_POP;
7921
7922
            return ret;
7923
    #endif
7924
        }
7925
7926
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
7927
                                        const byte* iv, int dir)
7928
        {
7929
            if (aes == NULL) {
7930
                return BAD_FUNC_ARG;
7931
            }
7932
            if (len > sizeof(aes->key)) {
7933
                return BAD_FUNC_ARG;
7934
            }
7935
7936
            return wc_AesSetKey(aes, key, len, iv, dir);
7937
        }
7938
7939
    #endif /* NEED_AES_CTR_SOFT */
7940
7941
#endif /* WOLFSSL_AES_COUNTER */
7942
7943
#ifndef WC_AES_HAVE_PREFETCH_ARG
7944
    #ifndef AesEncrypt_preFetchOpt
7945
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
7946
            wc_AesEncrypt(aes, inBlock, outBlock)
7947
    #endif
7948
    #ifndef AesDecrypt_preFetchOpt
7949
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
7950
            wc_AesDecrypt(aes, inBlock, outBlock)
7951
    #endif
7952
#endif
7953
7954
#else  /* WOLFSSL_RISCV_ASM */
7955
7956
#define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
7957
    wc_AesEncryptDirect(aes, outBlock, inBlock)
7958
#define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
7959
    wc_AesDecryptDirect(aes, outBlock, inBlock)
7960
7961
#endif /* WOLFSSL_RISCV_ASM */
7962
7963
/*
7964
 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
7965
 * of two parts in order:
7966
 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
7967
 *      to the implicit IV.
7968
 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
7969
 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
7970
 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
7971
 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
7972
 * block counter during the encryption.
7973
 */
7974
7975
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
7976
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
7977
0
{
7978
0
    int i;
7979
0
    for (i = (int)ctrSz - 1; i >= 0; i--) {
7980
0
        if (++ctr[i])
7981
0
            break;
7982
0
    }
7983
0
}
7984
#endif /* HAVE_AESGCM || HAVE_AESCCM */
7985
7986
7987
#ifdef HAVE_AESGCM
7988
7989
#ifdef WOLFSSL_AESGCM_STREAM
7990
    /* Access initialization counter data. */
7991
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
7992
    /* Access counter data. */
7993
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
7994
    /* Access tag data. */
7995
    #define AES_TAG(aes)            ((aes)->streamData + 2 * WC_AES_BLOCK_SIZE)
7996
    /* Access last GHASH block. */
7997
    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE)
7998
    /* Access last encrypted block. */
7999
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
8000
8001
    #define GHASH_ONE_BLOCK     GHASH_ONE_BLOCK_SW
8002
#endif
8003
8004
#if defined(HAVE_COLDFIRE_SEC)
8005
    #error "Coldfire SEC doesn't currently support AES-GCM mode"
8006
8007
#endif
8008
8009
#if !defined(NO_INLINE) && defined(__GNUC__) && !defined(__cplusplus)
8010
/* Inline for callers here in aes.c, but a callable local function for outside
8011
 * callers.  Don't use WC_INLINE unconditionally, because we can't count on
8012
 * correct behavior beyond gcc/clang, and we don't want the the WC_MAYBE_UNUSED
8013
 * attribute in NO_INLINE builds.
8014
 */
8015
WC_INLINE
8016
#endif
8017
0
int wc_local_AesGcmCheckTagSz(word32 authTagSz) {
8018
#ifdef WC_AES_GCM_ALLOW_NONSTANDARD_TAG_LENGTH
8019
    #ifdef HAVE_FIPS
8020
        #error WC_AES_GCM_ALLOW_NONSTANDARD_TAG_LENGTH not allowed with FIPS 140.
8021
    #endif
8022
    wc_static_assert(WOLFSSL_MIN_AUTH_TAG_SZ >= 4);
8023
    if ((authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) ||
8024
        (authTagSz > WC_AES_BLOCK_SIZE))
8025
    {
8026
        WOLFSSL_MSG("AES-GCM unsupported authTagSz");
8027
        return BAD_FUNC_ARG;
8028
    }
8029
    else
8030
        return 0;
8031
#else
8032
    /* A switch is actually better for the optimizer than most hand-rolled
8033
     * equivalents, because it hands the compiler the exact value set and lets
8034
     * it pick the best lowering per WOLFSSL_MIN_AUTH_TAG_SZ configuration.
8035
     */
8036
0
    switch (authTagSz) {
8037
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 4
8038
    case 4:
8039
#endif
8040
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 8
8041
    case 8:
8042
#endif
8043
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 12
8044
0
    case 12:
8045
0
#endif
8046
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 13
8047
0
    case 13:
8048
0
#endif
8049
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 14
8050
0
    case 14:
8051
0
#endif
8052
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 15
8053
0
    case 15:
8054
0
#endif
8055
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 16
8056
0
    case 16:
8057
0
#endif
8058
0
        return 0;
8059
0
    default:
8060
0
        WOLFSSL_MSG("AES-GCM unsupported authTagSz");
8061
0
        return BAD_FUNC_ARG;
8062
0
    }
8063
0
#endif
8064
0
}
8065
8066
#if defined(WOLFSSL_RISCV_ASM)
8067
    /* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
8068
8069
#elif defined(WOLFSSL_AFALG)
8070
    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
8071
8072
#elif defined(WOLFSSL_KCAPI_AES)
8073
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
8074
8075
#elif defined(WOLFSSL_DEVCRYPTO_AES)
8076
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
8077
8078
#else /* software + AESNI implementation */
8079
8080
#if !defined(FREESCALE_LTC_AES_GCM)
8081
#if (!(defined(__aarch64__) && defined(WOLFSSL_ARMASM))) || \
8082
    defined(WOLFSSL_AESGCM_STREAM)
8083
static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
8084
0
{
8085
0
    int i;
8086
8087
    /* in network byte order so start at end and work back */
8088
0
    for (i = WC_AES_BLOCK_SIZE - 1; i >= WC_AES_BLOCK_SIZE - CTR_SZ; i--) {
8089
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
8090
0
            return;
8091
0
    }
8092
0
}
8093
#endif
8094
#endif /* !FREESCALE_LTC_AES_GCM */
8095
8096
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
8097
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8098
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8099
8100
static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
8101
0
{
8102
    /* Multiply the sz by 8 */
8103
0
    word32 szHi = (sz >> (8*sizeof(sz) - 3));
8104
0
    sz <<= 3;
8105
8106
    /* copy over the words of the sz into the destination buffer */
8107
0
    buf[0] = (byte)(szHi >> 24);
8108
0
    buf[1] = (byte)(szHi >> 16);
8109
0
    buf[2] = (byte)(szHi >>  8);
8110
0
    buf[3] = (byte)szHi;
8111
0
    buf[4] = (byte)(sz >> 24);
8112
0
    buf[5] = (byte)(sz >> 16);
8113
0
    buf[6] = (byte)(sz >>  8);
8114
0
    buf[7] = (byte)sz;
8115
0
}
8116
8117
8118
static WC_INLINE void RIGHTSHIFTX(byte* x)
8119
0
{
8120
0
    int i;
8121
0
    int carryIn = 0;
8122
0
    volatile byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
8123
8124
0
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
8125
0
        int carryOut = (x[i] & 0x01) << 7;
8126
0
        x[i] = (byte) ((x[i] >> 1) | carryIn);
8127
0
        carryIn = carryOut;
8128
0
    }
8129
0
    x[0] ^= borrow;
8130
0
}
8131
8132
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
8133
8134
8135
#ifdef GCM_TABLE
8136
8137
void GenerateM0(Gcm* gcm)
8138
{
8139
    int i, j;
8140
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
8141
8142
    XMEMCPY(m[128], gcm->H, WC_AES_BLOCK_SIZE);
8143
8144
    for (i = 64; i > 0; i /= 2) {
8145
        XMEMCPY(m[i], m[i*2], WC_AES_BLOCK_SIZE);
8146
        RIGHTSHIFTX(m[i]);
8147
    }
8148
8149
    for (i = 2; i < 256; i *= 2) {
8150
        for (j = 1; j < i; j++) {
8151
            XMEMCPY(m[i+j], m[i], WC_AES_BLOCK_SIZE);
8152
            xorbuf(m[i+j], m[j], WC_AES_BLOCK_SIZE);
8153
        }
8154
    }
8155
8156
#if defined(WOLFSSL_PPC64_ASM)
8157
    for (i = 1; i < 256; i++) {
8158
        word64* m64 = (word64*)gcm->M0[i];
8159
        m64[0] = ByteReverseWord64(m64[0]);
8160
        m64[1] = ByteReverseWord64(m64[1]);
8161
    }
8162
#endif
8163
    XMEMSET(m[0], 0, WC_AES_BLOCK_SIZE);
8164
}
8165
8166
#elif defined(GCM_TABLE_4BIT)
8167
8168
#if !defined(WC_16BIT_CPU)
8169
static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
8170
0
{
8171
0
    int i;
8172
0
    for (i = 15; i > 0; i--)
8173
0
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
8174
0
    r8[0] = (byte)(z8[0] >> 4);
8175
0
}
8176
#endif
8177
8178
void GenerateM0(Gcm* gcm)
8179
0
{
8180
0
#if !defined(WC_16BIT_CPU)
8181
0
    int i;
8182
0
#endif
8183
0
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
8184
8185
    /* 0 times -> 0x0 */
8186
0
    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
8187
    /* 1 times -> 0x8 */
8188
0
    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
8189
    /* 2 times -> 0x4 */
8190
0
    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
8191
0
    RIGHTSHIFTX(m[0x4]);
8192
    /* 4 times -> 0x2 */
8193
0
    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
8194
0
    RIGHTSHIFTX(m[0x2]);
8195
    /* 8 times -> 0x1 */
8196
0
    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
8197
0
    RIGHTSHIFTX(m[0x1]);
8198
8199
    /* 0x3 */
8200
0
    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
8201
0
    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
8202
8203
    /* 0x5 -> 0x7 */
8204
0
    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
8205
0
    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
8206
0
    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
8207
0
    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
8208
0
    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
8209
0
    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
8210
8211
    /* 0x9 -> 0xf */
8212
0
    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
8213
0
    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
8214
0
    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
8215
0
    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
8216
0
    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
8217
0
    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
8218
0
    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
8219
0
    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
8220
0
    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
8221
0
    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
8222
0
    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
8223
0
    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
8224
0
    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
8225
0
    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
8226
8227
0
#if !defined(WC_16BIT_CPU)
8228
0
    for (i = 0; i < 16; i++) {
8229
0
        Shift4_M0(m[16+i], m[i]);
8230
0
    }
8231
0
#endif
8232
8233
#if defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8234
    for (i = 0; i < 32; i++) {
8235
    #if !defined(__aarch64__)
8236
        word32* m32 = (word32*)gcm->M0[i];
8237
        m32[0] = ByteReverseWord32(m32[0]);
8238
        m32[1] = ByteReverseWord32(m32[1]);
8239
        m32[2] = ByteReverseWord32(m32[2]);
8240
        m32[3] = ByteReverseWord32(m32[3]);
8241
    #else
8242
        word64* m64 = (word64*)gcm->M0[i];
8243
        m64[0] = ByteReverseWord64(m64[0]);
8244
        m64[1] = ByteReverseWord64(m64[1]);
8245
    #endif
8246
    }
8247
#endif
8248
0
}
8249
8250
#endif /* GCM_TABLE */
8251
#endif
8252
8253
#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
8254
    #define HAVE_INTEL_AVX1
8255
    #ifndef NO_AVX2_SUPPORT
8256
        #define HAVE_INTEL_AVX2
8257
    #endif
8258
    #ifdef WOLFSSL_X86_64_BUILD
8259
        #ifndef NO_VAES_SUPPORT
8260
            #define HAVE_INTEL_VAES
8261
        #endif
8262
        #ifndef NO_AVX512_SUPPORT
8263
            #define HAVE_INTEL_AVX512
8264
        #endif
8265
    #endif
8266
#endif
8267
8268
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \
8269
    defined(WC_C_DYNAMIC_FALLBACK)
8270
void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m)
8271
                           XASM_LINK("GCM_generate_m0_aesni");
8272
#ifdef HAVE_INTEL_AVX1
8273
void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m)
8274
                          XASM_LINK("GCM_generate_m0_avx1");
8275
#endif
8276
#ifdef HAVE_INTEL_AVX2
8277
void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
8278
                          XASM_LINK("GCM_generate_m0_avx2");
8279
#endif
8280
#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */
8281
8282
/* Software AES - GCM SetKey */
8283
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
8284
0
{
8285
0
    int  ret;
8286
0
    byte iv[WC_AES_BLOCK_SIZE];
8287
8288
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
8289
        byte   local[32];
8290
        word32 localSz = 32;
8291
8292
        if (len == (16 + WC_CAAM_BLOB_SZ) ||
8293
          len == (24 + WC_CAAM_BLOB_SZ) ||
8294
          len == (32 + WC_CAAM_BLOB_SZ)) {
8295
            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
8296
                 return BAD_FUNC_ARG;
8297
            }
8298
8299
            /* set local values */
8300
            key = local;
8301
            len = localSz;
8302
        }
8303
    #endif
8304
8305
0
    if (!((len == 16) || (len == 24) || (len == 32)))
8306
0
        return BAD_FUNC_ARG;
8307
8308
0
    if (aes == NULL || key == NULL) {
8309
#ifdef WOLFSSL_IMX6_CAAM_BLOB
8310
        ForceZero(local, sizeof(local));
8311
#endif
8312
0
        return BAD_FUNC_ARG;
8313
0
    }
8314
#ifdef OPENSSL_EXTRA
8315
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
8316
    aes->gcm.aadLen = 0;
8317
#endif
8318
0
    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
8319
0
    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
8320
#ifdef WOLF_CRYPTO_CB_ONLY_AES
8321
    /* do key scheduling so that ECB-only devices can still do GCM */
8322
    if (ret == 0) {
8323
        ret = wc_CryptoCb_AesEcbEncrypt(aes, aes->gcm.H, iv, WC_AES_BLOCK_SIZE);
8324
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8325
        if (ret == 0)
8326
            GenerateM0(&aes->gcm);
8327
#endif
8328
    }
8329
    return ret;
8330
#endif
8331
#ifdef WOLFSSL_AESGCM_STREAM
8332
    aes->gcmKeySet = 1;
8333
#endif
8334
    #if defined(WOLFSSL_SECO_CAAM)
8335
        if (aes->devId == WOLFSSL_SECO_DEVID) {
8336
            return ret;
8337
        }
8338
    #endif /* WOLFSSL_SECO_CAAM */
8339
8340
    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
8341
        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
8342
        return ret;
8343
    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
8344
8345
/* GCM setup needs one AES block encrypt of the all-zero IV to generate
8346
 * the hash subkey H. STM32_CRYPTO stores only the raw key (no expanded
8347
 * key schedule), so the ARMASM AES_ECB_encrypt helpers used here cannot
8348
 * be used. Excluding STM32_CRYPTO from this block falls back to the
8349
 * non-ARMASM wc_AesEncrypt implementation, which on STM32 routes to
8350
 * CRYP. */
8351
#if defined(WOLFSSL_ARMASM) && !defined(STM32_CRYPTO)
8352
    if (ret == 0) {
8353
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
8354
    #if !defined(__aarch64__)
8355
        AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
8356
    #else
8357
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
8358
            AES_GCM_set_key_AARCH64(iv, (byte*)aes->key, aes->gcm.H,
8359
                aes->rounds);
8360
        }
8361
        else
8362
    #endif /* !__aarch64__ */
8363
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
8364
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
8365
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
8366
        {
8367
            AES_ECB_encrypt_NEON(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
8368
                (const unsigned char*)aes->key, aes->rounds);
8369
        }
8370
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8371
        {
8372
            AES_ECB_encrypt(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
8373
                (const unsigned char*)aes->key, aes->rounds);
8374
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8375
            GenerateM0(&aes->gcm);
8376
        #endif /* GCM_TABLE */
8377
        }
8378
#endif
8379
    }
8380
#else
8381
0
#if !defined(FREESCALE_LTC_AES_GCM) && !defined(WOLFSSL_PSOC6_CRYPTO)
8382
8383
8384
#ifdef WOLF_CRYPTO_CB_AES_SETKEY
8385
    if ((ret == 0) && (aes->devId != INVALID_DEVID && aes->devCtx != NULL)) {
8386
        /* SE owns key - skip H and M table generation */
8387
    }
8388
    else
8389
#endif
8390
0
    if (ret == 0) {
8391
0
        VECTOR_REGISTERS_PUSH;
8392
8393
        /* Generate H = AES_Encrypt(key, 0^128) */
8394
0
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
8395
8396
0
        if (ret == 0) {
8397
0
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8398
    #if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT)
8399
            if (aes->use_aesni) {
8400
        #if defined(WC_C_DYNAMIC_FALLBACK)
8401
            #ifdef HAVE_INTEL_AVX2
8402
                if (IS_INTEL_AVX2(intel_flags)) {
8403
                    GCM_generate_m0_avx2(aes->gcm.H,
8404
                        (byte*)aes->gcm.M0);
8405
                }
8406
                else
8407
            #endif
8408
            #if defined(HAVE_INTEL_AVX1)
8409
                if (IS_INTEL_AVX1(intel_flags)) {
8410
                    GCM_generate_m0_avx1(aes->gcm.H,
8411
                        (byte*)aes->gcm.M0);
8412
                }
8413
                else
8414
            #endif
8415
                {
8416
                    GCM_generate_m0_aesni(aes->gcm.H,
8417
                        (byte*)aes->gcm.M0);
8418
                }
8419
        #endif /* WC_C_DYNAMIC_FALLBACK */
8420
            }
8421
            else
8422
    #endif /* AESNI */
8423
0
            {
8424
0
                GenerateM0(&aes->gcm);
8425
0
            }
8426
0
#endif /* GCM_TABLE || GCM_TABLE_4BIT */
8427
0
        }
8428
8429
0
        VECTOR_REGISTERS_POP;
8430
0
    }
8431
0
#endif /* !FREESCALE_LTC_AES_GCM && !WOLFSSL_PSOC6_CRYPTO */
8432
0
#endif
8433
8434
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
8435
    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
8436
#endif
8437
8438
#ifdef WOLF_CRYPTO_CB
8439
    if (aes->devId != INVALID_DEVID) {
8440
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
8441
        if (aes->devCtx != NULL) {
8442
            /* SE owns key - don't copy to devKey */
8443
        }
8444
        else
8445
    #endif
8446
        {
8447
            XMEMCPY(aes->devKey, key, len);
8448
        }
8449
    }
8450
#endif
8451
8452
#ifdef WOLFSSL_IMX6_CAAM_BLOB
8453
    ForceZero(local, sizeof(local));
8454
#endif
8455
0
    return ret;
8456
0
}
8457
8458
8459
#ifdef WOLFSSL_AESNI
8460
8461
void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
8462
                     const unsigned char* addt, const unsigned char* ivec,
8463
                     unsigned char *tag, word32 nbytes,
8464
                     word32 abytes, word32 ibytes,
8465
                     word32 tbytes, const unsigned char* key, int nr)
8466
                     XASM_LINK("AES_GCM_encrypt_aesni");
8467
#ifdef HAVE_INTEL_AVX1
8468
void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
8469
                          const unsigned char* addt, const unsigned char* ivec,
8470
                          unsigned char *tag, word32 nbytes,
8471
                          word32 abytes, word32 ibytes,
8472
                          word32 tbytes, const unsigned char* key,
8473
                          int nr)
8474
                          XASM_LINK("AES_GCM_encrypt_avx1");
8475
#ifdef HAVE_INTEL_AVX2
8476
void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
8477
                          const unsigned char* addt, const unsigned char* ivec,
8478
                          unsigned char *tag, word32 nbytes,
8479
                          word32 abytes, word32 ibytes,
8480
                          word32 tbytes, const unsigned char* key,
8481
                          int nr)
8482
                          XASM_LINK("AES_GCM_encrypt_avx2");
8483
#ifdef HAVE_INTEL_AVX512
8484
void AES_GCM_encrypt_avx512(const unsigned char *in, unsigned char *out,
8485
                          const unsigned char* addt, const unsigned char* ivec,
8486
                          unsigned char *tag, word32 nbytes,
8487
                          word32 abytes, word32 ibytes,
8488
                          word32 tbytes, const unsigned char* key,
8489
                          int nr)
8490
                          XASM_LINK("AES_GCM_encrypt_avx512");
8491
#endif
8492
#ifdef HAVE_INTEL_VAES
8493
void AES_GCM_encrypt_vaes(const unsigned char *in, unsigned char *out,
8494
                          const unsigned char* addt, const unsigned char* ivec,
8495
                          unsigned char *tag, word32 nbytes,
8496
                          word32 abytes, word32 ibytes,
8497
                          word32 tbytes, const unsigned char* key,
8498
                          int nr)
8499
                          XASM_LINK("AES_GCM_encrypt_vaes");
8500
#endif
8501
#endif /* HAVE_INTEL_AVX2 */
8502
#endif /* HAVE_INTEL_AVX1 */
8503
8504
#ifdef HAVE_AES_DECRYPT
8505
void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
8506
                     const unsigned char* addt, const unsigned char* ivec,
8507
                     const unsigned char *tag, word32 nbytes, word32 abytes,
8508
                     word32 ibytes, word32 tbytes, const unsigned char* key,
8509
                     int nr, int* res)
8510
                     XASM_LINK("AES_GCM_decrypt_aesni");
8511
#ifdef HAVE_INTEL_AVX1
8512
void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
8513
                          const unsigned char* addt, const unsigned char* ivec,
8514
                          const unsigned char *tag, word32 nbytes,
8515
                          word32 abytes, word32 ibytes, word32 tbytes,
8516
                          const unsigned char* key, int nr, int* res)
8517
                          XASM_LINK("AES_GCM_decrypt_avx1");
8518
#ifdef HAVE_INTEL_AVX2
8519
void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
8520
                          const unsigned char* addt, const unsigned char* ivec,
8521
                          const unsigned char *tag, word32 nbytes,
8522
                          word32 abytes, word32 ibytes, word32 tbytes,
8523
                          const unsigned char* key, int nr, int* res)
8524
                          XASM_LINK("AES_GCM_decrypt_avx2");
8525
#ifdef HAVE_INTEL_AVX512
8526
void AES_GCM_decrypt_avx512(const unsigned char *in, unsigned char *out,
8527
                          const unsigned char* addt, const unsigned char* ivec,
8528
                          const unsigned char *tag, word32 nbytes,
8529
                          word32 abytes, word32 ibytes, word32 tbytes,
8530
                          const unsigned char* key, int nr, int* res)
8531
                          XASM_LINK("AES_GCM_decrypt_avx512");
8532
#endif
8533
#ifdef HAVE_INTEL_VAES
8534
void AES_GCM_decrypt_vaes(const unsigned char *in, unsigned char *out,
8535
                          const unsigned char* addt, const unsigned char* ivec,
8536
                          const unsigned char *tag, word32 nbytes,
8537
                          word32 abytes, word32 ibytes, word32 tbytes,
8538
                          const unsigned char* key, int nr, int* res)
8539
                          XASM_LINK("AES_GCM_decrypt_vaes");
8540
#endif
8541
#endif /* HAVE_INTEL_AVX2 */
8542
#endif /* HAVE_INTEL_AVX1 */
8543
#endif /* HAVE_AES_DECRYPT */
8544
8545
#endif /* WOLFSSL_AESNI */
8546
8547
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
8548
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8549
#if defined(GCM_SMALL)
8550
static void GMULT(byte* X, byte* Y)
8551
{
8552
    byte Z[WC_AES_BLOCK_SIZE];
8553
    byte V[WC_AES_BLOCK_SIZE];
8554
    int i, j;
8555
8556
    XMEMSET(Z, 0, WC_AES_BLOCK_SIZE);
8557
    XMEMCPY(V, X, WC_AES_BLOCK_SIZE);
8558
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++)
8559
    {
8560
        byte y = Y[i];
8561
        for (j = 0; j < 8; j++)
8562
        {
8563
            if (y & 0x80) {
8564
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
8565
            }
8566
8567
            RIGHTSHIFTX(V);
8568
            y = y << 1;
8569
        }
8570
    }
8571
    XMEMCPY(X, Z, WC_AES_BLOCK_SIZE);
8572
}
8573
8574
8575
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8576
    word32 cSz, byte* s, word32 sSz)
8577
{
8578
    byte x[WC_AES_BLOCK_SIZE];
8579
    byte scratch[WC_AES_BLOCK_SIZE];
8580
    word32 blocks, partial;
8581
    byte* h;
8582
8583
    h = gcm->H;
8584
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
8585
8586
    /* Hash in A, the Additional Authentication Data */
8587
    if (aSz != 0 && a != NULL) {
8588
        blocks = aSz / WC_AES_BLOCK_SIZE;
8589
        partial = aSz % WC_AES_BLOCK_SIZE;
8590
        while (blocks--) {
8591
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
8592
            GMULT(x, h);
8593
            a += WC_AES_BLOCK_SIZE;
8594
        }
8595
        if (partial != 0) {
8596
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8597
            XMEMCPY(scratch, a, partial);
8598
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8599
            GMULT(x, h);
8600
        }
8601
    }
8602
8603
    /* Hash in C, the Ciphertext */
8604
    if (cSz != 0 && c != NULL) {
8605
        blocks = cSz / WC_AES_BLOCK_SIZE;
8606
        partial = cSz % WC_AES_BLOCK_SIZE;
8607
        while (blocks--) {
8608
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
8609
            GMULT(x, h);
8610
            c += WC_AES_BLOCK_SIZE;
8611
        }
8612
        if (partial != 0) {
8613
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8614
            XMEMCPY(scratch, c, partial);
8615
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8616
            GMULT(x, h);
8617
        }
8618
    }
8619
8620
    /* Hash in the lengths of A and C in bits */
8621
    FlattenSzInBits(&scratch[0], aSz);
8622
    FlattenSzInBits(&scratch[8], cSz);
8623
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8624
    GMULT(x, h);
8625
8626
    /* Copy the result into s. */
8627
    XMEMCPY(s, x, sSz);
8628
}
8629
8630
#ifdef WOLFSSL_AESGCM_STREAM
8631
/* No extra initialization for small implementation.
8632
 *
8633
 * @param [in] aes  AES GCM object.
8634
 */
8635
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8636
8637
/* GHASH one block of data..
8638
 *
8639
 * XOR block into tag and GMULT with H.
8640
 *
8641
 * @param [in, out] aes    AES GCM object.
8642
 * @param [in]      block  Block of AAD or cipher text.
8643
 */
8644
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
8645
    do {                                                \
8646
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
8647
        GMULT(AES_TAG(aes), (aes)->gcm.H);              \
8648
    }                                                   \
8649
    while (0)
8650
#endif /* WOLFSSL_AESGCM_STREAM */
8651
8652
#if defined(WOLFSSL_ARMASM) && (!defined(__aarch64__) || \
8653
    defined(WOLFSSL_ARMASM_NO_NEON))
8654
static void GCM_gmult_len_armasm_C(
8655
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
8656
{
8657
    byte Z[AES_BLOCK_SIZE];
8658
    byte V[AES_BLOCK_SIZE];
8659
    int i;
8660
    int j;
8661
8662
    while (len >= AES_BLOCK_SIZE) {
8663
        xorbuf(x, a, AES_BLOCK_SIZE);
8664
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
8665
        XMEMCPY(V, x, AES_BLOCK_SIZE);
8666
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
8667
            byte y = h[i];
8668
            for (j = 0; j < 8; j++) {
8669
                if (y & 0x80) {
8670
                    xorbuf(Z, V, AES_BLOCK_SIZE);
8671
                }
8672
                RIGHTSHIFTX(V);
8673
                y = y << 1;
8674
            }
8675
        }
8676
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
8677
        len -= AES_BLOCK_SIZE;
8678
        a += AES_BLOCK_SIZE;
8679
    }
8680
}
8681
8682
#define GCM_GMULT_LEN(gcm, x, a, len) \
8683
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
8684
#elif defined(WOLFSSL_ARMASM)
8685
#define GCM_GMULT_LEN(gcm, x, a, len) \
8686
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
8687
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
8688
static void GCM_gmult_len_armasm_C(
8689
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
8690
{
8691
    byte Z[AES_BLOCK_SIZE];
8692
    byte V[AES_BLOCK_SIZE];
8693
    int i;
8694
    int j;
8695
8696
    while (len >= AES_BLOCK_SIZE) {
8697
        xorbuf(x, a, AES_BLOCK_SIZE);
8698
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
8699
        XMEMCPY(V, x, AES_BLOCK_SIZE);
8700
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
8701
            byte y = h[i];
8702
            for (j = 0; j < 8; j++) {
8703
                if (y & 0x80) {
8704
                    xorbuf(Z, V, AES_BLOCK_SIZE);
8705
                }
8706
                RIGHTSHIFTX(V);
8707
                y = y << 1;
8708
            }
8709
        }
8710
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
8711
        len -= AES_BLOCK_SIZE;
8712
        a += AES_BLOCK_SIZE;
8713
    }
8714
}
8715
8716
#define GCM_GMULT_LEN(gcm, x, a, len) \
8717
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
8718
#endif
8719
8720
#elif defined(GCM_TABLE)
8721
8722
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
8723
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8724
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
8725
#define GCM_GMULT_LEN(gcm, x, a, len) \
8726
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
8727
#else
8728
#define GCM_GMULT_LEN(gcm, x, a, len) \
8729
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
8730
#endif
8731
#elif defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
8732
#define GCM_GMULT_LEN(gcm, x, a, len) \
8733
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
8734
#else
8735
ALIGN16 static const byte R[256][2] = {
8736
    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
8737
    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
8738
    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
8739
    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
8740
    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
8741
    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
8742
    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
8743
    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
8744
    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
8745
    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
8746
    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
8747
    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
8748
    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
8749
    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
8750
    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
8751
    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
8752
    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
8753
    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
8754
    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
8755
    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
8756
    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
8757
    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
8758
    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
8759
    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
8760
    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
8761
    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
8762
    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
8763
    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
8764
    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
8765
    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
8766
    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
8767
    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
8768
    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
8769
    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
8770
    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
8771
    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
8772
    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
8773
    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
8774
    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
8775
    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
8776
    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
8777
    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
8778
    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
8779
    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
8780
    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
8781
    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
8782
    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
8783
    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
8784
    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
8785
    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
8786
    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
8787
    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
8788
    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
8789
    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
8790
    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
8791
    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
8792
    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
8793
    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
8794
    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
8795
    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
8796
    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
8797
    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
8798
    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
8799
    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
8800
8801
8802
static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE])
8803
{
8804
#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
8805
    int i, j;
8806
    byte Z[WC_AES_BLOCK_SIZE];
8807
    byte a;
8808
8809
    XMEMSET(Z, 0, sizeof(Z));
8810
8811
    for (i = 15; i > 0; i--) {
8812
        xorbuf(Z, m[x[i]], WC_AES_BLOCK_SIZE);
8813
        a = Z[15];
8814
8815
        for (j = 15; j > 0; j--) {
8816
            Z[j] = Z[j-1];
8817
        }
8818
8819
        Z[0]  = R[a][0];
8820
        Z[1] ^= R[a][1];
8821
    }
8822
    xorbuf(Z, m[x[0]], WC_AES_BLOCK_SIZE);
8823
8824
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
8825
#elif defined(WC_32BIT_CPU)
8826
#ifndef WOLFSSL_USE_ALIGN
8827
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
8828
    byte a;
8829
    word32* pZ;
8830
    word32* pm;
8831
    word32* px = (word32*)(x);
8832
    int i;
8833
8834
    pZ = (word32*)(Z + 15 + 1);
8835
    pm = (word32*)(m[x[15]]);
8836
    pZ[0] = pm[0];
8837
    pZ[1] = pm[1];
8838
    pZ[2] = pm[2];
8839
    pZ[3] = pm[3];
8840
    a = Z[16 + 15];
8841
    Z[15]  = R[a][0];
8842
    Z[16] ^= R[a][1];
8843
    for (i = 14; i > 0; i--) {
8844
        pZ = (word32*)(Z + i + 1);
8845
        pm = (word32*)(m[x[i]]);
8846
        pZ[0] ^= pm[0];
8847
        pZ[1] ^= pm[1];
8848
        pZ[2] ^= pm[2];
8849
        pZ[3] ^= pm[3];
8850
        a = Z[16 + i];
8851
        Z[i]    = R[a][0];
8852
        Z[i+1] ^= R[a][1];
8853
    }
8854
    pZ = (word32*)(Z + 1);
8855
    pm = (word32*)(m[x[0]]);
8856
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
8857
    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
8858
#else
8859
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
8860
    byte a;
8861
    int i;
8862
8863
    XMEMCPY(Z + 16, m[x[15]], WC_AES_BLOCK_SIZE);
8864
    a = Z[16 + 15];
8865
    Z[15]  = R[a][0];
8866
    Z[16] ^= R[a][1];
8867
    for (i = 14; i > 0; i--) {
8868
        xorbuf(Z + i + 1, m[x[i]], WC_AES_BLOCK_SIZE);
8869
        a = Z[16 + i];
8870
        Z[i]    = R[a][0];
8871
        Z[i+1] ^= R[a][1];
8872
    }
8873
    xorbuf(Z + 1, m[x[0]], WC_AES_BLOCK_SIZE);
8874
    XMEMCPY(x, Z + 1, WC_AES_BLOCK_SIZE);
8875
#endif
8876
#else
8877
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
8878
    byte a;
8879
    word64* pZ;
8880
    word64* pm;
8881
    word64* px = (word64*)(x);
8882
    int i;
8883
8884
    pZ = (word64*)(Z + 15 + 1);
8885
    pm = (word64*)(m[x[15]]);
8886
    pZ[0] = pm[0];
8887
    pZ[1] = pm[1];
8888
    a = Z[16 + 15];
8889
    Z[15]  = R[a][0];
8890
    Z[16] ^= R[a][1];
8891
    for (i = 14; i > 0; i--) {
8892
        pZ = (word64*)(Z + i + 1);
8893
        pm = (word64*)(m[x[i]]);
8894
        pZ[0] ^= pm[0];
8895
        pZ[1] ^= pm[1];
8896
        a = Z[16 + i];
8897
        Z[i]    = R[a][0];
8898
        Z[i+1] ^= R[a][1];
8899
    }
8900
    pZ = (word64*)(Z + 1);
8901
    pm = (word64*)(m[x[0]]);
8902
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
8903
#endif
8904
}
8905
#endif
8906
8907
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8908
    word32 cSz, byte* s, word32 sSz)
8909
{
8910
    byte x[WC_AES_BLOCK_SIZE];
8911
    byte scratch[WC_AES_BLOCK_SIZE];
8912
    word32 blocks, partial;
8913
8914
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
8915
8916
    /* Hash in A, the Additional Authentication Data */
8917
    if (aSz != 0 && a != NULL) {
8918
        blocks = aSz / WC_AES_BLOCK_SIZE;
8919
        partial = aSz % WC_AES_BLOCK_SIZE;
8920
    #ifdef GCM_GMULT_LEN
8921
        if (blocks > 0) {
8922
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
8923
            a += blocks * WC_AES_BLOCK_SIZE;
8924
        }
8925
        if (partial != 0) {
8926
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8927
            XMEMCPY(scratch, a, partial);
8928
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8929
        }
8930
    #else
8931
        while (blocks--) {
8932
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
8933
            GMULT(x, gcm->M0);
8934
            a += WC_AES_BLOCK_SIZE;
8935
        }
8936
        if (partial != 0) {
8937
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8938
            XMEMCPY(scratch, a, partial);
8939
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8940
            GMULT(x, gcm->M0);
8941
        }
8942
    #endif
8943
    }
8944
8945
    /* Hash in C, the Ciphertext */
8946
    if (cSz != 0 && c != NULL) {
8947
        blocks = cSz / WC_AES_BLOCK_SIZE;
8948
        partial = cSz % WC_AES_BLOCK_SIZE;
8949
    #ifdef GCM_GMULT_LEN
8950
        if (blocks > 0) {
8951
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
8952
            c += blocks * WC_AES_BLOCK_SIZE;
8953
        }
8954
        if (partial != 0) {
8955
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8956
            XMEMCPY(scratch, c, partial);
8957
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8958
        }
8959
    #else
8960
        while (blocks--) {
8961
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
8962
            GMULT(x, gcm->M0);
8963
            c += WC_AES_BLOCK_SIZE;
8964
        }
8965
        if (partial != 0) {
8966
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8967
            XMEMCPY(scratch, c, partial);
8968
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8969
            GMULT(x, gcm->M0);
8970
        }
8971
    #endif
8972
    }
8973
8974
    /* Hash in the lengths of A and C in bits */
8975
    FlattenSzInBits(&scratch[0], aSz);
8976
    FlattenSzInBits(&scratch[8], cSz);
8977
#ifdef GCM_GMULT_LEN
8978
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
8979
#else
8980
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8981
    GMULT(x, gcm->M0);
8982
#endif
8983
8984
    /* Copy the result into s. */
8985
    XMEMCPY(s, x, sSz);
8986
}
8987
8988
#ifdef WOLFSSL_AESGCM_STREAM
8989
/* No extra initialization for table implementation.
8990
 *
8991
 * @param [in] aes  AES GCM object.
8992
 */
8993
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8994
8995
/* GHASH one block of data..
8996
 *
8997
 * XOR block into tag and GMULT with H using pre-computed table.
8998
 *
8999
 * @param [in, out] aes    AES GCM object.
9000
 * @param [in]      block  Block of AAD or cipher text.
9001
 */
9002
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9003
    do {                                                \
9004
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
9005
        GMULT(AES_TAG(aes), aes->gcm.M0);               \
9006
    }                                                   \
9007
    while (0)
9008
#endif /* WOLFSSL_AESGCM_STREAM */
9009
/* end GCM_TABLE */
9010
#elif defined(GCM_TABLE_4BIT)
9011
/* ARM assembly */
9012
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
9013
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
9014
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
9015
#define GCM_GMULT_LEN(gcm, x, a, len) \
9016
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
9017
#define GMULT(x, m)                                                      \
9018
    GCM_gmult_NEON(x, (const byte**)m)
9019
#else
9020
#define GCM_GMULT_LEN(gcm, x, a, len) \
9021
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9022
#define GMULT(x, m)                                                      \
9023
    GCM_gmult(x, (const byte**)m)
9024
#endif
9025
9026
/* PPC64 assembly */
9027
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
9028
#define GCM_GMULT_LEN(gcm, x, a, len)                                    \
9029
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9030
#define GMULT(x, m)                                                      \
9031
    GCM_gmult(x, (const byte**)m)
9032
9033
#else
9034
/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
9035
 *  R shifts right a reverse bit pair of bytes such that:
9036
 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
9037
 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
9038
 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
9039
 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
9040
 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
9041
 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
9042
 *  To calculate te rest, XOR result for each bit.
9043
 *   e.g. 6 = 4 ^ 2 => 48,c0
9044
 *
9045
 * Second half is same values rotated by 4-bits.
9046
 */
9047
#if defined(WC_16BIT_CPU)
9048
static const byte R[16][2] = {
9049
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
9050
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
9051
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
9052
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
9053
};
9054
#elif defined(BIG_ENDIAN_ORDER)
9055
static const word16 R[32] = {
9056
          0x0000,       0x1c20,       0x3840,       0x2460,
9057
          0x7080,       0x6ca0,       0x48c0,       0x54e0,
9058
          0xe100,       0xfd20,       0xd940,       0xc560,
9059
          0x9180,       0x8da0,       0xa9c0,       0xb5e0,
9060
9061
          0x0000,       0x01c2,       0x0384,       0x0246,
9062
          0x0708,       0x06ca,       0x048c,       0x054e,
9063
          0x0e10,       0x0fd2,       0x0d94,       0x0c56,
9064
          0x0918,       0x08da,       0x0a9c,       0x0b5e,
9065
};
9066
#else
9067
static const word16 R[32] = {
9068
          0x0000,       0x201c,       0x4038,       0x6024,
9069
          0x8070,       0xa06c,       0xc048,       0xe054,
9070
          0x00e1,       0x20fd,       0x40d9,       0x60c5,
9071
          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
9072
9073
          0x0000,       0xc201,       0x8403,       0x4602,
9074
          0x0807,       0xca06,       0x8c04,       0x4e05,
9075
          0x100e,       0xd20f,       0x940d,       0x560c,
9076
          0x1809,       0xda08,       0x9c0a,       0x5e0b,
9077
};
9078
#endif
9079
9080
/* Multiply in GF(2^128) defined by polynomial:
9081
 *   x^128 + x^7 + x^2 + x^1 + 1.
9082
 *
9083
 * H: hash key = encrypt(key, 0)
9084
 * x = x * H in field
9085
 *
9086
 * x: cumulative result
9087
 * m: 4-bit table
9088
 *    [0..15] * H
9089
 */
9090
#if defined(WC_16BIT_CPU)
9091
static void GMULT(byte *x, byte m[16][WC_AES_BLOCK_SIZE])
9092
{
9093
    int i, j, n;
9094
    byte Z[WC_AES_BLOCK_SIZE];
9095
    byte a;
9096
9097
    XMEMSET(Z, 0, sizeof(Z));
9098
9099
    for (i = 15; i >= 0; i--) {
9100
        for (n = 0; n < 2; n++) {
9101
            if (n == 0)
9102
                xorbuf(Z, m[x[i] & 0xf], WC_AES_BLOCK_SIZE);
9103
            else {
9104
                xorbuf(Z, m[x[i] >> 4], WC_AES_BLOCK_SIZE);
9105
                if (i == 0)
9106
                    break;
9107
            }
9108
            a = Z[15] & 0xf;
9109
9110
            for (j = 15; j > 0; j--)
9111
                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
9112
            Z[0] >>= 4;
9113
9114
            Z[0] ^= R[a][0];
9115
            Z[1] ^= R[a][1];
9116
        }
9117
    }
9118
9119
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
9120
}
9121
#elif defined(WC_32BIT_CPU) && defined(BIG_ENDIAN_ORDER)
9122
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9123
{
9124
    int i;
9125
    word32 z8[4] = {0, 0, 0, 0};
9126
    byte a;
9127
    word32* x8 = (word32*)x;
9128
    word32* m8;
9129
    byte xi;
9130
9131
    for (i = 15; i > 0; i--) {
9132
        xi = x[i];
9133
9134
        /* XOR in (msn * H) */
9135
        m8 = (word32*)m[xi & 0xf];
9136
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9137
9138
        /* Cache top byte for remainder calculations - lost in rotate. */
9139
        a = (byte)(z8[3] & 0xff);
9140
9141
        /* Rotate Z by 8-bits */
9142
        z8[3] = (z8[2] << 24) | (z8[3] >> 8);
9143
        z8[2] = (z8[1] << 24) | (z8[2] >> 8);
9144
        z8[1] = (z8[0] << 24) | (z8[1] >> 8);
9145
        z8[0] >>= 8;
9146
9147
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9148
        z8[0] ^= ((word32)R[16 + (a & 0xf)]) << 16;
9149
9150
        xi >>= 4;
9151
        /* XOR in next significant nibble (XORed with H) * remainder */
9152
        m8 = (word32*)m[xi];
9153
        a ^= (byte)(m8[3] >> 12) & 0xf;
9154
        a ^= (byte)((m8[3] << 4) & 0xf0);
9155
        z8[0] ^= ((word32)R[a >> 4]) << 16;
9156
9157
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9158
        m8 = (word32*)m[16 + xi];
9159
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
9160
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
9161
    }
9162
9163
    xi = x[0];
9164
9165
    /* XOR in most significant nibble * H */
9166
    m8 = (word32*)m[xi & 0xf];
9167
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9168
9169
    /* Cache top byte for remainder calculations - lost in rotate. */
9170
    a = (byte)(z8[3] & 0x0f);
9171
9172
    z8[3] = (z8[2] << 28) | (z8[3] >> 4);
9173
    z8[2] = (z8[1] << 28) | (z8[2] >> 4);
9174
    z8[1] = (z8[0] << 28) | (z8[1] >> 4);
9175
    z8[0] >>= 4;
9176
9177
    /* XOR in most significant nibble * remainder */
9178
    z8[0] ^= ((word32)R[a]) << 16;
9179
    /* XOR in next significant nibble * H */
9180
    m8 = (word32*)m[xi >> 4];
9181
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9182
9183
    /* Write back result. */
9184
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
9185
}
9186
#elif defined(WC_32BIT_CPU)
9187
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9188
{
9189
    int i;
9190
    word32 z8[4] = {0, 0, 0, 0};
9191
    byte a;
9192
    word32* x8 = (word32*)x;
9193
    word32* m8;
9194
    byte xi;
9195
    word32 n7, n6, n5, n4, n3, n2, n1, n0;
9196
9197
    for (i = 15; i > 0; i--) {
9198
        xi = x[i];
9199
9200
        /* XOR in (msn * H) */
9201
        m8 = (word32*)m[xi & 0xf];
9202
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9203
9204
        /* Cache top byte for remainder calculations - lost in rotate. */
9205
        a = (byte)(z8[3] >> 24);
9206
9207
        /* Rotate Z by 8-bits */
9208
        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
9209
        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
9210
        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
9211
        z8[0] <<= 8;
9212
9213
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9214
        z8[0] ^= (word32)R[16 + (a & 0xf)];
9215
9216
        xi >>= 4;
9217
        /* XOR in next significant nibble (XORed with H) * remainder */
9218
        m8 = (word32*)m[xi];
9219
        a ^= (byte)(m8[3] >> 20);
9220
        z8[0] ^= (word32)R[a >> 4];
9221
9222
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9223
        m8 = (word32*)m[16 + xi];
9224
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
9225
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
9226
    }
9227
9228
    xi = x[0];
9229
9230
    /* XOR in most significant nibble * H */
9231
    m8 = (word32*)m[xi & 0xf];
9232
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9233
9234
    /* Cache top byte for remainder calculations - lost in rotate. */
9235
    a = (z8[3] >> 24) & 0xf;
9236
9237
    /* Rotate z by 4-bits */
9238
    n7 = z8[3] & 0xf0f0f0f0ULL;
9239
    n6 = z8[3] & 0x0f0f0f0fULL;
9240
    n5 = z8[2] & 0xf0f0f0f0ULL;
9241
    n4 = z8[2] & 0x0f0f0f0fULL;
9242
    n3 = z8[1] & 0xf0f0f0f0ULL;
9243
    n2 = z8[1] & 0x0f0f0f0fULL;
9244
    n1 = z8[0] & 0xf0f0f0f0ULL;
9245
    n0 = z8[0] & 0x0f0f0f0fULL;
9246
    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
9247
    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
9248
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
9249
    z8[0] = (n1 >> 4) | (n0 << 12);
9250
9251
    /* XOR in most significant nibble * remainder */
9252
    z8[0] ^= (word32)R[a];
9253
    /* XOR in next significant nibble * H */
9254
    m8 = (word32*)m[xi >> 4];
9255
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9256
9257
    /* Write back result. */
9258
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
9259
}
9260
#elif defined(WC_64BIT_CPU) && defined(BIG_ENDIAN_ORDER)
9261
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9262
{
9263
    int i;
9264
    word64 z8[2] = {0, 0};
9265
    byte a;
9266
    word64* x8 = (word64*)x;
9267
    word64* m8;
9268
    byte xi;
9269
9270
    for (i = 15; i > 0; i--) {
9271
        xi = x[i];
9272
9273
        /* XOR in (msn * H) */
9274
        m8 = (word64*)m[xi & 0xf];
9275
        z8[0] ^= m8[0];
9276
        z8[1] ^= m8[1];
9277
9278
        /* Cache top byte for remainder calculations - lost in rotate. */
9279
        a = (byte)(z8[1] & 0xff);
9280
9281
        /* Rotate Z by 8-bits */
9282
        z8[1] = (z8[0] << 56) | (z8[1] >> 8);
9283
        z8[0] >>= 8;
9284
9285
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9286
        m8 = (word64*)m[16 + (xi >> 4)];
9287
        z8[0] ^= m8[0];
9288
        z8[1] ^= m8[1];
9289
9290
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9291
        z8[0] ^= ((word64)R[16 + (a & 0xf)]) << 48;
9292
        /* XOR in next significant nibble (XORed with H) * remainder */
9293
        m8 = (word64*)m[xi >> 4];
9294
        a ^= (byte)(m8[1] >> 12) & 0xf;
9295
        a ^= (byte)((m8[1] << 4) & 0xf0);
9296
        z8[0] ^= ((word64)R[a >> 4]) << 48;
9297
    }
9298
9299
    xi = x[0];
9300
9301
    /* XOR in most significant nibble * H */
9302
    m8 = (word64*)m[xi & 0xf];
9303
    z8[0] ^= m8[0];
9304
    z8[1] ^= m8[1];
9305
9306
    /* Cache top byte for remainder calculations - lost in rotate. */
9307
    a = (byte)(z8[1] & 0x0f);
9308
9309
    /* Rotate z by 4-bits */
9310
    z8[1] = (z8[0] << 60) | (z8[1] >> 4);
9311
    z8[0] >>= 4;
9312
9313
    /* XOR in next significant nibble * H */
9314
    m8 = (word64*)m[xi >> 4];
9315
    z8[0] ^= m8[0];
9316
    z8[1] ^= m8[1];
9317
    /* XOR in most significant nibble * remainder */
9318
    z8[0] ^= ((word64)R[a]) << 48;
9319
9320
    /* Write back result. */
9321
    x8[0] = z8[0];
9322
    x8[1] = z8[1];
9323
}
9324
#else
9325
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9326
0
{
9327
0
    int i;
9328
0
    word64 z8[2] = {0, 0};
9329
0
    byte a;
9330
0
    word64* x8 = (word64*)x;
9331
0
    word64* m8;
9332
0
    word64 n0, n1, n2, n3;
9333
0
    byte xi;
9334
9335
0
    for (i = 15; i > 0; i--) {
9336
0
        xi = x[i];
9337
9338
        /* XOR in (msn * H) */
9339
0
        m8 = (word64*)m[xi & 0xf];
9340
0
        z8[0] ^= m8[0];
9341
0
        z8[1] ^= m8[1];
9342
9343
        /* Cache top byte for remainder calculations - lost in rotate. */
9344
0
        a = (byte)(z8[1] >> 56);
9345
9346
        /* Rotate Z by 8-bits */
9347
0
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
9348
0
        z8[0] <<= 8;
9349
9350
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9351
0
        m8 = (word64*)m[16 + (xi >> 4)];
9352
0
        z8[0] ^= m8[0];
9353
0
        z8[1] ^= m8[1];
9354
9355
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9356
0
        z8[0] ^= (word64)R[16 + (a & 0xf)];
9357
        /* XOR in next significant nibble (XORed with H) * remainder */
9358
0
        m8 = (word64*)m[xi >> 4];
9359
0
        a ^= (byte)(m8[1] >> 52);
9360
0
        z8[0] ^= (word64)R[a >> 4];
9361
0
    }
9362
9363
0
    xi = x[0];
9364
9365
    /* XOR in most significant nibble * H */
9366
0
    m8 = (word64*)m[xi & 0xf];
9367
0
    z8[0] ^= m8[0];
9368
0
    z8[1] ^= m8[1];
9369
9370
    /* Cache top byte for remainder calculations - lost in rotate. */
9371
0
    a = (z8[1] >> 56) & 0xf;
9372
9373
    /* Rotate z by 4-bits */
9374
0
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
9375
0
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
9376
0
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
9377
0
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
9378
0
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
9379
0
    z8[0] = (n1 >> 4) | (n0 << 12);
9380
9381
    /* XOR in next significant nibble * H */
9382
0
    m8 = (word64*)m[xi >> 4];
9383
0
    z8[0] ^= m8[0];
9384
0
    z8[1] ^= m8[1];
9385
    /* XOR in most significant nibble * remainder */
9386
0
    z8[0] ^= (word64)R[a];
9387
9388
    /* Write back result. */
9389
0
    x8[0] = z8[0];
9390
0
    x8[1] = z8[1];
9391
0
}
9392
#endif
9393
#endif
9394
9395
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9396
    word32 cSz, byte* s, word32 sSz)
9397
0
{
9398
0
    byte x[WC_AES_BLOCK_SIZE];
9399
0
    byte scratch[WC_AES_BLOCK_SIZE];
9400
0
    word32 blocks, partial;
9401
9402
0
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9403
9404
    /* Hash in A, the Additional Authentication Data */
9405
0
    if (aSz != 0 && a != NULL) {
9406
0
        blocks = aSz / WC_AES_BLOCK_SIZE;
9407
0
        partial = aSz % WC_AES_BLOCK_SIZE;
9408
    #ifdef GCM_GMULT_LEN
9409
        if (blocks > 0) {
9410
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
9411
            a += blocks * WC_AES_BLOCK_SIZE;
9412
        }
9413
        if (partial != 0) {
9414
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9415
            XMEMCPY(scratch, a, partial);
9416
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9417
        }
9418
    #else
9419
0
        while (blocks--) {
9420
0
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
9421
0
            GMULT(x, gcm->M0);
9422
0
            a += WC_AES_BLOCK_SIZE;
9423
0
        }
9424
0
        if (partial != 0) {
9425
0
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9426
0
            XMEMCPY(scratch, a, partial);
9427
0
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9428
0
            GMULT(x, gcm->M0);
9429
0
        }
9430
0
    #endif
9431
0
    }
9432
9433
    /* Hash in C, the Ciphertext */
9434
0
    if (cSz != 0 && c != NULL) {
9435
0
        blocks = cSz / WC_AES_BLOCK_SIZE;
9436
0
        partial = cSz % WC_AES_BLOCK_SIZE;
9437
    #ifdef GCM_GMULT_LEN
9438
        if (blocks > 0) {
9439
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
9440
            c += blocks * WC_AES_BLOCK_SIZE;
9441
        }
9442
        if (partial != 0) {
9443
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9444
            XMEMCPY(scratch, c, partial);
9445
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9446
        }
9447
    #else
9448
0
        while (blocks--) {
9449
0
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
9450
0
            GMULT(x, gcm->M0);
9451
0
            c += WC_AES_BLOCK_SIZE;
9452
0
        }
9453
0
        if (partial != 0) {
9454
0
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9455
0
            XMEMCPY(scratch, c, partial);
9456
0
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9457
0
            GMULT(x, gcm->M0);
9458
0
        }
9459
0
    #endif
9460
0
    }
9461
9462
    /* Hash in the lengths of A and C in bits */
9463
0
    FlattenSzInBits(&scratch[0], aSz);
9464
0
    FlattenSzInBits(&scratch[8], cSz);
9465
#ifdef GCM_GMULT_LEN
9466
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9467
#else
9468
0
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9469
0
    GMULT(x, gcm->M0);
9470
0
#endif
9471
9472
    /* Copy the result into s. */
9473
0
    XMEMCPY(s, x, sSz);
9474
0
}
9475
9476
#ifdef WOLFSSL_AESGCM_STREAM
9477
/* No extra initialization for 4-bit table implementation.
9478
 *
9479
 * @param [in] aes  AES GCM object.
9480
 */
9481
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9482
9483
#ifdef GCM_GMULT_LEN
9484
/* GHASH one block of data.
9485
 *
9486
 * @param [in, out] aes    AES GCM object.
9487
 * @param [in]      block  Block of AAD or cipher text.
9488
 */
9489
#define GHASH_ONE_BLOCK_SW(aes, block)                                  \
9490
   GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
9491
#else
9492
/* GHASH one block of data.
9493
 *
9494
 * XOR block into tag and GMULT with H using pre-computed table.
9495
 *
9496
 * @param [in, out] aes    AES GCM object.
9497
 * @param [in]      block  Block of AAD or cipher text.
9498
 */
9499
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9500
    do {                                                \
9501
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
9502
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
9503
    }                                                   \
9504
    while (0)
9505
#endif
9506
#endif /* WOLFSSL_AESGCM_STREAM */
9507
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
9508
9509
#if !defined(FREESCALE_LTC_AES_GCM)
9510
static void GMULT(word64* X, word64* Y)
9511
{
9512
    word64 Z[2] = {0,0};
9513
    word64 V[2];
9514
    int i, j;
9515
    word64 v1;
9516
    V[0] = X[0];  V[1] = X[1];
9517
9518
    for (i = 0; i < 2; i++)
9519
    {
9520
        word64 y = Y[i];
9521
        for (j = 0; j < 64; j++)
9522
        {
9523
#ifndef AES_GCM_GMULT_NCT
9524
            word64 mask = 0 - (y >> 63);
9525
            Z[0] ^= V[0] & mask;
9526
            Z[1] ^= V[1] & mask;
9527
#else
9528
            if (y & 0x8000000000000000ULL) {
9529
                Z[0] ^= V[0];
9530
                Z[1] ^= V[1];
9531
            }
9532
#endif
9533
9534
            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
9535
            V[1] >>= 1;
9536
            V[1] |= V[0] << 63;
9537
            V[0] >>= 1;
9538
            V[0] ^= v1;
9539
            y <<= 1;
9540
        }
9541
    }
9542
    X[0] = Z[0];
9543
    X[1] = Z[1];
9544
}
9545
9546
9547
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9548
    word32 cSz, byte* s, word32 sSz)
9549
{
9550
    word64 x[2] = {0,0};
9551
    word32 blocks, partial;
9552
    word64 bigH[2];
9553
9554
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
9555
    #ifdef LITTLE_ENDIAN_ORDER
9556
        ByteReverseWords64(bigH, bigH, WC_AES_BLOCK_SIZE);
9557
    #endif
9558
9559
    /* Hash in A, the Additional Authentication Data */
9560
    if (aSz != 0 && a != NULL) {
9561
        word64 bigA[2];
9562
        blocks = aSz / WC_AES_BLOCK_SIZE;
9563
        partial = aSz % WC_AES_BLOCK_SIZE;
9564
        while (blocks--) {
9565
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
9566
            #ifdef LITTLE_ENDIAN_ORDER
9567
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
9568
            #endif
9569
            x[0] ^= bigA[0];
9570
            x[1] ^= bigA[1];
9571
            GMULT(x, bigH);
9572
            a += WC_AES_BLOCK_SIZE;
9573
        }
9574
        if (partial != 0) {
9575
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
9576
            XMEMCPY(bigA, a, partial);
9577
            #ifdef LITTLE_ENDIAN_ORDER
9578
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
9579
            #endif
9580
            x[0] ^= bigA[0];
9581
            x[1] ^= bigA[1];
9582
            GMULT(x, bigH);
9583
        }
9584
#ifdef OPENSSL_EXTRA
9585
        /* store AAD partial tag for next call */
9586
        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
9587
        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
9588
        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
9589
        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
9590
#endif
9591
    }
9592
9593
    /* Hash in C, the Ciphertext */
9594
    if (cSz != 0 && c != NULL) {
9595
        word64 bigC[2];
9596
        blocks = cSz / WC_AES_BLOCK_SIZE;
9597
        partial = cSz % WC_AES_BLOCK_SIZE;
9598
#ifdef OPENSSL_EXTRA
9599
        /* Start from last AAD partial tag */
9600
        if(gcm->aadLen) {
9601
            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
9602
            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
9603
         }
9604
#endif
9605
        while (blocks--) {
9606
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
9607
            #ifdef LITTLE_ENDIAN_ORDER
9608
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
9609
            #endif
9610
            x[0] ^= bigC[0];
9611
            x[1] ^= bigC[1];
9612
            GMULT(x, bigH);
9613
            c += WC_AES_BLOCK_SIZE;
9614
        }
9615
        if (partial != 0) {
9616
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
9617
            XMEMCPY(bigC, c, partial);
9618
            #ifdef LITTLE_ENDIAN_ORDER
9619
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
9620
            #endif
9621
            x[0] ^= bigC[0];
9622
            x[1] ^= bigC[1];
9623
            GMULT(x, bigH);
9624
        }
9625
    }
9626
9627
    /* Hash in the lengths in bits of A and C */
9628
    {
9629
        word64 len[2];
9630
        len[0] = aSz; len[1] = cSz;
9631
#ifdef OPENSSL_EXTRA
9632
        if (gcm->aadLen)
9633
            len[0] = (word64)gcm->aadLen;
9634
#endif
9635
        /* Lengths are in bytes. Convert to bits. */
9636
        len[0] *= 8;
9637
        len[1] *= 8;
9638
9639
        x[0] ^= len[0];
9640
        x[1] ^= len[1];
9641
        GMULT(x, bigH);
9642
    }
9643
    #ifdef LITTLE_ENDIAN_ORDER
9644
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
9645
    #endif
9646
    XMEMCPY(s, x, sSz);
9647
}
9648
#endif /* !FREESCALE_LTC_AES_GCM */
9649
9650
#ifdef WOLFSSL_AESGCM_STREAM
9651
9652
#ifdef LITTLE_ENDIAN_ORDER
9653
9654
/* No extra initialization for small implementation.
9655
 *
9656
 * @param [in] aes  AES GCM object.
9657
 */
9658
#define GHASH_INIT_EXTRA(aes)                                               \
9659
    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, WC_AES_BLOCK_SIZE)
9660
9661
/* GHASH one block of data..
9662
 *
9663
 * XOR block into tag and GMULT with H.
9664
 *
9665
 * @param [in, out] aes    AES GCM object.
9666
 * @param [in]      block  Block of AAD or cipher text.
9667
 */
9668
#define GHASH_ONE_BLOCK_SW(aes, block)                              \
9669
    do {                                                            \
9670
        word64* x = (word64*)AES_TAG(aes);                          \
9671
        word64* h = (word64*)aes->gcm.H;                            \
9672
        word64 block64[2];                                          \
9673
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);                 \
9674
        ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE);    \
9675
        x[0] ^= block64[0];                                         \
9676
        x[1] ^= block64[1];                                         \
9677
        GMULT(x, h);                                                \
9678
    }                                                               \
9679
    while (0)
9680
9681
#ifdef OPENSSL_EXTRA
9682
/* GHASH in AAD and cipher text lengths in bits.
9683
 *
9684
 * Convert tag back to little-endian.
9685
 *
9686
 * @param [in, out] aes  AES GCM object.
9687
 */
9688
#define GHASH_LEN_BLOCK(aes)                            \
9689
    do {                                                \
9690
        word64* x = (word64*)AES_TAG(aes);              \
9691
        word64* h = (word64*)aes->gcm.H;                \
9692
        word64 len[2];                                  \
9693
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9694
        if (aes->gcm.aadLen)                            \
9695
            len[0] = (word64)aes->gcm.aadLen;           \
9696
        /* Lengths are in bytes. Convert to bits. */    \
9697
        len[0] *= 8;                                    \
9698
        len[1] *= 8;                                    \
9699
                                                        \
9700
        x[0] ^= len[0];                                 \
9701
        x[1] ^= len[1];                                 \
9702
        GMULT(x, h);                                    \
9703
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
9704
    }                                                   \
9705
    while (0)
9706
#else
9707
/* GHASH in AAD and cipher text lengths in bits.
9708
 *
9709
 * Convert tag back to little-endian.
9710
 *
9711
 * @param [in, out] aes  AES GCM object.
9712
 */
9713
#define GHASH_LEN_BLOCK(aes)                            \
9714
    do {                                                \
9715
        word64* x = (word64*)AES_TAG(aes);              \
9716
        word64* h = (word64*)aes->gcm.H;                \
9717
        word64 len[2];                                  \
9718
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9719
        /* Lengths are in bytes. Convert to bits. */    \
9720
        len[0] *= 8;                                    \
9721
        len[1] *= 8;                                    \
9722
                                                        \
9723
        x[0] ^= len[0];                                 \
9724
        x[1] ^= len[1];                                 \
9725
        GMULT(x, h);                                    \
9726
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
9727
    }                                                   \
9728
    while (0)
9729
#endif
9730
9731
#else
9732
9733
/* No extra initialization for small implementation.
9734
 *
9735
 * @param [in] aes  AES GCM object.
9736
 */
9737
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9738
9739
/* GHASH one block of data..
9740
 *
9741
 * XOR block into tag and GMULT with H.
9742
 *
9743
 * @param [in, out] aes    AES GCM object.
9744
 * @param [in]      block  Block of AAD or cipher text.
9745
 */
9746
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9747
    do {                                                \
9748
        word64* x = (word64*)AES_TAG(aes);              \
9749
        word64* h = (word64*)aes->gcm.H;                \
9750
        word64 block64[2];                              \
9751
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);        \
9752
        x[0] ^= block64[0];                             \
9753
        x[1] ^= block64[1];                             \
9754
        GMULT(x, h);                                    \
9755
    }                                                   \
9756
    while (0)
9757
9758
#ifdef OPENSSL_EXTRA
9759
/* GHASH in AAD and cipher text lengths in bits.
9760
 *
9761
 * Convert tag back to little-endian.
9762
 *
9763
 * @param [in, out] aes  AES GCM object.
9764
 */
9765
#define GHASH_LEN_BLOCK(aes)                            \
9766
    do {                                                \
9767
        word64* x = (word64*)AES_TAG(aes);              \
9768
        word64* h = (word64*)aes->gcm.H;                \
9769
        word64 len[2];                                  \
9770
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9771
        if (aes->gcm.aadLen)                            \
9772
            len[0] = (word64)aes->gcm.aadLen;           \
9773
        /* Lengths are in bytes. Convert to bits. */    \
9774
        len[0] *= 8;                                    \
9775
        len[1] *= 8;                                    \
9776
                                                        \
9777
        x[0] ^= len[0];                                 \
9778
        x[1] ^= len[1];                                 \
9779
        GMULT(x, h);                                    \
9780
    }                                                   \
9781
    while (0)
9782
#else
9783
/* GHASH in AAD and cipher text lengths in bits.
9784
 *
9785
 * Convert tag back to little-endian.
9786
 *
9787
 * @param [in, out] aes  AES GCM object.
9788
 */
9789
#define GHASH_LEN_BLOCK(aes)                            \
9790
    do {                                                \
9791
        word64* x = (word64*)AES_TAG(aes);              \
9792
        word64* h = (word64*)aes->gcm.H;                \
9793
        word64 len[2];                                  \
9794
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9795
        /* Lengths are in bytes. Convert to bits. */    \
9796
        len[0] *= 8;                                    \
9797
        len[1] *= 8;                                    \
9798
                                                        \
9799
        x[0] ^= len[0];                                 \
9800
        x[1] ^= len[1];                                 \
9801
        GMULT(x, h);                                    \
9802
    }                                                   \
9803
    while (0)
9804
#endif
9805
9806
#endif /* !LITTLE_ENDIAN_ORDER */
9807
9808
#endif /* WOLFSSL_AESGCM_STREAM */
9809
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
9810
#else /* GCM_WORD32 */
9811
9812
static void GMULT(word32* X, word32* Y)
9813
{
9814
    word32 Z[4] = {0,0,0,0};
9815
    word32 V[4];
9816
    int i, j;
9817
9818
    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
9819
9820
    for (i = 0; i < 4; i++)
9821
    {
9822
        word32 y = Y[i];
9823
        for (j = 0; j < 32; j++)
9824
        {
9825
            if (y & 0x80000000) {
9826
                Z[0] ^= V[0];
9827
                Z[1] ^= V[1];
9828
                Z[2] ^= V[2];
9829
                Z[3] ^= V[3];
9830
            }
9831
9832
            if (V[3] & 0x00000001) {
9833
                V[3] >>= 1;
9834
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
9835
                V[2] >>= 1;
9836
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
9837
                V[1] >>= 1;
9838
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
9839
                V[0] >>= 1;
9840
                V[0] ^= 0xE1000000;
9841
            } else {
9842
                V[3] >>= 1;
9843
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
9844
                V[2] >>= 1;
9845
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
9846
                V[1] >>= 1;
9847
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
9848
                V[0] >>= 1;
9849
            }
9850
            y <<= 1;
9851
        }
9852
    }
9853
    X[0] = Z[0];
9854
    X[1] = Z[1];
9855
    X[2] = Z[2];
9856
    X[3] = Z[3];
9857
}
9858
9859
9860
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9861
    word32 cSz, byte* s, word32 sSz)
9862
{
9863
    word32 x[4] = {0,0,0,0};
9864
    word32 blocks, partial;
9865
    word32 bigH[4];
9866
9867
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
9868
    #ifdef LITTLE_ENDIAN_ORDER
9869
        ByteReverseWords(bigH, bigH, WC_AES_BLOCK_SIZE);
9870
    #endif
9871
9872
    /* Hash in A, the Additional Authentication Data */
9873
    if (aSz != 0 && a != NULL) {
9874
        word32 bigA[4];
9875
        blocks = aSz / WC_AES_BLOCK_SIZE;
9876
        partial = aSz % WC_AES_BLOCK_SIZE;
9877
        while (blocks--) {
9878
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
9879
            #ifdef LITTLE_ENDIAN_ORDER
9880
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
9881
            #endif
9882
            x[0] ^= bigA[0];
9883
            x[1] ^= bigA[1];
9884
            x[2] ^= bigA[2];
9885
            x[3] ^= bigA[3];
9886
            GMULT(x, bigH);
9887
            a += WC_AES_BLOCK_SIZE;
9888
        }
9889
        if (partial != 0) {
9890
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
9891
            XMEMCPY(bigA, a, partial);
9892
            #ifdef LITTLE_ENDIAN_ORDER
9893
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
9894
            #endif
9895
            x[0] ^= bigA[0];
9896
            x[1] ^= bigA[1];
9897
            x[2] ^= bigA[2];
9898
            x[3] ^= bigA[3];
9899
            GMULT(x, bigH);
9900
        }
9901
    }
9902
9903
    /* Hash in C, the Ciphertext */
9904
    if (cSz != 0 && c != NULL) {
9905
        word32 bigC[4];
9906
        blocks = cSz / WC_AES_BLOCK_SIZE;
9907
        partial = cSz % WC_AES_BLOCK_SIZE;
9908
        while (blocks--) {
9909
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
9910
            #ifdef LITTLE_ENDIAN_ORDER
9911
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
9912
            #endif
9913
            x[0] ^= bigC[0];
9914
            x[1] ^= bigC[1];
9915
            x[2] ^= bigC[2];
9916
            x[3] ^= bigC[3];
9917
            GMULT(x, bigH);
9918
            c += WC_AES_BLOCK_SIZE;
9919
        }
9920
        if (partial != 0) {
9921
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
9922
            XMEMCPY(bigC, c, partial);
9923
            #ifdef LITTLE_ENDIAN_ORDER
9924
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
9925
            #endif
9926
            x[0] ^= bigC[0];
9927
            x[1] ^= bigC[1];
9928
            x[2] ^= bigC[2];
9929
            x[3] ^= bigC[3];
9930
            GMULT(x, bigH);
9931
        }
9932
    }
9933
9934
    /* Hash in the lengths in bits of A and C */
9935
    {
9936
        word32 len[4];
9937
9938
        /* Lengths are in bytes. Convert to bits. */
9939
        len[0] = (aSz >> (8*sizeof(aSz) - 3));
9940
        len[1] = aSz << 3;
9941
        len[2] = (cSz >> (8*sizeof(cSz) - 3));
9942
        len[3] = cSz << 3;
9943
9944
        x[0] ^= len[0];
9945
        x[1] ^= len[1];
9946
        x[2] ^= len[2];
9947
        x[3] ^= len[3];
9948
        GMULT(x, bigH);
9949
    }
9950
    #ifdef LITTLE_ENDIAN_ORDER
9951
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
9952
    #endif
9953
    XMEMCPY(s, x, sSz);
9954
}
9955
9956
#ifdef WOLFSSL_AESGCM_STREAM
9957
#ifdef LITTLE_ENDIAN_ORDER
9958
/* Little-endian 32-bit word implementation requires byte reversal of H.
9959
 *
9960
 * H is all-zeros block encrypted with key.
9961
 *
9962
 * @param [in, out] aes  AES GCM object.
9963
 */
9964
#define GHASH_INIT_EXTRA(aes) \
9965
    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, WC_AES_BLOCK_SIZE)
9966
9967
/* GHASH one block of data..
9968
 *
9969
 * XOR block, in big-endian form, into tag and GMULT with H.
9970
 *
9971
 * @param [in, out] aes    AES GCM object.
9972
 * @param [in]      block  Block of AAD or cipher text.
9973
 */
9974
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
9975
    do {                                                        \
9976
        word32* x = (word32*)AES_TAG(aes);                      \
9977
        word32* h = (word32*)aes->gcm.H;                        \
9978
        word32 bigEnd[4];                                       \
9979
        XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE);              \
9980
        ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE);    \
9981
        x[0] ^= bigEnd[0];                                      \
9982
        x[1] ^= bigEnd[1];                                      \
9983
        x[2] ^= bigEnd[2];                                      \
9984
        x[3] ^= bigEnd[3];                                      \
9985
        GMULT(x, h);                                            \
9986
    }                                                           \
9987
    while (0)
9988
9989
/* GHASH in AAD and cipher text lengths in bits.
9990
 *
9991
 * Convert tag back to little-endian.
9992
 *
9993
 * @param [in, out] aes  AES GCM object.
9994
 */
9995
#define GHASH_LEN_BLOCK(aes)                                \
9996
    do {                                                    \
9997
        word32 len[4];                                      \
9998
        word32* x = (word32*)AES_TAG(aes);                  \
9999
        word32* h = (word32*)aes->gcm.H;                    \
10000
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
10001
        len[1] = aes->aSz << 3;                             \
10002
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
10003
        len[3] = aes->cSz << 3;                             \
10004
        x[0] ^= len[0];                                     \
10005
        x[1] ^= len[1];                                     \
10006
        x[2] ^= len[2];                                     \
10007
        x[3] ^= len[3];                                     \
10008
        GMULT(x, h);                                        \
10009
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);          \
10010
    }                                                       \
10011
    while (0)
10012
#else
10013
/* No extra initialization for 32-bit word implementation.
10014
 *
10015
 * @param [in] aes  AES GCM object.
10016
 */
10017
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
10018
10019
/* GHASH one block of data..
10020
 *
10021
 * XOR block into tag and GMULT with H.
10022
 *
10023
 * @param [in, out] aes    AES GCM object.
10024
 * @param [in]      block  Block of AAD or cipher text.
10025
 */
10026
#define GHASH_ONE_BLOCK_SW(aes, block)                      \
10027
    do {                                                    \
10028
        word32* x = (word32*)AES_TAG(aes);                  \
10029
        word32* h = (word32*)aes->gcm.H;                    \
10030
        word32 block32[4];                                  \
10031
        XMEMCPY(block32, block, WC_AES_BLOCK_SIZE);         \
10032
        x[0] ^= block32[0];                                 \
10033
        x[1] ^= block32[1];                                 \
10034
        x[2] ^= block32[2];                                 \
10035
        x[3] ^= block32[3];                                 \
10036
        GMULT(x, h);                                        \
10037
    }                                                       \
10038
    while (0)
10039
10040
/* GHASH in AAD and cipher text lengths in bits.
10041
 *
10042
 * @param [in, out] aes  AES GCM object.
10043
 */
10044
#define GHASH_LEN_BLOCK(aes)                                \
10045
    do {                                                    \
10046
        word32 len[4];                                      \
10047
        word32* x = (word32*)AES_TAG(aes);                  \
10048
        word32* h = (word32*)aes->gcm.H;                    \
10049
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
10050
        len[1] = aes->aSz << 3;                             \
10051
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
10052
        len[3] = aes->cSz << 3;                             \
10053
        x[0] ^= len[0];                                     \
10054
        x[1] ^= len[1];                                     \
10055
        x[2] ^= len[2];                                     \
10056
        x[3] ^= len[3];                                     \
10057
        GMULT(x, h);                                        \
10058
    }                                                       \
10059
    while (0)
10060
#endif /* LITTLE_ENDIAN_ORDER */
10061
#endif /* WOLFSSL_AESGCM_STREAM */
10062
#endif /* end GCM_WORD32 */
10063
#endif
10064
10065
#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
10066
#ifdef WOLFSSL_AESGCM_STREAM
10067
#ifndef GHASH_LEN_BLOCK
10068
/* Hash in the lengths of the AAD and cipher text in bits.
10069
 *
10070
 * Default implementation.
10071
 *
10072
 * @param [in, out] aes  AES GCM object.
10073
 */
10074
#define GHASH_LEN_BLOCK(aes)                      \
10075
    do {                                          \
10076
        byte scratch[WC_AES_BLOCK_SIZE];          \
10077
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
10078
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
10079
        GHASH_ONE_BLOCK(aes, scratch);            \
10080
    }                                             \
10081
    while (0)
10082
#endif
10083
10084
/* Initialize a GHASH for streaming operations.
10085
 *
10086
 * @param [in, out] aes  AES GCM object.
10087
 */
10088
static void GHASH_INIT(Aes* aes) {
10089
    /* Set tag to all zeros as initial value. */
10090
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
10091
    /* Reset counts of AAD and cipher text. */
10092
    aes->aOver = 0;
10093
    aes->cOver = 0;
10094
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10095
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10096
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10097
        ; /* Don't do extra initialization. */
10098
    }
10099
    else
10100
#endif
10101
    {
10102
        /* Extra initialization based on implementation. */
10103
        GHASH_INIT_EXTRA(aes);
10104
    }
10105
}
10106
10107
/* Update the GHASH with AAD and/or cipher text.
10108
 *
10109
 * @param [in,out] aes   AES GCM object.
10110
 * @param [in]     a     Additional authentication data buffer.
10111
 * @param [in]     aSz   Size of data in AAD buffer.
10112
 * @param [in]     c     Cipher text buffer.
10113
 * @param [in]     cSz   Size of data in cipher text buffer.
10114
 */
10115
static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
10116
    word32 cSz)
10117
{
10118
    word32 blocks;
10119
    word32 partial;
10120
10121
    /* Hash in A, the Additional Authentication Data */
10122
    if (aSz != 0 && a != NULL) {
10123
        /* Update count of AAD we have hashed. */
10124
        aes->aSz += aSz;
10125
        /* Check if we have unprocessed data. */
10126
        if (aes->aOver > 0) {
10127
            /* Calculate amount we can use - fill up the block. */
10128
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10129
            if (sz > aSz) {
10130
                sz = (byte)aSz;
10131
            }
10132
            /* Copy extra into last GHASH block array and update count. */
10133
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
10134
            aes->aOver = (byte)(aes->aOver + sz);
10135
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
10136
                /* We have filled up the block and can process. */
10137
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10138
                /* Reset count. */
10139
                aes->aOver = 0;
10140
            }
10141
            /* Used up some data. */
10142
            aSz -= sz;
10143
            a += sz;
10144
        }
10145
10146
        /* Calculate number of blocks of AAD and the leftover. */
10147
        blocks = aSz / WC_AES_BLOCK_SIZE;
10148
        partial = aSz % WC_AES_BLOCK_SIZE;
10149
        /* GHASH full blocks now. */
10150
        while (blocks--) {
10151
            GHASH_ONE_BLOCK(aes, a);
10152
            a += WC_AES_BLOCK_SIZE;
10153
        }
10154
        if (partial != 0) {
10155
            /* Cache the partial block. */
10156
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
10157
            aes->aOver = (byte)partial;
10158
        }
10159
    }
10160
    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
10161
        /* No more AAD coming and we have a partial block. */
10162
        /* Fill the rest of the block with zeros. */
10163
        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10164
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
10165
        /* GHASH last AAD block. */
10166
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10167
        /* Clear partial count for next time through. */
10168
        aes->aOver = 0;
10169
    }
10170
10171
    /* Hash in C, the Ciphertext */
10172
    if (cSz != 0 && c != NULL) {
10173
        /* Update count of cipher text we have hashed. */
10174
        aes->cSz += cSz;
10175
        if (aes->cOver > 0) {
10176
            /* Calculate amount we can use - fill up the block. */
10177
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
10178
            if (sz > cSz) {
10179
                sz = (byte)cSz;
10180
            }
10181
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
10182
            /* Update count of unused encrypted counter. */
10183
            aes->cOver = (byte)(aes->cOver + sz);
10184
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
10185
                /* We have filled up the block and can process. */
10186
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10187
                /* Reset count. */
10188
                aes->cOver = 0;
10189
            }
10190
            /* Used up some data. */
10191
            cSz -= sz;
10192
            c += sz;
10193
        }
10194
10195
        /* Calculate number of blocks of cipher text and the leftover. */
10196
        blocks = cSz / WC_AES_BLOCK_SIZE;
10197
        partial = cSz % WC_AES_BLOCK_SIZE;
10198
        /* GHASH full blocks now. */
10199
        while (blocks--) {
10200
            GHASH_ONE_BLOCK(aes, c);
10201
            c += WC_AES_BLOCK_SIZE;
10202
        }
10203
        if (partial != 0) {
10204
            /* Cache the partial block. */
10205
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
10206
            aes->cOver = (byte)partial;
10207
        }
10208
    }
10209
}
10210
10211
/* Finalize the GHASH calculation.
10212
 *
10213
 * Complete hashing cipher text and hash the AAD and cipher text lengths.
10214
 *
10215
 * @param [in, out] aes  AES GCM object.
10216
 * @param [out]     s    Authentication tag.
10217
 * @param [in]      sSz  Size of authentication tag required.
10218
 */
10219
static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
10220
{
10221
    /* AAD block incomplete when > 0 */
10222
    byte over = aes->aOver;
10223
10224
    if (aes->cOver > 0) {
10225
        /* Cipher text block incomplete. */
10226
        over = aes->cOver;
10227
    }
10228
    if (over > 0) {
10229
        /* Zeroize the unused part of the block. */
10230
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
10231
            (size_t)WC_AES_BLOCK_SIZE - over);
10232
        /* Hash the last block of cipher text. */
10233
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10234
    }
10235
    /* Hash in the lengths of AAD and cipher text in bits */
10236
    GHASH_LEN_BLOCK(aes);
10237
    /* Copy the result into s. */
10238
    XMEMCPY(s, AES_TAG(aes), sSz);
10239
    /* reset aes->gcm.H in case of reuse */
10240
    GHASH_INIT_EXTRA(aes);
10241
}
10242
#endif /* WOLFSSL_AESGCM_STREAM */
10243
10244
10245
#ifdef FREESCALE_LTC_AES_GCM
10246
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10247
                   const byte* iv, word32 ivSz,
10248
                   byte* authTag, word32 authTagSz,
10249
                   const byte* authIn, word32 authInSz)
10250
{
10251
    status_t status;
10252
    word32 keySize;
10253
10254
    /* argument checks */
10255
    if (aes == NULL || ivSz == 0) {
10256
        return BAD_FUNC_ARG;
10257
    }
10258
10259
    status = wc_local_AesGcmCheckTagSz(authTagSz);
10260
    if (status != 0)
10261
        return status;
10262
10263
    status = wc_AesGetKeySize(aes, &keySize);
10264
    if (status)
10265
        return status;
10266
10267
    status = wolfSSL_CryptHwMutexLock();
10268
    if (status != 0)
10269
        return status;
10270
10271
    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
10272
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
10273
    wolfSSL_CryptHwMutexUnLock();
10274
10275
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
10276
}
10277
10278
#else
10279
10280
#ifdef STM32_CRYPTO_AES_GCM
10281
10282
/* this function supports inline encrypt */
10283
static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
10284
                                  Aes* aes, byte* out, const byte* in, word32 sz,
10285
                                  const byte* iv, word32 ivSz,
10286
                                  byte* authTag, word32 authTagSz,
10287
                                  const byte* authIn, word32 authInSz)
10288
{
10289
    int ret;
10290
#ifdef WOLFSSL_STM32_CUBEMX
10291
    CRYP_HandleTypeDef hcryp;
10292
#else
10293
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
10294
#endif
10295
    word32 keySize;
10296
#ifdef WOLFSSL_STM32_CUBEMX
10297
    int status = HAL_OK;
10298
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10299
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
10300
#else
10301
    int status = SUCCESS;
10302
#endif
10303
    word32 partial = sz % WC_AES_BLOCK_SIZE;
10304
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
10305
    word32 ctrInit[WC_AES_BLOCK_SIZE/sizeof(word32)];
10306
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10307
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10308
    byte* authInPadded = NULL;
10309
    int authPadSz, wasAlloc = 0, useSwGhash = 0;
10310
10311
    ret = wc_AesGetKeySize(aes, &keySize);
10312
    if (ret != 0)
10313
        return ret;
10314
10315
#ifdef WOLFSSL_STM32_CUBEMX
10316
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
10317
    if (ret != 0)
10318
        return ret;
10319
#endif
10320
10321
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
10322
    if (ivSz == GCM_NONCE_MID_SZ) {
10323
        byte* pCtr = (byte*)ctr;
10324
        XMEMCPY(ctr, iv, ivSz);
10325
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
10326
    }
10327
    else {
10328
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
10329
    }
10330
    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
10331
10332
    /* Authentication buffer */
10333
#if STM_CRYPT_HEADER_WIDTH == 1
10334
    authPadSz = 0; /* CubeHAL supports byte mode */
10335
#else
10336
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
10337
#endif
10338
#ifdef WOLFSSL_STM32MP13
10339
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
10340
     * minimum of 16 bytes for the auth */
10341
    if ((authInSz > 0) && (authInSz < 16)) {
10342
        authPadSz = 16 - authInSz;
10343
    }
10344
#endif
10345
    if (authPadSz != 0) {
10346
        if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) {
10347
            authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
10348
        }
10349
        if (authPadSz <= sizeof(authhdr)) {
10350
            authInPadded = (byte*)authhdr;
10351
        }
10352
        else {
10353
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
10354
                DYNAMIC_TYPE_TMP_BUFFER);
10355
            if (authInPadded == NULL) {
10356
                wolfSSL_CryptHwMutexUnLock();
10357
                return MEMORY_E;
10358
            }
10359
            wasAlloc = 1;
10360
        }
10361
        XMEMSET(authInPadded, 0, authPadSz);
10362
        XMEMCPY(authInPadded, authIn, authInSz);
10363
    } else {
10364
        authPadSz = authInSz;
10365
        authInPadded = (byte*)authIn;
10366
    }
10367
10368
    /* for cases where hardware cannot be used for authTag calculate it */
10369
    /* if IV is not 12 calculate GHASH using software */
10370
    if (ivSz != GCM_NONCE_MID_SZ
10371
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
10372
        /* or hardware that does not support partial block */
10373
        || sz == 0 || partial != 0
10374
    #endif
10375
    #if STM_CRYPT_HEADER_WIDTH == 4
10376
        /* or authIn is not a multiple of 4  */
10377
        || authPadSz != authInSz
10378
    #endif
10379
    ) {
10380
        useSwGhash = 1;
10381
    }
10382
10383
    /* Hardware requires counter + 1 */
10384
    IncrementGcmCounter((byte*)ctr);
10385
10386
    ret = wolfSSL_CryptHwMutexLock();
10387
    if (ret != 0) {
10388
        return ret;
10389
    }
10390
10391
#ifdef WOLFSSL_STM32_CUBEMX
10392
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10393
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
10394
10395
#if defined(STM32_HAL_V2)
10396
    hcryp.Init.Algorithm = CRYP_AES_GCM;
10397
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
10398
    #ifdef CRYP_KEYIVCONFIG_ONCE
10399
    /* allows repeated calls to HAL_CRYP_Encrypt */
10400
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
10401
    #endif
10402
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
10403
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10404
    HAL_CRYP_Init(&hcryp);
10405
10406
    #ifndef CRYP_KEYIVCONFIG_ONCE
10407
    /* GCM payload phase - can handle partial blocks */
10408
    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
10409
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
10410
    #else
10411
    /* GCM payload phase - blocks */
10412
    if (blocks) {
10413
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
10414
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
10415
    }
10416
    /* GCM payload phase - partial remainder */
10417
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10418
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10419
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10420
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
10421
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
10422
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10423
    }
10424
    #endif
10425
    if (status == HAL_OK && !useSwGhash) {
10426
        /* Compute the authTag */
10427
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
10428
            STM32_HAL_TIMEOUT);
10429
    }
10430
#elif defined(STM32_CRYPTO_AES_ONLY)
10431
    /* Set the CRYP parameters */
10432
    hcryp.Init.HeaderSize = authPadSz;
10433
    if (authPadSz == 0)
10434
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
10435
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
10436
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
10437
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
10438
    HAL_CRYP_Init(&hcryp);
10439
10440
    /* GCM init phase */
10441
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10442
    if (status == HAL_OK) {
10443
        /* GCM header phase */
10444
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
10445
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10446
    }
10447
    if (status == HAL_OK) {
10448
        /* GCM payload phase - blocks */
10449
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
10450
        if (blocks) {
10451
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
10452
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10453
        }
10454
    }
10455
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
10456
        /* GCM payload phase - partial remainder */
10457
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10458
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10459
        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
10460
                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
10461
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10462
    }
10463
    if (status == HAL_OK && !useSwGhash) {
10464
        /* GCM final phase */
10465
        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
10466
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
10467
    }
10468
#else
10469
    hcryp.Init.HeaderSize = authPadSz;
10470
    HAL_CRYP_Init(&hcryp);
10471
    if (blocks) {
10472
        /* GCM payload phase - blocks */
10473
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
10474
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10475
    }
10476
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10477
        /* GCM payload phase - partial remainder */
10478
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10479
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10480
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
10481
            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
10482
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10483
    }
10484
    if (status == HAL_OK && !useSwGhash) {
10485
        /* Compute the authTag */
10486
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
10487
    }
10488
#endif
10489
10490
    if (status != HAL_OK)
10491
        ret = AES_GCM_AUTH_E;
10492
    HAL_CRYP_DeInit(&hcryp);
10493
10494
#else /* Standard Peripheral Library */
10495
    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
10496
    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
10497
                         (uint8_t*)keyCopy,      keySize * 8,
10498
                         (uint8_t*)in,           sz,
10499
                         (uint8_t*)authInPadded, authInSz,
10500
                         (uint8_t*)out,          (uint8_t*)tag);
10501
    if (status != SUCCESS)
10502
        ret = AES_GCM_AUTH_E;
10503
#endif /* WOLFSSL_STM32_CUBEMX */
10504
    wolfSSL_CryptHwMutexUnLock();
10505
    wc_Stm32_Aes_Cleanup();
10506
10507
    if (ret == 0) {
10508
        /* return authTag */
10509
        if (authTag) {
10510
            if (useSwGhash) {
10511
                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
10512
                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
10513
                if (ret == 0) {
10514
                    xorbuf(authTag, tag, authTagSz);
10515
                }
10516
            }
10517
            else {
10518
                /* use hardware calculated tag */
10519
                XMEMCPY(authTag, tag, authTagSz);
10520
            }
10521
        }
10522
    }
10523
10524
    /* Free memory */
10525
    if (wasAlloc) {
10526
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
10527
    }
10528
10529
    return ret;
10530
}
10531
10532
#endif /* STM32_CRYPTO_AES_GCM */
10533
10534
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
10535
#ifdef WOLFSSL_AESNI
10536
/* For performance reasons, this code needs to be not inlined. */
10537
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
10538
                      Aes* aes, byte* out, const byte* in, word32 sz,
10539
                      const byte* iv, word32 ivSz,
10540
                      byte* authTag, word32 authTagSz,
10541
                      const byte* authIn, word32 authInSz);
10542
#else
10543
static
10544
#endif
10545
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
10546
                      Aes* aes, byte* out, const byte* in, word32 sz,
10547
                      const byte* iv, word32 ivSz,
10548
                      byte* authTag, word32 authTagSz,
10549
                      const byte* authIn, word32 authInSz)
10550
0
{
10551
0
    int ret = 0;
10552
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10553
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
10554
0
    const byte* p = in;
10555
0
    byte* c = out;
10556
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
10557
0
    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
10558
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
10559
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
10560
0
    int did_prefetches = 0;
10561
0
#endif
10562
10563
0
    if (ivSz == GCM_NONCE_MID_SZ) {
10564
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
10565
0
        XMEMCPY(counter, iv, ivSz);
10566
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
10567
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
10568
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
10569
0
    }
10570
0
    else {
10571
        /* Counter is GHASH of IV. */
10572
#ifdef OPENSSL_EXTRA
10573
        word32 aadTemp = aes->gcm.aadLen;
10574
        aes->gcm.aadLen = 0;
10575
#endif
10576
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
10577
#ifdef OPENSSL_EXTRA
10578
        aes->gcm.aadLen = aadTemp;
10579
#endif
10580
0
    }
10581
0
    XMEMCPY(initialCounter, counter, WC_AES_BLOCK_SIZE);
10582
10583
#ifdef 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_ENCRYPTION, 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
#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
    if (c != p && blocks > 0) { /* can not handle inline encryption */
10602
        while (blocks--) {
10603
            IncrementGcmCounter(counter);
10604
            XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
10605
            c += WC_AES_BLOCK_SIZE;
10606
        }
10607
10608
        /* reset number of blocks and then do encryption */
10609
        blocks = sz / WC_AES_BLOCK_SIZE;
10610
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
10611
        xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
10612
        p += WC_AES_BLOCK_SIZE * blocks;
10613
    }
10614
    else
10615
#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
10616
0
    {
10617
0
        while (blocks--) {
10618
0
            IncrementGcmCounter(counter);
10619
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
10620
0
            ret = AesEncrypt_preFetchOpt(aes, counter, scratch,
10621
0
                                            &did_prefetches);
10622
0
            if (ret != 0)
10623
0
                return ret;
10624
0
            xorbufout(c, scratch, p, 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 = AesEncrypt_preFetchOpt(aes, counter, scratch, &did_prefetches);
10634
0
        if (ret != 0)
10635
0
            return ret;
10636
0
        xorbufout(c, scratch, p, partial);
10637
0
    }
10638
0
    if (authTag) {
10639
0
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
10640
0
        ret = AesEncrypt_preFetchOpt(aes, initialCounter, scratch,
10641
0
                                        &did_prefetches);
10642
0
        if (ret != 0)
10643
0
            return ret;
10644
0
        xorbuf(authTag, scratch, authTagSz);
10645
#ifdef OPENSSL_EXTRA
10646
        if (!in && !sz)
10647
            /* store AAD size for next call */
10648
            aes->gcm.aadLen = authInSz;
10649
#endif
10650
0
    }
10651
10652
0
    return ret;
10653
0
}
10654
#elif (defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
10655
      (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
10656
static int AES_GCM_encrypt_ASM(Aes* aes, byte* out, const byte* in,
10657
    word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
10658
    const byte* authIn, word32 authInSz)
10659
{
10660
    word32 blocks;
10661
    word32 partial;
10662
    byte counter[WC_AES_BLOCK_SIZE];
10663
    byte initialCounter[WC_AES_BLOCK_SIZE];
10664
    byte x[WC_AES_BLOCK_SIZE];
10665
    byte scratch[WC_AES_BLOCK_SIZE];
10666
10667
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
10668
    if (ivSz == GCM_NONCE_MID_SZ) {
10669
        XMEMCPY(initialCounter, iv, ivSz);
10670
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
10671
    }
10672
    else {
10673
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
10674
    }
10675
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
10676
10677
    /* Hash in the Additional Authentication Data */
10678
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
10679
    if (authInSz != 0 && authIn != NULL) {
10680
        blocks = authInSz / WC_AES_BLOCK_SIZE;
10681
        partial = authInSz % WC_AES_BLOCK_SIZE;
10682
        if (blocks > 0) {
10683
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
10684
            authIn += blocks * WC_AES_BLOCK_SIZE;
10685
        }
10686
        if (partial != 0) {
10687
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10688
            XMEMCPY(scratch, authIn, partial);
10689
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10690
        }
10691
    }
10692
10693
    /* do as many blocks as possible */
10694
    blocks = sz / WC_AES_BLOCK_SIZE;
10695
    partial = sz % WC_AES_BLOCK_SIZE;
10696
    if (blocks > 0) {
10697
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
10698
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10699
        if (sz >= 32)
10700
    #endif
10701
        {
10702
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
10703
                (const unsigned char*)aes->key, aes->rounds, counter);
10704
        }
10705
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10706
        else
10707
    #endif
10708
    #endif
10709
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10710
        {
10711
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
10712
                (const unsigned char*)aes->key, aes->rounds, counter);
10713
        }
10714
    #endif
10715
        GCM_GMULT_LEN(&aes->gcm, x, out, blocks * WC_AES_BLOCK_SIZE);
10716
        in += blocks * WC_AES_BLOCK_SIZE;
10717
        out += blocks * WC_AES_BLOCK_SIZE;
10718
    }
10719
    /* take care of partial block sizes leftover */
10720
    if (partial != 0) {
10721
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10722
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10723
        {
10724
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
10725
                (const unsigned char*)aes->key, aes->rounds, counter);
10726
        }
10727
    #else
10728
        {
10729
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
10730
                (const unsigned char*)aes->key, aes->rounds, counter);
10731
        }
10732
    #endif
10733
        XMEMCPY(out, scratch, partial);
10734
10735
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10736
        XMEMCPY(scratch, out, partial);
10737
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10738
    }
10739
10740
    /* Hash in the lengths of A and C in bits */
10741
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10742
    FlattenSzInBits(&scratch[0], authInSz);
10743
    FlattenSzInBits(&scratch[8], sz);
10744
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10745
    if (authTagSz > WC_AES_BLOCK_SIZE) {
10746
        XMEMCPY(authTag, x, WC_AES_BLOCK_SIZE);
10747
    }
10748
    else {
10749
        /* authTagSz can be smaller than WC_AES_BLOCK_SIZE */
10750
        XMEMCPY(authTag, x, authTagSz);
10751
    }
10752
10753
    /* Auth tag calculation. */
10754
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10755
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10756
    {
10757
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10758
            (const unsigned char*)aes->key, aes->rounds);
10759
    }
10760
#else
10761
    {
10762
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10763
            (const unsigned char*)aes->key, aes->rounds);
10764
    }
10765
#endif
10766
    xorbuf(authTag, scratch, authTagSz);
10767
10768
    return 0;
10769
}
10770
#endif
10771
10772
/* Software AES - GCM Encrypt */
10773
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10774
                   const byte* iv, word32 ivSz,
10775
                   byte* authTag, word32 authTagSz,
10776
                   const byte* authIn, word32 authInSz)
10777
0
{
10778
0
    int ret;
10779
10780
    /* argument checks */
10781
    /* If sz is non-zero, both in and out must be set; if sz is 0, in and
10782
     * out are don't cares (GMAC case), matching wc_AesGcmDecrypt. */
10783
0
    if (aes == NULL || iv == NULL || ivSz == 0 ||
10784
0
        (sz != 0 && (in == NULL || out == NULL)) ||
10785
0
        authTag == NULL ||
10786
0
        ((authInSz > 0) && (authIn == NULL)))
10787
0
    {
10788
0
        return BAD_FUNC_ARG;
10789
0
    }
10790
10791
0
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
10792
0
    if (ret != 0)
10793
0
        return ret;
10794
10795
#ifdef WOLF_CRYPTO_CB
10796
    #ifndef WOLF_CRYPTO_CB_FIND
10797
    if (aes->devId != INVALID_DEVID)
10798
    #endif
10799
    {
10800
        int crypto_cb_ret =
10801
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
10802
                                      authTagSz, authIn, authInSz);
10803
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
10804
            return crypto_cb_ret;
10805
        /* fall-through when unavailable */
10806
    }
10807
#endif
10808
10809
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
10810
    /* if async and byte count above threshold */
10811
    /* only 12-byte IV is supported in HW */
10812
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
10813
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
10814
    #if defined(HAVE_CAVIUM)
10815
        #ifdef HAVE_CAVIUM_V
10816
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
10817
            return NitroxAesGcmEncrypt(aes, out, in, sz,
10818
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10819
                authTag, authTagSz, authIn, authInSz);
10820
        }
10821
        #endif
10822
    #elif defined(HAVE_INTEL_QA)
10823
        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
10824
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10825
            authTag, authTagSz, authIn, authInSz);
10826
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
10827
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
10828
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
10829
            sw->aes.aes = aes;
10830
            sw->aes.out = out;
10831
            sw->aes.in = in;
10832
            sw->aes.sz = sz;
10833
            sw->aes.iv = iv;
10834
            sw->aes.ivSz = ivSz;
10835
            sw->aes.authTag = authTag;
10836
            sw->aes.authTagSz = authTagSz;
10837
            sw->aes.authIn = authIn;
10838
            sw->aes.authInSz = authInSz;
10839
            return WC_PENDING_E;
10840
        }
10841
    #endif
10842
    }
10843
#endif /* WOLFSSL_ASYNC_CRYPT */
10844
10845
#ifdef WOLFSSL_SILABS_SE_ACCEL
10846
    return wc_AesGcmEncrypt_silabs(
10847
        aes, out, in, sz,
10848
        iv, ivSz,
10849
        authTag, authTagSz,
10850
        authIn, authInSz);
10851
#endif
10852
10853
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
10854
#ifndef TA_AES_GCM_MAX_DATA_SIZE
10855
    #define TA_AES_GCM_MAX_DATA_SIZE 996u
10856
#endif
10857
    if (aes != NULL &&
10858
        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
10859
        ivSz == TA_AES_GCM_IV_LENGTH &&
10860
        authTagSz == TA_AES_GCM_TAG_LENGTH &&
10861
        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
10862
        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
10863
        return wc_Microchip_AesGcmEncrypt(
10864
            aes, out, in, sz,
10865
            iv, ivSz,
10866
            authTag, authTagSz,
10867
            authIn, authInSz);
10868
    }
10869
#endif
10870
10871
#if defined(WOLFSSL_STM32_BARE) && defined(STM32_CRYPTO)
10872
    ret = wc_Stm32_Aes_Gcm(aes, out, in, sz, iv, ivSz,
10873
                           authTag, authTagSz,
10874
                           authIn, authInSz, 1 /* enc */);
10875
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
10876
        return ret;
10877
    /* fall through to SW GCM (still uses HW AES via wc_AesEncrypt) */
10878
#endif /* WOLFSSL_STM32_BARE && STM32_CRYPTO */
10879
10880
10881
#ifdef STM32_CRYPTO_AES_GCM
10882
    return wc_AesGcmEncrypt_STM32(
10883
        aes, out, in, sz, iv, ivSz,
10884
        authTag, authTagSz, authIn, authInSz);
10885
#endif /* STM32_CRYPTO_AES_GCM */
10886
10887
#if defined(WOLFSSL_PSOC6_CRYPTO)
10888
    return wc_Psoc6_Aes_GcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
10889
                                   authTagSz, authIn, authInSz);
10890
#endif /* WOLFSSL_PSOC6_CRYPTO */
10891
10892
0
    VECTOR_REGISTERS_PUSH;
10893
10894
#if defined(WOLFSSL_ARMASM)
10895
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
10896
#if !defined(__aarch64__)
10897
    AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
10898
        authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
10899
        aes->rounds);
10900
    ret = 0;
10901
#else
10902
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10903
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
10904
        if (aes->use_sha3_hw_crypto) {
10905
            AES_GCM_encrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
10906
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
10907
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
10908
        }
10909
        else
10910
    #endif
10911
        {
10912
            AES_GCM_encrypt_AARCH64(in, out, sz, iv, ivSz, authTag, authTagSz,
10913
                authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
10914
                (byte*)aes->reg, aes->rounds);
10915
        }
10916
        ret = 0;
10917
    }
10918
    else
10919
#endif /* !__aarch64__ */
10920
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
10921
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10922
    {
10923
        ret = AES_GCM_encrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
10924
            authTagSz, authIn, authInSz);
10925
    }
10926
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
10927
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
10928
    ret = AES_GCM_encrypt_ASM(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
10929
        authIn, authInSz);
10930
#else
10931
#ifdef WOLFSSL_AESNI
10932
    if (aes->use_aesni) {
10933
#ifdef HAVE_INTEL_AVX512
10934
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
10935
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
10936
            AES_GCM_encrypt_avx512(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10937
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
10938
            ret = 0;
10939
        }
10940
        else
10941
#endif
10942
#ifdef HAVE_INTEL_VAES
10943
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
10944
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
10945
            AES_GCM_encrypt_vaes(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10946
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
10947
            ret = 0;
10948
        }
10949
        else
10950
#endif
10951
#ifdef HAVE_INTEL_AVX2
10952
        if (IS_INTEL_AVX2(intel_flags)) {
10953
            AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10954
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
10955
            ret = 0;
10956
        }
10957
        else
10958
#endif
10959
#if defined(HAVE_INTEL_AVX1)
10960
        if (IS_INTEL_AVX1(intel_flags)) {
10961
            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10962
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
10963
            ret = 0;
10964
        } else
10965
#endif
10966
        {
10967
            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10968
                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
10969
            ret = 0;
10970
        }
10971
    }
10972
    else
10973
#endif /* WOLFSSL_AESNI */
10974
0
    {
10975
0
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
10976
0
                                authIn, authInSz);
10977
0
    }
10978
0
#endif
10979
10980
0
    VECTOR_REGISTERS_POP;
10981
10982
0
    return ret;
10983
0
}
10984
#endif
10985
10986
10987
/* AES GCM Decrypt */
10988
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
10989
#ifdef FREESCALE_LTC_AES_GCM
10990
int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10991
                   const byte* iv, word32 ivSz,
10992
                   const byte* authTag, word32 authTagSz,
10993
                   const byte* authIn, word32 authInSz)
10994
{
10995
    int ret;
10996
    word32 keySize;
10997
    status_t status;
10998
10999
    /* argument checks */
11000
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
11001
     * in and out are don't cares, as this is is the GMAC case. */
11002
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
11003
        authTag == NULL || ivSz == 0 ||
11004
        ((authInSz > 0) && (authIn == NULL)))
11005
    {
11006
        return BAD_FUNC_ARG;
11007
    }
11008
11009
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
11010
    if (ret != 0)
11011
        return ret;
11012
11013
    ret = wc_AesGetKeySize(aes, &keySize);
11014
    if (ret != 0) {
11015
        return ret;
11016
    }
11017
11018
    status = wolfSSL_CryptHwMutexLock();
11019
    if (status != 0)
11020
        return status;
11021
11022
    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
11023
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
11024
    wolfSSL_CryptHwMutexUnLock();
11025
11026
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
11027
}
11028
11029
#else
11030
11031
#ifdef STM32_CRYPTO_AES_GCM
11032
/* this function supports inline decrypt */
11033
static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
11034
                                  Aes* aes, byte* out,
11035
                                  const byte* in, word32 sz,
11036
                                  const byte* iv, word32 ivSz,
11037
                                  const byte* authTag, word32 authTagSz,
11038
                                  const byte* authIn, word32 authInSz)
11039
{
11040
    int ret;
11041
#ifdef WOLFSSL_STM32_CUBEMX
11042
    int status = HAL_OK;
11043
    CRYP_HandleTypeDef hcryp;
11044
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
11045
#else
11046
    int status = SUCCESS;
11047
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
11048
#endif
11049
    word32 keySize;
11050
    word32 partial = sz % WC_AES_BLOCK_SIZE;
11051
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
11052
    word32 tagExpected[WC_AES_BLOCK_SIZE/sizeof(word32)];
11053
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
11054
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
11055
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
11056
    byte* authInPadded = NULL;
11057
    int authPadSz, wasAlloc = 0, tagComputed = 0;
11058
11059
    ret = wc_AesGetKeySize(aes, &keySize);
11060
    if (ret != 0)
11061
        return ret;
11062
11063
#ifdef WOLFSSL_STM32_CUBEMX
11064
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
11065
    if (ret != 0)
11066
        return ret;
11067
#endif
11068
11069
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
11070
    if (ivSz == GCM_NONCE_MID_SZ) {
11071
        byte* pCtr = (byte*)ctr;
11072
        XMEMCPY(ctr, iv, ivSz);
11073
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
11074
    }
11075
    else {
11076
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
11077
    }
11078
11079
    /* Make copy of expected authTag, which could get corrupted in some
11080
     * Cube HAL versions without proper partial block support.
11081
     * For TLS blocks the authTag is after the output buffer, so save it */
11082
    XMEMCPY(tagExpected, authTag, authTagSz);
11083
11084
    /* Authentication buffer */
11085
#if STM_CRYPT_HEADER_WIDTH == 1
11086
    authPadSz = 0; /* CubeHAL supports byte mode */
11087
#else
11088
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
11089
#endif
11090
#ifdef WOLFSSL_STM32MP13
11091
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
11092
     * minimum of 16 bytes for the auth */
11093
    if ((authInSz > 0) && (authInSz < 16)) {
11094
        authPadSz = 16 - authInSz;
11095
    }
11096
#else
11097
    if (authPadSz != 0) {
11098
        authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
11099
    }
11100
    else {
11101
        authPadSz = authInSz;
11102
    }
11103
#endif
11104
11105
    /* for cases where hardware cannot be used for authTag calculate it */
11106
    /* if IV is not 12 calculate GHASH using software */
11107
    if (ivSz != GCM_NONCE_MID_SZ
11108
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
11109
        /* or hardware that does not support partial block */
11110
        || sz == 0 || partial != 0
11111
    #endif
11112
    #if STM_CRYPT_HEADER_WIDTH == 4
11113
        /* or authIn is not a multiple of 4  */
11114
        || authPadSz != authInSz
11115
    #endif
11116
    ) {
11117
        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
11118
        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
11119
        if (ret != 0)
11120
            return ret;
11121
        xorbuf(tag, partialBlock, sizeof(tag));
11122
        tagComputed = 1;
11123
    }
11124
11125
    /* if using hardware for authentication tag make sure its aligned and zero padded */
11126
    if (authPadSz != authInSz && !tagComputed) {
11127
        if (authPadSz <= sizeof(authhdr)) {
11128
            authInPadded = (byte*)authhdr;
11129
        }
11130
        else {
11131
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
11132
                DYNAMIC_TYPE_TMP_BUFFER);
11133
            if (authInPadded == NULL) {
11134
                wolfSSL_CryptHwMutexUnLock();
11135
                return MEMORY_E;
11136
            }
11137
            wasAlloc = 1;
11138
        }
11139
        XMEMSET(authInPadded, 0, authPadSz);
11140
        XMEMCPY(authInPadded, authIn, authInSz);
11141
    } else {
11142
        authInPadded = (byte*)authIn;
11143
    }
11144
11145
    /* Hardware requires counter + 1 */
11146
    IncrementGcmCounter((byte*)ctr);
11147
11148
    ret = wolfSSL_CryptHwMutexLock();
11149
    if (ret != 0) {
11150
        if (wasAlloc) {
11151
            XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11152
        }
11153
        return ret;
11154
    }
11155
11156
#ifdef WOLFSSL_STM32_CUBEMX
11157
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11158
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
11159
11160
#if defined(STM32_HAL_V2)
11161
    hcryp.Init.Algorithm = CRYP_AES_GCM;
11162
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
11163
    #ifdef CRYP_KEYIVCONFIG_ONCE
11164
    /* allows repeated calls to HAL_CRYP_Decrypt */
11165
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
11166
    #endif
11167
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
11168
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11169
    HAL_CRYP_Init(&hcryp);
11170
11171
    #ifndef CRYP_KEYIVCONFIG_ONCE
11172
    /* GCM payload phase - can handle partial blocks */
11173
    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
11174
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
11175
    #else
11176
    /* GCM payload phase - blocks */
11177
    if (blocks) {
11178
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
11179
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
11180
    }
11181
    /* GCM payload phase - partial remainder */
11182
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11183
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11184
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11185
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
11186
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
11187
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11188
    }
11189
    #endif
11190
    if (status == HAL_OK && !tagComputed) {
11191
        /* Compute the authTag */
11192
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
11193
            STM32_HAL_TIMEOUT);
11194
    }
11195
#elif defined(STM32_CRYPTO_AES_ONLY)
11196
    /* Set the CRYP parameters */
11197
    hcryp.Init.HeaderSize = authPadSz;
11198
    if (authPadSz == 0)
11199
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
11200
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
11201
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
11202
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
11203
    HAL_CRYP_Init(&hcryp);
11204
11205
    /* GCM init phase */
11206
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11207
    if (status == HAL_OK) {
11208
        /* GCM header phase */
11209
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
11210
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11211
    }
11212
    if (status == HAL_OK) {
11213
        /* GCM payload phase - blocks */
11214
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
11215
        if (blocks) {
11216
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
11217
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11218
        }
11219
    }
11220
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
11221
        /* GCM payload phase - partial remainder */
11222
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11223
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11224
        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
11225
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
11226
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11227
    }
11228
    if (status == HAL_OK && tagComputed == 0) {
11229
        /* GCM final phase */
11230
        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
11231
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
11232
    }
11233
#else
11234
    hcryp.Init.HeaderSize = authPadSz;
11235
    HAL_CRYP_Init(&hcryp);
11236
    if (blocks) {
11237
        /* GCM payload phase - blocks */
11238
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
11239
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11240
    }
11241
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11242
        /* GCM payload phase - partial remainder */
11243
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11244
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11245
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
11246
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
11247
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11248
    }
11249
    if (status == HAL_OK && tagComputed == 0) {
11250
        /* Compute the authTag */
11251
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
11252
    }
11253
#endif
11254
11255
    if (status != HAL_OK)
11256
        ret = AES_GCM_AUTH_E;
11257
11258
    HAL_CRYP_DeInit(&hcryp);
11259
11260
#else /* Standard Peripheral Library */
11261
    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
11262
11263
    /* Input size and auth size need to be the actual sizes, even though
11264
     * they are not block aligned, because this length (in bits) is used
11265
     * in the final GHASH. */
11266
    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
11267
    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
11268
                         (uint8_t*)keyCopy,      keySize * 8,
11269
                         (uint8_t*)in,           sz,
11270
                         (uint8_t*)authInPadded, authInSz,
11271
                         (uint8_t*)out,          (uint8_t*)partialBlock);
11272
    if (status != SUCCESS)
11273
        ret = AES_GCM_AUTH_E;
11274
    if (tagComputed == 0)
11275
        XMEMCPY(tag, partialBlock, authTagSz);
11276
#endif /* WOLFSSL_STM32_CUBEMX */
11277
    wolfSSL_CryptHwMutexUnLock();
11278
    wc_Stm32_Aes_Cleanup();
11279
11280
    /* Check authentication tag */
11281
    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
11282
        ret = AES_GCM_AUTH_E;
11283
    }
11284
11285
    /* Free memory */
11286
    if (wasAlloc) {
11287
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11288
    }
11289
11290
    return ret;
11291
}
11292
11293
#endif /* STM32_CRYPTO_AES_GCM */
11294
11295
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11296
#ifdef WOLFSSL_AESNI
11297
/* For performance reasons, this code needs to be not inlined. */
11298
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
11299
                      Aes* aes, byte* out, const byte* in, word32 sz,
11300
                      const byte* iv, word32 ivSz,
11301
                      const byte* authTag, word32 authTagSz,
11302
                      const byte* authIn, word32 authInSz);
11303
#else
11304
static
11305
#endif
11306
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
11307
                      Aes* aes, byte* out, const byte* in, word32 sz,
11308
                      const byte* iv, word32 ivSz,
11309
                      const byte* authTag, word32 authTagSz,
11310
                      const byte* authIn, word32 authInSz)
11311
0
{
11312
0
    int ret;
11313
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
11314
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
11315
0
    const byte* c = in;
11316
0
    byte* p = out;
11317
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
11318
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
11319
0
    ALIGN16 byte Tprime[WC_AES_BLOCK_SIZE];
11320
0
    ALIGN16 byte EKY0[WC_AES_BLOCK_SIZE];
11321
0
    volatile sword32 res;
11322
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
11323
0
    byte mask;
11324
0
    word32 i;
11325
0
#endif
11326
11327
0
    if (ivSz == GCM_NONCE_MID_SZ) {
11328
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
11329
0
        XMEMCPY(counter, iv, ivSz);
11330
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
11331
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
11332
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
11333
0
    }
11334
0
    else {
11335
        /* Counter is GHASH of IV. */
11336
#ifdef OPENSSL_EXTRA
11337
        word32 aadTemp = aes->gcm.aadLen;
11338
        aes->gcm.aadLen = 0;
11339
#endif
11340
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
11341
#ifdef OPENSSL_EXTRA
11342
        aes->gcm.aadLen = aadTemp;
11343
#endif
11344
0
    }
11345
11346
    /* Calc the authTag again using received auth data and the cipher text */
11347
0
    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
11348
0
    ret = wc_AesEncrypt(aes, counter, EKY0);
11349
0
    if (ret != 0)
11350
0
        return ret;
11351
0
    xorbuf(Tprime, EKY0, sizeof(Tprime));
11352
#ifdef WC_AES_GCM_DEC_AUTH_EARLY
11353
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
11354
     * the pairwise bytes in the strings.
11355
     */
11356
    res = ConstantCompare(authTag, Tprime, authTagSz);
11357
    /* convert positive retval from ConstantCompare() to all-1s word, in
11358
     * constant time.
11359
     */
11360
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
11361
    ret = res & AES_GCM_AUTH_E;
11362
    if (ret != 0)
11363
        return ret;
11364
#endif
11365
11366
#ifdef OPENSSL_EXTRA
11367
    if (!out) {
11368
        /* authenticated, non-confidential data */
11369
        /* store AAD size for next call */
11370
        aes->gcm.aadLen = authInSz;
11371
    }
11372
#endif
11373
11374
#if defined(WOLFSSL_PIC32MZ_CRYPT)
11375
    if (blocks) {
11376
        /* use initial IV for HW, but don't use it below */
11377
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
11378
11379
        ret = wc_Pic32AesCrypt(
11380
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
11381
            out, in, (blocks * WC_AES_BLOCK_SIZE),
11382
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
11383
        if (ret != 0)
11384
            return ret;
11385
    }
11386
    /* process remainder using partial handling */
11387
#endif
11388
11389
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
11390
    /* some hardware acceleration can gain performance from doing AES encryption
11391
     * of the whole buffer at once */
11392
    if (c != p && blocks > 0) { /* can not handle inline decryption */
11393
        while (blocks--) {
11394
            IncrementGcmCounter(counter);
11395
            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
11396
            p += WC_AES_BLOCK_SIZE;
11397
        }
11398
11399
        /* reset number of blocks and then do encryption */
11400
        blocks = sz / WC_AES_BLOCK_SIZE;
11401
11402
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
11403
        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
11404
        c += WC_AES_BLOCK_SIZE * blocks;
11405
    }
11406
    else
11407
#endif /* HAVE_AES_ECB && !PIC32MZ */
11408
0
    {
11409
0
        while (blocks--) {
11410
0
            IncrementGcmCounter(counter);
11411
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
11412
0
            ret = wc_AesEncrypt(aes, counter, scratch);
11413
0
            if (ret != 0)
11414
0
                return ret;
11415
0
            xorbufout(p, scratch, c, WC_AES_BLOCK_SIZE);
11416
0
        #endif
11417
0
            p += WC_AES_BLOCK_SIZE;
11418
0
            c += WC_AES_BLOCK_SIZE;
11419
0
        }
11420
0
    }
11421
11422
0
    if (partial != 0) {
11423
0
        IncrementGcmCounter(counter);
11424
0
        ret = wc_AesEncrypt(aes, counter, scratch);
11425
0
        if (ret != 0)
11426
0
            return ret;
11427
0
        xorbuf(scratch, c, partial);
11428
0
        XMEMCPY(p, scratch, partial);
11429
0
    }
11430
11431
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
11432
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
11433
     * the pairwise bytes in the strings.
11434
     */
11435
0
    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
11436
    /* convert positive retval from ConstantCompare() to all-1s word, in
11437
     * constant time.
11438
     */
11439
0
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
11440
    /* now use res as a mask for constant time return of ret, unless tag
11441
     * mismatch, whereupon AES_GCM_AUTH_E is returned.
11442
     */
11443
0
    ret = (ret & ~res);
11444
0
    ret |= (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
11445
    /* Mask the output on auth failure instead of branching, to keep the tag
11446
     * compare constant time. res is all-ones on mismatch, zero on match. A
11447
     * single vectorizable pass is cheaper than folding the mask into the
11448
     * decrypt loop. Not needed for WC_AES_GCM_DEC_AUTH_EARLY: there the tag is
11449
     * checked before decryption, so out is never written on a mismatch. */
11450
0
    mask = (byte)res;
11451
0
    for (i = 0; i < sz; i++) {
11452
0
        out[i] &= (byte)~mask;
11453
0
    }
11454
0
#endif
11455
0
    return ret;
11456
0
}
11457
#elif (defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
11458
      (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11459
static int AES_GCM_decrypt_ASM(Aes* aes, byte* out, const byte* in,
11460
    word32 sz, const byte* iv, word32 ivSz, const byte* authTag,
11461
    word32 authTagSz, const byte* authIn, word32 authInSz)
11462
{
11463
    word32 blocks;
11464
    word32 partial;
11465
    byte counter[WC_AES_BLOCK_SIZE];
11466
    byte initialCounter[WC_AES_BLOCK_SIZE];
11467
    byte scratch[WC_AES_BLOCK_SIZE];
11468
    byte x[WC_AES_BLOCK_SIZE];
11469
11470
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
11471
    if (ivSz == GCM_NONCE_MID_SZ) {
11472
        XMEMCPY(initialCounter, iv, ivSz);
11473
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
11474
    }
11475
    else {
11476
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
11477
    }
11478
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
11479
11480
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
11481
    /* Hash in the Additional Authentication Data */
11482
    if (authInSz != 0 && authIn != NULL) {
11483
        blocks = authInSz / WC_AES_BLOCK_SIZE;
11484
        partial = authInSz % WC_AES_BLOCK_SIZE;
11485
        if (blocks > 0) {
11486
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
11487
            authIn += blocks * WC_AES_BLOCK_SIZE;
11488
        }
11489
        if (partial != 0) {
11490
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11491
            XMEMCPY(scratch, authIn, partial);
11492
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11493
        }
11494
    }
11495
11496
    blocks = sz / WC_AES_BLOCK_SIZE;
11497
    partial = sz % WC_AES_BLOCK_SIZE;
11498
    /* do as many blocks as possible */
11499
    if (blocks > 0) {
11500
        GCM_GMULT_LEN(&aes->gcm, x, in, blocks * WC_AES_BLOCK_SIZE);
11501
11502
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
11503
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11504
        if (sz >= 32)
11505
    #endif
11506
        {
11507
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
11508
                (const unsigned char*)aes->key, aes->rounds, counter);
11509
        }
11510
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11511
        else
11512
    #endif
11513
    #endif
11514
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11515
        {
11516
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
11517
                (const unsigned char*)aes->key, aes->rounds, counter);
11518
        }
11519
    #endif
11520
        in += blocks * WC_AES_BLOCK_SIZE;
11521
        out += blocks * WC_AES_BLOCK_SIZE;
11522
    }
11523
    if (partial != 0) {
11524
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11525
        XMEMCPY(scratch, in, partial);
11526
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11527
11528
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
11529
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
11530
        {
11531
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
11532
                (const unsigned char*)aes->key, aes->rounds, counter);
11533
        }
11534
    #else
11535
        {
11536
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
11537
                (const unsigned char*)aes->key, aes->rounds, counter);
11538
        }
11539
    #endif
11540
        XMEMCPY(out, scratch, partial);
11541
    }
11542
11543
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11544
    FlattenSzInBits(&scratch[0], authInSz);
11545
    FlattenSzInBits(&scratch[8], sz);
11546
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11547
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
11548
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
11549
    {
11550
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
11551
            (const unsigned char*)aes->key, aes->rounds);
11552
    }
11553
#else
11554
    {
11555
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
11556
            (const unsigned char*)aes->key, aes->rounds);
11557
    }
11558
#endif
11559
    xorbuf(x, scratch, authTagSz);
11560
    if (authTag != NULL) {
11561
        if (ConstantCompare(authTag, x, authTagSz) != 0) {
11562
            return AES_GCM_AUTH_E;
11563
        }
11564
    }
11565
11566
    return 0;
11567
}
11568
#endif
11569
11570
/* Software AES - GCM Decrypt */
11571
int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
11572
                     const byte* iv, word32 ivSz,
11573
                     const byte* authTag, word32 authTagSz,
11574
                     const byte* authIn, word32 authInSz)
11575
0
{
11576
0
    int ret;
11577
#ifdef WOLFSSL_AESNI
11578
    int res = WC_NO_ERR_TRACE(AES_GCM_AUTH_E);
11579
#endif
11580
11581
    /* argument checks */
11582
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
11583
     * in and out are don't cares, as this is is the GMAC case. */
11584
0
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
11585
0
        authTag == NULL || ivSz == 0)
11586
0
    {
11587
0
        return BAD_FUNC_ARG;
11588
0
    }
11589
11590
0
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
11591
0
    if (ret != 0)
11592
0
        return ret;
11593
11594
#ifdef WOLF_CRYPTO_CB
11595
    #ifndef WOLF_CRYPTO_CB_FIND
11596
    if (aes->devId != INVALID_DEVID)
11597
    #endif
11598
    {
11599
        int crypto_cb_ret =
11600
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
11601
                                      authTag, authTagSz, authIn, authInSz);
11602
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11603
            return crypto_cb_ret;
11604
        /* fall-through when unavailable */
11605
    }
11606
#endif
11607
11608
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
11609
    /* if async and byte count above threshold */
11610
    /* only 12-byte IV is supported in HW */
11611
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
11612
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
11613
    #if defined(HAVE_CAVIUM)
11614
        #ifdef HAVE_CAVIUM_V
11615
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
11616
            return NitroxAesGcmDecrypt(aes, out, in, sz,
11617
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
11618
                authTag, authTagSz, authIn, authInSz);
11619
        }
11620
        #endif
11621
    #elif defined(HAVE_INTEL_QA)
11622
        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
11623
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
11624
            authTag, authTagSz, authIn, authInSz);
11625
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
11626
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
11627
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
11628
            sw->aes.aes = aes;
11629
            sw->aes.out = out;
11630
            sw->aes.in = in;
11631
            sw->aes.sz = sz;
11632
            sw->aes.iv = iv;
11633
            sw->aes.ivSz = ivSz;
11634
            sw->aes.authTag = (byte*)authTag;
11635
            sw->aes.authTagSz = authTagSz;
11636
            sw->aes.authIn = authIn;
11637
            sw->aes.authInSz = authInSz;
11638
            return WC_PENDING_E;
11639
        }
11640
    #endif
11641
    }
11642
#endif /* WOLFSSL_ASYNC_CRYPT */
11643
11644
#ifdef WOLFSSL_SILABS_SE_ACCEL
11645
    return wc_AesGcmDecrypt_silabs(
11646
        aes, out, in, sz, iv, ivSz,
11647
        authTag, authTagSz, authIn, authInSz);
11648
11649
#endif
11650
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
11651
#ifndef TA_AES_GCM_MAX_DATA_SIZE
11652
    #define TA_AES_GCM_MAX_DATA_SIZE 996u
11653
#endif
11654
    if (aes != NULL &&
11655
        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
11656
        ivSz == TA_AES_GCM_IV_LENGTH &&
11657
        authTagSz == TA_AES_GCM_TAG_LENGTH &&
11658
        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
11659
        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
11660
        return wc_Microchip_AesGcmDecrypt(
11661
            aes, out, in, sz, iv, ivSz,
11662
            authTag, authTagSz, authIn, authInSz);
11663
    }
11664
#endif
11665
11666
    /* BARE: GCM decrypt always uses SW path (with HW AES blocks via
11667
     * wc_AesEncrypt). Encrypt is HW-accelerated above; decrypt + tag
11668
     * verification stays in well-tested SW for now. */
11669
11670
#ifdef STM32_CRYPTO_AES_GCM
11671
    /* The STM standard peripheral library API's doesn't support partial blocks */
11672
    return wc_AesGcmDecrypt_STM32(
11673
        aes, out, in, sz, iv, ivSz,
11674
        authTag, authTagSz, authIn, authInSz);
11675
#endif /* STM32_CRYPTO_AES_GCM */
11676
11677
#if defined(WOLFSSL_PSOC6_CRYPTO)
11678
    return wc_Psoc6_Aes_GcmDecrypt(aes, out, in, sz, iv, ivSz, authTag,
11679
                                   authTagSz, authIn, authInSz);
11680
#endif /* WOLFSSL_PSOC6_CRYPTO */
11681
11682
0
    VECTOR_REGISTERS_PUSH;
11683
11684
#if defined(WOLFSSL_ARMASM)
11685
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
11686
#ifndef __aarch64__
11687
    {
11688
    #ifdef OPENSSL_EXTRA
11689
        word32 reg[WC_AES_BLOCK_SIZE / sizeof(word32)];
11690
        XMEMCPY(reg, aes->reg, sizeof(reg));
11691
    #endif
11692
        ret = AES_GCM_decrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
11693
            authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
11694
            (byte*)aes->reg, aes->rounds);
11695
    #ifdef OPENSSL_EXTRA
11696
        XMEMCPY(aes->reg, reg, sizeof(reg));
11697
    #endif
11698
    }
11699
#else
11700
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11701
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11702
        if (aes->use_sha3_hw_crypto) {
11703
            ret = AES_GCM_decrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
11704
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11705
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
11706
        }
11707
        else
11708
    #endif
11709
        {
11710
            ret = AES_GCM_decrypt_AARCH64(in, out, sz, iv, ivSz, authTag,
11711
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11712
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
11713
        }
11714
    }
11715
    else
11716
#endif /* !__aarch64__ */
11717
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
11718
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11719
    {
11720
        ret = AES_GCM_decrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
11721
            authTagSz, authIn, authInSz);
11722
    }
11723
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
11724
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11725
    {
11726
        ret = AES_GCM_decrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
11727
            authTagSz, authIn, authInSz);
11728
    }
11729
#else
11730
#ifdef WOLFSSL_AESNI
11731
    if (aes->use_aesni) {
11732
#ifdef HAVE_INTEL_AVX512
11733
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11734
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11735
            AES_GCM_decrypt_avx512(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11736
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11737
            if (res == 0)
11738
                ret = AES_GCM_AUTH_E;
11739
            else
11740
                ret = 0;
11741
        }
11742
        else
11743
#endif
11744
#ifdef HAVE_INTEL_VAES
11745
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11746
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11747
            AES_GCM_decrypt_vaes(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11748
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11749
            if (res == 0)
11750
                ret = AES_GCM_AUTH_E;
11751
            else
11752
                ret = 0;
11753
        }
11754
        else
11755
#endif
11756
#ifdef HAVE_INTEL_AVX2
11757
        if (IS_INTEL_AVX2(intel_flags)) {
11758
            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11759
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11760
            if (res == 0)
11761
                ret = AES_GCM_AUTH_E;
11762
            else
11763
                ret = 0;
11764
        }
11765
        else
11766
#endif
11767
#if defined(HAVE_INTEL_AVX1)
11768
        if (IS_INTEL_AVX1(intel_flags)) {
11769
            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11770
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11771
            if (res == 0)
11772
                ret = AES_GCM_AUTH_E;
11773
            else
11774
                ret = 0;
11775
        }
11776
        else
11777
#endif
11778
        {
11779
            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11780
                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11781
            if (res == 0)
11782
                ret = AES_GCM_AUTH_E;
11783
            else
11784
                ret = 0;
11785
        }
11786
    }
11787
    else
11788
#endif /* WOLFSSL_AESNI */
11789
0
    {
11790
0
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11791
0
                                                             authIn, authInSz);
11792
0
    }
11793
0
#endif
11794
11795
0
    VECTOR_REGISTERS_POP;
11796
11797
0
    return ret;
11798
0
}
11799
#endif
11800
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
11801
11802
#ifdef WOLFSSL_AESGCM_STREAM
11803
11804
/* Initialize the AES GCM cipher with an IV. C implementation.
11805
 *
11806
 * @param [in, out] aes   AES object.
11807
 * @param [in]      iv    IV/nonce buffer.
11808
 * @param [in]      ivSz  Length of IV/nonce data.
11809
 */
11810
static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
11811
{
11812
    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
11813
    int ret;
11814
11815
    if (ivSz == GCM_NONCE_MID_SZ) {
11816
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
11817
        XMEMCPY(counter, iv, ivSz);
11818
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
11819
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
11820
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
11821
    }
11822
    else {
11823
        /* Counter is GHASH of IV. */
11824
    #ifdef OPENSSL_EXTRA
11825
        word32 aadTemp = aes->gcm.aadLen;
11826
        aes->gcm.aadLen = 0;
11827
    #endif
11828
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
11829
    #ifdef OPENSSL_EXTRA
11830
        aes->gcm.aadLen = aadTemp;
11831
    #endif
11832
    }
11833
11834
    /* Copy in the counter for use with cipher. */
11835
    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
11836
    /* Encrypt initial counter into a buffer for GCM. */
11837
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
11838
    if (ret != 0)
11839
        return ret;
11840
    /* Reset state fields. */
11841
    aes->over = 0;
11842
    aes->aSz = 0;
11843
    aes->cSz = 0;
11844
    /* Initialization for GHASH. */
11845
    GHASH_INIT(aes);
11846
11847
    return 0;
11848
}
11849
11850
/* Update the AES GCM cipher with data. C implementation.
11851
 *
11852
 * Only enciphers data.
11853
 *
11854
 * @param [in, out] aes  AES object.
11855
 * @param [in]      out  Cipher text or plaintext buffer.
11856
 * @param [in]      in   Plaintext or cipher text buffer.
11857
 * @param [in]      sz   Length of data.
11858
 */
11859
static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
11860
    Aes* aes, byte* out, const byte* in, word32 sz)
11861
{
11862
    word32 blocks;
11863
    word32 partial;
11864
    int ret;
11865
11866
    /* Check if previous encrypted block was not used up. */
11867
    if (aes->over > 0) {
11868
        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
11869
        if (pSz > sz) pSz = (byte)sz;
11870
11871
        /* Use some/all of last encrypted block. */
11872
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
11873
        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
11874
11875
        /* Some data used. */
11876
        sz  -= pSz;
11877
        in  += pSz;
11878
        out += pSz;
11879
    }
11880
11881
    /* Calculate the number of blocks needing to be encrypted and any leftover.
11882
     */
11883
    blocks  = sz / WC_AES_BLOCK_SIZE;
11884
    partial = sz & (WC_AES_BLOCK_SIZE - 1);
11885
11886
#if defined(HAVE_AES_ECB)
11887
    /* Some hardware acceleration can gain performance from doing AES encryption
11888
     * of the whole buffer at once.
11889
     * Overwrites the cipher text before using plaintext - no inline encryption.
11890
     */
11891
    if ((out != in) && blocks > 0) {
11892
        word32 b;
11893
        /* Place incrementing counter blocks into cipher text. */
11894
        for (b = 0; b < blocks; b++) {
11895
            IncrementGcmCounter(AES_COUNTER(aes));
11896
            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
11897
        }
11898
11899
        /* Encrypt counter blocks. */
11900
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
11901
        /* XOR in plaintext. */
11902
        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
11903
        /* Skip over processed data. */
11904
        in += WC_AES_BLOCK_SIZE * blocks;
11905
        out += WC_AES_BLOCK_SIZE * blocks;
11906
    }
11907
    else
11908
#endif /* HAVE_AES_ECB */
11909
    {
11910
        /* Encrypt block by block. */
11911
        while (blocks--) {
11912
            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
11913
            IncrementGcmCounter(AES_COUNTER(aes));
11914
            /* Encrypt counter into a buffer. */
11915
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
11916
            if (ret != 0)
11917
                return ret;
11918
            /* XOR plain text into encrypted counter into cipher text buffer. */
11919
            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
11920
            /* Data complete. */
11921
            in  += WC_AES_BLOCK_SIZE;
11922
            out += WC_AES_BLOCK_SIZE;
11923
        }
11924
    }
11925
11926
    if (partial != 0) {
11927
        /* Generate an extra block and use up as much as needed. */
11928
        IncrementGcmCounter(AES_COUNTER(aes));
11929
        /* Encrypt counter into cache. */
11930
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
11931
        if (ret != 0)
11932
            return ret;
11933
        /* XOR plain text into encrypted counter into cipher text buffer. */
11934
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
11935
        /* Keep amount of encrypted block used. */
11936
        aes->over = (byte)partial;
11937
    }
11938
11939
    return 0;
11940
}
11941
11942
/* Calculates authentication tag for AES GCM. C implementation.
11943
 *
11944
 * @param [in, out] aes        AES object.
11945
 * @param [out]     authTag    Buffer to store authentication tag in.
11946
 * @param [in]      authTagSz  Length of tag to create.
11947
 */
11948
static WARN_UNUSED_RESULT int AesGcmFinal_C(
11949
    Aes* aes, byte* authTag, word32 authTagSz)
11950
{
11951
    /* Calculate authentication tag. */
11952
    GHASH_FINAL(aes, authTag, authTagSz);
11953
    /* XOR in as much of encrypted counter as is required. */
11954
    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
11955
#ifdef OPENSSL_EXTRA
11956
    /* store AAD size for next call */
11957
    aes->gcm.aadLen = aes->aSz;
11958
#endif
11959
    /* Zeroize last block to protect sensitive data. */
11960
    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
11961
11962
    return 0;
11963
}
11964
11965
#ifdef WOLFSSL_AESNI
11966
11967
#ifdef __cplusplus
11968
    extern "C" {
11969
#endif
11970
11971
/* Assembly code implementations in: aes_gcm_asm.S */
11972
#ifdef HAVE_INTEL_AVX2
11973
extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
11974
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
11975
    unsigned char* counter, unsigned char* initCtr);
11976
#ifdef HAVE_INTEL_AVX512
11977
extern void AES_GCM_init_avx512(const unsigned char* key, int nr,
11978
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
11979
    unsigned char* counter, unsigned char* initCtr);
11980
#endif
11981
#ifdef HAVE_INTEL_VAES
11982
extern void AES_GCM_init_vaes(const unsigned char* key, int nr,
11983
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
11984
    unsigned char* counter, unsigned char* initCtr);
11985
#endif
11986
extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
11987
    unsigned int abytes, unsigned char* tag, unsigned char* h);
11988
#ifdef HAVE_INTEL_AVX512
11989
extern void AES_GCM_aad_update_avx512(const unsigned char* addt,
11990
    unsigned int abytes, unsigned char* tag, unsigned char* h);
11991
#endif
11992
#ifdef HAVE_INTEL_VAES
11993
extern void AES_GCM_aad_update_vaes(const unsigned char* addt,
11994
    unsigned int abytes, unsigned char* tag, unsigned char* h);
11995
#endif
11996
extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
11997
    unsigned char* out, const unsigned char* in, unsigned char* counter);
11998
#ifdef HAVE_INTEL_AVX512
11999
extern void AES_GCM_encrypt_block_avx512(const unsigned char* key, int nr,
12000
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12001
#endif
12002
#ifdef HAVE_INTEL_VAES
12003
extern void AES_GCM_encrypt_block_vaes(const unsigned char* key, int nr,
12004
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12005
#endif
12006
extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
12007
    unsigned char* tag, unsigned char* h);
12008
#ifdef HAVE_INTEL_AVX512
12009
extern void AES_GCM_ghash_block_avx512(const unsigned char* data,
12010
    unsigned char* tag, unsigned char* h);
12011
#endif
12012
#ifdef HAVE_INTEL_VAES
12013
extern void AES_GCM_ghash_block_vaes(const unsigned char* data,
12014
    unsigned char* tag, unsigned char* h);
12015
#endif
12016
12017
extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
12018
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12019
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12020
#ifdef HAVE_INTEL_AVX512
12021
extern void AES_GCM_encrypt_update_avx512(const unsigned char* key, int nr,
12022
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12023
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12024
#endif
12025
#ifdef HAVE_INTEL_VAES
12026
extern void AES_GCM_encrypt_update_vaes(const unsigned char* key, int nr,
12027
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12028
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12029
#endif
12030
extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
12031
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12032
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12033
#ifdef HAVE_INTEL_AVX512
12034
extern void AES_GCM_encrypt_final_avx512(unsigned char* tag,
12035
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12036
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12037
#endif
12038
#ifdef HAVE_INTEL_VAES
12039
extern void AES_GCM_encrypt_final_vaes(unsigned char* tag,
12040
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12041
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12042
#endif
12043
#endif
12044
#ifdef HAVE_INTEL_AVX1
12045
extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
12046
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12047
    unsigned char* counter, unsigned char* initCtr);
12048
extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
12049
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12050
extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
12051
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12052
extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
12053
    unsigned char* tag, unsigned char* h);
12054
12055
extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
12056
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12057
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12058
extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
12059
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12060
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12061
#endif
12062
extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
12063
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12064
    unsigned char* counter, unsigned char* initCtr);
12065
extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
12066
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12067
extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
12068
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12069
extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
12070
    unsigned char* tag, unsigned char* h);
12071
12072
extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
12073
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12074
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12075
extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
12076
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12077
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12078
12079
#ifdef __cplusplus
12080
    } /* extern "C" */
12081
#endif
12082
12083
/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
12084
 *
12085
 * @param [in, out] aes   AES object.
12086
 * @param [in]      iv    IV/nonce buffer.
12087
 * @param [in]      ivSz  Length of IV/nonce data.
12088
 */
12089
static WARN_UNUSED_RESULT int AesGcmInit_aesni(
12090
    Aes* aes, const byte* iv, word32 ivSz)
12091
{
12092
    ASSERT_SAVED_VECTOR_REGISTERS();
12093
12094
    /* Reset state fields. */
12095
    aes->over = 0;
12096
    aes->aSz = 0;
12097
    aes->cSz = 0;
12098
    /* Set tag to all zeros as initial value. */
12099
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
12100
    /* Reset counts of AAD and cipher text. */
12101
    aes->aOver = 0;
12102
    aes->cOver = 0;
12103
12104
#ifdef HAVE_INTEL_AVX512
12105
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12106
        AES_GCM_init_avx512((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12107
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12108
    }
12109
    else
12110
#endif
12111
#ifdef HAVE_INTEL_VAES
12112
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12113
        AES_GCM_init_vaes((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12114
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12115
    }
12116
    else
12117
#endif
12118
#ifdef HAVE_INTEL_AVX2
12119
    if (IS_INTEL_AVX2(intel_flags)) {
12120
        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12121
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12122
    }
12123
    else
12124
#endif
12125
#ifdef HAVE_INTEL_AVX1
12126
    if (IS_INTEL_AVX1(intel_flags)) {
12127
        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12128
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12129
    }
12130
    else
12131
#endif
12132
    {
12133
        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12134
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12135
    }
12136
12137
    return 0;
12138
}
12139
12140
/* Update the AES GCM for encryption with authentication data.
12141
 *
12142
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
12143
 *
12144
 * @param [in, out] aes   AES object.
12145
 * @param [in]      a     Buffer holding authentication data.
12146
 * @param [in]      aSz   Length of authentication data in bytes.
12147
 * @param [in]      endA  Whether no more authentication data is expected.
12148
 */
12149
static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
12150
    Aes* aes, const byte* a, word32 aSz, int endA)
12151
{
12152
    word32 blocks;
12153
    int partial;
12154
12155
    ASSERT_SAVED_VECTOR_REGISTERS();
12156
12157
    if (aSz != 0 && a != NULL) {
12158
        /* Total count of AAD updated. */
12159
        aes->aSz += aSz;
12160
        /* Check if we have unprocessed data. */
12161
        if (aes->aOver > 0) {
12162
            /* Calculate amount we can use - fill up the block. */
12163
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
12164
            if (sz > aSz) {
12165
                sz = (byte)aSz;
12166
            }
12167
            /* Copy extra into last GHASH block array and update count. */
12168
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
12169
            aes->aOver = (byte)(aes->aOver + sz);
12170
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
12171
                /* We have filled up the block and can process. */
12172
#ifdef HAVE_INTEL_AVX512
12173
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12174
                    AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12175
                                             aes->gcm.H);
12176
                }
12177
                else
12178
#endif
12179
#ifdef HAVE_INTEL_VAES
12180
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12181
                    AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12182
                                             aes->gcm.H);
12183
                }
12184
                else
12185
#endif
12186
            #ifdef HAVE_INTEL_AVX2
12187
                if (IS_INTEL_AVX2(intel_flags)) {
12188
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12189
                                             aes->gcm.H);
12190
                }
12191
                else
12192
            #endif
12193
            #ifdef HAVE_INTEL_AVX1
12194
                if (IS_INTEL_AVX1(intel_flags)) {
12195
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
12196
                                             aes->gcm.H);
12197
                }
12198
                else
12199
            #endif
12200
                {
12201
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
12202
                                              aes->gcm.H);
12203
                }
12204
                /* Reset count. */
12205
                aes->aOver = 0;
12206
            }
12207
            /* Used up some data. */
12208
            aSz -= sz;
12209
            a += sz;
12210
        }
12211
12212
        /* Calculate number of blocks of AAD and the leftover. */
12213
        blocks = aSz / WC_AES_BLOCK_SIZE;
12214
        partial = aSz % WC_AES_BLOCK_SIZE;
12215
        if (blocks > 0) {
12216
            /* GHASH full blocks now. */
12217
#ifdef HAVE_INTEL_AVX512
12218
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12219
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12220
                AES_GCM_aad_update_avx512(a, blocks * WC_AES_BLOCK_SIZE,
12221
                                        AES_TAG(aes), aes->gcm.H);
12222
            }
12223
            else
12224
#endif
12225
#ifdef HAVE_INTEL_VAES
12226
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12227
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12228
                AES_GCM_aad_update_vaes(a, blocks * WC_AES_BLOCK_SIZE,
12229
                                        AES_TAG(aes), aes->gcm.H);
12230
            }
12231
            else
12232
#endif
12233
        #ifdef HAVE_INTEL_AVX2
12234
            if (IS_INTEL_AVX2(intel_flags)) {
12235
                AES_GCM_aad_update_avx2(a, blocks * WC_AES_BLOCK_SIZE,
12236
                                        AES_TAG(aes), aes->gcm.H);
12237
            }
12238
            else
12239
        #endif
12240
        #ifdef HAVE_INTEL_AVX1
12241
            if (IS_INTEL_AVX1(intel_flags)) {
12242
                AES_GCM_aad_update_avx1(a, blocks * WC_AES_BLOCK_SIZE,
12243
                                        AES_TAG(aes), aes->gcm.H);
12244
            }
12245
            else
12246
        #endif
12247
            {
12248
                AES_GCM_aad_update_aesni(a, blocks * WC_AES_BLOCK_SIZE,
12249
                                         AES_TAG(aes), aes->gcm.H);
12250
            }
12251
            /* Skip over to end of AAD blocks. */
12252
            a += blocks * WC_AES_BLOCK_SIZE;
12253
        }
12254
        if (partial != 0) {
12255
            /* Cache the partial block. */
12256
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
12257
            aes->aOver = (byte)partial;
12258
        }
12259
    }
12260
    if (endA && (aes->aOver > 0)) {
12261
        /* No more AAD coming and we have a partial block. */
12262
        /* Fill the rest of the block with zeros. */
12263
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
12264
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
12265
        /* GHASH last AAD block. */
12266
#ifdef HAVE_INTEL_AVX512
12267
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12268
            AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12269
                                     aes->gcm.H);
12270
        }
12271
        else
12272
#endif
12273
#ifdef HAVE_INTEL_VAES
12274
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12275
            AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12276
                                     aes->gcm.H);
12277
        }
12278
        else
12279
#endif
12280
    #ifdef HAVE_INTEL_AVX2
12281
        if (IS_INTEL_AVX2(intel_flags)) {
12282
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12283
                                     aes->gcm.H);
12284
        }
12285
        else
12286
    #endif
12287
    #ifdef HAVE_INTEL_AVX1
12288
        if (IS_INTEL_AVX1(intel_flags)) {
12289
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
12290
                                     aes->gcm.H);
12291
        }
12292
        else
12293
    #endif
12294
        {
12295
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
12296
                                      aes->gcm.H);
12297
        }
12298
        /* Clear partial count for next time through. */
12299
        aes->aOver = 0;
12300
    }
12301
12302
    return 0;
12303
}
12304
12305
/* Update the AES GCM for encryption with data and/or authentication data.
12306
 *
12307
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
12308
 *
12309
 * @param [in, out] aes  AES object.
12310
 * @param [out]     c    Buffer to hold cipher text.
12311
 * @param [in]      p    Buffer holding plaintext.
12312
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
12313
 * @param [in]      a    Buffer holding authentication data.
12314
 * @param [in]      aSz  Length of authentication data in bytes.
12315
 */
12316
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
12317
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
12318
{
12319
    word32 blocks;
12320
    int partial;
12321
    int ret;
12322
12323
    ASSERT_SAVED_VECTOR_REGISTERS();
12324
12325
    /* Hash in A, the Authentication Data */
12326
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
12327
    if (ret != 0)
12328
        return ret;
12329
12330
    /* Encrypt plaintext and Hash in C, the Cipher text */
12331
    if (cSz != 0 && c != NULL) {
12332
        /* Update count of cipher text we have hashed. */
12333
        aes->cSz += cSz;
12334
        if (aes->cOver > 0) {
12335
            /* Calculate amount we can use - fill up the block. */
12336
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
12337
            if (sz > cSz) {
12338
                sz = (byte)cSz;
12339
            }
12340
            /* Encrypt some of the plaintext. */
12341
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
12342
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
12343
            /* Update count of unused encrypted counter. */
12344
            aes->cOver = (byte)(aes->cOver + sz);
12345
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
12346
                /* We have filled up the block and can process. */
12347
#ifdef HAVE_INTEL_AVX512
12348
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12349
                    AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12350
                                             aes->gcm.H);
12351
                }
12352
                else
12353
#endif
12354
#ifdef HAVE_INTEL_VAES
12355
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12356
                    AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12357
                                             aes->gcm.H);
12358
                }
12359
                else
12360
#endif
12361
            #ifdef HAVE_INTEL_AVX2
12362
                if (IS_INTEL_AVX2(intel_flags)) {
12363
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12364
                                             aes->gcm.H);
12365
                }
12366
                else
12367
            #endif
12368
            #ifdef HAVE_INTEL_AVX1
12369
                if (IS_INTEL_AVX1(intel_flags)) {
12370
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
12371
                                             aes->gcm.H);
12372
                }
12373
                else
12374
            #endif
12375
                {
12376
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
12377
                                              aes->gcm.H);
12378
                }
12379
                /* Reset count. */
12380
                aes->cOver = 0;
12381
            }
12382
            /* Used up some data. */
12383
            cSz -= sz;
12384
            p += sz;
12385
            c += sz;
12386
        }
12387
12388
        /* Calculate number of blocks of plaintext and the leftover. */
12389
        blocks = cSz / WC_AES_BLOCK_SIZE;
12390
        partial = cSz % WC_AES_BLOCK_SIZE;
12391
        if (blocks > 0) {
12392
            /* Encrypt and GHASH full blocks now. */
12393
#ifdef HAVE_INTEL_AVX512
12394
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12395
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12396
                AES_GCM_encrypt_update_avx512((byte*)aes->key, (int)aes->rounds,
12397
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12398
                    AES_COUNTER(aes));
12399
            }
12400
            else
12401
#endif
12402
#ifdef HAVE_INTEL_VAES
12403
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12404
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12405
                AES_GCM_encrypt_update_vaes((byte*)aes->key, (int)aes->rounds,
12406
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12407
                    AES_COUNTER(aes));
12408
            }
12409
            else
12410
#endif
12411
        #ifdef HAVE_INTEL_AVX2
12412
            if (IS_INTEL_AVX2(intel_flags)) {
12413
                AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
12414
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12415
                    AES_COUNTER(aes));
12416
            }
12417
            else
12418
        #endif
12419
        #ifdef HAVE_INTEL_AVX1
12420
            if (IS_INTEL_AVX1(intel_flags)) {
12421
                AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
12422
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12423
                    AES_COUNTER(aes));
12424
            }
12425
            else
12426
        #endif
12427
            {
12428
                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
12429
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12430
                    AES_COUNTER(aes));
12431
            }
12432
            /* Skip over to end of blocks. */
12433
            p += blocks * WC_AES_BLOCK_SIZE;
12434
            c += blocks * WC_AES_BLOCK_SIZE;
12435
        }
12436
        if (partial != 0) {
12437
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
12438
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
12439
#ifdef HAVE_INTEL_AVX512
12440
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12441
                AES_GCM_encrypt_block_avx512((byte*)aes->key, (int)aes->rounds,
12442
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12443
            }
12444
            else
12445
#endif
12446
#ifdef HAVE_INTEL_VAES
12447
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12448
                AES_GCM_encrypt_block_vaes((byte*)aes->key, (int)aes->rounds,
12449
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12450
            }
12451
            else
12452
#endif
12453
        #ifdef HAVE_INTEL_AVX2
12454
            if (IS_INTEL_AVX2(intel_flags)) {
12455
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
12456
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12457
            }
12458
            else
12459
        #endif
12460
        #ifdef HAVE_INTEL_AVX1
12461
            if (IS_INTEL_AVX1(intel_flags)) {
12462
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
12463
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12464
            }
12465
            else
12466
        #endif
12467
            {
12468
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
12469
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12470
            }
12471
            /* XOR the remaining plaintext to calculate cipher text.
12472
             * Keep cipher text for GHASH of last partial block.
12473
             */
12474
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
12475
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
12476
            /* Update count of the block used. */
12477
            aes->cOver = (byte)partial;
12478
        }
12479
    }
12480
    return 0;
12481
}
12482
12483
/* Finalize the AES GCM for encryption and calculate the authentication tag.
12484
 *
12485
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
12486
 *
12487
 * @param [in, out] aes        AES object.
12488
 * @param [in]      authTag    Buffer to hold authentication tag.
12489
 * @param [in]      authTagSz  Length of authentication tag in bytes.
12490
 * @return  0 on success.
12491
 */
12492
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
12493
    Aes* aes, byte* authTag, word32 authTagSz)
12494
{
12495
    /* AAD block incomplete when > 0 */
12496
    byte over = aes->aOver;
12497
12498
    ASSERT_SAVED_VECTOR_REGISTERS();
12499
12500
    if (aes->cOver > 0) {
12501
        /* Cipher text block incomplete. */
12502
        over = aes->cOver;
12503
    }
12504
    if (over > 0) {
12505
        /* Fill the rest of the block with zeros. */
12506
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
12507
        /* GHASH last cipher block. */
12508
#ifdef HAVE_INTEL_AVX512
12509
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12510
            AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12511
                                     aes->gcm.H);
12512
        }
12513
        else
12514
#endif
12515
#ifdef HAVE_INTEL_VAES
12516
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12517
            AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12518
                                     aes->gcm.H);
12519
        }
12520
        else
12521
#endif
12522
    #ifdef HAVE_INTEL_AVX2
12523
        if (IS_INTEL_AVX2(intel_flags)) {
12524
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12525
                                     aes->gcm.H);
12526
        }
12527
        else
12528
    #endif
12529
    #ifdef HAVE_INTEL_AVX1
12530
        if (IS_INTEL_AVX1(intel_flags)) {
12531
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
12532
                                     aes->gcm.H);
12533
        }
12534
        else
12535
    #endif
12536
        {
12537
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
12538
                                      aes->gcm.H);
12539
        }
12540
    }
12541
    /* Calculate the authentication tag. */
12542
#ifdef HAVE_INTEL_AVX512
12543
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12544
        AES_GCM_encrypt_final_avx512(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12545
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12546
    }
12547
    else
12548
#endif
12549
#ifdef HAVE_INTEL_VAES
12550
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12551
        AES_GCM_encrypt_final_vaes(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12552
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12553
    }
12554
    else
12555
#endif
12556
#ifdef HAVE_INTEL_AVX2
12557
    if (IS_INTEL_AVX2(intel_flags)) {
12558
        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12559
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12560
    }
12561
    else
12562
#endif
12563
#ifdef HAVE_INTEL_AVX1
12564
    if (IS_INTEL_AVX1(intel_flags)) {
12565
        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12566
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12567
    }
12568
    else
12569
#endif
12570
    {
12571
        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12572
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12573
    }
12574
12575
    return 0;
12576
}
12577
12578
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
12579
12580
#ifdef __cplusplus
12581
    extern "C" {
12582
#endif
12583
12584
/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
12585
#ifdef HAVE_INTEL_AVX2
12586
extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
12587
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12588
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12589
#ifdef HAVE_INTEL_AVX512
12590
extern void AES_GCM_decrypt_update_avx512(const unsigned char* key, int nr,
12591
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12592
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12593
#endif
12594
#ifdef HAVE_INTEL_VAES
12595
extern void AES_GCM_decrypt_update_vaes(const unsigned char* key, int nr,
12596
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12597
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12598
#endif
12599
extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
12600
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12601
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12602
#ifdef HAVE_INTEL_AVX512
12603
extern void AES_GCM_decrypt_final_avx512(unsigned char* tag,
12604
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12605
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12606
#endif
12607
#ifdef HAVE_INTEL_VAES
12608
extern void AES_GCM_decrypt_final_vaes(unsigned char* tag,
12609
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12610
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12611
#endif
12612
#endif
12613
#ifdef HAVE_INTEL_AVX1
12614
extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
12615
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12616
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12617
extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
12618
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12619
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12620
#endif
12621
extern void AES_GCM_decrypt_update_aesni(const unsigned char* key, int nr,
12622
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12623
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12624
extern void AES_GCM_decrypt_final_aesni(unsigned char* tag,
12625
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12626
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12627
12628
#ifdef __cplusplus
12629
    } /* extern "C" */
12630
#endif
12631
12632
/* Update the AES GCM for decryption with data and/or authentication data.
12633
 *
12634
 * @param [in, out] aes  AES object.
12635
 * @param [out]     p    Buffer to hold plaintext.
12636
 * @param [in]      c    Buffer holding cipher text.
12637
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
12638
 * @param [in]      a    Buffer holding authentication data.
12639
 * @param [in]      aSz  Length of authentication data in bytes.
12640
 */
12641
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
12642
    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
12643
{
12644
    word32 blocks;
12645
    int partial;
12646
    int ret;
12647
12648
    ASSERT_SAVED_VECTOR_REGISTERS();
12649
12650
    /* Hash in A, the Authentication Data */
12651
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
12652
    if (ret != 0)
12653
        return ret;
12654
12655
    /* Hash in C, the Cipher text, and decrypt. */
12656
    if (cSz != 0 && p != NULL) {
12657
        /* Update count of cipher text we have hashed. */
12658
        aes->cSz += cSz;
12659
        if (aes->cOver > 0) {
12660
            /* Calculate amount we can use - fill up the block. */
12661
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
12662
            if (sz > cSz) {
12663
                sz = (byte)cSz;
12664
            }
12665
            /* Keep a copy of the cipher text for GHASH. */
12666
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
12667
            /* Decrypt some of the cipher text. */
12668
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
12669
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
12670
            /* Update count of unused encrypted counter. */
12671
            aes->cOver = (byte)(aes->cOver + sz);
12672
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
12673
                /* We have filled up the block and can process. */
12674
#ifdef HAVE_INTEL_AVX512
12675
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12676
                    AES_GCM_ghash_block_avx512(AES_LASTBLOCK(aes), AES_TAG(aes),
12677
                                             aes->gcm.H);
12678
                }
12679
                else
12680
#endif
12681
#ifdef HAVE_INTEL_VAES
12682
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12683
                    AES_GCM_ghash_block_vaes(AES_LASTBLOCK(aes), AES_TAG(aes),
12684
                                             aes->gcm.H);
12685
                }
12686
                else
12687
#endif
12688
            #ifdef HAVE_INTEL_AVX2
12689
                if (IS_INTEL_AVX2(intel_flags)) {
12690
                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
12691
                                             aes->gcm.H);
12692
                }
12693
                else
12694
            #endif
12695
            #ifdef HAVE_INTEL_AVX1
12696
                if (IS_INTEL_AVX1(intel_flags)) {
12697
                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
12698
                                             aes->gcm.H);
12699
                }
12700
                else
12701
            #endif
12702
                {
12703
                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
12704
                                              aes->gcm.H);
12705
                }
12706
                /* Reset count. */
12707
                aes->cOver = 0;
12708
            }
12709
            /* Used up some data. */
12710
            cSz -= sz;
12711
            c += sz;
12712
            p += sz;
12713
        }
12714
12715
        /* Calculate number of blocks of plaintext and the leftover. */
12716
        blocks = cSz / WC_AES_BLOCK_SIZE;
12717
        partial = cSz % WC_AES_BLOCK_SIZE;
12718
        if (blocks > 0) {
12719
            /* Decrypt and GHASH full blocks now. */
12720
#ifdef HAVE_INTEL_AVX512
12721
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12722
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12723
                AES_GCM_decrypt_update_avx512((byte*)aes->key, (int)aes->rounds,
12724
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12725
                    AES_COUNTER(aes));
12726
            }
12727
            else
12728
#endif
12729
#ifdef HAVE_INTEL_VAES
12730
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12731
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12732
                AES_GCM_decrypt_update_vaes((byte*)aes->key, (int)aes->rounds,
12733
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12734
                    AES_COUNTER(aes));
12735
            }
12736
            else
12737
#endif
12738
        #ifdef HAVE_INTEL_AVX2
12739
            if (IS_INTEL_AVX2(intel_flags)) {
12740
                AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
12741
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12742
                    AES_COUNTER(aes));
12743
            }
12744
            else
12745
        #endif
12746
        #ifdef HAVE_INTEL_AVX1
12747
            if (IS_INTEL_AVX1(intel_flags)) {
12748
                AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
12749
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12750
                    AES_COUNTER(aes));
12751
            }
12752
            else
12753
        #endif
12754
            {
12755
                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
12756
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12757
                    AES_COUNTER(aes));
12758
            }
12759
            /* Skip over to end of blocks. */
12760
            c += blocks * WC_AES_BLOCK_SIZE;
12761
            p += blocks * WC_AES_BLOCK_SIZE;
12762
        }
12763
        if (partial != 0) {
12764
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
12765
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
12766
#ifdef HAVE_INTEL_AVX512
12767
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12768
                AES_GCM_encrypt_block_avx512((byte*)aes->key, (int)aes->rounds,
12769
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12770
            }
12771
            else
12772
#endif
12773
#ifdef HAVE_INTEL_VAES
12774
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12775
                AES_GCM_encrypt_block_vaes((byte*)aes->key, (int)aes->rounds,
12776
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12777
            }
12778
            else
12779
#endif
12780
        #ifdef HAVE_INTEL_AVX2
12781
            if (IS_INTEL_AVX2(intel_flags)) {
12782
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
12783
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12784
            }
12785
            else
12786
        #endif
12787
        #ifdef HAVE_INTEL_AVX1
12788
            if (IS_INTEL_AVX1(intel_flags)) {
12789
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
12790
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12791
            }
12792
            else
12793
        #endif
12794
            {
12795
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
12796
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12797
            }
12798
            /* Keep cipher text for GHASH of last partial block. */
12799
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
12800
            /* XOR the remaining cipher text to calculate plaintext. */
12801
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
12802
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
12803
            /* Update count of the block used. */
12804
            aes->cOver = (byte)partial;
12805
        }
12806
    }
12807
12808
    return 0;
12809
}
12810
12811
/* Finalize the AES GCM for decryption and check the authentication tag.
12812
 *
12813
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
12814
 *
12815
 * @param [in, out] aes        AES object.
12816
 * @param [in]      authTag    Buffer holding authentication tag.
12817
 * @param [in]      authTagSz  Length of authentication tag in bytes.
12818
 * @return  0 on success.
12819
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
12820
 *          value.
12821
 */
12822
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
12823
    Aes* aes, const byte* authTag, word32 authTagSz)
12824
{
12825
    int ret = 0;
12826
    int res;
12827
    /* AAD block incomplete when > 0 */
12828
    byte over = aes->aOver;
12829
    byte *lastBlock = AES_LASTGBLOCK(aes);
12830
12831
    ASSERT_SAVED_VECTOR_REGISTERS();
12832
12833
    if (aes->cOver > 0) {
12834
        /* Cipher text block incomplete. */
12835
        over = aes->cOver;
12836
        lastBlock = AES_LASTBLOCK(aes);
12837
    }
12838
    if (over > 0) {
12839
        /* Zeroize the unused part of the block. */
12840
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
12841
        /* Hash the last block of cipher text. */
12842
#ifdef HAVE_INTEL_AVX512
12843
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12844
            AES_GCM_ghash_block_avx512(lastBlock, AES_TAG(aes), aes->gcm.H);
12845
        }
12846
        else
12847
#endif
12848
#ifdef HAVE_INTEL_VAES
12849
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12850
            AES_GCM_ghash_block_vaes(lastBlock, AES_TAG(aes), aes->gcm.H);
12851
        }
12852
        else
12853
#endif
12854
    #ifdef HAVE_INTEL_AVX2
12855
        if (IS_INTEL_AVX2(intel_flags)) {
12856
            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
12857
        }
12858
        else
12859
    #endif
12860
    #ifdef HAVE_INTEL_AVX1
12861
        if (IS_INTEL_AVX1(intel_flags)) {
12862
            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
12863
        }
12864
        else
12865
    #endif
12866
        {
12867
            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
12868
        }
12869
    }
12870
    /* Calculate and compare the authentication tag. */
12871
#ifdef HAVE_INTEL_AVX512
12872
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12873
        AES_GCM_decrypt_final_avx512(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12874
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
12875
    }
12876
    else
12877
#endif
12878
#ifdef HAVE_INTEL_VAES
12879
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12880
        AES_GCM_decrypt_final_vaes(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12881
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
12882
    }
12883
    else
12884
#endif
12885
#ifdef HAVE_INTEL_AVX2
12886
    if (IS_INTEL_AVX2(intel_flags)) {
12887
        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12888
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
12889
    }
12890
    else
12891
#endif
12892
#ifdef HAVE_INTEL_AVX1
12893
    if (IS_INTEL_AVX1(intel_flags)) {
12894
        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12895
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
12896
    }
12897
    else
12898
#endif
12899
    {
12900
        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12901
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
12902
    }
12903
12904
    /* Return error code when calculated doesn't match input. */
12905
    if (res == 0) {
12906
        ret = AES_GCM_AUTH_E;
12907
    }
12908
    return ret;
12909
}
12910
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
12911
#endif /* WOLFSSL_AESNI */
12912
12913
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12914
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12915
/* Initialize the AES GCM cipher with an IV. Aarch64 HW Crypto implementations.
12916
 *
12917
 * @param [in, out] aes   AES object.
12918
 * @param [in]      iv    IV/nonce buffer.
12919
 * @param [in]      ivSz  Length of IV/nonce data.
12920
 */
12921
static WARN_UNUSED_RESULT int AesGcmInit_AARCH64(Aes* aes, const byte* iv,
12922
    word32 ivSz)
12923
{
12924
    /* Reset state fields. */
12925
    aes->over = 0;
12926
    aes->aSz = 0;
12927
    aes->cSz = 0;
12928
    /* Set tag to all zeros as initial value. */
12929
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
12930
    /* Reset counts of AAD and cipher text. */
12931
    aes->aOver = 0;
12932
    aes->cOver = 0;
12933
12934
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12935
    if (aes->use_sha3_hw_crypto) {
12936
        AES_GCM_init_AARCH64_EOR3((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12937
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12938
    }
12939
    else
12940
#endif
12941
    {
12942
        AES_GCM_init_AARCH64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12943
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12944
    }
12945
12946
    return 0;
12947
}
12948
12949
/* Update the AES GCM for encryption with authentication data.
12950
 *
12951
 * Implementation uses AARCH64 optimized assembly code.
12952
 *
12953
 * @param [in, out] aes   AES object.
12954
 * @param [in]      a     Buffer holding authentication data.
12955
 * @param [in]      aSz   Length of authentication data in bytes.
12956
 * @param [in]      endA  Whether no more authentication data is expected.
12957
 */
12958
static WARN_UNUSED_RESULT int AesGcmAadUpdate_AARCH64(
12959
    Aes* aes, const byte* a, word32 aSz, int endA)
12960
{
12961
    word32 blocks;
12962
    int partial;
12963
12964
    if (aSz != 0 && a != NULL) {
12965
        /* Total count of AAD updated. */
12966
        aes->aSz += aSz;
12967
        /* Check if we have unprocessed data. */
12968
        if (aes->aOver > 0) {
12969
            /* Calculate amount we can use - fill up the block. */
12970
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
12971
            if (sz > aSz) {
12972
                sz = (byte)aSz;
12973
            }
12974
            /* Copy extra into last GHASH block array and update count. */
12975
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
12976
            aes->aOver = (byte)(aes->aOver + sz);
12977
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
12978
                /* We have filled up the block and can process. */
12979
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12980
                if (aes->use_sha3_hw_crypto) {
12981
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
12982
                        AES_TAG(aes), aes->gcm.H);
12983
                }
12984
                else
12985
            #endif
12986
                {
12987
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
12988
                        AES_TAG(aes), aes->gcm.H);
12989
                }
12990
                /* Reset count. */
12991
                aes->aOver = 0;
12992
            }
12993
            /* Used up some data. */
12994
            aSz -= sz;
12995
            a += sz;
12996
        }
12997
12998
        /* Calculate number of blocks of AAD and the leftover. */
12999
        blocks = aSz / WC_AES_BLOCK_SIZE;
13000
        partial = aSz % WC_AES_BLOCK_SIZE;
13001
        if (blocks > 0) {
13002
            /* GHASH full blocks now. */
13003
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13004
            if (aes->use_sha3_hw_crypto) {
13005
                AES_GCM_aad_update_AARCH64_EOR3(a, blocks * WC_AES_BLOCK_SIZE,
13006
                    AES_TAG(aes), aes->gcm.H);
13007
            }
13008
            else
13009
        #endif
13010
            {
13011
                AES_GCM_aad_update_AARCH64(a, blocks * WC_AES_BLOCK_SIZE,
13012
                    AES_TAG(aes), aes->gcm.H);
13013
            }
13014
            /* Skip over to end of AAD blocks. */
13015
            a += blocks * WC_AES_BLOCK_SIZE;
13016
        }
13017
        if (partial != 0) {
13018
            /* Cache the partial block. */
13019
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
13020
            aes->aOver = (byte)partial;
13021
        }
13022
    }
13023
    if (endA && (aes->aOver > 0)) {
13024
        /* No more AAD coming and we have a partial block. */
13025
        /* Fill the rest of the block with zeros. */
13026
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
13027
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
13028
        /* GHASH last AAD block. */
13029
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13030
        if (aes->use_sha3_hw_crypto) {
13031
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13032
                AES_TAG(aes), aes->gcm.H);
13033
        }
13034
        else
13035
    #endif
13036
        {
13037
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13038
                AES_TAG(aes), aes->gcm.H);
13039
        }
13040
        /* Clear partial count for next time through. */
13041
        aes->aOver = 0;
13042
    }
13043
13044
    return 0;
13045
}
13046
13047
/* Update the AES GCM for encryption with data and/or authentication data.
13048
 *
13049
 * Implementation uses AARCH64 optimized assembly code.
13050
 *
13051
 * @param [in, out] aes  AES object.
13052
 * @param [out]     c    Buffer to hold cipher text.
13053
 * @param [in]      p    Buffer holding plaintext.
13054
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13055
 * @param [in]      a    Buffer holding authentication data.
13056
 * @param [in]      aSz  Length of authentication data in bytes.
13057
 */
13058
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_AARCH64(
13059
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
13060
{
13061
    word32 blocks;
13062
    int partial;
13063
    int ret;
13064
13065
    /* Hash in A, the Authentication Data */
13066
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, (cSz > 0) && (c != NULL));
13067
    if (ret != 0)
13068
        return ret;
13069
13070
    /* Encrypt plaintext and Hash in C, the Cipher text */
13071
    if (cSz != 0 && c != NULL) {
13072
        /* Update count of cipher text we have hashed. */
13073
        aes->cSz += cSz;
13074
        if (aes->cOver > 0) {
13075
            /* Calculate amount we can use - fill up the block. */
13076
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13077
            if (sz > cSz) {
13078
                sz = (byte)cSz;
13079
            }
13080
            /* Encrypt some of the plaintext. */
13081
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
13082
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13083
            /* Update count of unused encrypted counter. */
13084
            aes->cOver = (byte)(aes->cOver + sz);
13085
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13086
                /* We have filled up the block and can process. */
13087
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13088
                if (aes->use_sha3_hw_crypto) {
13089
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13090
                        AES_TAG(aes), aes->gcm.H);
13091
                }
13092
                else
13093
            #endif
13094
                {
13095
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13096
                        AES_TAG(aes), aes->gcm.H);
13097
                }
13098
                /* Reset count. */
13099
                aes->cOver = 0;
13100
            }
13101
            /* Used up some data. */
13102
            cSz -= sz;
13103
            p += sz;
13104
            c += sz;
13105
        }
13106
13107
        /* Calculate number of blocks of plaintext and the leftover. */
13108
        blocks = cSz / WC_AES_BLOCK_SIZE;
13109
        partial = cSz % WC_AES_BLOCK_SIZE;
13110
        if (blocks > 0) {
13111
            /* Encrypt and GHASH full blocks now. */
13112
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13113
            if (aes->use_sha3_hw_crypto) {
13114
                AES_GCM_encrypt_update_AARCH64_EOR3((byte*)aes->key,
13115
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
13116
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13117
            }
13118
            else
13119
        #endif
13120
            {
13121
                AES_GCM_encrypt_update_AARCH64((byte*)aes->key,
13122
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
13123
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13124
            }
13125
            /* Skip over to end of blocks. */
13126
            p += blocks * WC_AES_BLOCK_SIZE;
13127
            c += blocks * WC_AES_BLOCK_SIZE;
13128
        }
13129
        if (partial != 0) {
13130
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
13131
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13132
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13133
            if (aes->use_sha3_hw_crypto) {
13134
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
13135
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
13136
                    AES_COUNTER(aes));
13137
            }
13138
            else
13139
        #endif
13140
            {
13141
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
13142
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13143
            }
13144
            /* XOR the remaining plaintext to calculate cipher text.
13145
             * Keep cipher text for GHASH of last partial block.
13146
             */
13147
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
13148
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
13149
            /* Update count of the block used. */
13150
            aes->cOver = (byte)partial;
13151
        }
13152
    }
13153
    return 0;
13154
}
13155
13156
/* Finalize the AES GCM for encryption and calculate the authentication tag.
13157
 *
13158
 * Calls ARCH64 optimized assembly code.
13159
 *
13160
 * @param [in, out] aes        AES object.
13161
 * @param [in]      authTag    Buffer to hold authentication tag.
13162
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13163
 * @return  0 on success.
13164
 */
13165
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_AARCH64(Aes* aes,
13166
    byte* authTag, word32 authTagSz)
13167
{
13168
    /* AAD block incomplete when > 0 */
13169
    byte over = aes->aOver;
13170
13171
    ASSERT_SAVED_VECTOR_REGISTERS();
13172
13173
    if (aes->cOver > 0) {
13174
        /* Cipher text block incomplete. */
13175
        over = aes->cOver;
13176
    }
13177
    if (over > 0) {
13178
        /* Fill the rest of the block with zeros. */
13179
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
13180
            (size_t)WC_AES_BLOCK_SIZE - over);
13181
        /* GHASH last cipher block. */
13182
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13183
        if (aes->use_sha3_hw_crypto) {
13184
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes), AES_TAG(aes),
13185
                aes->gcm.H);
13186
        }
13187
        else
13188
    #endif
13189
        {
13190
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes), AES_TAG(aes),
13191
                aes->gcm.H);
13192
        }
13193
    }
13194
    /* Calculate the authentication tag. */
13195
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13196
    if (aes->use_sha3_hw_crypto) {
13197
        AES_GCM_encrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
13198
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13199
    }
13200
    else
13201
#endif
13202
    {
13203
        AES_GCM_encrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
13204
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13205
    }
13206
13207
    return 0;
13208
}
13209
13210
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
13211
/* Update the AES GCM for decryption with data and/or authentication data.
13212
 *
13213
 * @param [in, out] aes  AES object.
13214
 * @param [out]     p    Buffer to hold plaintext.
13215
 * @param [in]      c    Buffer holding cipher text.
13216
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13217
 * @param [in]      a    Buffer holding authentication data.
13218
 * @param [in]      aSz  Length of authentication data in bytes.
13219
 */
13220
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_AARCH64(Aes* aes, byte* p,
13221
    const byte* c, word32 cSz, const byte* a, word32 aSz)
13222
{
13223
    word32 blocks;
13224
    int partial;
13225
    int ret;
13226
13227
    /* Hash in A, the Authentication Data */
13228
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, cSz > 0);
13229
    if (ret != 0)
13230
        return ret;
13231
13232
    /* Hash in C, the Cipher text, and decrypt. */
13233
    if (cSz != 0 && p != NULL) {
13234
        /* Update count of cipher text we have hashed. */
13235
        aes->cSz += cSz;
13236
        if (aes->cOver > 0) {
13237
            /* Calculate amount we can use - fill up the block. */
13238
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13239
            if (sz > cSz) {
13240
                sz = (byte)cSz;
13241
            }
13242
            /* Keep a copy of the cipher text for GHASH. */
13243
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
13244
            /* Decrypt some of the cipher text. */
13245
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
13246
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13247
            /* Update count of unused encrypted counter. */
13248
            aes->cOver = (byte)(aes->cOver + sz);
13249
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13250
                /* We have filled up the block and can process. */
13251
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13252
                if (aes->use_sha3_hw_crypto) {
13253
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTBLOCK(aes),
13254
                        AES_TAG(aes), aes->gcm.H);
13255
                }
13256
                else
13257
            #endif
13258
                {
13259
                    AES_GCM_ghash_block_AARCH64(AES_LASTBLOCK(aes),
13260
                        AES_TAG(aes), aes->gcm.H);
13261
                }
13262
                /* Reset count. */
13263
                aes->cOver = 0;
13264
            }
13265
            /* Used up some data. */
13266
            cSz -= sz;
13267
            c += sz;
13268
            p += sz;
13269
        }
13270
13271
        /* Calculate number of blocks of plaintext and the leftover. */
13272
        blocks = cSz / WC_AES_BLOCK_SIZE;
13273
        partial = cSz % WC_AES_BLOCK_SIZE;
13274
        if (blocks > 0) {
13275
            /* Decrypt and GHASH full blocks now. */
13276
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13277
            if (aes->use_sha3_hw_crypto) {
13278
                AES_GCM_decrypt_update_AARCH64_EOR3((byte*)aes->key,
13279
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
13280
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13281
            }
13282
            else
13283
        #endif
13284
            {
13285
                AES_GCM_decrypt_update_AARCH64((byte*)aes->key,
13286
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
13287
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13288
            }
13289
            /* Skip over to end of blocks. */
13290
            c += blocks * WC_AES_BLOCK_SIZE;
13291
            p += blocks * WC_AES_BLOCK_SIZE;
13292
        }
13293
        if (partial != 0) {
13294
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
13295
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13296
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13297
            if (aes->use_sha3_hw_crypto) {
13298
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
13299
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
13300
                    AES_COUNTER(aes));
13301
            }
13302
            else
13303
        #endif
13304
            {
13305
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
13306
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13307
            }
13308
            /* Keep cipher text for GHASH of last partial block. */
13309
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
13310
            /* XOR the remaining cipher text to calculate plaintext. */
13311
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
13312
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
13313
            /* Update count of the block used. */
13314
            aes->cOver = (byte)partial;
13315
        }
13316
    }
13317
13318
    return 0;
13319
}
13320
13321
/* Finalize the AES GCM for decryption and check the authentication tag.
13322
 *
13323
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
13324
 *
13325
 * @param [in, out] aes        AES object.
13326
 * @param [in]      authTag    Buffer holding authentication tag.
13327
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13328
 * @return  0 on success.
13329
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
13330
 *          value.
13331
 */
13332
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_AARCH64(
13333
    Aes* aes, const byte* authTag, word32 authTagSz)
13334
{
13335
    int ret = 0;
13336
    int res;
13337
    /* AAD block incomplete when > 0 */
13338
    byte over = aes->aOver;
13339
    byte *lastBlock = AES_LASTGBLOCK(aes);
13340
13341
    ASSERT_SAVED_VECTOR_REGISTERS();
13342
13343
    if (aes->cOver > 0) {
13344
        /* Cipher text block incomplete. */
13345
        over = aes->cOver;
13346
        lastBlock = AES_LASTBLOCK(aes);
13347
    }
13348
    if (over > 0) {
13349
        /* Zeroize the unused part of the block. */
13350
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
13351
        /* Hash the last block of cipher text. */
13352
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13353
        if (aes->use_sha3_hw_crypto) {
13354
            AES_GCM_ghash_block_AARCH64_EOR3(lastBlock, AES_TAG(aes),
13355
                aes->gcm.H);
13356
        }
13357
        else
13358
    #endif
13359
        {
13360
            AES_GCM_ghash_block_AARCH64(lastBlock, AES_TAG(aes), aes->gcm.H);
13361
        }
13362
    }
13363
    /* Calculate and compare the authentication tag. */
13364
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13365
    if (aes->use_sha3_hw_crypto) {
13366
        AES_GCM_decrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
13367
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13368
    }
13369
    else
13370
#endif
13371
    {
13372
        AES_GCM_decrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
13373
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13374
    }
13375
13376
    /* Return error code when calculated doesn't match input. */
13377
    if (res == 0) {
13378
        ret = AES_GCM_AUTH_E;
13379
    }
13380
    return ret;
13381
}
13382
#endif
13383
#endif
13384
13385
/* Initialize an AES GCM cipher for encryption or decryption.
13386
 *
13387
 * Must call wc_AesInit() before calling this function.
13388
 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
13389
 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
13390
 *
13391
 * @param [in, out] aes   AES object.
13392
 * @param [in]      key   Buffer holding key.
13393
 * @param [in]      len   Length of key in bytes.
13394
 * @param [in]      iv    Buffer holding IV/nonce.
13395
 * @param [in]      ivSz  Length of IV/nonce in bytes.
13396
 * @return  0 on success.
13397
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
13398
 *          is NULL, or the IV is NULL and no previous IV has been set.
13399
 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
13400
 */
13401
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
13402
    word32 ivSz)
13403
{
13404
    int ret = 0;
13405
13406
    /* Check validity of parameters. */
13407
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
13408
            ((ivSz == 0) && (iv != NULL)) ||
13409
            ((ivSz > 0) && (iv == NULL))) {
13410
        ret = BAD_FUNC_ARG;
13411
    }
13412
13413
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
13414
    if ((ret == 0) && (aes->streamData == NULL)) {
13415
        /* Allocate buffers for streaming. */
13416
        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
13417
        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
13418
                                                              DYNAMIC_TYPE_AES);
13419
        if (aes->streamData == NULL) {
13420
            ret = MEMORY_E;
13421
        }
13422
    }
13423
#endif
13424
13425
    /* Set the key if passed in. */
13426
    if ((ret == 0) && (key != NULL)) {
13427
        ret = wc_AesGcmSetKey(aes, key, len);
13428
    }
13429
13430
    if (ret == 0) {
13431
        /* Set the IV passed in if it is smaller than a block. */
13432
        if ((iv != NULL) && (ivSz <= WC_AES_BLOCK_SIZE)) {
13433
            XMEMMOVE((byte*)aes->reg, iv, ivSz);
13434
            aes->nonceSz = ivSz;
13435
        }
13436
        /* No IV passed in, check for cached IV. */
13437
        if ((iv == NULL) && (aes->nonceSz != 0)) {
13438
            /* Use the cached copy. */
13439
            iv = (byte*)aes->reg;
13440
            ivSz = aes->nonceSz;
13441
        }
13442
13443
        if (iv != NULL) {
13444
            /* Initialize with the IV. */
13445
13446
        #ifdef WOLFSSL_AESNI
13447
            if (aes->use_aesni) {
13448
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
13449
                ret = AesGcmInit_aesni(aes, iv, ivSz);
13450
                RESTORE_VECTOR_REGISTERS();
13451
            }
13452
            else
13453
        #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13454
              !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13455
            if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
13456
                ret = AesGcmInit_AARCH64(aes, iv, ivSz);
13457
            }
13458
            else
13459
        #endif /* WOLFSSL_AESNI */
13460
            {
13461
                ret = AesGcmInit_C(aes, iv, ivSz);
13462
            }
13463
13464
            if (ret == 0)
13465
                aes->nonceSet = 1;
13466
        }
13467
    }
13468
13469
    return ret;
13470
}
13471
13472
/* Initialize an AES GCM cipher for encryption.
13473
 *
13474
 * Must call wc_AesInit() before calling this function.
13475
 *
13476
 * @param [in, out] aes   AES object.
13477
 * @param [in]      key   Buffer holding key.
13478
 * @param [in]      len   Length of key in bytes.
13479
 * @param [in]      iv    Buffer holding IV/nonce.
13480
 * @param [in]      ivSz  Length of IV/nonce in bytes.
13481
 * @return  0 on success.
13482
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
13483
 *          is NULL, or the IV is NULL and no previous IV has been set.
13484
 */
13485
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
13486
    word32 ivSz)
13487
{
13488
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
13489
}
13490
13491
/* Initialize an AES GCM cipher for encryption. Get IV.
13492
 *
13493
 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
13494
 * function.
13495
 * Must call wc_AesInit() before calling this function.
13496
 *
13497
 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
13498
 *
13499
 * @param [in, out] aes   AES object.
13500
 * @param [in]      key   Buffer holding key.
13501
 * @param [in]      len   Length of key in bytes.
13502
 * @param [in]      iv    Buffer holding IV/nonce.
13503
 * @param [in]      ivSz  Length of IV/nonce in bytes.
13504
 * @return  0 on success.
13505
 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
13506
 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
13507
 *          nonce size.
13508
 */
13509
int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
13510
    word32 ivOutSz)
13511
{
13512
    int ret;
13513
13514
    /* Check validity of parameters. */
13515
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
13516
        ret = BAD_FUNC_ARG;
13517
    }
13518
    else {
13519
        /* Copy out the IV including generated part for decryption. */
13520
        XMEMCPY(ivOut, aes->reg, ivOutSz);
13521
        /* Initialize AES GCM cipher with key and cached Iv. */
13522
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
13523
    }
13524
13525
    return ret;
13526
}
13527
13528
/* Update the AES GCM for encryption with data and/or authentication data. */
13529
int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
13530
    const byte* authIn, word32 authInSz)
13531
{
13532
    int ret = 0;
13533
13534
    /* Check validity of parameters. */
13535
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
13536
            ((out == NULL) || (in == NULL)))) {
13537
        ret = BAD_FUNC_ARG;
13538
    }
13539
13540
    /* Check key has been set. */
13541
    if ((ret == 0) && (!aes->gcmKeySet)) {
13542
        ret = MISSING_KEY;
13543
    }
13544
    /* Check IV has been set. */
13545
    if ((ret == 0) && (!aes->nonceSet)) {
13546
        ret = MISSING_IV;
13547
    }
13548
13549
    /* Prevent overflow of aes->cSz and ->aSz.  Per NIST SP 800-38D section
13550
     * 5.2.1.1, the maximum allowed ciphertext limit is 2^32 - 2 blocks, but we
13551
     * currently pass around the cumulative sizes in bytes as word32s, so we
13552
     * can't currently support the maximum allowed.
13553
     */
13554
    if ((ret == 0) &&
13555
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
13556
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
13557
    {
13558
        ret = AES_GCM_OVERFLOW_E;
13559
    }
13560
13561
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
13562
        aes->invokeCtr[0]++;
13563
        if (aes->invokeCtr[0] == 0) {
13564
            aes->invokeCtr[1]++;
13565
            if (aes->invokeCtr[1] == 0)
13566
                ret = AES_GCM_OVERFLOW_E;
13567
        }
13568
    }
13569
13570
    if (ret == 0) {
13571
        /* Encrypt with AAD and/or plaintext. */
13572
13573
    #ifdef WOLFSSL_AESNI
13574
        if (aes->use_aesni) {
13575
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13576
            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
13577
            RESTORE_VECTOR_REGISTERS();
13578
        }
13579
        else
13580
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13581
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13582
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
13583
            ret = AesGcmEncryptUpdate_AARCH64(aes, out, in, sz, authIn,
13584
                authInSz);
13585
        }
13586
        else
13587
    #endif
13588
        {
13589
            /* Encrypt the plaintext. */
13590
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
13591
            if (ret == 0) {
13592
                /* Update the authentication tag with any authentication data and the
13593
                 * new cipher text. */
13594
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
13595
            }
13596
        }
13597
    }
13598
13599
    return ret;
13600
}
13601
13602
/* Finalize the AES GCM for encryption and return the authentication tag.
13603
 *
13604
 * Must set key and IV before calling this function.
13605
 * Must call wc_AesGcmInit() before calling this function.
13606
 *
13607
 * @param [in, out] aes        AES object.
13608
 * @param [out]     authTag    Buffer to hold authentication tag.
13609
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13610
 * @return  0 on success.
13611
 */
13612
int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
13613
{
13614
    int ret = 0;
13615
13616
    /* Check validity of parameters. */
13617
    if ((aes == NULL) || (authTag == NULL)) {
13618
        ret = BAD_FUNC_ARG;
13619
    }
13620
13621
    if (ret == 0)
13622
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
13623
13624
    /* Check key has been set. */
13625
    if ((ret == 0) && (!aes->gcmKeySet)) {
13626
        ret = MISSING_KEY;
13627
    }
13628
    /* Check IV has been set. */
13629
    if ((ret == 0) && (!aes->nonceSet)) {
13630
        ret = MISSING_IV;
13631
    }
13632
13633
    if (ret == 0) {
13634
        /* Calculate authentication tag. */
13635
    #ifdef WOLFSSL_AESNI
13636
        if (aes->use_aesni) {
13637
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13638
            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
13639
            RESTORE_VECTOR_REGISTERS();
13640
        }
13641
        else
13642
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13643
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13644
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
13645
            ret = AesGcmEncryptFinal_AARCH64(aes, authTag, authTagSz);
13646
        }
13647
        else
13648
    #endif
13649
        {
13650
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
13651
        }
13652
    }
13653
13654
    if ((ret == 0) && aes->ctrSet) {
13655
        IncCtr((byte*)aes->reg, aes->nonceSz);
13656
    }
13657
13658
    return ret;
13659
}
13660
13661
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
13662
/* Initialize an AES GCM cipher for decryption.
13663
 *
13664
 * Must call wc_AesInit() before calling this function.
13665
 *
13666
 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
13667
 * instead.
13668
 *
13669
 * @param [in, out] aes   AES object.
13670
 * @param [in]      key   Buffer holding key.
13671
 * @param [in]      len   Length of key in bytes.
13672
 * @param [in]      iv    Buffer holding IV/nonce.
13673
 * @param [in]      ivSz  Length of IV/nonce in bytes.
13674
 * @return  0 on success.
13675
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
13676
 *          is NULL, or the IV is NULL and no previous IV has been set.
13677
 */
13678
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
13679
    word32 ivSz)
13680
{
13681
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
13682
}
13683
13684
/* Update the AES GCM for decryption with data and/or authentication data. */
13685
int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
13686
    const byte* authIn, word32 authInSz)
13687
{
13688
    int ret = 0;
13689
13690
    /* Check validity of parameters. */
13691
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
13692
            ((out == NULL) || (in == NULL)))) {
13693
        ret = BAD_FUNC_ARG;
13694
    }
13695
13696
    /* Check key has been set. */
13697
    if ((ret == 0) && (!aes->gcmKeySet)) {
13698
        ret = MISSING_KEY;
13699
    }
13700
    /* Check IV has been set. */
13701
    if ((ret == 0) && (!aes->nonceSet)) {
13702
        ret = MISSING_IV;
13703
    }
13704
13705
    /* Prevent overflow of aes->cSz and ->aSz.  Per NIST SP 800-38D section
13706
     * 5.2.1.1, the maximum allowed ciphertext limit is 2^32 - 2 blocks, but we
13707
     * currently pass around the cumulative sizes in bytes as word32s, so we
13708
     * can't currently support the maximum allowed.
13709
     */
13710
    if ((ret == 0) &&
13711
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
13712
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
13713
    {
13714
        ret = AES_GCM_OVERFLOW_E;
13715
    }
13716
13717
    if (ret == 0) {
13718
        /* Decrypt with AAD and/or cipher text. */
13719
    #ifdef WOLFSSL_AESNI
13720
        if (aes->use_aesni) {
13721
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13722
            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
13723
            RESTORE_VECTOR_REGISTERS();
13724
        }
13725
        else
13726
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13727
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13728
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
13729
            ret = AesGcmDecryptUpdate_AARCH64(aes, out, in, sz, authIn,
13730
                authInSz);
13731
        }
13732
        else
13733
    #endif
13734
        {
13735
            /* Update the authentication tag with any authentication data and
13736
             * cipher text. */
13737
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
13738
            /* Decrypt the cipher text. */
13739
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
13740
        }
13741
    }
13742
13743
    return ret;
13744
}
13745
13746
/* Finalize the AES GCM for decryption and check the authentication tag.
13747
 *
13748
 * Must set key and IV before calling this function.
13749
 * Must call wc_AesGcmInit() before calling this function.
13750
 *
13751
 * @param [in, out] aes        AES object.
13752
 * @param [in]      authTag    Buffer holding authentication tag.
13753
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13754
 * @return  0 on success.
13755
 */
13756
int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
13757
{
13758
    int ret = 0;
13759
13760
    /* Check validity of parameters. */
13761
    if ((aes == NULL) || (authTag == NULL)) {
13762
        ret = BAD_FUNC_ARG;
13763
    }
13764
13765
    if (ret == 0)
13766
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
13767
13768
    /* Check key has been set. */
13769
    if ((ret == 0) && (!aes->gcmKeySet)) {
13770
        ret = MISSING_KEY;
13771
    }
13772
    /* Check IV has been set. */
13773
    if ((ret == 0) && (!aes->nonceSet)) {
13774
        ret = MISSING_IV;
13775
    }
13776
13777
    if (ret == 0) {
13778
        /* Calculate authentication tag and compare with one passed in.. */
13779
    #ifdef WOLFSSL_AESNI
13780
        if (aes->use_aesni) {
13781
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13782
            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
13783
            RESTORE_VECTOR_REGISTERS();
13784
        }
13785
        else
13786
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13787
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13788
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
13789
            ret = AesGcmDecryptFinal_AARCH64(aes, authTag, authTagSz);
13790
        }
13791
        else
13792
    #endif
13793
        {
13794
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
13795
            /* Calculate authentication tag. */
13796
            ret = AesGcmFinal_C(aes, calcTag, WC_AES_BLOCK_SIZE);
13797
            if (ret == 0) {
13798
                /* Check calculated tag matches the one passed in. */
13799
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
13800
                    ret = AES_GCM_AUTH_E;
13801
                }
13802
            }
13803
        }
13804
    }
13805
13806
    return ret;
13807
}
13808
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
13809
#endif /* WOLFSSL_AESGCM_STREAM */
13810
#endif /* WOLFSSL_XILINX_CRYPT */
13811
#endif /* end of block for AESGCM implementation selection */
13812
13813
13814
/* Common to all, abstract functions that build off of lower level AESGCM
13815
 * functions */
13816
#ifndef WC_NO_RNG
13817
13818
0
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
13819
0
    return (ivSz == GCM_NONCE_MIN_SZ ||
13820
0
            ivSz == GCM_NONCE_MID_SZ ||
13821
0
            ivSz == GCM_NONCE_MAX_SZ);
13822
0
}
13823
13824
13825
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
13826
0
{
13827
0
    int ret = 0;
13828
13829
0
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
13830
0
        ret = BAD_FUNC_ARG;
13831
0
    }
13832
13833
0
    if (ret == 0) {
13834
0
        XMEMCPY((byte*)aes->reg, iv, ivSz);
13835
13836
        /* If the IV is 96, allow for a 2^64 invocation counter.
13837
         * For any other size for the nonce, limit the invocation
13838
         * counter to 32-bits. (SP 800-38D 8.3) */
13839
0
        aes->invokeCtr[0] = 0;
13840
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
13841
    #ifdef WOLFSSL_AESGCM_STREAM
13842
        aes->ctrSet = 1;
13843
    #endif
13844
0
        aes->nonceSz = ivSz;
13845
0
    }
13846
13847
0
    return ret;
13848
0
}
13849
13850
13851
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
13852
                   const byte* ivFixed, word32 ivFixedSz,
13853
                   WC_RNG* rng)
13854
0
{
13855
0
    int ret = 0;
13856
13857
0
    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
13858
0
        (ivFixed == NULL && ivFixedSz != 0) ||
13859
0
        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
13860
13861
0
        ret = BAD_FUNC_ARG;
13862
0
    }
13863
13864
0
    if (ret == 0) {
13865
0
        byte* iv = (byte*)aes->reg;
13866
13867
0
        if (ivFixedSz)
13868
0
            XMEMCPY(iv, ivFixed, ivFixedSz);
13869
13870
0
        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
13871
0
    }
13872
13873
0
    if (ret == 0) {
13874
        /* If the IV is 96, allow for a 2^64 invocation counter.
13875
         * For any other size for the nonce, limit the invocation
13876
         * counter to 32-bits. (SP 800-38D 8.3) */
13877
0
        aes->invokeCtr[0] = 0;
13878
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
13879
    #ifdef WOLFSSL_AESGCM_STREAM
13880
        aes->ctrSet = 1;
13881
    #endif
13882
0
        aes->nonceSz = ivSz;
13883
0
    }
13884
13885
0
    return ret;
13886
0
}
13887
13888
13889
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
13890
                        byte* ivOut, word32 ivOutSz,
13891
                        byte* authTag, word32 authTagSz,
13892
                        const byte* authIn, word32 authInSz)
13893
0
{
13894
0
    int ret = 0;
13895
13896
0
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
13897
0
        ivOut == NULL || ivOutSz != aes->nonceSz ||
13898
0
        (authIn == NULL && authInSz != 0)) {
13899
13900
0
        ret = BAD_FUNC_ARG;
13901
0
    }
13902
13903
0
    if (ret == 0) {
13904
0
        aes->invokeCtr[0]++;
13905
0
        if (aes->invokeCtr[0] == 0) {
13906
0
            aes->invokeCtr[1]++;
13907
0
            if (aes->invokeCtr[1] == 0)
13908
0
                ret = AES_GCM_OVERFLOW_E;
13909
0
        }
13910
0
    }
13911
13912
0
    if (ret == 0) {
13913
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
13914
0
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
13915
0
                               (byte*)aes->reg, ivOutSz,
13916
0
                               authTag, authTagSz,
13917
0
                               authIn, authInSz);
13918
0
        if (ret == 0)
13919
0
            IncCtr((byte*)aes->reg, ivOutSz);
13920
0
    }
13921
13922
0
    return ret;
13923
0
}
13924
13925
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
13926
            const byte* authIn, word32 authInSz,
13927
            byte* authTag, word32 authTagSz, WC_RNG* rng)
13928
0
{
13929
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
13930
0
    int ret;
13931
13932
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
13933
0
        authTag == NULL || authTagSz == 0 || rng == NULL) {
13934
13935
0
        return BAD_FUNC_ARG;
13936
0
    }
13937
13938
#ifdef WOLFSSL_SMALL_STACK
13939
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
13940
#else
13941
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
13942
0
#endif
13943
0
    if (ret != 0)
13944
0
        return ret;
13945
13946
0
    ret = wc_AesGcmSetKey(aes, key, keySz);
13947
0
    if (ret == 0)
13948
0
        ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
13949
0
    if (ret == 0)
13950
0
        ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
13951
0
                                  authTag, authTagSz, authIn, authInSz);
13952
13953
#ifdef WOLFSSL_SMALL_STACK
13954
    wc_AesDelete(aes, NULL);
13955
#else
13956
0
    wc_AesFree(aes);
13957
0
#endif
13958
13959
0
    return ret;
13960
0
}
13961
13962
int wc_GmacVerify(const byte* key, word32 keySz,
13963
                  const byte* iv, word32 ivSz,
13964
                  const byte* authIn, word32 authInSz,
13965
                  const byte* authTag, word32 authTagSz)
13966
0
{
13967
0
    int ret;
13968
0
#ifdef HAVE_AES_DECRYPT
13969
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
13970
13971
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
13972
0
        authTag == NULL || authTagSz == 0 || authTagSz > WC_AES_BLOCK_SIZE) {
13973
13974
0
        return BAD_FUNC_ARG;
13975
0
    }
13976
13977
#ifdef WOLFSSL_SMALL_STACK
13978
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
13979
#else
13980
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
13981
0
#endif
13982
0
    if (ret == 0) {
13983
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
13984
0
        if (ret == 0)
13985
0
            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
13986
0
                                  authTag, authTagSz, authIn, authInSz);
13987
13988
0
    }
13989
#ifdef WOLFSSL_SMALL_STACK
13990
    wc_AesDelete(aes, NULL);
13991
#else
13992
0
    wc_AesFree(aes);
13993
0
#endif
13994
#else
13995
    (void)key;
13996
    (void)keySz;
13997
    (void)iv;
13998
    (void)ivSz;
13999
    (void)authIn;
14000
    (void)authInSz;
14001
    (void)authTag;
14002
    (void)authTagSz;
14003
    ret = NOT_COMPILED_IN;
14004
#endif
14005
0
    return ret;
14006
0
}
14007
14008
#endif /* WC_NO_RNG */
14009
14010
14011
int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
14012
0
{
14013
0
    if (gmac == NULL || key == NULL) {
14014
0
        return BAD_FUNC_ARG;
14015
0
    }
14016
0
    return wc_AesGcmSetKey(&gmac->aes, key, len);
14017
0
}
14018
14019
14020
/* Note, wc_GmacUpdate() is not a streaming API, it's a one-shot calculation of
14021
 * the authTag.
14022
 */
14023
int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
14024
                              const byte* authIn, word32 authInSz,
14025
                              byte* authTag, word32 authTagSz)
14026
0
{
14027
0
    if (gmac == NULL) {
14028
0
        return BAD_FUNC_ARG;
14029
0
    }
14030
14031
0
    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
14032
0
                                         authTag, authTagSz, authIn, authInSz);
14033
0
}
14034
14035
#endif /* HAVE_AESGCM */
14036
14037
#ifdef HAVE_AESCCM
14038
14039
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
14040
{
14041
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
14042
        return BAD_FUNC_ARG;
14043
14044
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
14045
}
14046
14047
14048
/* Checks if the tag size is an accepted value based on RFC 3610 section 2
14049
 * returns 0 if tag size is ok
14050
 */
14051
int wc_AesCcmCheckTagSize(int sz)
14052
{
14053
    /* values here are from RFC 3610 section 2 */
14054
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
14055
            && sz != 16) {
14056
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
14057
        return BAD_FUNC_ARG;
14058
    }
14059
    return 0;
14060
}
14061
14062
#if defined(WOLFSSL_RISCV_ASM)
14063
    /* implementation located in wolfcrypt/src/port/riscv/riscv-64-aes.c */
14064
14065
#elif defined(HAVE_COLDFIRE_SEC)
14066
    #error "Coldfire SEC doesn't currently support AES-CCM mode"
14067
14068
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
14069
        !defined(WOLFSSL_QNX_CAAM)
14070
    /* implemented in wolfcrypt/src/port/caam_aes.c */
14071
14072
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
14073
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
14074
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14075
                   const byte* nonce, word32 nonceSz,
14076
                   byte* authTag, word32 authTagSz,
14077
                   const byte* authIn, word32 authInSz)
14078
{
14079
    return wc_AesCcmEncrypt_silabs(
14080
        aes, out, in, inSz,
14081
        nonce, nonceSz,
14082
        authTag, authTagSz,
14083
        authIn, authInSz);
14084
}
14085
14086
#ifdef HAVE_AES_DECRYPT
14087
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14088
                   const byte* nonce, word32 nonceSz,
14089
                   const byte* authTag, word32 authTagSz,
14090
                   const byte* authIn, word32 authInSz)
14091
{
14092
    return wc_AesCcmDecrypt_silabs(
14093
        aes, out, in, inSz,
14094
        nonce, nonceSz,
14095
        authTag, authTagSz,
14096
        authIn, authInSz);
14097
}
14098
#endif
14099
#elif defined(FREESCALE_LTC)
14100
14101
/* return 0 on success */
14102
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14103
                   const byte* nonce, word32 nonceSz,
14104
                   byte* authTag, word32 authTagSz,
14105
                   const byte* authIn, word32 authInSz)
14106
{
14107
    byte *key;
14108
    word32 keySize;
14109
    status_t status;
14110
14111
    /* sanity check on arguments */
14112
    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
14113
     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
14114
     * don't allow it here either.
14115
     */
14116
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
14117
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
14118
        return BAD_FUNC_ARG;
14119
    }
14120
14121
    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
14122
        return BAD_FUNC_ARG;
14123
    }
14124
14125
    key = (byte*)aes->key;
14126
14127
    status = wc_AesGetKeySize(aes, &keySize);
14128
    if (status != 0) {
14129
        return status;
14130
    }
14131
14132
    {
14133
        word32 lenSz = (word32)WC_AES_BLOCK_SIZE - 1U - nonceSz;
14134
        /* With a large nonce, B[] runs out of room to represent inSz, and beyond
14135
         * that, the counter itself can wrap.
14136
         */
14137
        if ((lenSz < sizeof(inSz)) &&
14138
            (inSz >= ((word32)1 << (lenSz * 8))))
14139
        {
14140
            return AES_CCM_OVERFLOW_E;
14141
        }
14142
    }
14143
14144
    status = wolfSSL_CryptHwMutexLock();
14145
    if (status != 0)
14146
        return status;
14147
14148
    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
14149
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
14150
    wolfSSL_CryptHwMutexUnLock();
14151
14152
    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
14153
}
14154
14155
#ifdef HAVE_AES_DECRYPT
14156
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14157
                   const byte* nonce, word32 nonceSz,
14158
                   const byte* authTag, word32 authTagSz,
14159
                   const byte* authIn, word32 authInSz)
14160
{
14161
    byte *key;
14162
    word32 keySize;
14163
    status_t status;
14164
14165
    /* sanity check on arguments */
14166
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
14167
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
14168
        return BAD_FUNC_ARG;
14169
    }
14170
14171
    key = (byte*)aes->key;
14172
14173
    status = wc_AesGetKeySize(aes, &keySize);
14174
    if (status != 0) {
14175
        return status;
14176
    }
14177
14178
    {
14179
        word32 lenSz = (word32)WC_AES_BLOCK_SIZE - 1U - nonceSz;
14180
        /* With a large nonce, B[] runs out of room to represent inSz, and beyond
14181
         * that, the counter itself can wrap.
14182
         */
14183
        if ((lenSz < sizeof(inSz)) &&
14184
            (inSz >= ((word32)1 << (lenSz * 8))))
14185
        {
14186
            return AES_CCM_OVERFLOW_E;
14187
        }
14188
    }
14189
14190
    status = wolfSSL_CryptHwMutexLock();
14191
    if (status != 0)
14192
        return status;
14193
    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
14194
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
14195
    wolfSSL_CryptHwMutexUnLock();
14196
14197
    if (status != kStatus_Success) {
14198
        XMEMSET(out, 0, inSz);
14199
        return AES_CCM_AUTH_E;
14200
    }
14201
    return 0;
14202
}
14203
#endif /* HAVE_AES_DECRYPT */
14204
14205
#else
14206
14207
/* Software CCM */
14208
static WARN_UNUSED_RESULT int roll_x(
14209
    Aes* aes, const byte* in, word32 inSz, byte* out)
14210
{
14211
    int ret;
14212
14213
    /* process the bulk of the data */
14214
    while (inSz >= WC_AES_BLOCK_SIZE) {
14215
        xorbuf(out, in, WC_AES_BLOCK_SIZE);
14216
        in += WC_AES_BLOCK_SIZE;
14217
        inSz -= WC_AES_BLOCK_SIZE;
14218
14219
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
14220
         * roll_x() after the AES cache lines are already hot -- no need to
14221
         * absorb additional prefetch overhead here.
14222
         */
14223
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
14224
        if (ret != 0)
14225
            return ret;
14226
    }
14227
14228
    /* process remainder of the data */
14229
    if (inSz > 0) {
14230
        xorbuf(out, in, inSz);
14231
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
14232
         * roll_x() after the AES cache lines are already hot -- no need to
14233
         * absorb additional prefetch overhead here.
14234
         */
14235
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
14236
        if (ret != 0)
14237
            return ret;
14238
    }
14239
14240
    return 0;
14241
}
14242
14243
static WARN_UNUSED_RESULT int roll_auth(
14244
    Aes* aes, const byte* in, word32 inSz, byte* out)
14245
{
14246
    word32 authLenSz;
14247
    word32 remainder;
14248
    int ret;
14249
14250
    /* encode the length in */
14251
    if (inSz <= 0xFEFF) {
14252
        authLenSz = 2;
14253
        out[0] ^= (byte)(inSz >> 8);
14254
        out[1] ^= (byte)inSz;
14255
    }
14256
    else {
14257
        authLenSz = 6;
14258
        out[0] ^= 0xFF;
14259
        out[1] ^= 0xFE;
14260
        out[2] ^= (byte)(inSz >> 24);
14261
        out[3] ^= (byte)(inSz >> 16);
14262
        out[4] ^= (byte)(inSz >>  8);
14263
        out[5] ^= (byte)inSz;
14264
    }
14265
    /* Note, the protocol handles auth data up to 2^64, but we are
14266
     * using 32-bit sizes right now, so the bigger data isn't handled
14267
     * else {}
14268
     */
14269
14270
    /* start fill out the rest of the first block */
14271
    remainder = WC_AES_BLOCK_SIZE - authLenSz;
14272
    if (inSz >= remainder) {
14273
        /* plenty of bulk data to fill the remainder of this block */
14274
        xorbuf(out + authLenSz, in, remainder);
14275
        inSz -= remainder;
14276
        in += remainder;
14277
    }
14278
    else {
14279
        /* not enough bulk data, copy what is available, and pad zero */
14280
        xorbuf(out + authLenSz, in, inSz);
14281
        inSz = 0;
14282
    }
14283
    /* wc_AesCcmEncrypt() and wc_AesCcmDecrypt() only call roll_auth() after the
14284
     * AES cache lines are already hot -- no need to absorb additional prefetch
14285
     * overhead here.
14286
     */
14287
    ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
14288
14289
    if ((ret == 0) && (inSz > 0)) {
14290
        ret = roll_x(aes, in, inSz, out);
14291
    }
14292
14293
    return ret;
14294
}
14295
14296
14297
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
14298
{
14299
    word32 i;
14300
14301
    for (i = 0; i < lenSz; i++) {
14302
        if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
14303
    }
14304
}
14305
14306
#ifdef WOLFSSL_AESNI
14307
static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
14308
{
14309
    word32 i;
14310
14311
    /* B+1 = B */
14312
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 1, B, WC_AES_BLOCK_SIZE);
14313
    /* B+2,B+3 = B,B+1 */
14314
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 2, B, WC_AES_BLOCK_SIZE * 2);
14315
14316
    for (i = 0; i < lenSz; i++) {
14317
        if (++B[WC_AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
14318
    }
14319
    B[WC_AES_BLOCK_SIZE * 3 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 3 - 1] + 2U);
14320
    if (B[WC_AES_BLOCK_SIZE * 3 - 1] < 2U) {
14321
        for (i = 1; i < lenSz; i++) {
14322
            if (++B[WC_AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
14323
        }
14324
    }
14325
    B[WC_AES_BLOCK_SIZE * 4 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 4 - 1] + 3U);
14326
    if (B[WC_AES_BLOCK_SIZE * 4 - 1] < 3U) {
14327
        for (i = 1; i < lenSz; i++) {
14328
            if (++B[WC_AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
14329
        }
14330
    }
14331
}
14332
14333
static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
14334
{
14335
    word32 i;
14336
14337
    B[WC_AES_BLOCK_SIZE - 1] = (byte)(B[WC_AES_BLOCK_SIZE - 1] + 4U);
14338
    if (B[WC_AES_BLOCK_SIZE - 1] < 4U) {
14339
        for (i = 1; i < lenSz; i++) {
14340
            if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) break;
14341
        }
14342
    }
14343
}
14344
#endif
14345
14346
/* Software AES - CCM Encrypt */
14347
/* return 0 on success */
14348
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14349
                   const byte* nonce, word32 nonceSz,
14350
                   byte* authTag, word32 authTagSz,
14351
                   const byte* authIn, word32 authInSz)
14352
{
14353
#ifdef WOLFSSL_AESNI
14354
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
14355
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
14356
#else
14357
    byte A[WC_AES_BLOCK_SIZE];
14358
    byte B[WC_AES_BLOCK_SIZE];
14359
#endif
14360
    byte lenSz;
14361
    word32 i;
14362
    byte mask = 0xFF;
14363
    const word32 wordSz = (word32)sizeof(word32);
14364
    int ret;
14365
14366
    /* sanity check on arguments */
14367
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
14368
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
14369
            authTagSz > WC_AES_BLOCK_SIZE)
14370
        return BAD_FUNC_ARG;
14371
14372
    /* Sanity check on authIn to prevent segfault in xorbuf() where
14373
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
14374
    if (authIn == NULL && authInSz > 0)
14375
        return BAD_FUNC_ARG;
14376
14377
    /* sanity check on tag size */
14378
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
14379
        return BAD_FUNC_ARG;
14380
    }
14381
14382
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
14383
14384
    /* With a large nonce, B[] runs out of room to represent inSz, and beyond
14385
     * that, the counter itself can wrap.
14386
     */
14387
    if ((lenSz < sizeof(inSz)) &&
14388
        (inSz >= ((word32)1 << (lenSz * 8))))
14389
    {
14390
        return AES_CCM_OVERFLOW_E;
14391
    }
14392
14393
#ifdef WOLF_CRYPTO_CB
14394
    #ifndef WOLF_CRYPTO_CB_FIND
14395
    if (aes->devId != INVALID_DEVID)
14396
    #endif
14397
    {
14398
        int crypto_cb_ret =
14399
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
14400
                                      authTag, authTagSz, authIn, authInSz);
14401
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
14402
            return crypto_cb_ret;
14403
        /* fall-through when unavailable */
14404
    }
14405
#endif
14406
14407
    XMEMSET(A, 0, sizeof(A));
14408
    XMEMCPY(B+1, nonce, nonceSz);
14409
14410
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
14411
                  + (8 * (((byte)authTagSz - 2) / 2))
14412
                  + (lenSz - 1));
14413
    for (i = 0; i < lenSz; i++) {
14414
        if (mask && i >= wordSz)
14415
            mask = 0x00;
14416
        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
14417
    }
14418
14419
#ifdef WOLFSSL_CHECK_MEM_ZERO
14420
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
14421
#endif
14422
14423
    VECTOR_REGISTERS_PUSH;
14424
    /* note this wc_AesEncrypt() will perform cache prefetches if needed, so
14425
     * that the later encrypt ops don't need to.
14426
     */
14427
    ret = wc_AesEncrypt(aes, B, A);
14428
#ifdef WOLFSSL_CHECK_MEM_ZERO
14429
    if (ret == 0)
14430
        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
14431
#endif
14432
14433
    if ((ret == 0) && (authInSz > 0))
14434
        ret = roll_auth(aes, authIn, authInSz, A);
14435
14436
    if ((ret == 0) && (inSz > 0))
14437
        ret = roll_x(aes, in, inSz, A);
14438
14439
    if (ret == 0) {
14440
        XMEMCPY(authTag, A, authTagSz);
14441
14442
        B[0] = (byte)(lenSz - 1U);
14443
        for (i = 0; i < lenSz; i++)
14444
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
14445
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
14446
    }
14447
14448
    if (ret == 0) {
14449
        xorbuf(authTag, A, authTagSz);
14450
        B[15] = 1;
14451
    }
14452
#ifdef WOLFSSL_AESNI
14453
    if ((ret == 0) && aes->use_aesni) {
14454
        while (inSz >= WC_AES_BLOCK_SIZE * 4) {
14455
            AesCcmCtrIncSet4(B, lenSz);
14456
14457
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
14458
                            (int)aes->rounds);
14459
14460
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
14461
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE * 4);
14462
14463
            inSz -= WC_AES_BLOCK_SIZE * 4;
14464
            in += WC_AES_BLOCK_SIZE * 4;
14465
            out += WC_AES_BLOCK_SIZE * 4;
14466
14467
            AesCcmCtrInc4(B, lenSz);
14468
        }
14469
    }
14470
#endif
14471
    if (ret == 0) {
14472
        while (inSz >= WC_AES_BLOCK_SIZE) {
14473
            ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
14474
            if (ret != 0)
14475
                break;
14476
            xorbuf(A, in, WC_AES_BLOCK_SIZE);
14477
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
14478
14479
            AesCcmCtrInc(B, lenSz);
14480
            inSz -= WC_AES_BLOCK_SIZE;
14481
            in += WC_AES_BLOCK_SIZE;
14482
            out += WC_AES_BLOCK_SIZE;
14483
        }
14484
    }
14485
    if ((ret == 0) && (inSz > 0)) {
14486
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
14487
    }
14488
    if ((ret == 0) && (inSz > 0)) {
14489
        xorbuf(A, in, inSz);
14490
        XMEMCPY(out, A, inSz);
14491
    }
14492
14493
    ForceZero(A, sizeof(A));
14494
    ForceZero(B, sizeof(B));
14495
14496
#ifdef WOLFSSL_CHECK_MEM_ZERO
14497
    wc_MemZero_Check(A, sizeof(A));
14498
    wc_MemZero_Check(B, sizeof(B));
14499
#endif
14500
14501
    VECTOR_REGISTERS_POP;
14502
14503
    return ret;
14504
}
14505
14506
#ifdef HAVE_AES_DECRYPT
14507
/* Software AES - CCM Decrypt */
14508
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14509
                   const byte* nonce, word32 nonceSz,
14510
                   const byte* authTag, word32 authTagSz,
14511
                   const byte* authIn, word32 authInSz)
14512
{
14513
#ifdef WOLFSSL_AESNI
14514
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
14515
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
14516
#else
14517
    byte A[WC_AES_BLOCK_SIZE];
14518
    byte B[WC_AES_BLOCK_SIZE];
14519
#endif
14520
    byte* o;
14521
    byte lenSz;
14522
    word32 i, oSz;
14523
    byte mask = 0xFF;
14524
    const word32 wordSz = (word32)sizeof(word32);
14525
    int ret = 0;
14526
#ifdef WC_AES_HAVE_PREFETCH_ARG
14527
    int did_prefetches = 0;
14528
#endif
14529
14530
    /* sanity check on arguments */
14531
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
14532
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
14533
        authTagSz > WC_AES_BLOCK_SIZE)
14534
        return BAD_FUNC_ARG;
14535
14536
    /* Sanity check on authIn to prevent segfault in xorbuf() where
14537
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
14538
    if (authIn == NULL && authInSz > 0)
14539
        return BAD_FUNC_ARG;
14540
14541
    /* sanity check on tag size */
14542
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
14543
        return BAD_FUNC_ARG;
14544
    }
14545
14546
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
14547
14548
    /* With a large nonce, B[] runs out of room to represent inSz, and beyond
14549
     * that, the counter itself can wrap.
14550
     */
14551
    if ((lenSz < sizeof(inSz)) &&
14552
        (inSz >= ((word32)1 << (lenSz * 8))))
14553
    {
14554
        return AES_CCM_OVERFLOW_E;
14555
    }
14556
14557
#ifdef WOLF_CRYPTO_CB
14558
    #ifndef WOLF_CRYPTO_CB_FIND
14559
    if (aes->devId != INVALID_DEVID)
14560
    #endif
14561
    {
14562
        int crypto_cb_ret =
14563
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
14564
            authTag, authTagSz, authIn, authInSz);
14565
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
14566
            return crypto_cb_ret;
14567
        /* fall-through when unavailable */
14568
    }
14569
#endif
14570
14571
    o = out;
14572
    oSz = inSz;
14573
    XMEMSET(A, 0, sizeof A);
14574
    XMEMCPY(B+1, nonce, nonceSz);
14575
14576
    B[0] = (byte)(lenSz - 1U);
14577
    for (i = 0; i < lenSz; i++)
14578
        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
14579
    B[15] = 1;
14580
14581
#ifdef WOLFSSL_CHECK_MEM_ZERO
14582
    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
14583
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
14584
#endif
14585
14586
    VECTOR_REGISTERS_PUSH;
14587
14588
#ifdef WOLFSSL_AESNI
14589
    if (aes->use_aesni) {
14590
        while (oSz >= WC_AES_BLOCK_SIZE * 4) {
14591
            AesCcmCtrIncSet4(B, lenSz);
14592
14593
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
14594
                            (int)aes->rounds);
14595
14596
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
14597
            XMEMCPY(o, A, WC_AES_BLOCK_SIZE * 4);
14598
14599
            oSz -= WC_AES_BLOCK_SIZE * 4;
14600
            in += WC_AES_BLOCK_SIZE * 4;
14601
            o += WC_AES_BLOCK_SIZE * 4;
14602
14603
            AesCcmCtrInc4(B, lenSz);
14604
        }
14605
    }
14606
#endif
14607
14608
    while (oSz >= WC_AES_BLOCK_SIZE) {
14609
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
14610
        if (ret != 0)
14611
            break;
14612
        xorbuf(A, in, WC_AES_BLOCK_SIZE);
14613
        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
14614
        AesCcmCtrInc(B, lenSz);
14615
        oSz -= WC_AES_BLOCK_SIZE;
14616
        in += WC_AES_BLOCK_SIZE;
14617
        o += WC_AES_BLOCK_SIZE;
14618
    }
14619
14620
    if ((ret == 0) && (inSz > 0))
14621
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
14622
14623
    if ((ret == 0) && (inSz > 0)) {
14624
        xorbuf(A, in, oSz);
14625
        XMEMCPY(o, A, oSz);
14626
        for (i = 0; i < lenSz; i++)
14627
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
14628
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
14629
    }
14630
14631
    if (ret == 0) {
14632
        o = out;
14633
        oSz = inSz;
14634
14635
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
14636
                      + (8 * (((byte)authTagSz - 2) / 2))
14637
                      + (lenSz - 1));
14638
        for (i = 0; i < lenSz; i++) {
14639
            if (mask && i >= wordSz)
14640
                mask = 0x00;
14641
            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
14642
        }
14643
14644
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
14645
    }
14646
14647
    if (ret == 0) {
14648
        if (authInSz > 0)
14649
            ret = roll_auth(aes, authIn, authInSz, A);
14650
    }
14651
    if ((ret == 0) && (inSz > 0))
14652
        ret = roll_x(aes, o, oSz, A);
14653
14654
    if (ret == 0) {
14655
        B[0] = (byte)(lenSz - 1U);
14656
        for (i = 0; i < lenSz; i++)
14657
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
14658
        ret = AesEncrypt_preFetchOpt(aes, B, B, &did_prefetches);
14659
    }
14660
14661
    if (ret == 0)
14662
        xorbuf(A, B, authTagSz);
14663
14664
    if (ret == 0) {
14665
        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
14666
            /* If the authTag check fails, don't keep the decrypted data.
14667
             * Unfortunately, you need the decrypted data to calculate the
14668
             * check value. */
14669
            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
14670
                        defined(ACVP_VECTOR_TESTING)
14671
            WOLFSSL_MSG("Preserve output for vector responses");
14672
            #else
14673
            if (inSz > 0)
14674
                XMEMSET(out, 0, inSz);
14675
            #endif
14676
            ret = AES_CCM_AUTH_E;
14677
        }
14678
    }
14679
14680
    ForceZero(A, sizeof(A));
14681
    ForceZero(B, sizeof(B));
14682
    o = NULL;
14683
14684
#ifdef WOLFSSL_CHECK_MEM_ZERO
14685
    wc_MemZero_Check(A, sizeof(A));
14686
    wc_MemZero_Check(B, sizeof(B));
14687
#endif
14688
14689
    VECTOR_REGISTERS_POP;
14690
14691
    return ret;
14692
}
14693
14694
#endif /* HAVE_AES_DECRYPT */
14695
#endif /* software CCM */
14696
14697
/* abstract functions that call lower level AESCCM functions */
14698
#ifndef WC_NO_RNG
14699
14700
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
14701
{
14702
    int ret = 0;
14703
14704
    if (aes == NULL || nonce == NULL ||
14705
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
14706
14707
        ret = BAD_FUNC_ARG;
14708
    }
14709
14710
    if (ret == 0) {
14711
        XMEMCPY(aes->reg, nonce, nonceSz);
14712
        aes->nonceSz = nonceSz;
14713
14714
        /* Invocation counter should be 2^61 */
14715
        aes->invokeCtr[0] = 0;
14716
        aes->invokeCtr[1] = 0xE0000000;
14717
    }
14718
14719
    return ret;
14720
}
14721
14722
14723
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
14724
                        byte* ivOut, word32 ivOutSz,
14725
                        byte* authTag, word32 authTagSz,
14726
                        const byte* authIn, word32 authInSz)
14727
{
14728
    int ret = 0;
14729
14730
    if (aes == NULL || out == NULL ||
14731
        (in == NULL && sz != 0) ||
14732
        ivOut == NULL ||
14733
        (authIn == NULL && authInSz != 0) ||
14734
        (ivOutSz != aes->nonceSz)) {
14735
14736
        ret = BAD_FUNC_ARG;
14737
    }
14738
14739
    if (ret == 0) {
14740
        aes->invokeCtr[0]++;
14741
        if (aes->invokeCtr[0] == 0) {
14742
            aes->invokeCtr[1]++;
14743
            if (aes->invokeCtr[1] == 0)
14744
                ret = AES_CCM_OVERFLOW_E;
14745
        }
14746
    }
14747
14748
    if (ret == 0) {
14749
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
14750
                               (byte*)aes->reg, aes->nonceSz,
14751
                               authTag, authTagSz,
14752
                               authIn, authInSz);
14753
        if (ret == 0) {
14754
            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
14755
            IncCtr((byte*)aes->reg, aes->nonceSz);
14756
        }
14757
    }
14758
14759
    return ret;
14760
}
14761
14762
#endif /* WC_NO_RNG */
14763
14764
#endif /* HAVE_AESCCM */
14765
14766
#ifndef WC_NO_CONSTRUCTORS
14767
14768
0
#define AES_NEW_INIT_PLAIN  0
14769
#ifdef WOLF_PRIVATE_KEY_ID
14770
#define AES_NEW_INIT_ID     1
14771
#define AES_NEW_INIT_LABEL  2
14772
#endif
14773
14774
static Aes* _AesNew_common(void* heap, int devId, int *result_code,
14775
                            int aesInitType, unsigned char* id,
14776
                            int idLen, const char* label)
14777
0
{
14778
0
    int ret;
14779
0
    Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
14780
0
    if (aes == NULL) {
14781
0
        ret = MEMORY_E;
14782
0
    }
14783
0
    else {
14784
0
        switch (aesInitType) {
14785
#ifdef WOLF_PRIVATE_KEY_ID
14786
        case AES_NEW_INIT_ID:
14787
            if (id == NULL || idLen == 0 || label != NULL) {
14788
                ret = BAD_FUNC_ARG;
14789
            }
14790
            else {
14791
                ret = wc_AesInit_Id(aes, id, idLen, heap, devId);
14792
            }
14793
            break;
14794
        case AES_NEW_INIT_LABEL:
14795
            if (label == NULL || id != NULL || idLen != 0) {
14796
                ret = BAD_FUNC_ARG;
14797
            }
14798
            else {
14799
                ret = wc_AesInit_Label(aes, label, heap, devId);
14800
            }
14801
            break;
14802
#endif
14803
0
        default:
14804
0
            if (id != NULL || idLen != 0 || label != NULL) {
14805
0
                ret = BAD_FUNC_ARG;
14806
0
            }
14807
0
            else {
14808
0
                ret = wc_AesInit(aes, heap, devId);
14809
0
            }
14810
0
            break;
14811
0
        }
14812
0
        if (ret != 0) {
14813
0
            XFREE(aes, heap, DYNAMIC_TYPE_AES);
14814
0
            aes = NULL;
14815
0
        }
14816
0
    }
14817
0
    (void)aesInitType;
14818
0
    (void)id;
14819
0
    (void)idLen;
14820
0
    (void)label;
14821
14822
0
    if (result_code != NULL) {
14823
0
        *result_code = ret;
14824
0
    }
14825
14826
0
    return aes;
14827
0
}
14828
14829
Aes* wc_AesNew(void* heap, int devId, int *result_code)
14830
0
{
14831
0
    return _AesNew_common(heap, devId, result_code,
14832
0
                          AES_NEW_INIT_PLAIN, NULL, 0, NULL);
14833
0
}
14834
14835
#ifdef WOLF_PRIVATE_KEY_ID
14836
Aes* wc_AesNew_Id(unsigned char* id, int len, void* heap, int devId,
14837
                   int *result_code)
14838
{
14839
    return _AesNew_common(heap, devId, result_code,
14840
                          AES_NEW_INIT_ID, id, len, NULL);
14841
}
14842
14843
Aes* wc_AesNew_Label(const char* label, void* heap, int devId,
14844
                      int *result_code)
14845
{
14846
    return _AesNew_common(heap, devId, result_code,
14847
                          AES_NEW_INIT_LABEL, NULL, 0, label);
14848
}
14849
#endif /* WOLF_PRIVATE_KEY_ID */
14850
14851
int wc_AesDelete(Aes *aes, Aes** aes_p)
14852
0
{
14853
0
    void* heap;
14854
0
    if (aes == NULL)
14855
0
        return BAD_FUNC_ARG;
14856
0
    heap = aes->heap;
14857
0
    wc_AesFree(aes);
14858
0
    XFREE(aes, heap, DYNAMIC_TYPE_AES);
14859
0
    if (aes_p != NULL)
14860
0
        *aes_p = NULL;
14861
0
    return 0;
14862
0
}
14863
#endif /* !WC_NO_CONSTRUCTORS */
14864
14865
/* Initialize Aes */
14866
int wc_AesInit(Aes* aes, void* heap, int devId)
14867
0
{
14868
0
    int ret = 0;
14869
14870
0
    if (aes == NULL)
14871
0
        return BAD_FUNC_ARG;
14872
14873
0
    XMEMSET(aes, 0, sizeof(*aes));
14874
14875
0
    aes->heap = heap;
14876
14877
#if defined(WOLF_CRYPTO_CB)
14878
    aes->devId = devId;
14879
    aes->devCtx = NULL;
14880
#else
14881
0
    (void)devId;
14882
0
#endif
14883
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
14884
    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
14885
                                                        aes->heap, devId);
14886
#endif /* WOLFSSL_ASYNC_CRYPT */
14887
14888
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
14889
    aes->alFd = WC_SOCK_NOTSET;
14890
    aes->rdFd = WC_SOCK_NOTSET;
14891
#endif
14892
#if defined(WOLFSSL_DEVCRYPTO) && \
14893
   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
14894
    aes->ctx.cfd = -1;
14895
#endif
14896
#if defined(WOLFSSL_IMXRT_DCP)
14897
    DCPAesInit(aes);
14898
#endif
14899
14900
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
14901
    ret = wc_psa_aes_init(aes);
14902
#endif
14903
14904
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
14905
    if (ret == 0)
14906
        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
14907
#endif
14908
14909
0
    return ret;
14910
0
}
14911
14912
#ifdef WOLF_PRIVATE_KEY_ID
14913
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
14914
{
14915
    int ret = 0;
14916
14917
    if (aes == NULL)
14918
        ret = BAD_FUNC_ARG;
14919
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
14920
        ret = BUFFER_E;
14921
14922
    if (ret == 0)
14923
        ret = wc_AesInit(aes, heap, devId);
14924
    if (ret == 0) {
14925
        XMEMCPY(aes->id, id, (size_t)len);
14926
        aes->idLen = len;
14927
        aes->labelLen = 0;
14928
    }
14929
14930
    return ret;
14931
}
14932
14933
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
14934
{
14935
    int ret = 0;
14936
    size_t labelLen = 0;
14937
14938
    if (aes == NULL || label == NULL)
14939
        ret = BAD_FUNC_ARG;
14940
    if (ret == 0) {
14941
        labelLen = XSTRLEN(label);
14942
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
14943
            ret = BUFFER_E;
14944
    }
14945
14946
    if (ret == 0)
14947
        ret = wc_AesInit(aes, heap, devId);
14948
    if (ret == 0) {
14949
        XMEMCPY(aes->label, label, labelLen);
14950
        aes->labelLen = (int)labelLen;
14951
        aes->idLen = 0;
14952
    }
14953
14954
    return ret;
14955
}
14956
#endif
14957
14958
/* Free Aes resources */
14959
void wc_AesFree(Aes* aes)
14960
0
{
14961
0
    if (aes == NULL) {
14962
0
        return;
14963
0
    }
14964
14965
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
14966
    #ifndef WOLF_CRYPTO_CB_FIND
14967
    if (aes->devId != INVALID_DEVID)
14968
    #endif
14969
    {
14970
        int ret = wc_CryptoCb_Free(aes->devId, WC_ALGO_TYPE_CIPHER,
14971
                                   WC_CIPHER_AES, 0, aes);
14972
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
14973
        aes->devCtx = NULL;  /* Clear device context handle */
14974
    #endif
14975
        /* If callback wants standard free, it can set devId to INVALID_DEVID.
14976
         * Otherwise assume the callback handled cleanup. */
14977
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
14978
            return;
14979
        /* fall-through when unavailable */
14980
    }
14981
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
14982
14983
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
14984
    (void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
14985
#endif
14986
14987
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
14988
    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
14989
#endif /* WOLFSSL_ASYNC_CRYPT */
14990
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
14991
    if (aes->rdFd > 0) { /* negative is error case */
14992
        close(aes->rdFd);
14993
        aes->rdFd = WC_SOCK_NOTSET;
14994
    }
14995
    if (aes->alFd > 0) {
14996
        close(aes->alFd);
14997
        aes->alFd = WC_SOCK_NOTSET;
14998
    }
14999
#endif /* WOLFSSL_AFALG */
15000
#ifdef WOLFSSL_KCAPI_AES
15001
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
15002
    if (aes->init == 1) {
15003
        kcapi_cipher_destroy(aes->handle);
15004
    }
15005
    aes->init = 0;
15006
    aes->handle = NULL;
15007
#endif
15008
#if defined(WOLFSSL_DEVCRYPTO) && \
15009
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
15010
    wc_DevCryptoFree(&aes->ctx);
15011
#endif
15012
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
15013
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
15014
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
15015
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
15016
#endif
15017
#if defined(WOLFSSL_IMXRT_DCP)
15018
    DCPAesFree(aes);
15019
#endif
15020
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
15021
    !defined(WOLFSSL_AESNI)
15022
    if (aes->streamData != NULL) {
15023
        ForceZero(aes->streamData, aes->streamData_sz);
15024
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
15025
        aes->streamData = NULL;
15026
    }
15027
#endif
15028
15029
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
15030
    if (aes->useSWCrypt == 0) {
15031
        se050_aes_free(aes);
15032
    }
15033
#endif
15034
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
15035
    wc_Microchip_aes_free(aes);
15036
#endif
15037
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
15038
    wc_psa_aes_free(aes);
15039
#endif
15040
15041
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
15042
    wc_MAXQ10XX_AesFree(aes);
15043
#endif
15044
15045
#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
15046
    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
15047
    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
15048
    wc_fspsm_Aesfree(aes);
15049
#endif
15050
15051
0
    ForceZero(aes, sizeof(Aes));
15052
15053
#ifdef WOLFSSL_CHECK_MEM_ZERO
15054
    wc_MemZero_Check(aes, sizeof(Aes));
15055
#endif
15056
0
}
15057
15058
int wc_AesGetKeySize(Aes* aes, word32* keySize)
15059
0
{
15060
0
    int ret = 0;
15061
15062
0
    if (aes == NULL || keySize == NULL) {
15063
0
        return BAD_FUNC_ARG;
15064
0
    }
15065
15066
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
15067
    return wc_psa_aes_get_key_size(aes, keySize);
15068
#endif
15069
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
15070
    *keySize = aes->ctx.key.keySize;
15071
    return ret;
15072
#endif
15073
0
    switch (aes->rounds) {
15074
0
#ifdef WOLFSSL_AES_128
15075
0
    case 10:
15076
0
        *keySize = 16;
15077
0
        break;
15078
0
#endif
15079
0
#ifdef WOLFSSL_AES_192
15080
0
    case 12:
15081
0
        *keySize = 24;
15082
0
        break;
15083
0
#endif
15084
0
#ifdef WOLFSSL_AES_256
15085
0
    case 14:
15086
0
        *keySize = 32;
15087
0
        break;
15088
0
#endif
15089
0
    default:
15090
0
        *keySize = 0;
15091
0
        ret = BAD_FUNC_ARG;
15092
0
    }
15093
15094
0
    return ret;
15095
0
}
15096
15097
#endif /* !WOLFSSL_TI_CRYPT */
15098
15099
/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
15100
 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
15101
 */
15102
#ifndef VECTOR_REGISTERS_PUSH
15103
    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
15104
#endif
15105
#ifndef VECTOR_REGISTERS_POP
15106
    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
15107
#endif
15108
15109
#ifdef HAVE_AES_ECB
15110
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
15111
        !defined(WOLFSSL_QNX_CAAM)
15112
    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
15113
15114
#elif defined(WOLFSSL_AFALG)
15115
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
15116
15117
#elif defined(WOLFSSL_DEVCRYPTO_AES)
15118
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
15119
15120
#elif defined(WOLFSSL_RISCV_ASM)
15121
    /* implemented in wolfcrypt/src/port/riscv/riscv-64-aes.c */
15122
15123
#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
15124
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
15125
15126
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
15127
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
15128
15129
#elif defined(MAX3266X_AES)
15130
15131
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15132
{
15133
    int status;
15134
    word32 keySize;
15135
15136
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15137
        return BAD_FUNC_ARG;
15138
15139
    status = wc_AesGetKeySize(aes, &keySize);
15140
    if (status != 0) {
15141
        return status;
15142
    }
15143
15144
    status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key,
15145
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
15146
15147
    return status;
15148
}
15149
15150
#ifdef HAVE_AES_DECRYPT
15151
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15152
{
15153
    int status;
15154
    word32 keySize;
15155
15156
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15157
        return BAD_FUNC_ARG;
15158
15159
    status = wc_AesGetKeySize(aes, &keySize);
15160
    if (status != 0) {
15161
        return status;
15162
    }
15163
15164
    status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key,
15165
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
15166
15167
    return status;
15168
}
15169
#endif /* HAVE_AES_DECRYPT */
15170
15171
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
15172
15173
/* Software AES - ECB */
15174
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15175
{
15176
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15177
        return BAD_FUNC_ARG;
15178
15179
    return AES_ECB_encrypt(aes, in, out, sz);
15180
}
15181
15182
15183
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15184
{
15185
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15186
        return BAD_FUNC_ARG;
15187
15188
    return AES_ECB_decrypt(aes, in, out, sz);
15189
}
15190
15191
#elif defined(WOLFSSL_PSOC6_CRYPTO)
15192
15193
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15194
{
15195
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15196
        return BAD_FUNC_ARG;
15197
15198
    return wc_Psoc6_Aes_EcbEncrypt(aes, out, in, sz);
15199
}
15200
15201
#define _AesEcbEncrypt(aes, out, in, sz) wc_AesEcbEncrypt(aes, out, in, sz)
15202
15203
#ifdef HAVE_AES_DECRYPT
15204
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15205
{
15206
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15207
        return BAD_FUNC_ARG;
15208
15209
    return wc_Psoc6_Aes_EcbDecrypt(aes, out, in, sz);
15210
}
15211
15212
#define _AesEcbDecrypt(aes, out, in, sz) wc_AesEcbDecrypt(aes, out, in, sz)
15213
#endif /* HAVE_AES_DECRYPT */
15214
15215
#else
15216
15217
/* Software AES - ECB */
15218
static WARN_UNUSED_RESULT int _AesEcbEncrypt(
15219
    Aes* aes, byte* out, const byte* in, word32 sz)
15220
{
15221
    int ret = 0;
15222
15223
#ifdef WOLF_CRYPTO_CB
15224
    #ifndef WOLF_CRYPTO_CB_FIND
15225
    if (aes->devId != INVALID_DEVID)
15226
    #endif
15227
    {
15228
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
15229
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15230
            return ret;
15231
        ret = 0;
15232
        /* fall-through when unavailable */
15233
    }
15234
#endif
15235
#ifdef WOLF_CRYPTO_CB_ONLY_AES
15236
    /* No software fallback: the per-block loop below would only re-invoke
15237
     * cryptocb ECB and propagate UNAVAILABLE; short-circuit instead. */
15238
    return NO_VALID_DEVID;
15239
#endif
15240
#ifdef WOLFSSL_IMXRT_DCP
15241
    if (aes->keylen == 16)
15242
        return DCPAesEcbEncrypt(aes, out, in, sz);
15243
#endif
15244
15245
    VECTOR_REGISTERS_PUSH;
15246
15247
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15248
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
15249
    AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15250
#else
15251
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
15252
#endif
15253
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15254
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15255
    if (aes->use_aes_hw_crypto) {
15256
        AES_encrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
15257
            (int)aes->rounds);
15258
    }
15259
    else
15260
#endif
15261
#if !defined(WOLFSSL_ARMASM_NO_NEON)
15262
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15263
    if (sz >= 32)
15264
#endif
15265
    {
15266
        AES_ECB_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
15267
            aes->rounds);
15268
    }
15269
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15270
    else
15271
#endif
15272
#endif
15273
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15274
    {
15275
        AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key,
15276
            aes->rounds);
15277
    }
15278
#endif
15279
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
15280
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
15281
    ret = 0;
15282
#else
15283
#ifdef WOLFSSL_AESNI
15284
    if (aes->use_aesni) {
15285
    #ifdef WOLFSSL_X86_64_BUILD
15286
        AesEcbEncryptBlocks(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15287
    #else
15288
        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15289
    #endif
15290
    }
15291
    else
15292
#endif
15293
    {
15294
#if defined(NEED_AES_TABLES)
15295
        AesEncryptBlocks_C(aes, in, out, sz);
15296
#else
15297
        word32 i;
15298
#ifdef WC_AES_HAVE_PREFETCH_ARG
15299
        int did_prefetches = 0;
15300
#endif
15301
15302
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
15303
            ret = AesEncrypt_preFetchOpt(aes, in, out, &did_prefetches);
15304
            if (ret != 0)
15305
                break;
15306
            in += WC_AES_BLOCK_SIZE;
15307
            out += WC_AES_BLOCK_SIZE;
15308
        }
15309
#endif
15310
    }
15311
#endif
15312
15313
    VECTOR_REGISTERS_POP;
15314
15315
    return ret;
15316
}
15317
15318
#ifdef HAVE_AES_DECRYPT
15319
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
15320
    Aes* aes, byte* out, const byte* in, word32 sz)
15321
{
15322
    int ret = 0;
15323
15324
#ifdef WOLF_CRYPTO_CB
15325
    #ifndef WOLF_CRYPTO_CB_FIND
15326
    if (aes->devId != INVALID_DEVID)
15327
    #endif
15328
    {
15329
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
15330
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15331
            return ret;
15332
        ret = 0;
15333
        /* fall-through when unavailable */
15334
    }
15335
#endif
15336
#ifdef WOLF_CRYPTO_CB_ONLY_AES
15337
    return NO_VALID_DEVID;
15338
#endif
15339
#ifdef WOLFSSL_IMXRT_DCP
15340
    if (aes->keylen == 16)
15341
        return DCPAesEcbDecrypt(aes, out, in, sz);
15342
#endif
15343
15344
    VECTOR_REGISTERS_PUSH;
15345
15346
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15347
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
15348
    AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15349
#else
15350
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
15351
#endif
15352
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15353
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15354
    if (aes->use_aes_hw_crypto) {
15355
        AES_decrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
15356
            (int)aes->rounds);
15357
    }
15358
    else
15359
#endif
15360
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
15361
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15362
    if (sz >= 64)
15363
#endif
15364
    {
15365
        AES_ECB_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
15366
            aes->rounds);
15367
    }
15368
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15369
    else
15370
#endif
15371
#endif
15372
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15373
    {
15374
        AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key,
15375
            aes->rounds);
15376
    }
15377
#endif
15378
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
15379
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
15380
    ret = 0;
15381
#else
15382
#ifdef WOLFSSL_AESNI
15383
    if (aes->use_aesni) {
15384
    #ifdef WOLFSSL_X86_64_BUILD
15385
        AesEcbDecryptBlocks(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15386
    #else
15387
        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15388
    #endif
15389
    }
15390
    else
15391
#endif
15392
    {
15393
#if defined(NEED_AES_TABLES)
15394
        AesDecryptBlocks_C(aes, in, out, sz);
15395
#else
15396
        word32 i;
15397
15398
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
15399
            ret = wc_AesDecryptDirect(aes, out, in);
15400
            if (ret != 0)
15401
                break;
15402
            in += WC_AES_BLOCK_SIZE;
15403
            out += WC_AES_BLOCK_SIZE;
15404
        }
15405
#endif
15406
    }
15407
#endif
15408
15409
    VECTOR_REGISTERS_POP;
15410
15411
    return ret;
15412
}
15413
#endif
15414
15415
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15416
{
15417
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15418
      return BAD_FUNC_ARG;
15419
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
15420
        return BAD_LENGTH_E;
15421
    }
15422
15423
    return _AesEcbEncrypt(aes, out, in, sz);
15424
}
15425
15426
#ifdef HAVE_AES_DECRYPT
15427
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15428
{
15429
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15430
      return BAD_FUNC_ARG;
15431
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
15432
        return BAD_LENGTH_E;
15433
    }
15434
15435
    return _AesEcbDecrypt(aes, out, in, sz);
15436
}
15437
#endif /* HAVE_AES_DECRYPT */
15438
#endif
15439
#endif /* HAVE_AES_ECB */
15440
15441
#if defined(WOLFSSL_AES_CFB)
15442
15443
#if defined(WOLFSSL_NXP_HASHCRYPT_AES)
15444
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
15445
15446
#elif defined(WOLFSSL_PSOC6_CRYPTO)
15447
15448
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15449
{
15450
    return wc_Psoc6_Aes_CfbEncrypt(aes, out, in, sz);
15451
}
15452
15453
#ifdef HAVE_AES_DECRYPT
15454
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15455
{
15456
    return wc_Psoc6_Aes_CfbDecrypt(aes, out, in, sz);
15457
}
15458
#endif /* HAVE_AES_DECRYPT */
15459
15460
#else
15461
/* Feedback AES mode
15462
 *
15463
 * aes structure holding key to use for encryption
15464
 * out buffer to hold result of encryption (must be at least as large as input
15465
 *     buffer)
15466
 * in  buffer to encrypt
15467
 * sz  size of input buffer
15468
 * mode flag to specify AES mode
15469
 *
15470
 * returns 0 on success and negative error values on failure
15471
 */
15472
/* Software AES - CFB Encrypt */
15473
static WARN_UNUSED_RESULT int AesCfbEncrypt_C(Aes* aes, byte* out,
15474
    const byte* in, word32 sz)
15475
{
15476
    int ret = 0;
15477
    word32 processed;
15478
#ifdef WC_AES_HAVE_PREFETCH_ARG
15479
    int did_prefetches = 0;
15480
#endif
15481
15482
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
15483
        return BAD_FUNC_ARG;
15484
    }
15485
    if (sz == 0) {
15486
        return 0;
15487
    }
15488
15489
    if (aes->left > 0) {
15490
        /* consume any unused bytes left in aes->tmp */
15491
        processed = min(aes->left, sz);
15492
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
15493
            processed);
15494
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out,
15495
            processed);
15496
        aes->left -= processed;
15497
        out += processed;
15498
        in += processed;
15499
        sz -= processed;
15500
    }
15501
15502
    VECTOR_REGISTERS_PUSH;
15503
15504
    while (sz >= WC_AES_BLOCK_SIZE) {
15505
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
15506
                                        &did_prefetches);
15507
        if (ret != 0) {
15508
            break;
15509
        }
15510
        xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
15511
        XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
15512
        out += WC_AES_BLOCK_SIZE;
15513
        in  += WC_AES_BLOCK_SIZE;
15514
        sz  -= WC_AES_BLOCK_SIZE;
15515
    }
15516
15517
    /* encrypt left over data */
15518
    if ((ret == 0) && sz) {
15519
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
15520
                                     &did_prefetches);
15521
        if (ret == 0) {
15522
            xorbufout(out, in, aes->tmp, sz);
15523
            XMEMCPY(aes->reg, out, sz);
15524
            aes->left = WC_AES_BLOCK_SIZE - sz;
15525
        }
15526
    }
15527
15528
    VECTOR_REGISTERS_POP;
15529
15530
    return ret;
15531
}
15532
15533
15534
#if defined(HAVE_AES_DECRYPT)
15535
/* CFB 128
15536
 *
15537
 * aes structure holding key to use for decryption
15538
 * out buffer to hold result of decryption (must be at least as large as input
15539
 *     buffer)
15540
 * in  buffer to decrypt
15541
 * sz  size of input buffer
15542
 *
15543
 * returns 0 on success and negative error values on failure
15544
 */
15545
/* Software AES - CFB Decrypt */
15546
static WARN_UNUSED_RESULT int AesCfbDecrypt_C(Aes* aes, byte* out,
15547
    const byte* in, word32 sz, byte mode)
15548
{
15549
    int ret = 0;
15550
    word32 processed;
15551
#ifdef WC_AES_HAVE_PREFETCH_ARG
15552
    int did_prefetches = 0;
15553
#endif
15554
#ifndef WC_AES_CFB_DEC_BUF_BLOCKS
15555
    #define WC_AES_CFB_DEC_BUF_BLOCKS 32
15556
#elif WC_AES_CFB_DEC_BUF_BLOCKS < 2
15557
    #error Invalid WC_AES_CFB_DEC_BUF_BLOCKS
15558
#endif
15559
#ifdef WOLFSSL_SMALL_STACK
15560
    byte *tmp = NULL;
15561
#endif
15562
15563
    (void)mode;
15564
15565
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
15566
        return BAD_FUNC_ARG;
15567
    }
15568
    if (sz == 0) {
15569
        return 0;
15570
    }
15571
15572
    if (aes->left > 0) {
15573
        /* consume any unused bytes left in aes->tmp */
15574
        processed = min(aes->left, sz);
15575
        /* copy input over to aes->reg */
15576
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, processed);
15577
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
15578
            processed);
15579
        aes->left -= processed;
15580
        out += processed;
15581
        in += processed;
15582
        sz -= processed;
15583
    }
15584
15585
#if defined(WOLFSSL_SMALL_STACK) && defined(HAVE_AES_ECB) &&    \
15586
    !defined(WOLFSSL_PIC32MZ_CRYPT) &&                          \
15587
    (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
15588
    /* Only suffer the heap overhead if sz is enough to warrant it.
15589
     *
15590
     * Allocate the working buffer before suspending interrupts, so that we can
15591
     * allocate with regular GFP_KERNEL.
15592
     */
15593
    if (sz >= WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE)
15594
        tmp = (byte *)XMALLOC(WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_AES);
15595
15596
    VECTOR_REGISTERS_PUSH2(XFREE(tmp, NULL, DYNAMIC_TYPE_AES););
15597
#else
15598
    VECTOR_REGISTERS_PUSH;
15599
#endif
15600
15601
    #if defined(HAVE_AES_ECB) && \
15602
        !defined(WOLFSSL_PIC32MZ_CRYPT) && \
15603
        (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
15604
#ifdef WOLFSSL_SMALL_STACK
15605
    if (tmp != NULL)
15606
#endif
15607
    {
15608
#ifndef WOLFSSL_SMALL_STACK
15609
        ALIGN16 byte tmp[WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE];
15610
#endif
15611
        if (sz >= 2 * WC_AES_BLOCK_SIZE) {
15612
            /* CFB-decrypt keystream block i is E(C_{i-1}): block 0 uses the
15613
             * feedback register, block i>=1 uses the previous cipher block.  So
15614
             * ECB the ciphertext straight out of 'in' (no shift-copy) to get
15615
             * E(C_0..C_{n-1}), XOR block i with the (i-1)th ECB output, and
15616
             * carry E(C_{n-1}) as the next chunk's block-0 keystream - E(reg)
15617
             * is computed only once here. */
15618
            ALIGN16 byte ks[WC_AES_BLOCK_SIZE];
15619
            ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, ks,
15620
                                         &did_prefetches);
15621
            while ((ret == 0) && (sz >= 2 * WC_AES_BLOCK_SIZE)) {
15622
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
15623
                word32 nbytes;
15624
                if (blocks > WC_AES_CFB_DEC_BUF_BLOCKS)
15625
                    blocks = WC_AES_CFB_DEC_BUF_BLOCKS;
15626
                nbytes = blocks * WC_AES_BLOCK_SIZE;
15627
                /* tmp[i] = E(C_i), read directly from the input. Already inside
15628
                 * VECTOR_REGISTERS_PUSH, so use the inner ECB (no nested
15629
                 * save/restore or re-dispatch) where available. */
15630
            #if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
15631
                if (aes->use_aesni) {
15632
                    AesEcbEncryptBlocks(in, tmp, nbytes, (byte*)aes->key,
15633
                                        (int)aes->rounds);
15634
                }
15635
                else
15636
            #endif
15637
                {
15638
                    ret = wc_AesEcbEncrypt(aes, tmp, in, nbytes);
15639
                    if (ret != 0)
15640
                        break;
15641
                }
15642
                /* Feedback for the tail = last cipher block; save it before the
15643
                 * XOR can overwrite 'in' (in == out case). */
15644
                XMEMCPY((byte*)aes->reg, in + nbytes - WC_AES_BLOCK_SIZE,
15645
                        WC_AES_BLOCK_SIZE);
15646
                /* P_0 = C_0 ^ E(feedback); P_i = C_i ^ E(C_{i-1}) =
15647
                 *       C_i ^ tmp[i-1]. */
15648
                xorbufout(out, in, ks, WC_AES_BLOCK_SIZE);
15649
                xorbufout(out + WC_AES_BLOCK_SIZE, in + WC_AES_BLOCK_SIZE, tmp,
15650
                          nbytes - WC_AES_BLOCK_SIZE);
15651
                /* Carry E(last cipher block) as the next chunk's block-0 KS. */
15652
                XMEMCPY(ks, tmp + nbytes - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
15653
                out += nbytes;
15654
                in  += nbytes;
15655
                sz  -= nbytes;
15656
            }
15657
        }
15658
    }
15659
    #endif
15660
    while (sz >= WC_AES_BLOCK_SIZE) {
15661
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
15662
                                        &did_prefetches);
15663
        if (ret != 0) {
15664
            break;
15665
        }
15666
        XMEMCPY((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
15667
        xorbufout(out, in, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
15668
        out += WC_AES_BLOCK_SIZE;
15669
        in  += WC_AES_BLOCK_SIZE;
15670
        sz  -= WC_AES_BLOCK_SIZE;
15671
    }
15672
15673
    /* decrypt left over data */
15674
    if ((ret == 0) && sz) {
15675
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
15676
                                        &did_prefetches);
15677
        if (ret == 0) {
15678
            XMEMCPY(aes->reg, in, sz);
15679
            xorbufout(out, in, aes->tmp, sz);
15680
            aes->left = WC_AES_BLOCK_SIZE - sz;
15681
        }
15682
    }
15683
15684
    VECTOR_REGISTERS_POP;
15685
15686
#ifdef WOLFSSL_SMALL_STACK
15687
    /* Free tmp after restoring interrupts, so that GFP_KERNEL is usable. */
15688
    XFREE(tmp, NULL, DYNAMIC_TYPE_AES);
15689
#endif
15690
15691
    return ret;
15692
}
15693
#endif /* HAVE_AES_DECRYPT */
15694
15695
/* CFB 128
15696
 *
15697
 * aes structure holding key to use for encryption
15698
 * out buffer to hold result of encryption (must be at least as large as input
15699
 *     buffer)
15700
 * in  buffer to encrypt
15701
 * sz  size of input buffer
15702
 *
15703
 * returns 0 on success and negative error values on failure
15704
 */
15705
/* Software AES - CFB Encrypt */
15706
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15707
{
15708
#ifdef WOLF_CRYPTO_CB
15709
    if (aes == NULL)
15710
        return BAD_FUNC_ARG;
15711
    #ifndef WOLF_CRYPTO_CB_FIND
15712
    if (aes->devId != INVALID_DEVID)
15713
    #endif
15714
    {
15715
        int crypto_cb_ret = wc_CryptoCb_AesCfbEncrypt(aes, out, in, sz);
15716
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15717
            return crypto_cb_ret;
15718
        /* fall-through when unavailable */
15719
    }
15720
#endif
15721
    return AesCfbEncrypt_C(aes, out, in, sz);
15722
}
15723
15724
15725
#ifdef HAVE_AES_DECRYPT
15726
/* CFB 128
15727
 *
15728
 * aes structure holding key to use for decryption
15729
 * out buffer to hold result of decryption (must be at least as large as input
15730
 *     buffer)
15731
 * in  buffer to decrypt
15732
 * sz  size of input buffer
15733
 *
15734
 * returns 0 on success and negative error values on failure
15735
 */
15736
/* Software AES - CFB Decrypt */
15737
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15738
{
15739
#ifdef WOLF_CRYPTO_CB
15740
    if (aes == NULL)
15741
        return BAD_FUNC_ARG;
15742
    #ifndef WOLF_CRYPTO_CB_FIND
15743
    if (aes->devId != INVALID_DEVID)
15744
    #endif
15745
    {
15746
        int crypto_cb_ret = wc_CryptoCb_AesCfbDecrypt(aes, out, in, sz);
15747
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15748
            return crypto_cb_ret;
15749
        /* fall-through when unavailable */
15750
    }
15751
#endif
15752
    return AesCfbDecrypt_C(aes, out, in, sz, AES_CFB_MODE);
15753
}
15754
#endif /* HAVE_AES_DECRYPT */
15755
#endif /* WOLFSSL_PSOC6_CRYPTO */
15756
15757
#ifndef WOLFSSL_NO_AES_CFB_1_8
15758
/* shift the whole WC_AES_BLOCK_SIZE array left by 8 or 1 bits */
15759
static void shiftLeftArray(byte* ary, byte shift)
15760
{
15761
    int i;
15762
15763
    if (shift == WOLFSSL_BIT_SIZE) {
15764
        /* shifting over by 8 bits */
15765
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
15766
            ary[i] = ary[i+1];
15767
        }
15768
        ary[i] = 0;
15769
    }
15770
    else {
15771
        /* shifting over by 7 or less bits */
15772
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
15773
            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
15774
            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
15775
            ary[i] = (byte)((ary[i] << shift) + carry);
15776
        }
15777
        ary[i] = (byte)(ary[i] << shift);
15778
    }
15779
}
15780
15781
15782
/* returns 0 on success and negative values on failure */
15783
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
15784
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
15785
{
15786
    byte *pt;
15787
    int ret = 0;
15788
#ifdef WC_AES_HAVE_PREFETCH_ARG
15789
    int did_prefetches = 0;
15790
#endif
15791
15792
    if (aes == NULL || out == NULL || in == NULL) {
15793
        return BAD_FUNC_ARG;
15794
    }
15795
15796
    if (sz == 0) {
15797
        return 0;
15798
    }
15799
15800
    VECTOR_REGISTERS_PUSH;
15801
15802
    while (sz > 0) {
15803
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
15804
                                        &did_prefetches);
15805
        if (ret != 0)
15806
            break;
15807
        if (dir == AES_DECRYPTION) {
15808
            pt = (byte*)aes->reg;
15809
15810
            /* LSB + CAT */
15811
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
15812
            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
15813
        }
15814
15815
        /* MSB + XOR */
15816
    #ifdef BIG_ENDIAN_ORDER
15817
        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
15818
    #endif
15819
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
15820
        if (dir == AES_ENCRYPTION) {
15821
            pt = (byte*)aes->reg;
15822
15823
            /* LSB + CAT */
15824
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
15825
            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
15826
        }
15827
15828
        out += 1;
15829
        in  += 1;
15830
        sz  -= 1;
15831
    }
15832
15833
    VECTOR_REGISTERS_POP;
15834
15835
    return ret;
15836
}
15837
15838
15839
/* returns 0 on success and negative values on failure */
15840
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
15841
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
15842
{
15843
    byte tmp;
15844
    byte cur = 0; /* hold current work in order to handle inline in=out */
15845
    byte* pt;
15846
    int bit = 7;
15847
    int ret = 0;
15848
#ifdef WC_AES_HAVE_PREFETCH_ARG
15849
    int did_prefetches = 0;
15850
#endif
15851
15852
    if (aes == NULL || out == NULL || in == NULL) {
15853
        return BAD_FUNC_ARG;
15854
    }
15855
15856
    if (sz == 0) {
15857
        return 0;
15858
    }
15859
15860
    VECTOR_REGISTERS_PUSH;
15861
15862
    while (sz > 0) {
15863
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
15864
                                        &did_prefetches);
15865
        if (ret != 0)
15866
            break;
15867
        if (dir == AES_DECRYPTION) {
15868
            pt = (byte*)aes->reg;
15869
15870
            /* LSB + CAT */
15871
            tmp = (byte)((0X01U << bit) & in[0]);
15872
            tmp = (byte)(tmp >> bit);
15873
            tmp &= 0x01;
15874
            shiftLeftArray((byte*)aes->reg, 1);
15875
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
15876
        }
15877
15878
        /* MSB  + XOR */
15879
        tmp = (byte)((0X01U << bit) & in[0]);
15880
        pt = (byte*)aes->tmp;
15881
        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
15882
        tmp &= 0x01;
15883
        cur = (byte)(cur | (tmp << bit));
15884
15885
15886
        if (dir == AES_ENCRYPTION) {
15887
            pt = (byte*)aes->reg;
15888
15889
            /* LSB + CAT */
15890
            shiftLeftArray((byte*)aes->reg, 1);
15891
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
15892
        }
15893
15894
        bit--;
15895
        if (bit < 0) {
15896
            out[0] = cur;
15897
            out += 1;
15898
            in  += 1;
15899
            sz  -= 1;
15900
            bit = 7U;
15901
            cur = 0;
15902
        }
15903
        else {
15904
            sz -= 1;
15905
        }
15906
    }
15907
15908
    if (ret == 0) {
15909
        if (bit >= 0 && bit < 7) {
15910
            out[0] = cur;
15911
        }
15912
    }
15913
15914
    VECTOR_REGISTERS_POP;
15915
15916
    return ret;
15917
}
15918
15919
15920
/* CFB 1
15921
 *
15922
 * aes structure holding key to use for encryption
15923
 * out buffer to hold result of encryption (must be at least as large as input
15924
 *     buffer)
15925
 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
15926
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
15927
 *
15928
 * returns 0 on success and negative values on failure
15929
 */
15930
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15931
{
15932
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
15933
}
15934
15935
15936
/* CFB 8
15937
 *
15938
 * aes structure holding key to use for encryption
15939
 * out buffer to hold result of encryption (must be at least as large as input
15940
 *     buffer)
15941
 * in  buffer to encrypt
15942
 * sz  size of input buffer
15943
 *
15944
 * returns 0 on success and negative values on failure
15945
 */
15946
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15947
{
15948
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
15949
}
15950
#ifdef HAVE_AES_DECRYPT
15951
15952
/* CFB 1
15953
 *
15954
 * aes structure holding key to use for encryption
15955
 * out buffer to hold result of encryption (must be at least as large as input
15956
 *     buffer)
15957
 * in  buffer to encrypt
15958
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
15959
 *
15960
 * returns 0 on success and negative values on failure
15961
 */
15962
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15963
{
15964
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
15965
}
15966
15967
15968
/* CFB 8
15969
 *
15970
 * aes structure holding key to use for encryption
15971
 * out buffer to hold result of encryption (must be at least as large as input
15972
 *     buffer)
15973
 * in  buffer to encrypt
15974
 * sz  size of input buffer
15975
 *
15976
 * returns 0 on success and negative values on failure
15977
 */
15978
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15979
{
15980
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
15981
}
15982
#endif /* HAVE_AES_DECRYPT */
15983
#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
15984
#endif /* WOLFSSL_AES_CFB */
15985
15986
#ifdef WOLFSSL_AES_OFB
15987
#ifdef WOLFSSL_NXP_HASHCRYPT_AES
15988
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
15989
15990
#else /* software */
15991
/* OFB AES mode
15992
 *
15993
 * aes structure holding key to use for encryption
15994
 * out buffer to hold result of encryption (must be at least as large as input
15995
 *     buffer)
15996
 * in  buffer to encrypt
15997
 * sz  size of input buffer
15998
 *
15999
 * returns 0 on success and negative error values on failure
16000
 */
16001
/* Software AES - OFB Encrypt/Decrypt */
16002
static WARN_UNUSED_RESULT int AesOfbCrypt_C(Aes* aes, byte* out, const byte* in,
16003
    word32 sz)
16004
{
16005
    int ret = 0;
16006
    word32 processed;
16007
#ifdef WC_AES_HAVE_PREFETCH_ARG
16008
    int did_prefetches = 0;
16009
#endif
16010
16011
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16012
        return BAD_FUNC_ARG;
16013
    }
16014
    if (sz == 0) {
16015
        return 0;
16016
    }
16017
16018
    if (aes->left > 0) {
16019
        /* consume any unused bytes left in aes->tmp */
16020
        processed = min(aes->left, sz);
16021
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16022
            processed);
16023
        aes->left -= processed;
16024
        out += processed;
16025
        in += processed;
16026
        sz -= processed;
16027
    }
16028
16029
    VECTOR_REGISTERS_PUSH;
16030
16031
    while (sz >= WC_AES_BLOCK_SIZE) {
16032
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
16033
                                        &did_prefetches);
16034
        if (ret != 0) {
16035
            break;
16036
        }
16037
        xorbufout(out, in, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
16038
        out += WC_AES_BLOCK_SIZE;
16039
        in  += WC_AES_BLOCK_SIZE;
16040
        sz  -= WC_AES_BLOCK_SIZE;
16041
    }
16042
16043
    /* encrypt left over data */
16044
    if ((ret == 0) && sz) {
16045
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16046
                                        &did_prefetches);
16047
        if (ret == 0) {
16048
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
16049
            xorbufout(out, in, aes->tmp, sz);
16050
            aes->left = WC_AES_BLOCK_SIZE - sz;
16051
        }
16052
    }
16053
16054
    VECTOR_REGISTERS_POP;
16055
16056
    return ret;
16057
}
16058
16059
/* OFB
16060
 *
16061
 * aes structure holding key to use for encryption
16062
 * out buffer to hold result of encryption (must be at least as large as input
16063
 *     buffer)
16064
 * in  buffer to encrypt
16065
 * sz  size of input buffer
16066
 *
16067
 * returns 0 on success and negative error values on failure
16068
 */
16069
/* Software AES - OFB Encrypt */
16070
int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16071
{
16072
#ifdef WOLF_CRYPTO_CB
16073
    if (aes == NULL)
16074
        return BAD_FUNC_ARG;
16075
    #ifndef WOLF_CRYPTO_CB_FIND
16076
    if (aes->devId != INVALID_DEVID)
16077
    #endif
16078
    {
16079
        int crypto_cb_ret = wc_CryptoCb_AesOfbEncrypt(aes, out, in, sz);
16080
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16081
            return crypto_cb_ret;
16082
        /* fall-through when unavailable */
16083
    }
16084
#endif
16085
    return AesOfbCrypt_C(aes, out, in, sz);
16086
}
16087
16088
16089
#ifdef HAVE_AES_DECRYPT
16090
/* OFB
16091
 *
16092
 * aes structure holding key to use for decryption
16093
 * out buffer to hold result of decryption (must be at least as large as input
16094
 *     buffer)
16095
 * in  buffer to decrypt
16096
 * sz  size of input buffer
16097
 *
16098
 * returns 0 on success and negative error values on failure
16099
 */
16100
/* Software AES - OFB Decrypt */
16101
int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16102
{
16103
#ifdef WOLF_CRYPTO_CB
16104
    if (aes == NULL)
16105
        return BAD_FUNC_ARG;
16106
    #ifndef WOLF_CRYPTO_CB_FIND
16107
    if (aes->devId != INVALID_DEVID)
16108
    #endif
16109
    {
16110
        int crypto_cb_ret = wc_CryptoCb_AesOfbDecrypt(aes, out, in, sz);
16111
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16112
            return crypto_cb_ret;
16113
        /* fall-through when unavailable */
16114
    }
16115
#endif
16116
    return AesOfbCrypt_C(aes, out, in, sz);
16117
}
16118
#endif /* HAVE_AES_DECRYPT */
16119
#endif /* software */
16120
#endif /* WOLFSSL_AES_OFB */
16121
16122
16123
#ifdef HAVE_AES_KEYWRAP
16124
16125
/* Initialize key wrap counter with value */
16126
static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
16127
{
16128
    word32 i;
16129
    word32 bytes;
16130
16131
    bytes = sizeof(word32);
16132
    for (i = 0; i < sizeof(word32); i++) {
16133
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
16134
        bytes--;
16135
    }
16136
}
16137
16138
/* Increment key wrap counter */
16139
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
16140
{
16141
    int i;
16142
16143
    /* in network byte order so start at end and work back */
16144
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
16145
        if (++inOutCtr[i])  /* we're done unless we overflow */
16146
            return;
16147
    }
16148
}
16149
16150
/* Decrement key wrap counter */
16151
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
16152
{
16153
    int i;
16154
16155
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
16156
        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
16157
            return;
16158
    }
16159
}
16160
16161
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
16162
        word32 outSz, const byte* iv)
16163
{
16164
    word32 i;
16165
    byte* r;
16166
    int j;
16167
    int ret = 0;
16168
16169
    byte t[KEYWRAP_BLOCK_SIZE];
16170
    byte tmp[WC_AES_BLOCK_SIZE];
16171
16172
    /* n must be at least 2 64-bit blocks, output size is (n + 1) 8 bytes (64-bit) */
16173
    if (aes == NULL || in  == NULL || inSz < 2*KEYWRAP_BLOCK_SIZE ||
16174
        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
16175
        return BAD_FUNC_ARG;
16176
16177
    /* input must be multiple of 64-bits */
16178
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
16179
        return BAD_FUNC_ARG;
16180
16181
    r = out + 8;
16182
    XMEMCPY(r, in, inSz);
16183
    XMEMSET(t, 0, sizeof(t));
16184
16185
    /* user IV is optional */
16186
    if (iv == NULL) {
16187
        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
16188
    } else {
16189
        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
16190
    }
16191
16192
    VECTOR_REGISTERS_PUSH;
16193
16194
    for (j = 0; j <= 5; j++) {
16195
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
16196
            /* load R[i] */
16197
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
16198
16199
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
16200
            if (ret != 0)
16201
                break;
16202
16203
            /* calculate new A */
16204
            IncrementKeyWrapCounter(t);
16205
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
16206
16207
            /* save R[i] */
16208
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
16209
            r += KEYWRAP_BLOCK_SIZE;
16210
        }
16211
        if (ret != 0)
16212
            break;
16213
        r = out + KEYWRAP_BLOCK_SIZE;
16214
    }
16215
16216
    VECTOR_REGISTERS_POP;
16217
16218
    if (ret != 0)
16219
        return ret;
16220
16221
    /* C[0] = A */
16222
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
16223
16224
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
16225
}
16226
16227
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
16228
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
16229
                  byte* out, word32 outSz, const byte* iv)
16230
{
16231
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16232
    int ret;
16233
16234
    if (key == NULL)
16235
        return BAD_FUNC_ARG;
16236
16237
#ifdef WOLFSSL_SMALL_STACK
16238
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
16239
                              DYNAMIC_TYPE_AES)) == NULL)
16240
        return MEMORY_E;
16241
#endif
16242
16243
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16244
    if (ret != 0)
16245
        goto out;
16246
16247
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
16248
    if (ret != 0) {
16249
        wc_AesFree(aes);
16250
        goto out;
16251
    }
16252
16253
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
16254
16255
    wc_AesFree(aes);
16256
16257
  out:
16258
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
16259
16260
    return ret;
16261
}
16262
16263
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
16264
        word32 outSz, const byte* iv)
16265
{
16266
    byte* r;
16267
    word32 i, n;
16268
    int j;
16269
    int ret = 0;
16270
16271
    byte t[KEYWRAP_BLOCK_SIZE];
16272
    byte tmp[WC_AES_BLOCK_SIZE];
16273
16274
    const byte* expIv;
16275
    const byte defaultIV[] = {
16276
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
16277
    };
16278
16279
    if (aes == NULL || in == NULL || inSz < 3 * KEYWRAP_BLOCK_SIZE ||
16280
        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
16281
        return BAD_FUNC_ARG;
16282
16283
    /* input must be multiple of 64-bits */
16284
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
16285
        return BAD_FUNC_ARG;
16286
16287
    /* user IV optional */
16288
    if (iv != NULL)
16289
        expIv = iv;
16290
    else
16291
        expIv = defaultIV;
16292
16293
    /* A = C[0], R[i] = C[i] */
16294
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
16295
    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
16296
    XMEMSET(t, 0, sizeof(t));
16297
16298
    VECTOR_REGISTERS_PUSH;
16299
16300
    /* initialize counter to 6n */
16301
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
16302
    InitKeyWrapCounter(t, 6 * n);
16303
16304
    for (j = 5; j >= 0; j--) {
16305
        for (i = n; i >= 1; i--) {
16306
16307
            /* calculate A */
16308
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
16309
            DecrementKeyWrapCounter(t);
16310
16311
            /* load R[i], starting at end of R */
16312
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
16313
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
16314
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
16315
            if (ret != 0)
16316
                break;
16317
16318
            /* save R[i] */
16319
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
16320
        }
16321
        if (ret != 0)
16322
            break;
16323
    }
16324
16325
    VECTOR_REGISTERS_POP;
16326
16327
    if (ret != 0)
16328
        return ret;
16329
16330
    /* verify IV */
16331
    if (ConstantCompare(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
16332
        return BAD_KEYWRAP_IV_E;
16333
16334
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
16335
}
16336
16337
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
16338
                    byte* out, word32 outSz, const byte* iv)
16339
{
16340
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16341
    int ret;
16342
16343
    (void)iv;
16344
16345
    if (key == NULL)
16346
        return BAD_FUNC_ARG;
16347
16348
#ifdef WOLFSSL_SMALL_STACK
16349
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
16350
                              DYNAMIC_TYPE_AES)) == NULL)
16351
        return MEMORY_E;
16352
#endif
16353
16354
16355
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16356
    if (ret != 0)
16357
        goto out;
16358
16359
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
16360
    if (ret != 0) {
16361
        wc_AesFree(aes);
16362
        goto out;
16363
    }
16364
16365
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
16366
16367
    wc_AesFree(aes);
16368
16369
  out:
16370
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
16371
16372
    return ret;
16373
}
16374
16375
#endif /* HAVE_AES_KEYWRAP */
16376
16377
#ifdef WOLFSSL_AES_XTS
16378
16379
/* Galois Field to use */
16380
#define GF_XTS 0x87
16381
16382
/* Set up keys for encryption and/or decryption.
16383
 *
16384
 * aes   buffer holding aes subkeys
16385
 * heap  heap hint to use for memory. Can be NULL
16386
 * devId id to use with async crypto. Can be 0
16387
 *
16388
 * return 0 on success
16389
 */
16390
int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
16391
{
16392
    int    ret = 0;
16393
16394
    if (aes == NULL) {
16395
        return BAD_FUNC_ARG;
16396
    }
16397
16398
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
16399
        return ret;
16400
    }
16401
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
16402
        (void)wc_AesFree(&aes->tweak);
16403
        return ret;
16404
    }
16405
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16406
    if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) {
16407
        (void)wc_AesFree(&aes->tweak);
16408
        (void)wc_AesFree(&aes->aes);
16409
        return ret;
16410
    }
16411
#endif
16412
16413
    return 0;
16414
}
16415
16416
/* Set up keys for encryption and/or decryption.
16417
 *
16418
 * aes   buffer holding aes subkeys
16419
 * key   AES key for encrypt/decrypt and tweak process (concatenated)
16420
 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
16421
 *       32 for a 16 byte key.
16422
 * dir   direction: AES_ENCRYPTION, AES_DECRYPTION, or
16423
 *       AES_ENCRYPTION_AND_DECRYPTION
16424
 *
16425
 * return 0 on success
16426
 */
16427
int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
16428
{
16429
    word32 keySz;
16430
    int    ret = 0;
16431
16432
    if (aes == NULL || key == NULL) {
16433
        return BAD_FUNC_ARG;
16434
    }
16435
16436
    if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION)
16437
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16438
        && (dir != AES_ENCRYPTION_AND_DECRYPTION)
16439
#endif
16440
        )
16441
    {
16442
        return BAD_FUNC_ARG;
16443
    }
16444
16445
    if ((len != (AES_128_KEY_SIZE*2)) &&
16446
#ifndef HAVE_FIPS
16447
        /* XTS-384 not allowed by FIPS and can not be treated like
16448
         * RSA-4096 bit keys back in the day, can not vendor affirm
16449
         * the use of 2 concatenated 192-bit keys (XTS-384) */
16450
        (len != (AES_192_KEY_SIZE*2)) &&
16451
#endif
16452
        (len != (AES_256_KEY_SIZE*2)))
16453
    {
16454
        WOLFSSL_MSG("Unsupported key size");
16455
        return WC_KEY_SIZE_E;
16456
    }
16457
16458
    keySz = len/2;
16459
16460
#if defined(HAVE_FIPS) || !defined(WC_AES_XTS_ALLOW_DUPLICATE_KEYS)
16461
    if (XMEMCMP(key, key + keySz, keySz) == 0) {
16462
        WOLFSSL_MSG("AES-XTS main and tweak keys must differ");
16463
        return BAD_FUNC_ARG;
16464
    }
16465
#endif
16466
16467
    if (dir == AES_ENCRYPTION
16468
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16469
        || dir == AES_ENCRYPTION_AND_DECRYPTION
16470
#endif
16471
        )
16472
    {
16473
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
16474
    }
16475
16476
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16477
    if ((ret == 0) && ((dir == AES_DECRYPTION)
16478
                       || (dir == AES_ENCRYPTION_AND_DECRYPTION)))
16479
        ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION);
16480
#else
16481
    if (dir == AES_DECRYPTION)
16482
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
16483
#endif
16484
16485
    if (ret == 0)
16486
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
16487
                AES_ENCRYPTION);
16488
16489
#ifdef WOLFSSL_AESNI
16490
    if (ret == 0) {
16491
        /* With WC_C_DYNAMIC_FALLBACK, the main and tweak keys could have
16492
         * conflicting _aesni status, but the AES-XTS asm implementations need
16493
         * them to all be AESNI.  If any aren't, disable AESNI on all.
16494
         */
16495
    #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16496
        if ((((dir == AES_ENCRYPTION) ||
16497
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
16498
             && (aes->aes.use_aesni != aes->tweak.use_aesni))
16499
            ||
16500
            (((dir == AES_DECRYPTION) ||
16501
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
16502
             && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)))
16503
        {
16504
        #ifdef WC_C_DYNAMIC_FALLBACK
16505
            aes->aes.use_aesni = 0;
16506
            aes->aes_decrypt.use_aesni = 0;
16507
            aes->tweak.use_aesni = 0;
16508
        #else
16509
            ret = SYSLIB_FAILED_E;
16510
        #endif
16511
        }
16512
    #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
16513
        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
16514
        #ifdef WC_C_DYNAMIC_FALLBACK
16515
            aes->aes.use_aesni = 0;
16516
            aes->tweak.use_aesni = 0;
16517
        #else
16518
            ret = SYSLIB_FAILED_E;
16519
        #endif
16520
        }
16521
    #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
16522
    }
16523
#endif /* WOLFSSL_AESNI */
16524
16525
    return ret;
16526
}
16527
16528
/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
16529
 *
16530
 * Note: is up to user to call wc_AesXtsFree when done.
16531
 *
16532
 * return 0 on success
16533
 */
16534
int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
16535
        void* heap, int devId)
16536
{
16537
    int    ret = 0;
16538
16539
    if (aes == NULL || key == NULL) {
16540
        return BAD_FUNC_ARG;
16541
    }
16542
16543
    ret = wc_AesXtsInit(aes, heap, devId);
16544
    if (ret != 0)
16545
        return ret;
16546
16547
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
16548
16549
    if (ret != 0)
16550
        wc_AesXtsFree(aes);
16551
16552
    return ret;
16553
}
16554
16555
16556
/* This is used to free up resources used by Aes structs
16557
 *
16558
 * aes AES keys to free
16559
 *
16560
 * return 0 on success
16561
 */
16562
int wc_AesXtsFree(XtsAes* aes)
16563
{
16564
    if (aes != NULL) {
16565
        wc_AesFree(&aes->aes);
16566
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16567
        wc_AesFree(&aes->aes_decrypt);
16568
#endif
16569
        wc_AesFree(&aes->tweak);
16570
    }
16571
16572
    return 0;
16573
}
16574
16575
16576
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
16577
 * instead of a byte array. This just converts the word64 to a byte array and
16578
 * calls wc_AesXtsEncrypt.
16579
 *
16580
 * aes    AES keys to use for block encrypt/decrypt
16581
 * out    output buffer to hold cipher text
16582
 * in     input plain text buffer to encrypt
16583
 * sz     size of both out and in buffers
16584
 * sector value to use for tweak
16585
 *
16586
 * returns 0 on success
16587
 */
16588
int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
16589
        word32 sz, word64 sector)
16590
{
16591
    byte* pt;
16592
    byte  i[WC_AES_BLOCK_SIZE];
16593
16594
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
16595
#ifdef BIG_ENDIAN_ORDER
16596
    sector = ByteReverseWord64(sector);
16597
#endif
16598
    pt = (byte*)&sector;
16599
    XMEMCPY(i, pt, sizeof(word64));
16600
16601
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
16602
}
16603
16604
#ifdef HAVE_AES_DECRYPT
16605
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
16606
 * instead of a byte array. This just converts the word64 to a byte array.
16607
 *
16608
 * aes    AES keys to use for block encrypt/decrypt
16609
 * out    output buffer to hold plain text
16610
 * in     input cipher text buffer to encrypt
16611
 * sz     size of both out and in buffers
16612
 * sector value to use for tweak
16613
 *
16614
 * returns 0 on success
16615
 */
16616
int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
16617
        word64 sector)
16618
{
16619
    byte* pt;
16620
    byte  i[WC_AES_BLOCK_SIZE];
16621
16622
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
16623
#ifdef BIG_ENDIAN_ORDER
16624
    sector = ByteReverseWord64(sector);
16625
#endif
16626
    pt = (byte*)&sector;
16627
    XMEMCPY(i, pt, sizeof(word64));
16628
16629
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
16630
}
16631
#endif
16632
16633
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
16634
16635
#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
16636
    #define USE_INTEL_SPEEDUP
16637
#endif
16638
16639
#if defined(USE_INTEL_SPEEDUP)
16640
    #define HAVE_INTEL_AVX1
16641
    #define HAVE_INTEL_AVX2
16642
#endif /* USE_INTEL_SPEEDUP */
16643
16644
void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
16645
                     const unsigned char* i, const unsigned char* key,
16646
                     const unsigned char* key2, int nr)
16647
                     XASM_LINK("AES_XTS_encrypt_aesni");
16648
#ifdef WOLFSSL_AESXTS_STREAM
16649
void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
16650
                     int tweak_nr)
16651
                     XASM_LINK("AES_XTS_init_aesni");
16652
void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
16653
                     const unsigned char* key, unsigned char *i, int nr)
16654
                     XASM_LINK("AES_XTS_encrypt_update_aesni");
16655
#endif
16656
#ifdef HAVE_INTEL_AVX1
16657
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
16658
                     word32 sz, const unsigned char* i,
16659
                     const unsigned char* key, const unsigned char* key2,
16660
                     int nr)
16661
                     XASM_LINK("AES_XTS_encrypt_avx1");
16662
#ifdef WOLFSSL_AESXTS_STREAM
16663
void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
16664
                     int tweak_nr)
16665
                     XASM_LINK("AES_XTS_init_avx1");
16666
void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
16667
                     const unsigned char* key, unsigned char *i, int nr)
16668
                     XASM_LINK("AES_XTS_encrypt_update_avx1");
16669
#endif
16670
#endif /* HAVE_INTEL_AVX1 */
16671
#ifdef HAVE_INTEL_VAES
16672
void AES_XTS_encrypt_vaes(const unsigned char *in, unsigned char *out,
16673
                     word32 sz, const unsigned char* i,
16674
                     const unsigned char* key, const unsigned char* key2,
16675
                     int nr)
16676
                     XASM_LINK("AES_XTS_encrypt_vaes");
16677
#ifdef WOLFSSL_AESXTS_STREAM
16678
void AES_XTS_init_vaes(unsigned char* i, const unsigned char* tweak_key,
16679
                     int tweak_nr)
16680
                     XASM_LINK("AES_XTS_init_vaes");
16681
void AES_XTS_encrypt_update_vaes(const unsigned char *in, unsigned char *out, word32 sz,
16682
                     const unsigned char* key, unsigned char *i, int nr)
16683
                     XASM_LINK("AES_XTS_encrypt_update_vaes");
16684
#endif
16685
#endif /* HAVE_INTEL_VAES */
16686
#ifdef HAVE_INTEL_AVX512
16687
void AES_XTS_encrypt_avx512(const unsigned char *in, unsigned char *out,
16688
                     word32 sz, const unsigned char* i,
16689
                     const unsigned char* key, const unsigned char* key2,
16690
                     int nr)
16691
                     XASM_LINK("AES_XTS_encrypt_avx512");
16692
#ifdef WOLFSSL_AESXTS_STREAM
16693
void AES_XTS_init_avx512(unsigned char* i, const unsigned char* tweak_key,
16694
                     int tweak_nr)
16695
                     XASM_LINK("AES_XTS_init_avx512");
16696
void AES_XTS_encrypt_update_avx512(const unsigned char *in, unsigned char *out, word32 sz,
16697
                     const unsigned char* key, unsigned char *i, int nr)
16698
                     XASM_LINK("AES_XTS_encrypt_update_avx512");
16699
#endif
16700
#endif /* HAVE_INTEL_AVX512 */
16701
16702
16703
#ifdef HAVE_AES_DECRYPT
16704
void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
16705
                     const unsigned char* i, const unsigned char* key,
16706
                     const unsigned char* key2, int nr)
16707
                     XASM_LINK("AES_XTS_decrypt_aesni");
16708
#ifdef WOLFSSL_AESXTS_STREAM
16709
void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
16710
                     const unsigned char* key, unsigned char *i, int nr)
16711
                     XASM_LINK("AES_XTS_decrypt_update_aesni");
16712
#endif
16713
#ifdef HAVE_INTEL_AVX1
16714
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
16715
                     word32 sz, const unsigned char* i,
16716
                     const unsigned char* key, const unsigned char* key2,
16717
                     int nr)
16718
                     XASM_LINK("AES_XTS_decrypt_avx1");
16719
#ifdef WOLFSSL_AESXTS_STREAM
16720
void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
16721
                     const unsigned char* key, unsigned char *i, int nr)
16722
                     XASM_LINK("AES_XTS_decrypt_update_avx1");
16723
#endif
16724
#endif /* HAVE_INTEL_AVX1 */
16725
#ifdef HAVE_INTEL_VAES
16726
void AES_XTS_decrypt_vaes(const unsigned char *in, unsigned char *out,
16727
                     word32 sz, const unsigned char* i,
16728
                     const unsigned char* key, const unsigned char* key2,
16729
                     int nr)
16730
                     XASM_LINK("AES_XTS_decrypt_vaes");
16731
#ifdef WOLFSSL_AESXTS_STREAM
16732
void AES_XTS_decrypt_update_vaes(const unsigned char *in, unsigned char *out, word32 sz,
16733
                     const unsigned char* key, unsigned char *i, int nr)
16734
                     XASM_LINK("AES_XTS_decrypt_update_vaes");
16735
#endif
16736
#endif /* HAVE_INTEL_VAES */
16737
#ifdef HAVE_INTEL_AVX512
16738
void AES_XTS_decrypt_avx512(const unsigned char *in, unsigned char *out,
16739
                     word32 sz, const unsigned char* i,
16740
                     const unsigned char* key, const unsigned char* key2,
16741
                     int nr)
16742
                     XASM_LINK("AES_XTS_decrypt_avx512");
16743
#ifdef WOLFSSL_AESXTS_STREAM
16744
void AES_XTS_decrypt_update_avx512(const unsigned char *in, unsigned char *out, word32 sz,
16745
                     const unsigned char* key, unsigned char *i, int nr)
16746
                     XASM_LINK("AES_XTS_decrypt_update_avx512");
16747
#endif
16748
#endif /* HAVE_INTEL_AVX512 */
16749
#endif /* HAVE_AES_DECRYPT */
16750
16751
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
16752
16753
#ifdef HAVE_AES_ECB
16754
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
16755
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
16756
/* helper function for encrypting / decrypting full buffer at once */
16757
static WARN_UNUSED_RESULT int _AesXtsHelper(
16758
    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
16759
{
16760
    word32 outSz   = sz;
16761
    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
16762
    byte*  pt      = out;
16763
16764
    outSz -= WC_AES_BLOCK_SIZE;
16765
16766
    while (outSz > 0) {
16767
        word32 j;
16768
        byte carry = 0;
16769
16770
        /* multiply by shift left and propagate carry */
16771
        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
16772
            byte tmpC;
16773
16774
            tmpC   = (pt[j] >> 7) & 0x01;
16775
            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
16776
            carry  = tmpC;
16777
        }
16778
        if (carry) {
16779
            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
16780
        }
16781
16782
        pt += WC_AES_BLOCK_SIZE;
16783
    }
16784
16785
    xorbuf(out, in, totalSz);
16786
#ifndef WOLFSSL_RISCV_ASM
16787
    if (dir == AES_ENCRYPTION) {
16788
        return _AesEcbEncrypt(aes, out, out, totalSz);
16789
    }
16790
    else {
16791
        return _AesEcbDecrypt(aes, out, out, totalSz);
16792
    }
16793
#else
16794
    if (dir == AES_ENCRYPTION) {
16795
        return wc_AesEcbEncrypt(aes, out, out, totalSz);
16796
    }
16797
    else {
16798
        return wc_AesEcbDecrypt(aes, out, out, totalSz);
16799
    }
16800
#endif
16801
}
16802
#endif
16803
#endif /* HAVE_AES_ECB */
16804
16805
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
16806
 *
16807
 * xaes  AES keys to use for block encrypt/decrypt
16808
 * out   output buffer to hold cipher text
16809
 * in    input plain text buffer to encrypt
16810
 * sz    size of both out and in buffers
16811
 * i     value to use for tweak
16812
 *
16813
 * returns 0 on success
16814
 */
16815
/* Software AES - XTS Encrypt  */
16816
16817
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
16818
     defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) && !defined(WOLFSSL_PPC64_ASM)
16819
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
16820
                                  word32 sz,
16821
                                  byte *i);
16822
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16823
        const byte* i)
16824
{
16825
    int ret;
16826
    byte tweak_block[WC_AES_BLOCK_SIZE];
16827
16828
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
16829
    if (ret != 0)
16830
        return ret;
16831
16832
    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
16833
}
16834
#endif
16835
16836
#ifdef WOLFSSL_AESXTS_STREAM
16837
16838
/* Block-streaming AES-XTS tweak setup.
16839
 *
16840
 * xaes  AES keys to use for block encrypt/decrypt
16841
 * i     readwrite value to use for tweak
16842
 *
16843
 * returns 0 on success
16844
 */
16845
static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
16846
    return wc_AesEncryptDirect(&xaes->tweak, i, i);
16847
}
16848
16849
#endif /* WOLFSSL_AESXTS_STREAM */
16850
16851
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
16852
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || defined(WOLFSSL_AESXTS_STREAM)
16853
/* Block-streaming AES-XTS.
16854
 *
16855
 * Supply block-aligned input data with successive calls.  Final call need not
16856
 * be block aligned.
16857
 *
16858
 * xaes  AES keys to use for block encrypt/decrypt
16859
 * out   output buffer to hold cipher text
16860
 * in    input plain text buffer to encrypt
16861
 * sz    size of both out and in buffers
16862
 *
16863
 * returns 0 on success
16864
 */
16865
/* Software AES - XTS Encrypt  */
16866
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
16867
                                  word32 sz,
16868
                                  byte *i)
16869
{
16870
    int ret = 0;
16871
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
16872
    Aes *aes = &xaes->aes;
16873
16874
#ifdef HAVE_AES_ECB
16875
    /* encrypt all of buffer at once when possible */
16876
    if (in != out) { /* can not handle inline */
16877
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
16878
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
16879
            return ret;
16880
    }
16881
#endif
16882
16883
    while (blocks > 0) {
16884
        word32 j;
16885
        byte carry = 0;
16886
16887
#ifdef HAVE_AES_ECB
16888
        if (in == out)
16889
#endif
16890
        { /* check for if inline */
16891
            byte buf[WC_AES_BLOCK_SIZE];
16892
16893
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
16894
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
16895
            ret = wc_AesEncryptDirect(aes, out, buf);
16896
            if (ret != 0)
16897
                return ret;
16898
        }
16899
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
16900
16901
        /* multiply by shift left and propagate carry */
16902
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
16903
            byte tmpC;
16904
16905
            tmpC   = (i[j] >> 7) & 0x01;
16906
            i[j] = (byte)((i[j] << 1) + carry);
16907
            carry  = tmpC;
16908
        }
16909
        if (carry) {
16910
            i[0] ^= GF_XTS;
16911
        }
16912
16913
        in  += WC_AES_BLOCK_SIZE;
16914
        out += WC_AES_BLOCK_SIZE;
16915
        sz  -= WC_AES_BLOCK_SIZE;
16916
        blocks--;
16917
    }
16918
16919
    /* stealing operation of XTS to handle left overs */
16920
    if (sz > 0) {
16921
        byte buf[WC_AES_BLOCK_SIZE];
16922
16923
        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
16924
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
16925
            return BUFFER_E;
16926
        }
16927
        if (in != out) {
16928
            XMEMCPY(out, buf, sz);
16929
            XMEMCPY(buf, in, sz);
16930
        }
16931
        else {
16932
            byte buf2[WC_AES_BLOCK_SIZE];
16933
16934
            XMEMCPY(buf2, buf, sz);
16935
            XMEMCPY(buf, in, sz);
16936
            XMEMCPY(out, buf2, sz);
16937
        }
16938
16939
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
16940
        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
16941
        if (ret == 0)
16942
            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
16943
    }
16944
16945
    return ret;
16946
}
16947
#endif
16948
16949
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
16950
 *
16951
 * xaes  AES keys to use for block encrypt/decrypt
16952
 * out   output buffer to hold cipher text
16953
 * in    input plain text buffer to encrypt
16954
 * sz    size of both out and in buffers
16955
 * i     value to use for tweak
16956
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
16957
 *       adds a sanity check on how the user calls the function.
16958
 *
16959
 * returns 0 on success
16960
 */
16961
int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16962
        const byte* i, word32 iSz)
16963
{
16964
    int ret;
16965
16966
    Aes *aes;
16967
16968
    if (xaes == NULL || out == NULL || in == NULL) {
16969
        return BAD_FUNC_ARG;
16970
    }
16971
16972
#if FIPS_VERSION3_GE(6,0,0)
16973
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
16974
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
16975
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
16976
     */
16977
    if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
16978
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
16979
        return BAD_FUNC_ARG;
16980
    }
16981
#endif
16982
16983
    aes = &xaes->aes;
16984
16985
    if (aes->keylen == 0) {
16986
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
16987
        return BAD_FUNC_ARG;
16988
    }
16989
16990
    if (iSz < WC_AES_BLOCK_SIZE) {
16991
        return BAD_FUNC_ARG;
16992
    }
16993
16994
    if (sz < WC_AES_BLOCK_SIZE) {
16995
        WOLFSSL_MSG("Plain text input too small for encryption");
16996
        return BAD_FUNC_ARG;
16997
    }
16998
16999
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
17000
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
17001
    AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
17002
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17003
    ret = 0;
17004
#elif defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17005
    if (aes->use_aesni) {
17006
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
17007
#if defined(HAVE_INTEL_AVX512)
17008
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17009
            AES_XTS_encrypt_avx512(in, out, sz, i,
17010
                                   (const byte*)aes->key,
17011
                                   (const byte*)xaes->tweak.key,
17012
                                   (int)aes->rounds);
17013
            ret = 0;
17014
        }
17015
        else
17016
#endif
17017
#if defined(HAVE_INTEL_VAES)
17018
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17019
            AES_XTS_encrypt_vaes(in, out, sz, i,
17020
                                 (const byte*)aes->key,
17021
                                 (const byte*)xaes->tweak.key,
17022
                                 (int)aes->rounds);
17023
            ret = 0;
17024
        }
17025
        else
17026
#endif
17027
#if defined(HAVE_INTEL_AVX1)
17028
        if (IS_INTEL_AVX1(intel_flags)) {
17029
            AES_XTS_encrypt_avx1(in, out, sz, i,
17030
                                 (const byte*)aes->key,
17031
                                 (const byte*)xaes->tweak.key,
17032
                                 (int)aes->rounds);
17033
            ret = 0;
17034
        }
17035
        else
17036
#endif
17037
        {
17038
            AES_XTS_encrypt_aesni(in, out, sz, i,
17039
                                  (const byte*)aes->key,
17040
                                  (const byte*)xaes->tweak.key,
17041
                                  (int)aes->rounds);
17042
            ret = 0;
17043
        }
17044
        RESTORE_VECTOR_REGISTERS();
17045
    }
17046
    else {
17047
        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
17048
    }
17049
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
17050
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
17051
    if (aes->use_aes_hw_crypto) {
17052
        AES_XTS_encrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
17053
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17054
        ret = 0;
17055
    }
17056
    else
17057
#endif
17058
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
17059
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
17060
    if (sz >= 32)
17061
#endif
17062
    {
17063
        AES_XTS_encrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
17064
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17065
        ret = 0;
17066
    }
17067
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
17068
    else
17069
#endif
17070
#endif
17071
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
17072
    {
17073
        AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
17074
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17075
        ret = 0;
17076
    }
17077
#endif
17078
#elif defined(WOLFSSL_PPC64_ASM)
17079
    AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
17080
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17081
    ret = 0;
17082
#else
17083
    ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
17084
#endif
17085
17086
    return ret;
17087
}
17088
17089
#ifdef WOLFSSL_AESXTS_STREAM
17090
17091
/* Block-streaming AES-XTS.
17092
 *
17093
 * xaes  AES keys to use for block encrypt/decrypt
17094
 * i     readwrite value to use for tweak
17095
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
17096
 *       adds a sanity check on how the user calls the function.
17097
 *
17098
 * returns 0 on success
17099
 */
17100
int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
17101
                         struct XtsAesStreamData *stream)
17102
{
17103
    int ret;
17104
17105
    Aes *aes;
17106
17107
    if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
17108
        return BAD_FUNC_ARG;
17109
    }
17110
17111
    if (iSz < WC_AES_BLOCK_SIZE) {
17112
        return BAD_FUNC_ARG;
17113
    }
17114
17115
    aes = &xaes->aes;
17116
17117
    if (aes->keylen == 0) {
17118
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
17119
        return BAD_FUNC_ARG;
17120
    }
17121
17122
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
17123
    stream->bytes_crypted_with_this_tweak = 0;
17124
17125
    {
17126
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17127
        if (aes->use_aesni) {
17128
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
17129
#if defined(HAVE_INTEL_AVX512)
17130
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17131
                AES_XTS_init_avx512(stream->tweak_block,
17132
                                    (const byte*)xaes->tweak.key,
17133
                                    (int)xaes->tweak.rounds);
17134
                ret = 0;
17135
            }
17136
            else
17137
#endif
17138
#if defined(HAVE_INTEL_VAES)
17139
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17140
                AES_XTS_init_vaes(stream->tweak_block,
17141
                                  (const byte*)xaes->tweak.key,
17142
                                  (int)xaes->tweak.rounds);
17143
                ret = 0;
17144
            }
17145
            else
17146
#endif
17147
#if defined(HAVE_INTEL_AVX1)
17148
            if (IS_INTEL_AVX1(intel_flags)) {
17149
                AES_XTS_init_avx1(stream->tweak_block,
17150
                                  (const byte*)xaes->tweak.key,
17151
                                  (int)xaes->tweak.rounds);
17152
                ret = 0;
17153
            }
17154
            else
17155
#endif
17156
            {
17157
                AES_XTS_init_aesni(stream->tweak_block,
17158
                                   (const byte*)xaes->tweak.key,
17159
                                   (int)xaes->tweak.rounds);
17160
                ret = 0;
17161
            }
17162
            RESTORE_VECTOR_REGISTERS();
17163
        }
17164
        else
17165
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
17166
        {
17167
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
17168
        }
17169
    }
17170
17171
    return ret;
17172
}
17173
17174
/* Block-streaming AES-XTS
17175
 *
17176
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
17177
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsEncryptUpdate().
17178
 * wc_AesXtsEncryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
17179
 *
17180
 * xaes  AES keys to use for block encrypt/decrypt
17181
 * out   output buffer to hold cipher text
17182
 * in    input plain text buffer to encrypt
17183
 * sz    size of both out and in buffers -- must be >= WC_AES_BLOCK_SIZE.
17184
 * i     value to use for tweak
17185
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
17186
 *       adds a sanity check on how the user calls the function.
17187
 *
17188
 * returns 0 on success
17189
 */
17190
static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17191
                           struct XtsAesStreamData *stream)
17192
{
17193
    int ret;
17194
17195
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17196
    Aes *aes;
17197
#endif
17198
17199
    if (xaes == NULL || out == NULL || in == NULL) {
17200
        return BAD_FUNC_ARG;
17201
    }
17202
17203
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17204
    aes = &xaes->aes;
17205
#endif
17206
17207
    if (sz < WC_AES_BLOCK_SIZE) {
17208
        WOLFSSL_MSG("Plain text input too small for encryption");
17209
        return BAD_FUNC_ARG;
17210
    }
17211
17212
    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
17213
    {
17214
        WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
17215
        return BAD_FUNC_ARG;
17216
    }
17217
17218
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
17219
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
17220
                             stream->bytes_crypted_with_this_tweak))
17221
    {
17222
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
17223
                    "in AesXtsEncryptUpdate().");
17224
    }
17225
#endif
17226
#if FIPS_VERSION3_GE(6,0,0)
17227
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
17228
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
17229
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
17230
     */
17231
    if (stream->bytes_crypted_with_this_tweak >
17232
        FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
17233
    {
17234
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
17235
        return BAD_FUNC_ARG;
17236
    }
17237
#endif
17238
    {
17239
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17240
        if (aes->use_aesni) {
17241
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
17242
#if defined(HAVE_INTEL_AVX512)
17243
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17244
                AES_XTS_encrypt_update_avx512(in, out, sz,
17245
                                              (const byte*)aes->key,
17246
                                              stream->tweak_block,
17247
                                              (int)aes->rounds);
17248
                ret = 0;
17249
            }
17250
            else
17251
#endif
17252
#if defined(HAVE_INTEL_VAES)
17253
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17254
                AES_XTS_encrypt_update_vaes(in, out, sz,
17255
                                            (const byte*)aes->key,
17256
                                            stream->tweak_block,
17257
                                            (int)aes->rounds);
17258
                ret = 0;
17259
            }
17260
            else
17261
#endif
17262
#if defined(HAVE_INTEL_AVX1)
17263
            if (IS_INTEL_AVX1(intel_flags)) {
17264
                AES_XTS_encrypt_update_avx1(in, out, sz,
17265
                                            (const byte*)aes->key,
17266
                                            stream->tweak_block,
17267
                                            (int)aes->rounds);
17268
                ret = 0;
17269
            }
17270
            else
17271
#endif
17272
            {
17273
                AES_XTS_encrypt_update_aesni(in, out, sz,
17274
                                            (const byte*)aes->key,
17275
                                            stream->tweak_block,
17276
                                            (int)aes->rounds);
17277
                ret = 0;
17278
            }
17279
            RESTORE_VECTOR_REGISTERS();
17280
        }
17281
        else
17282
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
17283
        {
17284
            ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
17285
        }
17286
    }
17287
17288
    return ret;
17289
}
17290
17291
int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17292
                           struct XtsAesStreamData *stream)
17293
{
17294
    if (stream == NULL)
17295
        return BAD_FUNC_ARG;
17296
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
17297
        return BAD_FUNC_ARG;
17298
    return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
17299
}
17300
17301
int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17302
                           struct XtsAesStreamData *stream)
17303
{
17304
    int ret;
17305
    if (stream == NULL)
17306
        return BAD_FUNC_ARG;
17307
    if (sz > 0)
17308
        ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
17309
    else
17310
        ret = 0;
17311
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
17312
     * after finalization.
17313
     */
17314
    stream->bytes_crypted_with_this_tweak |= 1U;
17315
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
17316
#ifdef WOLFSSL_CHECK_MEM_ZERO
17317
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
17318
#endif
17319
    return ret;
17320
}
17321
17322
#endif /* WOLFSSL_AESXTS_STREAM */
17323
17324
#ifdef HAVE_AES_DECRYPT
17325
17326
/* Same process as encryption but use aes_decrypt key.
17327
 *
17328
 * xaes  AES keys to use for block encrypt/decrypt
17329
 * out   output buffer to hold plain text
17330
 * in    input cipher text buffer to decrypt
17331
 * sz    size of both out and in buffers
17332
 * i     value to use for tweak
17333
 *
17334
 * returns 0 on success
17335
 */
17336
/* Software AES - XTS Decrypt */
17337
17338
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
17339
     defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) && !defined(WOLFSSL_PPC64_ASM)
17340
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
17341
                                  word32 sz, byte *i);
17342
17343
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17344
        const byte* i)
17345
{
17346
    int ret;
17347
    byte tweak_block[WC_AES_BLOCK_SIZE];
17348
17349
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
17350
    if (ret != 0)
17351
        return ret;
17352
17353
    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
17354
}
17355
#endif
17356
17357
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
17358
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
17359
/* Block-streaming AES-XTS.
17360
 *
17361
 * Same process as encryption but use decrypt key.
17362
 *
17363
 * Supply block-aligned input data with successive calls.  Final call need not
17364
 * be block aligned.
17365
 *
17366
 * xaes  AES keys to use for block encrypt/decrypt
17367
 * out   output buffer to hold plain text
17368
 * in    input cipher text buffer to decrypt
17369
 * sz    size of both out and in buffers
17370
 * i     value to use for tweak
17371
 *
17372
 * returns 0 on success
17373
 */
17374
/* Software AES - XTS Decrypt */
17375
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
17376
                                  word32 sz, byte *i)
17377
{
17378
    int ret = 0;
17379
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
17380
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
17381
    Aes *aes = &xaes->aes_decrypt;
17382
#else
17383
    Aes *aes = &xaes->aes;
17384
#endif
17385
    word32 j;
17386
    byte carry = 0;
17387
    byte stl = (sz % WC_AES_BLOCK_SIZE);
17388
17389
    /* if Stealing then break out of loop one block early to handle special
17390
     * case */
17391
    if (stl > 0) {
17392
        blocks--;
17393
    }
17394
17395
#ifdef HAVE_AES_ECB
17396
    /* decrypt all of buffer at once when possible */
17397
    if (in != out) { /* can not handle inline */
17398
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
17399
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
17400
            return ret;
17401
    }
17402
#endif
17403
17404
    while (blocks > 0) {
17405
#ifdef HAVE_AES_ECB
17406
        if (in == out)
17407
#endif
17408
        { /* check for if inline */
17409
            byte buf[WC_AES_BLOCK_SIZE];
17410
17411
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
17412
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
17413
            ret = wc_AesDecryptDirect(aes, out, buf);
17414
            if (ret != 0)
17415
                return ret;
17416
        }
17417
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
17418
17419
        /* multiply by shift left and propagate carry */
17420
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
17421
            byte tmpC;
17422
17423
            tmpC   = (i[j] >> 7) & 0x01;
17424
            i[j] = (byte)((i[j] << 1) + carry);
17425
            carry  = tmpC;
17426
        }
17427
        if (carry) {
17428
            i[0] ^= GF_XTS;
17429
        }
17430
        carry = 0;
17431
17432
        in  += WC_AES_BLOCK_SIZE;
17433
        out += WC_AES_BLOCK_SIZE;
17434
        sz  -= WC_AES_BLOCK_SIZE;
17435
        blocks--;
17436
    }
17437
17438
    /* stealing operation of XTS to handle left overs */
17439
    if (sz >= WC_AES_BLOCK_SIZE) {
17440
        byte buf[WC_AES_BLOCK_SIZE];
17441
        byte tmp2[WC_AES_BLOCK_SIZE];
17442
17443
        /* multiply by shift left and propagate carry */
17444
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
17445
            byte tmpC;
17446
17447
            tmpC   = (i[j] >> 7) & 0x01;
17448
            tmp2[j] = (byte)((i[j] << 1) + carry);
17449
            carry  = tmpC;
17450
        }
17451
        if (carry) {
17452
            tmp2[0] ^= GF_XTS;
17453
        }
17454
17455
        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
17456
        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
17457
        ret = wc_AesDecryptDirect(aes, out, buf);
17458
        if (ret != 0)
17459
            return ret;
17460
        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
17461
17462
        /* tmp2 holds partial | last */
17463
        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
17464
        in  += WC_AES_BLOCK_SIZE;
17465
        out += WC_AES_BLOCK_SIZE;
17466
        sz  -= WC_AES_BLOCK_SIZE;
17467
17468
        /* Make buffer with end of cipher text | last */
17469
        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
17470
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
17471
            return BUFFER_E;
17472
        }
17473
        XMEMCPY(buf, in,   sz);
17474
        XMEMCPY(out, tmp2, sz);
17475
17476
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
17477
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
17478
        if (ret != 0)
17479
            return ret;
17480
        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
17481
        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
17482
    }
17483
17484
    return ret;
17485
}
17486
#endif
17487
17488
/* Same process as encryption but Aes key is AES_DECRYPTION type.
17489
 *
17490
 * xaes  AES keys to use for block encrypt/decrypt
17491
 * out   output buffer to hold plain text
17492
 * in    input cipher text buffer to decrypt
17493
 * sz    size of both out and in buffers
17494
 * i     value to use for tweak
17495
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
17496
 *       adds a sanity check on how the user calls the function.
17497
 *
17498
 * returns 0 on success
17499
 */
17500
int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17501
        const byte* i, word32 iSz)
17502
{
17503
    int ret;
17504
    Aes *aes;
17505
17506
    if (xaes == NULL || out == NULL || in == NULL) {
17507
        return BAD_FUNC_ARG;
17508
    }
17509
17510
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
17511
    aes = &xaes->aes_decrypt;
17512
#else
17513
    aes = &xaes->aes;
17514
#endif
17515
17516
/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
17517
 * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
17518
 * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes or
17519
 * 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
17520
 * return whenever sz / WC_AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
17521
 * not a sequence of complete blocks.
17522
 */
17523
17524
    if (aes->keylen == 0) {
17525
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
17526
        return BAD_FUNC_ARG;
17527
    }
17528
17529
    if (iSz < WC_AES_BLOCK_SIZE) {
17530
        return BAD_FUNC_ARG;
17531
    }
17532
17533
    if (sz < WC_AES_BLOCK_SIZE) {
17534
        WOLFSSL_MSG("Cipher text input too small for decryption");
17535
        return BAD_FUNC_ARG;
17536
    }
17537
17538
#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
17539
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
17540
    AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
17541
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17542
    ret = 0;
17543
#elif defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17544
    if (aes->use_aesni) {
17545
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
17546
#if defined(HAVE_INTEL_AVX512)
17547
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17548
            AES_XTS_decrypt_avx512(in, out, sz, i,
17549
                                   (const byte*)aes->key,
17550
                                   (const byte*)xaes->tweak.key,
17551
                                   (int)aes->rounds);
17552
            ret = 0;
17553
        }
17554
        else
17555
#endif
17556
#if defined(HAVE_INTEL_VAES)
17557
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17558
            AES_XTS_decrypt_vaes(in, out, sz, i,
17559
                                 (const byte*)aes->key,
17560
                                 (const byte*)xaes->tweak.key,
17561
                                 (int)aes->rounds);
17562
            ret = 0;
17563
        }
17564
        else
17565
#endif
17566
#if defined(HAVE_INTEL_AVX1)
17567
        if (IS_INTEL_AVX1(intel_flags)) {
17568
            AES_XTS_decrypt_avx1(in, out, sz, i,
17569
                                 (const byte*)aes->key,
17570
                                 (const byte*)xaes->tweak.key,
17571
                                 (int)aes->rounds);
17572
            ret = 0;
17573
        }
17574
        else
17575
#endif
17576
        {
17577
            AES_XTS_decrypt_aesni(in, out, sz, i,
17578
                                  (const byte*)aes->key,
17579
                                  (const byte*)xaes->tweak.key,
17580
                                  (int)aes->rounds);
17581
            ret = 0;
17582
        }
17583
        RESTORE_VECTOR_REGISTERS();
17584
    }
17585
    else {
17586
        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
17587
    }
17588
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
17589
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
17590
    if (aes->use_aes_hw_crypto) {
17591
        AES_XTS_decrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
17592
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17593
        ret = 0;
17594
    }
17595
    else
17596
#endif
17597
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
17598
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
17599
    if (sz >= 64)
17600
#endif
17601
    {
17602
        AES_XTS_decrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
17603
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17604
        ret = 0;
17605
    }
17606
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
17607
    else
17608
#endif
17609
#endif
17610
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
17611
    {
17612
        AES_XTS_decrypt(in, out, sz, i, (byte*)xaes->aes.key,
17613
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17614
        ret = 0;
17615
    }
17616
#endif
17617
#elif defined(WOLFSSL_PPC64_ASM)
17618
    AES_XTS_decrypt(in, out, sz, i, (byte*)xaes->aes.key,
17619
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17620
    ret = 0;
17621
#else
17622
    ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
17623
#endif
17624
17625
    return ret;
17626
}
17627
17628
#ifdef WOLFSSL_AESXTS_STREAM
17629
17630
/* Same process as encryption but Aes key is AES_DECRYPTION type.
17631
 *
17632
 * xaes  AES keys to use for block encrypt/decrypt
17633
 * i     readwrite value to use for tweak
17634
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
17635
 *       adds a sanity check on how the user calls the function.
17636
 *
17637
 * returns 0 on success
17638
 */
17639
int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
17640
                         struct XtsAesStreamData *stream)
17641
{
17642
    int ret;
17643
    Aes *aes;
17644
17645
    if (xaes == NULL) {
17646
        return BAD_FUNC_ARG;
17647
    }
17648
17649
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
17650
    aes = &xaes->aes_decrypt;
17651
#else
17652
    aes = &xaes->aes;
17653
#endif
17654
17655
    if (aes->keylen == 0) {
17656
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
17657
        return BAD_FUNC_ARG;
17658
    }
17659
17660
    if (iSz < WC_AES_BLOCK_SIZE) {
17661
        return BAD_FUNC_ARG;
17662
    }
17663
17664
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
17665
    stream->bytes_crypted_with_this_tweak = 0;
17666
17667
    {
17668
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17669
        if (aes->use_aesni) {
17670
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
17671
#if defined(HAVE_INTEL_AVX512)
17672
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17673
                AES_XTS_init_avx512(stream->tweak_block,
17674
                                    (const byte*)xaes->tweak.key,
17675
                                    (int)xaes->tweak.rounds);
17676
                ret = 0;
17677
            }
17678
            else
17679
#endif
17680
#if defined(HAVE_INTEL_VAES)
17681
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17682
                AES_XTS_init_vaes(stream->tweak_block,
17683
                                  (const byte*)xaes->tweak.key,
17684
                                  (int)xaes->tweak.rounds);
17685
                ret = 0;
17686
            }
17687
            else
17688
#endif
17689
#if defined(HAVE_INTEL_AVX1)
17690
            if (IS_INTEL_AVX1(intel_flags)) {
17691
                AES_XTS_init_avx1(stream->tweak_block,
17692
                                  (const byte*)xaes->tweak.key,
17693
                                  (int)xaes->tweak.rounds);
17694
                ret = 0;
17695
            }
17696
            else
17697
#endif
17698
            {
17699
                AES_XTS_init_aesni(stream->tweak_block,
17700
                                   (const byte*)xaes->tweak.key,
17701
                                   (int)xaes->tweak.rounds);
17702
                ret = 0;
17703
            }
17704
            RESTORE_VECTOR_REGISTERS();
17705
        }
17706
        else
17707
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
17708
        {
17709
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
17710
        }
17711
17712
    }
17713
17714
    return ret;
17715
}
17716
17717
/* Block-streaming AES-XTS
17718
 *
17719
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
17720
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsDecryptUpdate().
17721
 * wc_AesXtsDecryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
17722
 *
17723
 * xaes  AES keys to use for block encrypt/decrypt
17724
 * out   output buffer to hold plain text
17725
 * in    input cipher text buffer to decrypt
17726
 * sz    size of both out and in buffers
17727
 * i     tweak buffer of size WC_AES_BLOCK_SIZE.
17728
 *
17729
 * returns 0 on success
17730
 */
17731
static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17732
                           struct XtsAesStreamData *stream)
17733
{
17734
    int ret;
17735
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17736
    Aes *aes;
17737
#endif
17738
17739
    if (xaes == NULL || out == NULL || in == NULL) {
17740
        return BAD_FUNC_ARG;
17741
    }
17742
17743
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17744
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
17745
    aes = &xaes->aes_decrypt;
17746
#else
17747
    aes = &xaes->aes;
17748
#endif
17749
#endif
17750
17751
    if (sz < WC_AES_BLOCK_SIZE) {
17752
        WOLFSSL_MSG("Cipher text input too small for decryption");
17753
        return BAD_FUNC_ARG;
17754
    }
17755
17756
    if (stream->bytes_crypted_with_this_tweak &
17757
        ((word32)WC_AES_BLOCK_SIZE - 1U))
17758
    {
17759
        WOLFSSL_MSG("AesXtsDecryptUpdate after previous finalizing call");
17760
        return BAD_FUNC_ARG;
17761
    }
17762
17763
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
17764
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
17765
                             stream->bytes_crypted_with_this_tweak))
17766
    {
17767
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
17768
                    "in AesXtsDecryptUpdate().");
17769
    }
17770
#endif
17771
17772
    {
17773
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17774
        if (aes->use_aesni) {
17775
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
17776
#if defined(HAVE_INTEL_AVX512)
17777
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17778
                AES_XTS_decrypt_update_avx512(in, out, sz,
17779
                                              (const byte*)aes->key,
17780
                                              stream->tweak_block,
17781
                                              (int)aes->rounds);
17782
                ret = 0;
17783
            }
17784
            else
17785
#endif
17786
#if defined(HAVE_INTEL_VAES)
17787
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17788
                AES_XTS_decrypt_update_vaes(in, out, sz,
17789
                                            (const byte*)aes->key,
17790
                                            stream->tweak_block,
17791
                                            (int)aes->rounds);
17792
                ret = 0;
17793
            }
17794
            else
17795
#endif
17796
#if defined(HAVE_INTEL_AVX1)
17797
            if (IS_INTEL_AVX1(intel_flags)) {
17798
                AES_XTS_decrypt_update_avx1(in, out, sz,
17799
                                            (const byte*)aes->key,
17800
                                            stream->tweak_block,
17801
                                            (int)aes->rounds);
17802
                ret = 0;
17803
            }
17804
            else
17805
#endif
17806
            {
17807
                AES_XTS_decrypt_update_aesni(in, out, sz,
17808
                                             (const byte*)aes->key,
17809
                                             stream->tweak_block,
17810
                                             (int)aes->rounds);
17811
                ret = 0;
17812
            }
17813
            RESTORE_VECTOR_REGISTERS();
17814
        }
17815
        else
17816
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
17817
        {
17818
            ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
17819
                                         stream->tweak_block);
17820
        }
17821
    }
17822
17823
    return ret;
17824
}
17825
17826
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17827
                           struct XtsAesStreamData *stream)
17828
{
17829
    if (stream == NULL)
17830
        return BAD_FUNC_ARG;
17831
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
17832
        return BAD_FUNC_ARG;
17833
    return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
17834
}
17835
17836
int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17837
                           struct XtsAesStreamData *stream)
17838
{
17839
    int ret;
17840
    if (stream == NULL)
17841
        return BAD_FUNC_ARG;
17842
    if (sz > 0)
17843
        ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
17844
    else
17845
        ret = 0;
17846
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
17847
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
17848
     * after finalization.
17849
     */
17850
    stream->bytes_crypted_with_this_tweak |= 1U;
17851
#ifdef WOLFSSL_CHECK_MEM_ZERO
17852
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
17853
#endif
17854
    return ret;
17855
}
17856
17857
#endif /* WOLFSSL_AESXTS_STREAM */
17858
#endif /* HAVE_AES_DECRYPT */
17859
17860
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
17861
 * sectorSz bytes
17862
 *
17863
 * xaes     AES keys to use for block encrypt
17864
 * out      output buffer to hold cipher text
17865
 * in       input plain text buffer to encrypt
17866
 * sz       size of both out and in buffers
17867
 * sector   value to use for tweak
17868
 * sectorSz size of the sector
17869
 *
17870
 * returns 0 on success
17871
 */
17872
int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
17873
        word32 sz, word64 sector, word32 sectorSz)
17874
{
17875
    int ret  = 0;
17876
    word32 iter = 0;
17877
    word32 sectorCount;
17878
    word32 remainder;
17879
17880
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
17881
        return BAD_FUNC_ARG;
17882
    }
17883
17884
    if (sz < WC_AES_BLOCK_SIZE) {
17885
        WOLFSSL_MSG("Cipher text input too small for encryption");
17886
        return BAD_FUNC_ARG;
17887
    }
17888
17889
    sectorCount  = sz / sectorSz;
17890
    remainder = sz % sectorSz;
17891
17892
    while (sectorCount) {
17893
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
17894
                in + (iter * sectorSz), sectorSz, sector);
17895
        if (ret != 0)
17896
            break;
17897
17898
        sectorCount--;
17899
        iter++;
17900
        sector++;
17901
    }
17902
17903
    if (remainder && ret == 0)
17904
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
17905
                in + (iter * sectorSz), remainder, sector);
17906
17907
    return ret;
17908
}
17909
17910
#ifdef HAVE_AES_DECRYPT
17911
17912
/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
17913
 *
17914
 * xaes     AES keys to use for block decrypt
17915
 * out      output buffer to hold cipher text
17916
 * in       input plain text buffer to encrypt
17917
 * sz       size of both out and in buffers
17918
 * sector   value to use for tweak
17919
 * sectorSz size of the sector
17920
 *
17921
 * returns 0 on success
17922
 */
17923
int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
17924
        word32 sz, word64 sector, word32 sectorSz)
17925
{
17926
    int ret  = 0;
17927
    word32 iter = 0;
17928
    word32 sectorCount;
17929
    word32 remainder;
17930
17931
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
17932
        return BAD_FUNC_ARG;
17933
    }
17934
17935
    if (sz < WC_AES_BLOCK_SIZE) {
17936
        WOLFSSL_MSG("Cipher text input too small for decryption");
17937
        return BAD_FUNC_ARG;
17938
    }
17939
17940
    sectorCount  = sz / sectorSz;
17941
    remainder = sz % sectorSz;
17942
17943
    while (sectorCount) {
17944
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
17945
                in + (iter * sectorSz), sectorSz, sector);
17946
        if (ret != 0)
17947
            break;
17948
17949
        sectorCount--;
17950
        iter++;
17951
        sector++;
17952
    }
17953
17954
    if (remainder && ret == 0)
17955
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
17956
                in + (iter * sectorSz), remainder, sector);
17957
17958
    return ret;
17959
}
17960
#endif /* HAVE_AES_DECRYPT */
17961
#endif /* WOLFSSL_AES_XTS */
17962
17963
#ifdef WOLFSSL_CMAC
17964
17965
int wc_local_CmacUpdateAes(struct Cmac *cmac, const byte* in, word32 inSz) {
17966
    int ret = 0;
17967
    Aes *aes = &cmac->aes;
17968
#ifdef WC_AES_HAVE_PREFETCH_ARG
17969
    int did_prefetches = 0;
17970
#endif
17971
17972
    VECTOR_REGISTERS_PUSH;
17973
17974
    while ((ret == 0) && (inSz != 0)) {
17975
        word32 add = min(inSz, WC_AES_BLOCK_SIZE - cmac->bufferSz);
17976
        XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
17977
17978
        cmac->bufferSz += add;
17979
        inSz -= add;
17980
        in += add;
17981
17982
        if (cmac->bufferSz == WC_AES_BLOCK_SIZE && inSz != 0) {
17983
            xorbuf(cmac->buffer, cmac->digest, WC_AES_BLOCK_SIZE);
17984
            ret = AesEncrypt_preFetchOpt(aes, cmac->buffer,
17985
                                            cmac->digest, &did_prefetches);
17986
            if (ret == 0) {
17987
                cmac->totalSz += WC_AES_BLOCK_SIZE;
17988
                cmac->bufferSz = 0;
17989
            }
17990
        }
17991
    }
17992
17993
    VECTOR_REGISTERS_POP;
17994
17995
    return ret;
17996
}
17997
17998
#endif /* WOLFSSL_CMAC */
17999
18000
#ifdef WOLFSSL_AES_SIV
18001
18002
/*
18003
 * See RFC 5297 Section 2.4.
18004
 */
18005
static WARN_UNUSED_RESULT int S2V(
18006
    const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc,
18007
    const byte* nonce, word32 nonceSz, const byte* data,
18008
    word32 dataSz, byte* out)
18009
{
18010
#ifdef WOLFSSL_SMALL_STACK
18011
    byte* tmp[3] = {NULL, NULL, NULL};
18012
    int i;
18013
    Cmac* cmac;
18014
#else
18015
    byte tmp[3][WC_AES_BLOCK_SIZE];
18016
    Cmac cmac[1];
18017
#endif
18018
    word32 macSz = WC_AES_BLOCK_SIZE;
18019
    int ret = 0;
18020
    byte tmpi = 0;
18021
    word32 ai;
18022
    word32 zeroBytes;
18023
18024
#ifdef WOLFSSL_SMALL_STACK
18025
    for (i = 0; i < 3; ++i) {
18026
        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18027
        if (tmp[i] == NULL) {
18028
            ret = MEMORY_E;
18029
            break;
18030
        }
18031
    }
18032
    if (ret == 0)
18033
#endif
18034
18035
    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
18036
        /* See RFC 5297 Section 7. */
18037
        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
18038
                    " 126.");
18039
        ret = BAD_FUNC_ARG;
18040
    }
18041
18042
    if (ret == 0) {
18043
        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
18044
        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
18045
18046
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
18047
                                 key, keySz);
18048
    }
18049
18050
    if (ret == 0) {
18051
        /* Loop over authenticated associated data AD1..ADn */
18052
        for (ai = 0; ai < numAssoc; ++ai) {
18053
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
18054
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
18055
                                     assoc[ai].assocSz, key, keySz);
18056
            if (ret != 0)
18057
                break;
18058
            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
18059
            tmpi = (byte)(1 - tmpi);
18060
        }
18061
18062
        /* Add nonce as final AD. See RFC 5297 Section 3. */
18063
        if ((ret == 0) && (nonceSz > 0)) {
18064
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
18065
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
18066
                                     nonceSz, key, keySz);
18067
            if (ret == 0) {
18068
                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
18069
            }
18070
            tmpi = (byte)(1U - tmpi);
18071
        }
18072
18073
        /* For simplicity of the remaining code, make sure the "final" result
18074
           is always in tmp[0]. */
18075
        if (tmpi == 1) {
18076
            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
18077
        }
18078
    }
18079
18080
    if (ret == 0) {
18081
        if (dataSz >= WC_AES_BLOCK_SIZE) {
18082
18083
            WC_ALLOC_VAR_EX(cmac, Cmac, 1, NULL, DYNAMIC_TYPE_CMAC,
18084
                ret=MEMORY_E);
18085
            if (WC_VAR_OK(cmac))
18086
            {
18087
            #ifdef WOLFSSL_CHECK_MEM_ZERO
18088
                /* Aes part is checked by wc_AesFree. */
18089
                wc_MemZero_Add("wc_AesCmacGenerate cmac",
18090
                    ((unsigned char *)cmac) + sizeof(Aes),
18091
                    sizeof(Cmac) - sizeof(Aes));
18092
            #endif
18093
                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
18094
                       WC_AES_BLOCK_SIZE);
18095
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
18096
                if (ret == 0) {
18097
                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
18098
                }
18099
                if (ret == 0) {
18100
                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
18101
                }
18102
                if (ret == 0) {
18103
                    ret = wc_CmacFinal(cmac, out, &macSz);
18104
                }
18105
            }
18106
        #ifdef WOLFSSL_SMALL_STACK
18107
            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
18108
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
18109
            wc_MemZero_Check(cmac, sizeof(Cmac));
18110
        #endif
18111
        }
18112
        else {
18113
            XMEMCPY(tmp[2], data, dataSz);
18114
            tmp[2][dataSz] |= 0x80;
18115
            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
18116
            if (zeroBytes != 0) {
18117
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
18118
            }
18119
            ShiftAndXorRb(tmp[1], tmp[0]);
18120
            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
18121
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
18122
                                     keySz);
18123
        }
18124
    }
18125
18126
#ifdef WOLFSSL_SMALL_STACK
18127
    for (i = 0; i < 3; ++i) {
18128
        if (tmp[i] != NULL) {
18129
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
18130
        }
18131
    }
18132
#endif
18133
18134
    return ret;
18135
}
18136
18137
static WARN_UNUSED_RESULT int AesSivCipher(
18138
    const byte* key, word32 keySz, const AesSivAssoc* assoc,
18139
    word32 numAssoc, const byte* nonce, word32 nonceSz,
18140
    const byte* data, word32 dataSz, byte* siv, byte* out,
18141
    int enc)
18142
{
18143
    int ret = 0;
18144
    WC_DECLARE_VAR(aes, Aes, 1, 0);
18145
    byte sivTmp[WC_AES_BLOCK_SIZE];
18146
18147
    if (key == NULL || siv == NULL || out == NULL) {
18148
        WOLFSSL_MSG("Bad parameter");
18149
        ret = BAD_FUNC_ARG;
18150
    }
18151
18152
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
18153
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
18154
        ret = BAD_FUNC_ARG;
18155
    }
18156
18157
    if (ret == 0) {
18158
        if (enc == 1) {
18159
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
18160
                      dataSz, sivTmp);
18161
            if (ret != 0) {
18162
                WOLFSSL_MSG("S2V failed.");
18163
            }
18164
            else {
18165
                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
18166
            }
18167
        }
18168
        else {
18169
            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
18170
        }
18171
    }
18172
18173
    if (ret == 0) {
18174
#ifdef WOLFSSL_SMALL_STACK
18175
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
18176
#else
18177
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
18178
#endif
18179
        if (ret != 0) {
18180
            WOLFSSL_MSG("Failed to initialized AES object.");
18181
        }
18182
    }
18183
18184
    if (ret == 0) {
18185
        if (dataSz > 0) {
18186
            sivTmp[12] &= 0x7f;
18187
            sivTmp[8] &= 0x7f;
18188
            ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
18189
                               AES_ENCRYPTION);
18190
            if (ret != 0) {
18191
                WOLFSSL_MSG("Failed to set key for AES-CTR.");
18192
            }
18193
            else {
18194
                ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
18195
                if (ret != 0) {
18196
                    WOLFSSL_MSG("AES-CTR encryption failed.");
18197
                }
18198
            }
18199
        }
18200
18201
        if (ret == 0 && enc == 0) {
18202
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out,
18203
                      dataSz, sivTmp);
18204
            if (ret != 0) {
18205
                WOLFSSL_MSG("S2V failed.");
18206
            }
18207
18208
            if (ret == 0 && ConstantCompare(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
18209
                WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
18210
                ret = AES_SIV_AUTH_E;
18211
            }
18212
        }
18213
18214
        if (ret != 0) {
18215
            ForceZero(out, dataSz);
18216
        }
18217
18218
    #ifdef WOLFSSL_SMALL_STACK
18219
        wc_AesDelete(aes, NULL);
18220
    #else
18221
        wc_AesFree(aes);
18222
    #endif
18223
    }
18224
18225
    ForceZero(sivTmp, sizeof(sivTmp));
18226
18227
    return ret;
18228
}
18229
18230
/*
18231
 * See RFC 5297 Section 2.6.
18232
 */
18233
int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
18234
                     word32 assocSz, const byte* nonce, word32 nonceSz,
18235
                     const byte* in, word32 inSz, byte* siv, byte* out)
18236
{
18237
    AesSivAssoc ad;
18238
    ad.assoc = assoc;
18239
    ad.assocSz = assocSz;
18240
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
18241
                        siv, out, 1);
18242
}
18243
18244
/*
18245
 * See RFC 5297 Section 2.7.
18246
 */
18247
int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
18248
                     word32 assocSz, const byte* nonce, word32 nonceSz,
18249
                     const byte* in, word32 inSz, byte* siv, byte* out)
18250
{
18251
    AesSivAssoc ad;
18252
    ad.assoc = assoc;
18253
    ad.assocSz = assocSz;
18254
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
18255
                        siv, out, 0);
18256
}
18257
18258
/*
18259
 * See RFC 5297 Section 2.6.
18260
 */
18261
int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
18262
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
18263
                        const byte* in, word32 inSz, byte* siv, byte* out)
18264
{
18265
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
18266
                        siv, out, 1);
18267
}
18268
18269
/*
18270
 * See RFC 5297 Section 2.7.
18271
 */
18272
int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
18273
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
18274
                        const byte* in, word32 inSz, byte* siv, byte* out)
18275
{
18276
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
18277
                        siv, out, 0);
18278
}
18279
18280
#endif /* WOLFSSL_AES_SIV */
18281
18282
#ifdef WOLFSSL_AESGCM_SIV
18283
18284
/* AES-GCM-SIV - a nonce misuse-resistant AEAD. See RFC 8452.
18285
 *
18286
 * The implementation here is portable C.  AES block operations reuse the
18287
 * internal wc_AesEncrypt(), so HAVE_AESGCM is required for that to be built.
18288
 */
18289
#ifndef HAVE_AESGCM
18290
    #error "WOLFSSL_AESGCM_SIV requires HAVE_AESGCM"
18291
#endif
18292
18293
#define AES_GCM_SIV_NONCE_SZ  12
18294
#define AES_GCM_SIV_TAG_SZ    WC_AES_BLOCK_SIZE
18295
18296
#ifndef GCM_SMALL
18297
/* GF(2^128) reduction table used by the table-based software multiplies; not
18298
 * needed by the table-free GCM_SMALL variant. R[a] is the contribution, to the
18299
 * top two bytes, of reducing a nibble 'a' shifted out past x^127 (the GHASH
18300
 * polynomial x^128+x^7+x^2+x+1). Same table wolfSSL uses for table GHASH. */
18301
static const byte AES_GCM_SIV_R[16][2] = {
18302
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
18303
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
18304
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
18305
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
18306
};
18307
#endif
18308
18309
/* Reverse the order of the 16 bytes of a block. in and out must not alias. */
18310
static WC_INLINE void AesGcmSivByteReverse(byte* out, const byte* in)
18311
{
18312
#if !defined(WOLFSSL_USE_ALIGN) && defined(WORD64_AVAILABLE)
18313
    /* Unaligned word access is permitted: reverse eight bytes at a time with a
18314
     * hardware byte-swap rather than one byte at a time. Endian independent -
18315
     * load native, reverse the value's bytes, store native: that reverses the
18316
     * bytes in memory on both little- and big-endian. */
18317
    word64 lo, hi;
18318
    XMEMCPY(&lo, in,     sizeof(lo));
18319
    XMEMCPY(&hi, in + 8, sizeof(hi));
18320
    lo = ByteReverseWord64(lo);
18321
    hi = ByteReverseWord64(hi);
18322
    XMEMCPY(out,     &hi, sizeof(hi));
18323
    XMEMCPY(out + 8, &lo, sizeof(lo));
18324
#else
18325
    int i;
18326
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
18327
        out[i] = in[WC_AES_BLOCK_SIZE - 1 - i];
18328
    }
18329
#endif
18330
}
18331
18332
/* POLYVAL state (RFC 8452 Section 3). POLYVAL is GHASH on byte-reversed inputs,
18333
 * so the field is the GHASH field with the most-significant bit of byte 0 the
18334
 * x^0 coefficient (see RFC 8452 Appendix A). The key is one of:
18335
 *  - GCM_SMALL: the 16-byte key (table-free, smallest footprint).
18336
 *  - word64:    a Shoup 4-bit table (256 bytes), word64 multiply - used when a
18337
 *               64-bit type is available and GCM_WORD32 is not requested.
18338
 *  - word32:    the same 4-bit table, word32 multiply - used for GCM_WORD32 or
18339
 *               when no 64-bit type is available.
18340
 *
18341
 * Every variant reads the message, key and running sum a byte at a time and
18342
 * (the word64/word32 variants) load/store their words with explicit shifts or
18343
 * a byte-swap rather than casting buffers, so all are independent of platform
18344
 * endianness; the word loads also respect WOLFSSL_USE_ALIGN, so input, key and
18345
 * output buffers may be little- or big-endian and aligned or unaligned.
18346
 */
18347
/* When the generated x86_64 AES-NI/PCLMUL POLYVAL multiply is available
18348
 * (aes_gcm_asm.S), the per-block multiply can be offloaded to it at runtime.
18349
 * This is the generated external assembly - no assembly lives in this file. */
18350
#if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
18351
    #define WC_POLYVAL_ASM
18352
#ifdef __cplusplus
18353
    extern "C" {
18354
#endif
18355
    /* s += POLYVAL of 'blocks' 16-byte blocks of data, hash key h prepared as
18356
     * the byte-reversed mulX_GHASH(ByteReverse(authKey)); s is POLYVAL byte
18357
     * order. */
18358
    void AES_GCMSIV_polyval_aesni(unsigned char* s, const unsigned char* h,
18359
        const unsigned char* data, word32 blocks)
18360
        XASM_LINK("AES_GCMSIV_polyval_aesni");
18361
#ifdef HAVE_INTEL_AVX1
18362
    void AES_GCMSIV_polyval_avx1(unsigned char* s, const unsigned char* h,
18363
        const unsigned char* data, word32 blocks)
18364
        XASM_LINK("AES_GCMSIV_polyval_avx1");
18365
#endif
18366
#ifdef HAVE_INTEL_VAES
18367
    /* Aggregated 2-blocks-per-ymm POLYVAL (VPCLMULQDQ). */
18368
    void AES_GCMSIV_polyval_vaes(unsigned char* s, const unsigned char* h,
18369
        const unsigned char* data, word32 blocks)
18370
        XASM_LINK("AES_GCMSIV_polyval_vaes");
18371
#endif
18372
#ifdef HAVE_INTEL_AVX512
18373
    /* Aggregated 4-blocks-per-zmm POLYVAL (VPCLMULQDQ). */
18374
    void AES_GCMSIV_polyval_avx512(unsigned char* s, const unsigned char* h,
18375
        const unsigned char* data, word32 blocks)
18376
        XASM_LINK("AES_GCMSIV_polyval_avx512");
18377
#endif
18378
    /* AES-GCM-SIV CTR keystream (RFC 8452): a 32-bit little-endian counter in
18379
     * the first 4 bytes of the block (mod 2^32, no carry), block used directly
18380
     * as the AES input. Encrypts the full-16-byte-block portion of 'length'
18381
     * bytes (pipelined), advancing and writing 'ctr' back. */
18382
    #define WC_GCMSIV_CTR_ASM
18383
    void AES_GCMSIV_ctr_aesni(const unsigned char* in, unsigned char* out,
18384
        unsigned long length, const unsigned char* KS, int nr,
18385
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_aesni");
18386
#ifdef HAVE_INTEL_AVX1
18387
    void AES_GCMSIV_ctr_avx1(const unsigned char* in, unsigned char* out,
18388
        unsigned long length, const unsigned char* KS, int nr,
18389
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_avx1");
18390
#endif
18391
#ifdef HAVE_INTEL_VAES
18392
    void AES_GCMSIV_ctr_vaes(const unsigned char* in, unsigned char* out,
18393
        unsigned long length, const unsigned char* KS, int nr,
18394
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_vaes");
18395
#endif
18396
#ifdef HAVE_INTEL_AVX512
18397
    void AES_GCMSIV_ctr_avx512(const unsigned char* in, unsigned char* out,
18398
        unsigned long length, const unsigned char* KS, int nr,
18399
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_avx512");
18400
#endif
18401
#ifdef __cplusplus
18402
    }
18403
#endif
18404
#elif defined(WOLFSSL_ARMASM) && defined(__aarch64__)
18405
    /* The generated AArch64 POLYVAL multiplies (armv8-aes-asm.S) offload the
18406
     * per-block multiply: PMULL when the CPU has the crypto extension, else the
18407
     * 8-bit-pmul NEON variant, else the scalar (base) variant. This is the
18408
     * generated external assembly - no assembly lives here. */
18409
    #define WC_POLYVAL_ASM
18410
    #define WC_POLYVAL_ASM_AARCH64
18411
    /* The base (scalar) variant multiplies through the word64 software table
18412
     * poly->m, so it is only available when that table is built. */
18413
    #if defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) && \
18414
        !defined(GCM_SMALL) && !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
18415
        #define WC_POLYVAL_ASM_AARCH64_BASE
18416
    #endif
18417
#ifdef __cplusplus
18418
    extern "C" {
18419
#endif
18420
    /* s += POLYVAL of 'blocks' 16-byte blocks of data. For the PMULL and NEON
18421
     * variants h is the prepared key (byte-reversed mulX_GHASH(ByteReverse(
18422
     * authKey))); for the base variant h is the word64 table poly->m. s is in
18423
     * POLYVAL byte order in every case. */
18424
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
18425
    void AES_GCMSIV_polyval_pmull(unsigned char* s, const unsigned char* h,
18426
        const unsigned char* data, word32 blocks)
18427
        XASM_LINK("AES_GCMSIV_polyval_pmull");
18428
#endif
18429
#ifndef WOLFSSL_ARMASM_NO_NEON
18430
    void AES_GCMSIV_polyval_neon(unsigned char* s, const unsigned char* h,
18431
        const unsigned char* data, word32 blocks)
18432
        XASM_LINK("AES_GCMSIV_polyval_neon");
18433
#endif
18434
#ifdef WC_POLYVAL_ASM_AARCH64_BASE
18435
    void AES_GCMSIV_polyval_base(unsigned char* s, const unsigned char* h,
18436
        const unsigned char* data, word32 blocks)
18437
        XASM_LINK("AES_GCMSIV_polyval_base");
18438
#endif
18439
    /* AES-GCM-SIV CTR keystream (RFC 8452): 32-bit little-endian counter in the
18440
     * first 4 bytes of the block, mod 2^32, block used directly. Full-block
18441
     * portion only (the C tail finishes any partial block). The crypto variant
18442
     * pipelines aese; the NEON/base variants pipeline software table AES. KS is
18443
     * the AES key schedule in every case. */
18444
    #define WC_GCMSIV_CTR_ASM
18445
    #define WC_GCMSIV_CTR_ASM_AARCH64
18446
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
18447
    void AES_GCMSIV_ctr_aarch64(const unsigned char* in, unsigned char* out,
18448
        unsigned long length, const unsigned char* KS, int nr,
18449
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_aarch64");
18450
#endif
18451
#ifndef WOLFSSL_ARMASM_NO_NEON
18452
    void AES_GCMSIV_ctr_neon(const unsigned char* in, unsigned char* out,
18453
        unsigned long length, const unsigned char* KS, int nr,
18454
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_neon");
18455
#endif
18456
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18457
    void AES_GCMSIV_ctr_base(const unsigned char* in, unsigned char* out,
18458
        unsigned long length, const unsigned char* KS, int nr,
18459
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_base");
18460
#endif
18461
#ifdef __cplusplus
18462
    }
18463
#endif
18464
#elif defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
18465
      !defined(WOLFSSL_ARMASM_THUMB2)
18466
    /* AArch32 (32-bit ARM). The generated armv8-32-aes-asm.S provides POLYVAL
18467
     * and CTR for the crypto (vmull.p64 / aese) and base (table) variants.
18468
     * crypto-vs-base is compile-time (WOLFSSL_ARMASM_NO_HW_CRYPTO) with no
18469
     * runtime fallback - the same as the rest of the AArch32 AES. */
18470
    #define WC_POLYVAL_ASM
18471
    #define WC_POLYVAL_ASM_AARCH32
18472
    #define WC_GCMSIV_CTR_ASM
18473
    #define WC_GCMSIV_CTR_ASM_AARCH32
18474
    /* The base POLYVAL multiplies through the word64 software table poly->m. It
18475
     * is only compiled in the base (no-crypto) build and only when that table
18476
     * is built. */
18477
    #if defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) && defined(WORD64_AVAILABLE) && \
18478
        !defined(GCM_WORD32) && !defined(GCM_SMALL)
18479
        #define WC_POLYVAL_ASM_AARCH32_BASE
18480
    #endif
18481
#ifdef __cplusplus
18482
    extern "C" {
18483
#endif
18484
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
18485
    void AES_GCMSIV_polyval_crypto(unsigned char* s, const unsigned char* h,
18486
        const unsigned char* data, word32 blocks)
18487
        XASM_LINK("AES_GCMSIV_polyval_crypto");
18488
    void AES_GCMSIV_ctr_crypto(const unsigned char* in, unsigned char* out,
18489
        unsigned long length, const unsigned char* KS, int nr,
18490
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_crypto");
18491
#else
18492
#ifdef WC_POLYVAL_ASM_AARCH32_BASE
18493
    void AES_GCMSIV_polyval_base(unsigned char* s, const unsigned char* h,
18494
        const unsigned char* data, word32 blocks)
18495
        XASM_LINK("AES_GCMSIV_polyval_base");
18496
#endif
18497
    void AES_GCMSIV_ctr_base(const unsigned char* in, unsigned char* out,
18498
        unsigned long length, const unsigned char* KS, int nr,
18499
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_base");
18500
#endif
18501
#ifdef __cplusplus
18502
    }
18503
#endif
18504
#elif defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_THUMB2)
18505
    /* Thumb-2 (32-bit ARM, Thumb-2 encoding). A single table-based variant
18506
     * (ported from the AArch32 base): POLYVAL multiplies through the word64
18507
     * software table poly->m; CTR is the table AES with the SIV counter. */
18508
    #define WC_GCMSIV_CTR_ASM
18509
    #define WC_GCMSIV_CTR_ASM_THUMB2
18510
    #if defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) && !defined(GCM_SMALL)
18511
        #define WC_POLYVAL_ASM
18512
        #define WC_POLYVAL_ASM_THUMB2
18513
    #endif
18514
#ifdef __cplusplus
18515
    extern "C" {
18516
#endif
18517
#ifdef WC_POLYVAL_ASM_THUMB2
18518
    void AES_GCMSIV_polyval_thumb2(unsigned char* s, const unsigned char* h,
18519
        const unsigned char* data, word32 blocks)
18520
        XASM_LINK("AES_GCMSIV_polyval_thumb2");
18521
#endif
18522
    void AES_GCMSIV_ctr_thumb2(const unsigned char* in, unsigned char* out,
18523
        unsigned long length, const unsigned char* KS, int nr,
18524
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_thumb2");
18525
#ifdef __cplusplus
18526
    }
18527
#endif
18528
#endif
18529
18530
#ifdef WC_POLYVAL_ASM
18531
    typedef void (*AesGcmSivPolyvalFn)(unsigned char* s, const unsigned char* h,
18532
        const unsigned char* data, word32 blocks);
18533
#endif
18534
#ifdef WC_GCMSIV_CTR_ASM
18535
    typedef void (*AesGcmSivCtrFn)(const unsigned char* in, unsigned char* out,
18536
        unsigned long length, const unsigned char* KS, int nr,
18537
        unsigned char* ctr);
18538
#endif
18539
18540
typedef struct AesGcmSivPolyval {
18541
#ifdef WC_POLYVAL_ASM
18542
    byte hHw[WC_AES_BLOCK_SIZE]; /* prepared key for the asm multiply */
18543
    const byte* asmKey;          /* key passed to fn: hHw, or the table below */
18544
    AesGcmSivPolyvalFn fn;       /* asm multiply, or NULL for software */
18545
#endif
18546
#if defined(GCM_SMALL)
18547
    byte   h[WC_AES_BLOCK_SIZE]; /* hash key = mulX_GHASH(ByteReverse(H)) */
18548
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
18549
    word64 m[16][2];             /* m[i] = i * mulX_GHASH(ByteReverse(H)) */
18550
#else
18551
    word32 m[16][4];             /* m[i] = i * mulX_GHASH(ByteReverse(H)) */
18552
#endif
18553
    byte s[WC_AES_BLOCK_SIZE];   /* running sum, GHASH representation */
18554
} AesGcmSivPolyval;
18555
18556
/* Multiply a GF(2^128) element (GHASH bit order: the most-significant bit of
18557
 * byte 0 is the x^0 coefficient) by x: shift the 128-bit value right by one
18558
 * and reduce with the GHASH polynomial. Branch free, so constant time. Used by
18559
 * the GCM_SMALL multiply and to derive the carry-less-multiply asm hash key
18560
 * (mulX_GHASH); the word64/word32 table variants use AesGcmSivMulX64/32, so this
18561
 * is only compiled when one of those two callers is. Placed after the
18562
 * WC_POLYVAL_ASM #defines above so that guard is resolved here. */
18563
#if defined(GCM_SMALL) || defined(WC_POLYVAL_ASM)
18564
static WC_INLINE void AesGcmSivMulX(byte* x)
18565
{
18566
    int i;
18567
    byte carryIn = 0;
18568
    byte borrow = (byte)((0x00U - (x[WC_AES_BLOCK_SIZE - 1] & 0x01U)) & 0xE1U);
18569
18570
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
18571
        byte carryOut = (byte)((x[i] & 0x01) << 7);
18572
        x[i] = (byte)((x[i] >> 1) | carryIn);
18573
        carryIn = carryOut;
18574
    }
18575
    x[0] ^= borrow;
18576
}
18577
#endif /* GCM_SMALL || WC_POLYVAL_ASM */
18578
18579
#if defined(GCM_SMALL)
18580
18581
/* s = s * h with no precomputed table: decompose h bit-by-bit and accumulate
18582
 * shifted copies of s. Mirrors wolfSSL's GCM_SMALL GMULT. */
18583
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
18584
{
18585
    byte Z[WC_AES_BLOCK_SIZE];
18586
    byte V[WC_AES_BLOCK_SIZE];
18587
    int i, j;
18588
18589
    XMEMSET(Z, 0, sizeof(Z));
18590
    XMEMCPY(V, poly->s, WC_AES_BLOCK_SIZE);
18591
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
18592
        byte y = poly->h[i];
18593
        for (j = 0; j < 8; j++) {
18594
            if (y & 0x80) {
18595
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
18596
            }
18597
            AesGcmSivMulX(V);
18598
            y = (byte)(y << 1);
18599
        }
18600
    }
18601
    XMEMCPY(poly->s, Z, WC_AES_BLOCK_SIZE);
18602
}
18603
18604
/* Store the hash key mulX_GHASH(ByteReverse(h)); no table to build. */
18605
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
18606
{
18607
    AesGcmSivByteReverse(poly->h, h);
18608
    AesGcmSivMulX(poly->h);
18609
    XMEMSET(poly->s, 0, sizeof(poly->s));
18610
}
18611
18612
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
18613
18614
/* Load/store a big-endian word64 - the high word is bytes 0..7 of the block,
18615
 * so byte 0 (the x^0..x^7 coefficients) is the most-significant byte.
18616
 *
18617
 * Where unaligned word access is permitted (!WOLFSSL_USE_ALIGN) this is a
18618
 * single word64 load/store plus a hardware byte-swap on little-endian; where
18619
 * alignment is required it is assembled a byte at a time. Both forms are
18620
 * endian independent. */
18621
#ifndef WOLFSSL_USE_ALIGN
18622
static WC_INLINE word64 AesGcmSivLoad64(const byte* b)
18623
{
18624
    word64 v;
18625
    XMEMCPY(&v, b, sizeof(v));
18626
#ifdef LITTLE_ENDIAN_ORDER
18627
    v = ByteReverseWord64(v);
18628
#endif
18629
    return v;
18630
}
18631
static WC_INLINE void AesGcmSivStore64(byte* b, word64 v)
18632
{
18633
#ifdef LITTLE_ENDIAN_ORDER
18634
    v = ByteReverseWord64(v);
18635
#endif
18636
    XMEMCPY(b, &v, sizeof(v));
18637
}
18638
#else
18639
static WC_INLINE word64 AesGcmSivLoad64(const byte* b)
18640
{
18641
    return ((word64)b[0] << 56) | ((word64)b[1] << 48) |
18642
           ((word64)b[2] << 40) | ((word64)b[3] << 32) |
18643
           ((word64)b[4] << 24) | ((word64)b[5] << 16) |
18644
           ((word64)b[6] <<  8) | ((word64)b[7]);
18645
}
18646
static WC_INLINE void AesGcmSivStore64(byte* b, word64 v)
18647
{
18648
    b[0] = (byte)(v >> 56); b[1] = (byte)(v >> 48);
18649
    b[2] = (byte)(v >> 40); b[3] = (byte)(v >> 32);
18650
    b[4] = (byte)(v >> 24); b[5] = (byte)(v >> 16);
18651
    b[6] = (byte)(v >>  8); b[7] = (byte)(v);
18652
}
18653
#endif
18654
18655
/* Multiply the 128-bit value (hi,lo) by x and reduce: a right shift by one of
18656
 * the whole value, XOR-ing the reduction polynomial (0xe1 into byte 0) when a
18657
 * one is shifted out past x^127 (the low bit of lo). */
18658
static WC_INLINE void AesGcmSivMulX64(word64* hi, word64* lo)
18659
{
18660
    word64 carry = *lo & 1;
18661
    *lo = (*lo >> 1) | (*hi << 63);
18662
    *hi = (*hi >> 1) ^ (W64LIT(0xe100000000000000) & (word64)(0 - carry));
18663
}
18664
18665
/* s = s * H. The accumulator is shifted right a nibble at a time; the nibble
18666
 * that falls off is reduced through AES_GCM_SIV_R into the top two bytes. */
18667
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
18668
{
18669
    byte* x = poly->s;
18670
    word64 (*m)[2] = poly->m;
18671
    word64 zHi = 0, zLo = 0;
18672
    int i;
18673
18674
    for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
18675
        byte xi = x[i];
18676
        byte a;
18677
18678
        /* low nibble */
18679
        zHi ^= m[xi & 0xf][0];
18680
        zLo ^= m[xi & 0xf][1];
18681
        a = (byte)(zLo & 0xf);
18682
        zLo = (zLo >> 4) | (zHi << 60);
18683
        zHi = zHi >> 4;
18684
        zHi ^= ((word64)AES_GCM_SIV_R[a][0] << 56) |
18685
               ((word64)AES_GCM_SIV_R[a][1] << 48);
18686
18687
        /* high nibble */
18688
        zHi ^= m[xi >> 4][0];
18689
        zLo ^= m[xi >> 4][1];
18690
        if (i == 0) {
18691
            break;
18692
        }
18693
        a = (byte)(zLo & 0xf);
18694
        zLo = (zLo >> 4) | (zHi << 60);
18695
        zHi = zHi >> 4;
18696
        zHi ^= ((word64)AES_GCM_SIV_R[a][0] << 56) |
18697
               ((word64)AES_GCM_SIV_R[a][1] << 48);
18698
    }
18699
18700
    AesGcmSivStore64(x,     zHi);
18701
    AesGcmSivStore64(x + 8, zLo);
18702
}
18703
18704
/* Build the 4-bit table for mulX_GHASH(ByteReverse(h)). */
18705
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
18706
{
18707
    byte hrev[WC_AES_BLOCK_SIZE];
18708
    word64 (*m)[2] = poly->m;
18709
    int i;
18710
18711
    /* m[8] = 1 * H = mulX_GHASH(ByteReverse(h)); successive halvings give the
18712
     * power-of-two nibble entries. */
18713
    AesGcmSivByteReverse(hrev, h);
18714
    m[0x8][0] = AesGcmSivLoad64(hrev);
18715
    m[0x8][1] = AesGcmSivLoad64(hrev + 8);
18716
    AesGcmSivMulX64(&m[0x8][0], &m[0x8][1]);
18717
    m[0x4][0] = m[0x8][0]; m[0x4][1] = m[0x8][1]; AesGcmSivMulX64(&m[0x4][0], &m[0x4][1]);
18718
    m[0x2][0] = m[0x4][0]; m[0x2][1] = m[0x4][1]; AesGcmSivMulX64(&m[0x2][0], &m[0x2][1]);
18719
    m[0x1][0] = m[0x2][0]; m[0x1][1] = m[0x2][1]; AesGcmSivMulX64(&m[0x1][0], &m[0x1][1]);
18720
18721
    /* The rest are sums of those basis entries (i = high bit + remainder). */
18722
    m[0x0][0] = 0; m[0x0][1] = 0;
18723
    for (i = 0; i < 16; i++) {
18724
        static const byte hibit[16] =
18725
            { 0, 0, 0, 2, 0, 4, 4, 4, 0, 8, 8, 8, 8, 8, 8, 8 };
18726
        int top = hibit[i];
18727
        if (top != 0) {
18728
            m[i][0] = m[top][0] ^ m[i - top][0];
18729
            m[i][1] = m[top][1] ^ m[i - top][1];
18730
        }
18731
    }
18732
18733
    XMEMSET(poly->s, 0, sizeof(poly->s));
18734
    /* hrev held ByteReverse(H), the per-message hash key; wipe it. */
18735
    ForceZero(hrev, sizeof(hrev));
18736
}
18737
18738
#else /* word32: GCM_WORD32 or no 64-bit type */
18739
18740
/* Load/store a big-endian word32 - byte 0 is the most-significant byte. Same
18741
 * aligned/unaligned split as AesGcmSivLoad64/Store64; both forms are endian
18742
 * independent. */
18743
#ifndef WOLFSSL_USE_ALIGN
18744
static WC_INLINE word32 AesGcmSivLoad32(const byte* b)
18745
{
18746
    word32 v;
18747
    XMEMCPY(&v, b, sizeof(v));
18748
#ifdef LITTLE_ENDIAN_ORDER
18749
    v = ByteReverseWord32(v);
18750
#endif
18751
    return v;
18752
}
18753
static WC_INLINE void AesGcmSivStore32(byte* b, word32 v)
18754
{
18755
#ifdef LITTLE_ENDIAN_ORDER
18756
    v = ByteReverseWord32(v);
18757
#endif
18758
    XMEMCPY(b, &v, sizeof(v));
18759
}
18760
#else
18761
static WC_INLINE word32 AesGcmSivLoad32(const byte* b)
18762
{
18763
    return ((word32)b[0] << 24) | ((word32)b[1] << 16) |
18764
           ((word32)b[2] <<  8) | ((word32)b[3]);
18765
}
18766
static WC_INLINE void AesGcmSivStore32(byte* b, word32 v)
18767
{
18768
    b[0] = (byte)(v >> 24); b[1] = (byte)(v >> 16);
18769
    b[2] = (byte)(v >>  8); b[3] = (byte)(v);
18770
}
18771
#endif
18772
18773
/* Multiply the 128-bit value (z[0] most significant) by x and reduce: shift
18774
 * the whole value right by one, XOR-ing 0xe1 into byte 0 when a one is shifted
18775
 * out past x^127 (the low bit of z[3]). */
18776
static WC_INLINE void AesGcmSivMulX32(word32* z)
18777
{
18778
    word32 carry = z[3] & 1;
18779
    z[3] = (z[3] >> 1) | (z[2] << 31);
18780
    z[2] = (z[2] >> 1) | (z[1] << 31);
18781
    z[1] = (z[1] >> 1) | (z[0] << 31);
18782
    z[0] = (z[0] >> 1) ^ (0xe1000000U & (word32)(0 - carry));
18783
}
18784
18785
/* s = s * H. The accumulator is shifted right a nibble at a time; the nibble
18786
 * that falls off is reduced through AES_GCM_SIV_R into the top two bytes. */
18787
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
18788
{
18789
    byte* x = poly->s;
18790
    word32 (*m)[4] = poly->m;
18791
    word32 z0 = 0, z1 = 0, z2 = 0, z3 = 0;
18792
    int i;
18793
18794
    for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
18795
        word32* mr;
18796
        byte xi = x[i];
18797
        byte a;
18798
18799
        /* low nibble */
18800
        mr = m[xi & 0xf];
18801
        z0 ^= mr[0]; z1 ^= mr[1]; z2 ^= mr[2]; z3 ^= mr[3];
18802
        a = (byte)(z3 & 0xf);
18803
        z3 = (z3 >> 4) | (z2 << 28);
18804
        z2 = (z2 >> 4) | (z1 << 28);
18805
        z1 = (z1 >> 4) | (z0 << 28);
18806
        z0 = z0 >> 4;
18807
        z0 ^= ((word32)AES_GCM_SIV_R[a][0] << 24) |
18808
              ((word32)AES_GCM_SIV_R[a][1] << 16);
18809
18810
        /* high nibble */
18811
        mr = m[xi >> 4];
18812
        z0 ^= mr[0]; z1 ^= mr[1]; z2 ^= mr[2]; z3 ^= mr[3];
18813
        if (i == 0) {
18814
            break;
18815
        }
18816
        a = (byte)(z3 & 0xf);
18817
        z3 = (z3 >> 4) | (z2 << 28);
18818
        z2 = (z2 >> 4) | (z1 << 28);
18819
        z1 = (z1 >> 4) | (z0 << 28);
18820
        z0 = z0 >> 4;
18821
        z0 ^= ((word32)AES_GCM_SIV_R[a][0] << 24) |
18822
              ((word32)AES_GCM_SIV_R[a][1] << 16);
18823
    }
18824
18825
    AesGcmSivStore32(x,      z0);
18826
    AesGcmSivStore32(x + 4,  z1);
18827
    AesGcmSivStore32(x + 8,  z2);
18828
    AesGcmSivStore32(x + 12, z3);
18829
}
18830
18831
/* Build the 4-bit table for mulX_GHASH(ByteReverse(h)). */
18832
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
18833
{
18834
    byte hrev[WC_AES_BLOCK_SIZE];
18835
    word32 (*m)[4] = poly->m;
18836
    int i;
18837
18838
    /* m[8] = 1 * H = mulX_GHASH(ByteReverse(h)); successive halvings give the
18839
     * power-of-two nibble entries. */
18840
    AesGcmSivByteReverse(hrev, h);
18841
    m[0x8][0] = AesGcmSivLoad32(hrev);
18842
    m[0x8][1] = AesGcmSivLoad32(hrev + 4);
18843
    m[0x8][2] = AesGcmSivLoad32(hrev + 8);
18844
    m[0x8][3] = AesGcmSivLoad32(hrev + 12);
18845
    AesGcmSivMulX32(m[0x8]);
18846
    XMEMCPY(m[0x4], m[0x8], sizeof(m[0x4])); AesGcmSivMulX32(m[0x4]);
18847
    XMEMCPY(m[0x2], m[0x4], sizeof(m[0x2])); AesGcmSivMulX32(m[0x2]);
18848
    XMEMCPY(m[0x1], m[0x2], sizeof(m[0x1])); AesGcmSivMulX32(m[0x1]);
18849
18850
    /* The rest are sums of those basis entries (i = high bit + remainder). */
18851
    m[0x0][0] = 0; m[0x0][1] = 0; m[0x0][2] = 0; m[0x0][3] = 0;
18852
    for (i = 0; i < 16; i++) {
18853
        static const byte hibit[16] =
18854
            { 0, 0, 0, 2, 0, 4, 4, 4, 0, 8, 8, 8, 8, 8, 8, 8 };
18855
        int top = hibit[i];
18856
        if (top != 0) {
18857
            m[i][0] = m[top][0] ^ m[i - top][0];
18858
            m[i][1] = m[top][1] ^ m[i - top][1];
18859
            m[i][2] = m[top][2] ^ m[i - top][2];
18860
            m[i][3] = m[top][3] ^ m[i - top][3];
18861
        }
18862
    }
18863
18864
    XMEMSET(poly->s, 0, sizeof(poly->s));
18865
    /* hrev held ByteReverse(H), the per-message hash key; wipe it. */
18866
    ForceZero(hrev, sizeof(hrev));
18867
}
18868
18869
#endif /* POLYVAL multiply variant */
18870
18871
#ifdef WC_POLYVAL_ASM_THUMB2
18872
/* Thumb-2: the single table POLYVAL variant. */
18873
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
18874
{
18875
    return &AES_GCMSIV_polyval_thumb2;
18876
}
18877
#elif defined(WC_POLYVAL_ASM_AARCH32)
18878
/* AArch32: crypto (vmull.p64) or base (table) POLYVAL, chosen at compile time. */
18879
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
18880
{
18881
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
18882
    return &AES_GCMSIV_polyval_crypto;
18883
#elif defined(WC_POLYVAL_ASM_AARCH32_BASE)
18884
    return &AES_GCMSIV_polyval_base;
18885
#else
18886
    return NULL;
18887
#endif
18888
}
18889
#elif defined(WC_POLYVAL_ASM_AARCH64)
18890
/* Select the best available generated POLYVAL multiply: PMULL when the CPU has
18891
 * the crypto extension, else the 8-bit-pmul NEON variant, else the scalar base
18892
 * variant, else NULL to fall back to software. */
18893
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
18894
{
18895
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
18896
    cpuid_get_flags_atomic(&cpuid_flags);
18897
    if (IS_AARCH64_PMULL(cpuid_flags)) {
18898
        return &AES_GCMSIV_polyval_pmull;
18899
    }
18900
#endif
18901
#ifndef WOLFSSL_ARMASM_NO_NEON
18902
    return &AES_GCMSIV_polyval_neon;
18903
#elif defined(WC_POLYVAL_ASM_AARCH64_BASE)
18904
    return &AES_GCMSIV_polyval_base;
18905
#else
18906
    return NULL;
18907
#endif
18908
}
18909
#elif defined(WC_POLYVAL_ASM)
18910
/* Select the best available generated POLYVAL multiply for this CPU, or NULL
18911
 * to fall back to software. PCLMUL is present on every AES-NI capable CPU, so
18912
 * AES-NI gates the base path (matching wolfSSL's AES-GCM). */
18913
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
18914
{
18915
    cpuid_get_flags_atomic(&intel_flags);
18916
    if (!IS_INTEL_AESNI(intel_flags)) {
18917
        return NULL;
18918
    }
18919
#ifdef HAVE_INTEL_AVX512
18920
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18921
        return &AES_GCMSIV_polyval_avx512;
18922
    }
18923
#endif
18924
#ifdef HAVE_INTEL_VAES
18925
    if (IS_INTEL_VAES(intel_flags) && IS_INTEL_AVX2(intel_flags)) {
18926
        return &AES_GCMSIV_polyval_vaes;
18927
    }
18928
#endif
18929
#ifdef HAVE_INTEL_AVX1
18930
    if (IS_INTEL_AVX1(intel_flags)) {
18931
        return &AES_GCMSIV_polyval_avx1;
18932
    }
18933
#endif
18934
    return &AES_GCMSIV_polyval_aesni;
18935
}
18936
#endif
18937
18938
#ifdef WC_GCMSIV_CTR_ASM_THUMB2
18939
/* Thumb-2: the single table CTR variant. */
18940
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
18941
{
18942
    return &AES_GCMSIV_ctr_thumb2;
18943
}
18944
#elif defined(WC_GCMSIV_CTR_ASM_AARCH32)
18945
/* AArch32: crypto (aese) or base (table) CTR, chosen at compile time. */
18946
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
18947
{
18948
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
18949
    return &AES_GCMSIV_ctr_crypto;
18950
#else
18951
    return &AES_GCMSIV_ctr_base;
18952
#endif
18953
}
18954
#elif defined(WC_GCMSIV_CTR_ASM_AARCH64)
18955
/* Select the best generated CTR keystream: pipelined aese when the CPU has the
18956
 * AES extension, else the NEON or base software-table variant, else NULL. */
18957
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
18958
{
18959
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
18960
    cpuid_get_flags_atomic(&cpuid_flags);
18961
    if (IS_AARCH64_AES(cpuid_flags)) {
18962
        return &AES_GCMSIV_ctr_aarch64;
18963
    }
18964
#endif
18965
#ifndef WOLFSSL_ARMASM_NO_NEON
18966
    return &AES_GCMSIV_ctr_neon;
18967
#elif !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
18968
    return &AES_GCMSIV_ctr_base;
18969
#else
18970
    return NULL;
18971
#endif
18972
}
18973
#elif defined(WC_GCMSIV_CTR_ASM)
18974
/* Select the best generated AES-GCM-SIV CTR keystream for this CPU. AES-NI is
18975
 * the base; AVX1/VAES/AVX512 are progressively wider pipelines. */
18976
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
18977
{
18978
    cpuid_get_flags_atomic(&intel_flags);
18979
    if (!IS_INTEL_AESNI(intel_flags)) {
18980
        return NULL;
18981
    }
18982
#ifdef HAVE_INTEL_AVX512
18983
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18984
        return &AES_GCMSIV_ctr_avx512;
18985
    }
18986
#endif
18987
#ifdef HAVE_INTEL_VAES
18988
    if (IS_INTEL_VAES(intel_flags) && IS_INTEL_AVX2(intel_flags)) {
18989
        return &AES_GCMSIV_ctr_vaes;
18990
    }
18991
#endif
18992
#ifdef HAVE_INTEL_AVX1
18993
    if (IS_INTEL_AVX1(intel_flags)) {
18994
        return &AES_GCMSIV_ctr_avx1;
18995
    }
18996
#endif
18997
    return &AES_GCMSIV_ctr_aesni;
18998
}
18999
#endif
19000
19001
/* Initialize POLYVAL with the 16-byte hash key h, using the generated assembly
19002
 * multiply when the CPU supports it and a software variant otherwise. */
19003
static void AesGcmSivPolyvalInit(AesGcmSivPolyval* poly, const byte* h)
19004
{
19005
#ifdef WC_POLYVAL_ASM
19006
    AesGcmSivPolyvalFn fn = AesGcmSivPolyvalAsm();
19007
    if (fn != NULL) {
19008
#if defined(WC_POLYVAL_ASM_AARCH64_BASE) || defined(WC_POLYVAL_ASM_AARCH32_BASE)
19009
        if (fn == &AES_GCMSIV_polyval_base) {
19010
            /* The scalar variant multiplies through the word64 software table,
19011
             * so build it and point the asm at it. */
19012
            AesGcmSivPolyvalInitSw(poly, h);
19013
            poly->asmKey = (const byte*)poly->m;
19014
            poly->fn = fn;
19015
            return;
19016
        }
19017
#endif
19018
#ifdef WC_POLYVAL_ASM_THUMB2
19019
        if (fn == &AES_GCMSIV_polyval_thumb2) {
19020
            /* Table variant: build the word64 software table and point at it. */
19021
            AesGcmSivPolyvalInitSw(poly, h);
19022
            poly->asmKey = (const byte*)poly->m;
19023
            poly->fn = fn;
19024
            return;
19025
        }
19026
#endif
19027
        {
19028
            byte t[WC_AES_BLOCK_SIZE];
19029
            /* Prepare the hash key for the asm: byte-reversed
19030
             * mulX_GHASH(ByteReverse(h)). */
19031
            AesGcmSivByteReverse(t, h);
19032
            AesGcmSivMulX(t);
19033
            AesGcmSivByteReverse(poly->hHw, t);
19034
            XMEMSET(poly->s, 0, sizeof(poly->s));
19035
            poly->asmKey = poly->hHw;
19036
            poly->fn = fn;
19037
            /* t held the prepared hash key; wipe the stack copy. */
19038
            ForceZero(t, sizeof(t));
19039
        }
19040
        return;
19041
    }
19042
    poly->fn = NULL;
19043
#endif
19044
    AesGcmSivPolyvalInitSw(poly, h);
19045
}
19046
19047
/* Add data to the POLYVAL sum. A trailing partial block is zero-padded to a
19048
 * full block, which is exactly the padding RFC 8452 applies to the AAD and
19049
 * the plaintext independently. */
19050
static void AesGcmSivPolyvalUpdate(AesGcmSivPolyval* poly, const byte* data,
19051
    word32 sz)
19052
{
19053
    byte block[WC_AES_BLOCK_SIZE];
19054
    byte rev[WC_AES_BLOCK_SIZE];
19055
    int k;
19056
19057
#ifdef WC_POLYVAL_ASM
19058
    if (poly->fn != NULL) {
19059
        word32 blocks = sz / WC_AES_BLOCK_SIZE;
19060
        word32 partial = sz % WC_AES_BLOCK_SIZE;
19061
        if (blocks > 0) {
19062
            poly->fn(poly->s, poly->asmKey, data, blocks);
19063
            data += blocks * WC_AES_BLOCK_SIZE;
19064
        }
19065
        if (partial > 0) {
19066
            XMEMSET(block, 0, sizeof(block));
19067
            XMEMCPY(block, data, partial);
19068
            poly->fn(poly->s, poly->asmKey, block, 1);
19069
        }
19070
        /* block may have held a padded AAD/plaintext tail; wipe it. */
19071
        ForceZero(block, sizeof(block));
19072
        return;
19073
    }
19074
#endif
19075
    while (sz >= WC_AES_BLOCK_SIZE) {
19076
        AesGcmSivByteReverse(rev, data);
19077
        for (k = 0; k < WC_AES_BLOCK_SIZE; k++) {
19078
            poly->s[k] ^= rev[k];
19079
        }
19080
        AesGcmSivGMult(poly);
19081
        data += WC_AES_BLOCK_SIZE;
19082
        sz   -= WC_AES_BLOCK_SIZE;
19083
    }
19084
    if (sz > 0) {
19085
        XMEMSET(block, 0, sizeof(block));
19086
        XMEMCPY(block, data, sz);
19087
        AesGcmSivByteReverse(rev, block);
19088
        for (k = 0; k < WC_AES_BLOCK_SIZE; k++) {
19089
            poly->s[k] ^= rev[k];
19090
        }
19091
        AesGcmSivGMult(poly);
19092
    }
19093
    /* block/rev held byte-reversed AAD/plaintext blocks; wipe them. */
19094
    ForceZero(block, sizeof(block));
19095
    ForceZero(rev, sizeof(rev));
19096
}
19097
19098
/* Output the 16-byte POLYVAL result and wipe the key material and state. */
19099
static void AesGcmSivPolyvalFinal(AesGcmSivPolyval* poly, byte* out)
19100
{
19101
    AesGcmSivByteReverse(out, poly->s);
19102
    ForceZero(poly, sizeof(*poly));
19103
}
19104
19105
/* Derive the message-authentication-key and message-encryption-key from the
19106
 * key-generating-key (loaded into kgk) and the nonce. See RFC 8452 Section 4.
19107
 *
19108
 * authKey is 16 bytes; encKey is keySz bytes (16 or 32). */
19109
static WARN_UNUSED_RESULT int AesGcmSivDeriveKeys(Aes* kgk, const byte* nonce,
19110
    word32 keySz, byte* authKey, byte* encKey)
19111
{
19112
    byte block[WC_AES_BLOCK_SIZE];
19113
    byte out[WC_AES_BLOCK_SIZE];
19114
    word32 ctr;
19115
    word32 encBlocks = keySz / 8; /* 2 for AES-128, 4 for AES-256 */
19116
    int ret = 0;
19117
19118
    /* Each derivation block is: LE32(counter) || nonce(12 bytes). The low 8
19119
     * bytes of each AES output are concatenated to form the derived keys. */
19120
    XMEMCPY(block + 4, nonce, AES_GCM_SIV_NONCE_SZ);
19121
19122
    for (ctr = 0; ctr < 2; ctr++) {
19123
        block[0] = (byte)ctr;
19124
        block[1] = 0; block[2] = 0; block[3] = 0;
19125
        ret = wc_AesEncrypt(kgk, block, out);
19126
        if (ret != 0)
19127
            break;
19128
        XMEMCPY(authKey + ctr * 8, out, 8);
19129
    }
19130
19131
    for (ctr = 0; (ret == 0) && (ctr < encBlocks); ctr++) {
19132
        block[0] = (byte)(ctr + 2);
19133
        block[1] = 0; block[2] = 0; block[3] = 0;
19134
        ret = wc_AesEncrypt(kgk, block, out);
19135
        if (ret != 0)
19136
            break;
19137
        XMEMCPY(encKey + ctr * 8, out, 8);
19138
    }
19139
19140
    ForceZero(block, sizeof(block));
19141
    ForceZero(out, sizeof(out));
19142
19143
    return ret;
19144
}
19145
19146
/* Compute the AES-GCM-SIV tag over the AAD and plaintext. enc holds the
19147
 * message-encryption-key. See RFC 8452 Section 4. */
19148
static WARN_UNUSED_RESULT int AesGcmSivCalcTag(Aes* enc, const byte* authKey,
19149
    const byte* nonce, const byte* aad, word32 aadSz, const byte* plain,
19150
    word32 plainSz, byte* tag)
19151
{
19152
    AesGcmSivPolyval poly;
19153
    byte lenBlock[WC_AES_BLOCK_SIZE];
19154
    byte s[WC_AES_BLOCK_SIZE];
19155
    /* Bit lengths (sz * 8) as 64-bit values, computed without needing a
19156
     * 64-bit type: low 32 bits and the 3 bits that carry into the next word. */
19157
    word32 aadLo = aadSz << 3, aadHi = aadSz >> 29;
19158
    word32 ptLo  = plainSz << 3, ptHi = plainSz >> 29;
19159
    int i;
19160
    int ret;
19161
19162
    AesGcmSivPolyvalInit(&poly, authKey);
19163
    AesGcmSivPolyvalUpdate(&poly, aad, aadSz);
19164
    AesGcmSivPolyvalUpdate(&poly, plain, plainSz);
19165
19166
    /* Length block: LE64(aad_bits) || LE64(plaintext_bits). */
19167
    lenBlock[0]  = (byte)aadLo; lenBlock[1] = (byte)(aadLo >> 8);
19168
    lenBlock[2]  = (byte)(aadLo >> 16); lenBlock[3] = (byte)(aadLo >> 24);
19169
    lenBlock[4]  = (byte)aadHi; lenBlock[5] = (byte)(aadHi >> 8);
19170
    lenBlock[6]  = (byte)(aadHi >> 16); lenBlock[7] = (byte)(aadHi >> 24);
19171
    lenBlock[8]  = (byte)ptLo; lenBlock[9] = (byte)(ptLo >> 8);
19172
    lenBlock[10] = (byte)(ptLo >> 16); lenBlock[11] = (byte)(ptLo >> 24);
19173
    lenBlock[12] = (byte)ptHi; lenBlock[13] = (byte)(ptHi >> 8);
19174
    lenBlock[14] = (byte)(ptHi >> 16); lenBlock[15] = (byte)(ptHi >> 24);
19175
    AesGcmSivPolyvalUpdate(&poly, lenBlock, WC_AES_BLOCK_SIZE);
19176
19177
    AesGcmSivPolyvalFinal(&poly, s);
19178
19179
    /* XOR the nonce into the first 12 bytes and clear the top bit of the
19180
     * last byte, then encrypt to produce the tag. */
19181
    for (i = 0; i < AES_GCM_SIV_NONCE_SZ; i++) {
19182
        s[i] ^= nonce[i];
19183
    }
19184
    s[WC_AES_BLOCK_SIZE - 1] &= 0x7f;
19185
19186
    ret = wc_AesEncrypt(enc, s, tag);
19187
19188
    ForceZero(s, sizeof(s));
19189
    return ret;
19190
}
19191
19192
/* Apply AES-GCM-SIV's counter mode to in, producing out. enc holds the
19193
 * message-encryption-key, tag is the 16-byte authentication tag. The counter
19194
 * is the tag with the top bit of the last byte set; only the first 4 bytes
19195
 * are incremented, as a little-endian 32-bit value, wrapping modulo 2^32.
19196
 * See RFC 8452 Section 4. */
19197
static WARN_UNUSED_RESULT int AesGcmSivCtr(Aes* enc, const byte* tag,
19198
    const byte* in, word32 sz, byte* out)
19199
{
19200
    byte ctrBlock[WC_AES_BLOCK_SIZE];
19201
    byte ks[WC_AES_BLOCK_SIZE];
19202
    word32 c;
19203
    int ret = 0;
19204
19205
    XMEMCPY(ctrBlock, tag, WC_AES_BLOCK_SIZE);
19206
    ctrBlock[WC_AES_BLOCK_SIZE - 1] |= 0x80;
19207
19208
#ifdef WC_GCMSIV_CTR_ASM
19209
    /* Offload the full-block keystream to the pipelined assembly; it advances
19210
     * and writes ctrBlock back. The final partial block (if any) is finished by
19211
     * the scalar loop below. */
19212
    {
19213
        AesGcmSivCtrFn fn = AesGcmSivCtrAsm();
19214
        if (fn != NULL) {
19215
            word32 full = sz & ~(word32)(WC_AES_BLOCK_SIZE - 1);
19216
            if (full > 0) {
19217
                fn(in, out, (unsigned long)full, (const byte*)enc->key,
19218
                    (int)enc->rounds, ctrBlock);
19219
                in  += full;
19220
                out += full;
19221
                sz  -= full;
19222
            }
19223
        }
19224
    }
19225
#endif
19226
19227
    c = (word32)ctrBlock[0]        | ((word32)ctrBlock[1] << 8) |
19228
        ((word32)ctrBlock[2] << 16) | ((word32)ctrBlock[3] << 24);
19229
19230
    while (sz > 0) {
19231
        word32 n = (sz < WC_AES_BLOCK_SIZE) ? sz : (word32)WC_AES_BLOCK_SIZE;
19232
        word32 i;
19233
19234
        ret = wc_AesEncrypt(enc, ctrBlock, ks);
19235
        if (ret != 0)
19236
            break;
19237
        for (i = 0; i < n; i++) {
19238
            out[i] = (byte)(in[i] ^ ks[i]);
19239
        }
19240
19241
        in  += n;
19242
        out += n;
19243
        sz  -= n;
19244
19245
        c++;
19246
        ctrBlock[0] = (byte)c;         ctrBlock[1] = (byte)(c >> 8);
19247
        ctrBlock[2] = (byte)(c >> 16); ctrBlock[3] = (byte)(c >> 24);
19248
    }
19249
19250
    ForceZero(ks, sizeof(ks));
19251
    ForceZero(ctrBlock, sizeof(ctrBlock));
19252
    return ret;
19253
}
19254
19255
/* Common validation for the encrypt/decrypt entry points. */
19256
static WARN_UNUSED_RESULT int AesGcmSivCheckArgs(const byte* key, word32 keySz,
19257
    const byte* nonce, word32 nonceSz, const byte* aad, word32 aadSz,
19258
    const byte* in, word32 inSz, const byte* out, const byte* tag,
19259
    word32 tagSz)
19260
{
19261
    if (key == NULL || nonce == NULL || tag == NULL) {
19262
        return BAD_FUNC_ARG;
19263
    }
19264
    if ((inSz != 0) && ((in == NULL) || (out == NULL))) {
19265
        return BAD_FUNC_ARG;
19266
    }
19267
    if ((aadSz != 0) && (aad == NULL)) {
19268
        return BAD_FUNC_ARG;
19269
    }
19270
    if ((keySz != 16) && (keySz != 32)) {
19271
        return BAD_FUNC_ARG;
19272
    }
19273
    if (nonceSz != AES_GCM_SIV_NONCE_SZ) {
19274
        return BAD_FUNC_ARG;
19275
    }
19276
    if (tagSz != AES_GCM_SIV_TAG_SZ) {
19277
        return BAD_FUNC_ARG;
19278
    }
19279
    return 0;
19280
}
19281
19282
/*
19283
 * Encrypt with AES-GCM-SIV. See RFC 8452 Section 4.
19284
 *
19285
 * out receives inSz bytes of ciphertext; tag receives the 16-byte tag.
19286
 */
19287
int wc_AesGcmSivEncrypt(const byte* key, word32 keySz, const byte* nonce,
19288
    word32 nonceSz, const byte* aad, word32 aadSz, const byte* in,
19289
    word32 inSz, byte* out, byte* tag, word32 tagSz)
19290
{
19291
    WC_DECLARE_VAR(aes, Aes, 1, 0);
19292
    byte authKey[WC_AES_BLOCK_SIZE];
19293
    byte encKey[32];
19294
    byte tagTmp[AES_GCM_SIV_TAG_SZ];
19295
    int ret;
19296
19297
    ret = AesGcmSivCheckArgs(key, keySz, nonce, nonceSz, aad, aadSz, in, inSz,
19298
                             out, tag, tagSz);
19299
19300
    if (ret == 0) {
19301
    #ifdef WOLFSSL_SMALL_STACK
19302
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
19303
    #else
19304
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
19305
    #endif
19306
    }
19307
19308
    if (ret == 0) {
19309
        /* Load the key-generating-key and derive the per-message keys. */
19310
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
19311
        if (ret == 0) {
19312
            ret = AesGcmSivDeriveKeys(aes, nonce, keySz, authKey, encKey);
19313
        }
19314
        /* Switch the AES object to the message-encryption-key. */
19315
        if (ret == 0) {
19316
            ret = wc_AesSetKey(aes, encKey, keySz, NULL, AES_ENCRYPTION);
19317
        }
19318
        /* Tag is computed over the plaintext, then the plaintext is
19319
         * encrypted with the tag-derived counter. */
19320
        if (ret == 0) {
19321
            ret = AesGcmSivCalcTag(aes, authKey, nonce, aad, aadSz, in, inSz,
19322
                                   tagTmp);
19323
        }
19324
        if (ret == 0) {
19325
            ret = AesGcmSivCtr(aes, tagTmp, in, inSz, out);
19326
        }
19327
        if (ret == 0) {
19328
            XMEMCPY(tag, tagTmp, AES_GCM_SIV_TAG_SZ);
19329
        }
19330
19331
    #ifdef WOLFSSL_SMALL_STACK
19332
        wc_AesDelete(aes, NULL);
19333
    #else
19334
        wc_AesFree(aes);
19335
    #endif
19336
    }
19337
19338
    ForceZero(authKey, sizeof(authKey));
19339
    ForceZero(encKey, sizeof(encKey));
19340
    ForceZero(tagTmp, sizeof(tagTmp));
19341
19342
    return ret;
19343
}
19344
19345
/*
19346
 * Decrypt with AES-GCM-SIV. See RFC 8452 Section 4.
19347
 *
19348
 * in is inSz bytes of ciphertext, tag is the received 16-byte tag. On a
19349
 * successful authentication out receives inSz bytes of plaintext; on failure
19350
 * out is zeroed and AES_GCM_AUTH_E is returned.
19351
 */
19352
int wc_AesGcmSivDecrypt(const byte* key, word32 keySz, const byte* nonce,
19353
    word32 nonceSz, const byte* aad, word32 aadSz, const byte* in,
19354
    word32 inSz, byte* out, const byte* tag, word32 tagSz)
19355
{
19356
    WC_DECLARE_VAR(aes, Aes, 1, 0);
19357
    byte authKey[WC_AES_BLOCK_SIZE];
19358
    byte encKey[32];
19359
    byte expTag[AES_GCM_SIV_TAG_SZ];
19360
    int ret;
19361
19362
    ret = AesGcmSivCheckArgs(key, keySz, nonce, nonceSz, aad, aadSz, in, inSz,
19363
                             out, tag, tagSz);
19364
19365
    if (ret == 0) {
19366
    #ifdef WOLFSSL_SMALL_STACK
19367
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
19368
    #else
19369
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
19370
    #endif
19371
    }
19372
19373
    if (ret == 0) {
19374
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
19375
        if (ret == 0) {
19376
            ret = AesGcmSivDeriveKeys(aes, nonce, keySz, authKey, encKey);
19377
        }
19378
        if (ret == 0) {
19379
            ret = wc_AesSetKey(aes, encKey, keySz, NULL, AES_ENCRYPTION);
19380
        }
19381
        /* Recover the plaintext, then recompute and verify the tag over it. */
19382
        if (ret == 0) {
19383
            ret = AesGcmSivCtr(aes, tag, in, inSz, out);
19384
        }
19385
        if (ret == 0) {
19386
            ret = AesGcmSivCalcTag(aes, authKey, nonce, aad, aadSz, out, inSz,
19387
                                   expTag);
19388
        }
19389
        if (ret == 0) {
19390
            if (ConstantCompare(expTag, tag, AES_GCM_SIV_TAG_SZ) != 0) {
19391
                ret = AES_GCM_AUTH_E;
19392
            }
19393
        }
19394
        if (ret != 0) {
19395
            ForceZero(out, inSz);
19396
        }
19397
19398
    #ifdef WOLFSSL_SMALL_STACK
19399
        wc_AesDelete(aes, NULL);
19400
    #else
19401
        wc_AesFree(aes);
19402
    #endif
19403
    }
19404
19405
    ForceZero(authKey, sizeof(authKey));
19406
    ForceZero(encKey, sizeof(encKey));
19407
    ForceZero(expTag, sizeof(expTag));
19408
19409
    return ret;
19410
}
19411
19412
#endif /* WOLFSSL_AESGCM_SIV */
19413
19414
#if defined(WOLFSSL_AES_EAX)
19415
19416
/*
19417
 * AES EAX one-shot API
19418
 * Encrypts input data and computes an auth tag over the input
19419
 * auth data and ciphertext
19420
 *
19421
 * Returns 0 on success
19422
 * Returns error code on failure
19423
 */
19424
int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
19425
                          const byte* in, word32 inSz,
19426
                          const byte* nonce, word32 nonceSz,
19427
                          /* output computed auth tag */
19428
                          byte* authTag, word32 authTagSz,
19429
                          /* input data to authenticate */
19430
                          const byte* authIn, word32 authInSz)
19431
{
19432
#if defined(WOLFSSL_SMALL_STACK)
19433
    AesEax *eax;
19434
#else
19435
    AesEax eax_mem;
19436
    AesEax *eax = &eax_mem;
19437
#endif
19438
    int ret;
19439
    int eaxInited = 0;
19440
19441
    if (key == NULL || nonce == NULL || authTag == NULL
19442
            || (inSz > 0 && (out == NULL || in == NULL))
19443
            || (authInSz > 0 && authIn == NULL)) {
19444
        return BAD_FUNC_ARG;
19445
    }
19446
19447
#if defined(WOLFSSL_SMALL_STACK)
19448
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
19449
                                 NULL,
19450
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
19451
        return MEMORY_E;
19452
    }
19453
#endif
19454
19455
    if ((ret = wc_AesEaxInit(eax,
19456
                             key, keySz,
19457
                             nonce, nonceSz,
19458
                             authIn, authInSz)) != 0) {
19459
        goto cleanup;
19460
    }
19461
    eaxInited = 1;
19462
19463
    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
19464
        goto cleanup;
19465
    }
19466
19467
    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
19468
        goto cleanup;
19469
    }
19470
19471
cleanup:
19472
    if (eaxInited)
19473
        wc_AesEaxFree(eax);
19474
#if defined(WOLFSSL_SMALL_STACK)
19475
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
19476
#endif
19477
    return ret;
19478
}
19479
19480
19481
/*
19482
 * AES EAX one-shot API
19483
 * Decrypts and authenticates data against a supplied auth tag
19484
 *
19485
 * Returns 0 on success
19486
 * Returns error code on failure
19487
 */
19488
int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
19489
                          const byte* in, word32 inSz,
19490
                          const byte* nonce, word32 nonceSz,
19491
                          /* auth tag to verify against */
19492
                          const byte* authTag, word32 authTagSz,
19493
                          /* input data to authenticate */
19494
                          const byte* authIn, word32 authInSz)
19495
{
19496
#if defined(WOLFSSL_SMALL_STACK)
19497
    AesEax *eax;
19498
#else
19499
    AesEax eax_mem;
19500
    AesEax *eax = &eax_mem;
19501
#endif
19502
    int ret;
19503
    int eaxInited = 0;
19504
19505
    if (key == NULL || nonce == NULL || authTag == NULL
19506
            || (inSz > 0 && (out == NULL || in == NULL))
19507
            || (authInSz > 0 && authIn == NULL)) {
19508
        return BAD_FUNC_ARG;
19509
    }
19510
19511
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ
19512
            || authTagSz > WC_AES_BLOCK_SIZE) {
19513
        return BAD_FUNC_ARG;
19514
    }
19515
19516
#if defined(WOLFSSL_SMALL_STACK)
19517
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
19518
                                 NULL,
19519
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
19520
        return MEMORY_E;
19521
    }
19522
#endif
19523
19524
    if ((ret = wc_AesEaxInit(eax,
19525
                             key, keySz,
19526
                             nonce, nonceSz,
19527
                             authIn, authInSz)) != 0) {
19528
19529
        goto cleanup;
19530
    }
19531
    eaxInited = 1;
19532
19533
    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
19534
        goto cleanup;
19535
    }
19536
19537
    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
19538
        goto cleanup;
19539
    }
19540
19541
cleanup:
19542
    if (eaxInited)
19543
        wc_AesEaxFree(eax);
19544
#if defined(WOLFSSL_SMALL_STACK)
19545
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
19546
#endif
19547
    return ret;
19548
}
19549
19550
19551
/*
19552
 * AES EAX Incremental API:
19553
 * Initializes an AES EAX encryption or decryption operation. This must be
19554
 * called before any other EAX APIs are used on the AesEax struct
19555
 *
19556
 * Returns 0 on success
19557
 * Returns error code on failure
19558
 */
19559
int  wc_AesEaxInit(AesEax* eax,
19560
                   const byte* key, word32 keySz,
19561
                   const byte* nonce, word32 nonceSz,
19562
                   const byte* authIn, word32 authInSz)
19563
{
19564
    int ret = 0;
19565
    word32 cmacSize;
19566
    int aesInited = 0;
19567
    int nonceCmacInited = 0;
19568
    int aadCmacInited = 0;
19569
19570
    if (eax == NULL || key == NULL ||  nonce == NULL) {
19571
        return BAD_FUNC_ARG;
19572
    }
19573
19574
    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
19575
19576
    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
19577
        goto out;
19578
    }
19579
    aesInited = 1;
19580
19581
    if ((ret = wc_AesSetKey(&eax->aes,
19582
                            key,
19583
                            keySz,
19584
                            NULL,
19585
                            AES_ENCRYPTION)) != 0) {
19586
        goto out;
19587
    }
19588
19589
    /*
19590
    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
19591
    *   N' = OMAC^0_K(N)
19592
    */
19593
    if ((ret = wc_InitCmac(&eax->nonceCmac,
19594
                           key,
19595
                           keySz,
19596
                           WC_CMAC_AES,
19597
                           NULL)) != 0) {
19598
        return ret;
19599
    }
19600
    nonceCmacInited = 1;
19601
19602
    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
19603
                             eax->prefixBuf,
19604
                             sizeof(eax->prefixBuf))) != 0) {
19605
        goto out;
19606
    }
19607
19608
    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
19609
        goto out;
19610
    }
19611
19612
    cmacSize = WC_AES_BLOCK_SIZE;
19613
    if ((ret = wc_CmacFinal(&eax->nonceCmac,
19614
                            eax->nonceCmacFinal,
19615
                            &cmacSize)) != 0) {
19616
        goto out;
19617
    }
19618
19619
    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
19620
        goto out;
19621
    }
19622
19623
    /*
19624
     * start the OMAC used to build the auth tag chunk for the AD .
19625
     * This CMAC is continued in subsequent update calls when more auth data is
19626
     * provided
19627
     *   H' = OMAC^1_K(H)
19628
     */
19629
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 1;
19630
    if ((ret = wc_InitCmac(&eax->aadCmac,
19631
                           key,
19632
                           keySz,
19633
                           WC_CMAC_AES,
19634
                           NULL)) != 0) {
19635
        goto out;
19636
    }
19637
    aadCmacInited = 1;
19638
19639
    if ((ret = wc_CmacUpdate(&eax->aadCmac,
19640
                             eax->prefixBuf,
19641
                             sizeof(eax->prefixBuf))) != 0) {
19642
        goto out;
19643
    }
19644
19645
    if (authIn != NULL) {
19646
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
19647
            goto out;
19648
        }
19649
    }
19650
19651
    /*
19652
     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
19653
     * updated in subsequent calls to encrypt/decrypt
19654
     *  C' = OMAC^2_K(C)
19655
     */
19656
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 2;
19657
    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
19658
                           key,
19659
                           keySz,
19660
                           WC_CMAC_AES,
19661
                           NULL)) != 0) {
19662
        goto out;
19663
    }
19664
19665
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
19666
                             eax->prefixBuf,
19667
                             sizeof(eax->prefixBuf))) != 0) {
19668
        goto out;
19669
    }
19670
19671
out:
19672
19673
    if (ret != 0) {
19674
        if (aesInited)
19675
            wc_AesFree(&eax->aes);
19676
        if (nonceCmacInited)
19677
            wc_CmacFree(&eax->nonceCmac);
19678
        if (aadCmacInited)
19679
            wc_CmacFree(&eax->aadCmac);
19680
    }
19681
19682
    return ret;
19683
}
19684
19685
19686
/*
19687
 * AES EAX Incremental API:
19688
 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
19689
 * the authentication stream
19690
 *
19691
 * Returns 0 on success
19692
 * Returns error code on failure
19693
 */
19694
int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
19695
                            const byte* in, word32 inSz,
19696
                            const byte* authIn, word32 authInSz)
19697
{
19698
    int ret;
19699
19700
    if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))
19701
            || (authInSz > 0 && authIn == NULL)) {
19702
        return BAD_FUNC_ARG;
19703
    }
19704
19705
    if (inSz > 0) {
19706
        /*
19707
         * Encrypt the plaintext using AES CTR
19708
         *  C = CTR(M)
19709
         */
19710
        if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
19711
            return ret;
19712
        }
19713
19714
        /*
19715
         * update OMAC with new ciphertext
19716
         *  C' = OMAC^2_K(C)
19717
         */
19718
        if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
19719
            return ret;
19720
        }
19721
    }
19722
19723
    /* If there exists new auth data, update the OMAC for that as well */
19724
    if (authIn != NULL) {
19725
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
19726
            return ret;
19727
        }
19728
    }
19729
19730
    return 0;
19731
}
19732
19733
19734
/*
19735
 * AES EAX Incremental API:
19736
 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
19737
 * the authentication stream
19738
 *
19739
 * Returns 0 on success
19740
 * Returns error code on failure
19741
 */
19742
int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
19743
                            const byte* in, word32 inSz,
19744
                            const byte* authIn, word32 authInSz)
19745
{
19746
    int ret;
19747
19748
    if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))
19749
            || (authInSz > 0 && authIn == NULL)) {
19750
        return BAD_FUNC_ARG;
19751
    }
19752
19753
    if (inSz > 0) {
19754
        /*
19755
         * Decrypt the plaintext using AES CTR
19756
         *  C = CTR(M)
19757
         */
19758
        if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
19759
            return ret;
19760
        }
19761
19762
        /*
19763
         * update OMAC with new ciphertext
19764
         *  C' = OMAC^2_K(C)
19765
         */
19766
        if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
19767
            return ret;
19768
        }
19769
    }
19770
19771
    /* If there exists new auth data, update the OMAC for that as well */
19772
    if (authIn != NULL) {
19773
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
19774
            return ret;
19775
        }
19776
    }
19777
19778
    return 0;
19779
}
19780
19781
19782
/*
19783
 * AES EAX Incremental API:
19784
 * Provides additional auth data information to the authentication
19785
 * stream for an authenticated encryption or decryption operation
19786
 *
19787
 * Returns 0 on success
19788
 * Returns error code on failure
19789
 */
19790
int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
19791
{
19792
    if (eax == NULL) {
19793
        return BAD_FUNC_ARG;
19794
    }
19795
    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
19796
}
19797
19798
19799
/*
19800
 * AES EAX Incremental API:
19801
 * Finalizes the authenticated encryption operation, computing the auth tag
19802
 * over previously supplied auth data and computed ciphertext
19803
 *
19804
 * Returns 0 on success
19805
 * Returns error code on failure
19806
 */
19807
int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
19808
{
19809
    word32 cmacSize;
19810
    int ret;
19811
    word32 i;
19812
19813
    if (eax == NULL || authTag == NULL || authTagSz == 0 ||
19814
            authTagSz > WC_AES_BLOCK_SIZE || authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
19815
        return BAD_FUNC_ARG;
19816
    }
19817
19818
    /* Complete the OMAC for the ciphertext */
19819
    cmacSize = WC_AES_BLOCK_SIZE;
19820
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
19821
                                  eax->ciphertextCmacFinal,
19822
                                  &cmacSize)) != 0) {
19823
        return ret;
19824
    }
19825
19826
    /* Complete the OMAC for auth data */
19827
    cmacSize = WC_AES_BLOCK_SIZE;
19828
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
19829
                                  eax->aadCmacFinal,
19830
                                  &cmacSize)) != 0) {
19831
        return ret;
19832
    }
19833
19834
    /*
19835
     * Concatenate all three auth tag chunks into the final tag, truncating
19836
     * at the specified tag length
19837
     *   T = Tag [first authTagSz bytes]
19838
     */
19839
    for (i = 0; i < authTagSz; i++) {
19840
        authTag[i] = eax->nonceCmacFinal[i]
19841
                    ^ eax->aadCmacFinal[i]
19842
                    ^ eax->ciphertextCmacFinal[i];
19843
    }
19844
19845
    return 0;
19846
}
19847
19848
19849
/*
19850
 * AES EAX Incremental API:
19851
 * Finalizes the authenticated decryption operation, computing the auth tag
19852
 * for the previously supplied auth data and cipher text and validating it
19853
 * against a provided auth tag
19854
 *
19855
 * Returns 0 on success
19856
 * Return error code for failure
19857
 */
19858
int wc_AesEaxDecryptFinal(AesEax* eax,
19859
                          const byte* authIn, word32 authInSz)
19860
{
19861
    int ret;
19862
    word32 i;
19863
    word32 cmacSize;
19864
19865
#if defined(WOLFSSL_SMALL_STACK)
19866
    byte *authTag;
19867
#else
19868
    byte authTag[WC_AES_BLOCK_SIZE];
19869
#endif
19870
19871
    if (eax == NULL || authIn == NULL || authInSz > WC_AES_BLOCK_SIZE
19872
            || authInSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
19873
        return BAD_FUNC_ARG;
19874
    }
19875
19876
    /* Complete the OMAC for the ciphertext */
19877
    cmacSize = WC_AES_BLOCK_SIZE;
19878
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
19879
                                  eax->ciphertextCmacFinal,
19880
                                  &cmacSize)) != 0) {
19881
        return ret;
19882
    }
19883
19884
    /* Complete the OMAC for auth data */
19885
    cmacSize = WC_AES_BLOCK_SIZE;
19886
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
19887
                                  eax->aadCmacFinal,
19888
                                  &cmacSize)) != 0) {
19889
        return ret;
19890
    }
19891
19892
#if defined(WOLFSSL_SMALL_STACK)
19893
    authTag = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19894
    if (authTag == NULL) {
19895
        return MEMORY_E;
19896
    }
19897
#endif
19898
19899
    /*
19900
     * Concatenate all three auth tag chunks into the final tag, truncating
19901
     * at the specified tag length
19902
     *   T = Tag [first authInSz bytes]
19903
     */
19904
    for (i = 0; i < authInSz; i++) {
19905
        authTag[i] = eax->nonceCmacFinal[i]
19906
                    ^ eax->aadCmacFinal[i]
19907
                    ^ eax->ciphertextCmacFinal[i];
19908
    }
19909
19910
    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
19911
        ret = AES_EAX_AUTH_E;
19912
    }
19913
    else {
19914
        ret = 0;
19915
    }
19916
19917
#if defined(WOLFSSL_SMALL_STACK)
19918
    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19919
#endif
19920
19921
    return ret;
19922
}
19923
19924
/*
19925
 * Frees the underlying CMAC and AES contexts. Must be called when done using
19926
 * the AES EAX context structure.
19927
 *
19928
 * Returns 0 on success
19929
 * Returns error code on failure
19930
 */
19931
int wc_AesEaxFree(AesEax* eax)
19932
{
19933
    if (eax == NULL) {
19934
        return BAD_FUNC_ARG;
19935
    }
19936
19937
    (void)wc_CmacFree(&eax->ciphertextCmac);
19938
    (void)wc_CmacFree(&eax->aadCmac);
19939
    wc_AesFree(&eax->aes);
19940
19941
    return 0;
19942
}
19943
19944
#endif /* WOLFSSL_AES_EAX */
19945
19946
#ifdef WOLFSSL_AES_CTS
19947
19948
19949
/* One-shot API */
19950
int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out,
19951
                     const byte* in, word32 inSz,
19952
                     const byte* iv)
19953
{
19954
    WC_DECLARE_VAR(aes, Aes, 1, 0);
19955
    int ret = 0;
19956
    word32 outSz = inSz;
19957
19958
    if (key == NULL || out == NULL || in == NULL || iv == NULL)
19959
        return BAD_FUNC_ARG;
19960
19961
#ifdef WOLFSSL_SMALL_STACK
19962
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
19963
#else
19964
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
19965
#endif
19966
    if (ret == 0)
19967
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
19968
    if (ret == 0)
19969
        ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz);
19970
    if (ret == 0) {
19971
        out += outSz;
19972
        outSz = inSz - outSz;
19973
        ret = wc_AesCtsEncryptFinal(aes, out, &outSz);
19974
    }
19975
19976
#ifdef WOLFSSL_SMALL_STACK
19977
    wc_AesDelete(aes, NULL);
19978
#else
19979
    wc_AesFree(aes);
19980
#endif
19981
    return ret;
19982
}
19983
19984
int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out,
19985
                     const byte* in, word32 inSz,
19986
                     const byte* iv)
19987
{
19988
    WC_DECLARE_VAR(aes, Aes, 1, 0);
19989
    int ret = 0;
19990
    word32 outSz = inSz;
19991
19992
    if (key == NULL || out == NULL || in == NULL || iv == NULL) {
19993
        return BAD_FUNC_ARG;
19994
    }
19995
19996
#ifdef WOLFSSL_SMALL_STACK
19997
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
19998
#else
19999
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
20000
#endif
20001
    if (ret == 0)
20002
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
20003
    if (ret == 0)
20004
        ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz);
20005
    if (ret == 0) {
20006
        out += outSz;
20007
        outSz = inSz - outSz;
20008
        ret = wc_AesCtsDecryptFinal(aes, out, &outSz);
20009
    }
20010
20011
#ifdef WOLFSSL_SMALL_STACK
20012
    wc_AesDelete(aes, NULL);
20013
#else
20014
    wc_AesFree(aes);
20015
#endif
20016
    return ret;
20017
}
20018
20019
static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz,
20020
                        const byte* in, word32 inSz, int enc)
20021
{
20022
    word32 blocks = 0;
20023
    int ret = 0;
20024
    word32 writtenSz = 0;
20025
    word32 tmpOutSz;
20026
20027
    if (aes == NULL || out == NULL || in == NULL || outSz == NULL)
20028
        return BAD_FUNC_ARG;
20029
20030
    /* Error out early for easy sanity check */
20031
    if (*outSz < inSz)
20032
        return BUFFER_E;
20033
    tmpOutSz = *outSz;
20034
20035
    /* We need to store last two blocks of plaintext */
20036
    if (aes->left > 0) {
20037
        word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left);
20038
        XMEMCPY(aes->ctsBlock + aes->left, in, copySz);
20039
        aes->left += copySz;
20040
        in += copySz;
20041
        inSz -= copySz;
20042
20043
        if (aes->left == WC_AES_BLOCK_SIZE * 2) {
20044
            if (inSz > WC_AES_BLOCK_SIZE) {
20045
                if (tmpOutSz < WC_AES_BLOCK_SIZE * 2)
20046
                    return BUFFER_E;
20047
                if (enc) {
20048
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
20049
                                           WC_AES_BLOCK_SIZE * 2);
20050
                }
20051
                else {
20052
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
20053
                                           WC_AES_BLOCK_SIZE * 2);
20054
                }
20055
                if (ret != 0)
20056
                    return ret;
20057
                out += WC_AES_BLOCK_SIZE * 2;
20058
                writtenSz += WC_AES_BLOCK_SIZE * 2;
20059
                tmpOutSz -= WC_AES_BLOCK_SIZE * 2;
20060
                aes->left = 0;
20061
            }
20062
            else if (inSz > 0) {
20063
                if (tmpOutSz < WC_AES_BLOCK_SIZE)
20064
                    return BUFFER_E;
20065
                if (enc) {
20066
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
20067
                                           WC_AES_BLOCK_SIZE);
20068
                }
20069
                else {
20070
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
20071
                                           WC_AES_BLOCK_SIZE);
20072
                }
20073
                if (ret != 0)
20074
                    return ret;
20075
                out += WC_AES_BLOCK_SIZE;
20076
                writtenSz += WC_AES_BLOCK_SIZE;
20077
                tmpOutSz -= WC_AES_BLOCK_SIZE;
20078
                /* Move the last block in ctsBlock to the beginning for
20079
                 * next operation */
20080
                XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE,
20081
                        WC_AES_BLOCK_SIZE);
20082
                XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz);
20083
                aes->left = WC_AES_BLOCK_SIZE + inSz;
20084
                *outSz = writtenSz;
20085
                return ret; /* Return the result of encryption */
20086
            }
20087
            else {
20088
                /* Can't output data as we need > 1 block for Final call */
20089
                *outSz = writtenSz;
20090
                return 0;
20091
            }
20092
        }
20093
        else {
20094
            /* All input has been absorbed into aes->ctsBlock */
20095
            *outSz = 0;
20096
            return 0;
20097
        }
20098
    }
20099
    if (inSz > WC_AES_BLOCK_SIZE) {
20100
        /* We need to store the last two full or partial blocks */
20101
        blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE;
20102
        blocks -= 2;
20103
    }
20104
    if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE)
20105
        return BUFFER_E;
20106
    if (enc)
20107
        ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
20108
    else
20109
        ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
20110
    in += blocks * WC_AES_BLOCK_SIZE;
20111
    inSz -= blocks * WC_AES_BLOCK_SIZE;
20112
    XMEMCPY(aes->ctsBlock, in, inSz);
20113
    aes->left = inSz;
20114
    writtenSz += blocks * WC_AES_BLOCK_SIZE;
20115
    *outSz = writtenSz;
20116
    return ret;
20117
}
20118
20119
/* Incremental API */
20120
int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz,
20121
                           const byte* in, word32 inSz)
20122
{
20123
    return AesCtsUpdate(aes, out, outSz, in, inSz, 1);
20124
}
20125
20126
int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz)
20127
{
20128
    int ret = 0;
20129
20130
    if (aes == NULL || out == NULL || outSz == NULL)
20131
        return BAD_FUNC_ARG;
20132
    if (*outSz < aes->left)
20133
        return BUFFER_E;
20134
20135
    /* Input must be at least two complete or partial blocks */
20136
    if (aes->left <= WC_AES_BLOCK_SIZE)
20137
        return BAD_FUNC_ARG;
20138
20139
    /* Zero padding */
20140
    XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left);
20141
20142
    ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock,
20143
                           WC_AES_BLOCK_SIZE * 2);
20144
    if (ret != 0)
20145
        return ret;
20146
20147
    XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
20148
    XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock,
20149
            aes->left - WC_AES_BLOCK_SIZE);
20150
    *outSz = aes->left;
20151
    return ret;
20152
}
20153
20154
int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz,
20155
                           const byte* in, word32 inSz)
20156
{
20157
    return AesCtsUpdate(aes, out, outSz, in, inSz, 0);
20158
}
20159
20160
int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz)
20161
{
20162
    int ret = 0;
20163
    byte iv[WC_AES_BLOCK_SIZE];
20164
    byte tmp[WC_AES_BLOCK_SIZE];
20165
    word32 partialSz;
20166
    word32 padSz;
20167
20168
    if (aes == NULL || out == NULL || outSz == NULL)
20169
        return BAD_FUNC_ARG;
20170
    if (*outSz < aes->left)
20171
        return BUFFER_E;
20172
20173
    /* Input must be at least two complete or partial blocks */
20174
    if (aes->left <= WC_AES_BLOCK_SIZE)
20175
        return BAD_FUNC_ARG;
20176
20177
    partialSz = aes->left - WC_AES_BLOCK_SIZE;
20178
    padSz = 2 * WC_AES_BLOCK_SIZE - aes->left;
20179
    /* Zero pad */
20180
    XMEMSET(aes->ctsBlock + aes->left, 0, padSz);
20181
20182
    /* Store IV */
20183
    XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE);
20184
    /* Load IV */
20185
    XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
20186
20187
    ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE);
20188
    if (ret != 0)
20189
        return ret;
20190
20191
    /* Write out partial block */
20192
    XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz);
20193
    /* Retrieve the padding */
20194
    XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz);
20195
    /* Restore IV */
20196
    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
20197
20198
    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE,
20199
                           WC_AES_BLOCK_SIZE);
20200
    if (ret != 0)
20201
        return ret;
20202
20203
    *outSz = aes->left;
20204
    return ret;
20205
}
20206
20207
#endif /* WOLFSSL_AES_CTS */
20208
20209
#endif /* !NO_AES */