Coverage Report

Created: 2026-07-22 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-fastmath/wolfcrypt/src/aes.c
Line
Count
Source
1
/* aes.c
2
 *
3
 * Copyright (C) 2006-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
#ifdef WOLFSSL_IMX6_CAAM_BLOB
207
    /* case of possibly not using hardware acceleration for AES but using key
208
       blobs */
209
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
210
#endif
211
212
#ifdef DEBUG_AESNI
213
    #include <stdio.h>
214
#endif
215
216
#ifdef _MSC_VER
217
    /* 4127 warning constant while(1)  */
218
    #pragma warning(disable: 4127)
219
#endif
220
221
#if (!defined(WOLFSSL_ARMASM) && FIPS_VERSION3_GE(6,0,0)) || \
222
    FIPS_VERSION3_GE(7,0,0)
223
    const unsigned int wolfCrypt_FIPS_aes_ro_sanity[2] =
224
                                                     { 0x1a2b3c4d, 0x00000002 };
225
    int wolfCrypt_FIPS_AES_sanity(void)
226
    {
227
        return 0;
228
    }
229
#endif
230
231
/* Define AES implementation includes and functions */
232
#if defined(STM32_CRYPTO) && !defined(WOLF_CRYPTO_CB_ONLY_AES)
233
     /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
234
235
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
236
237
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
238
        Aes* aes, const byte* inBlock, byte* outBlock)
239
    {
240
    #ifdef WOLFSSL_STM32_BARE
241
        /* Bare-metal driver handles mutex, clock and key/IV internally.
242
         * DHUK is routed via the crypto-callback framework, not here. */
243
        return wc_Stm32_Aes_Ecb(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE, 1);
244
    #else
245
        int ret = 0;
246
    #ifdef WOLFSSL_STM32_CUBEMX
247
        CRYP_HandleTypeDef hcryp;
248
    #else
249
        CRYP_InitTypeDef cryptInit;
250
        CRYP_KeyInitTypeDef keyInit;
251
    #endif
252
253
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
254
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
255
        if (ret < 0)
256
            return ret;
257
#endif
258
259
    #if defined(WOLFSSL_STM32_CUBEMX)
260
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
261
        if (ret != 0)
262
            return ret;
263
264
        ret = wolfSSL_CryptHwMutexLock();
265
        if (ret != 0)
266
            return ret;
267
268
    #if defined(STM32_HAL_V2)
269
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
270
    #elif defined(STM32_CRYPTO_AES_ONLY)
271
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
272
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
273
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
274
    #endif
275
        if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
276
            ret = BAD_FUNC_ARG;
277
        }
278
279
        if (ret == 0) {
280
        #if defined(STM32_HAL_V2)
281
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
282
                (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
283
        #elif defined(STM32_CRYPTO_AES_ONLY)
284
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
285
                outBlock, STM32_HAL_TIMEOUT);
286
        #else
287
            ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
288
                outBlock, STM32_HAL_TIMEOUT);
289
        #endif
290
            if (ret != HAL_OK) {
291
                ret = WC_TIMEOUT_E;
292
            }
293
            HAL_CRYP_DeInit(&hcryp);
294
        }
295
296
    #else /* Standard Peripheral Library */
297
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
298
        if (ret != 0)
299
            return ret;
300
301
        ret = wolfSSL_CryptHwMutexLock();
302
        if (ret != 0)
303
            return ret;
304
305
        /* reset registers to their default values */
306
        CRYP_DeInit();
307
308
        /* setup key */
309
        CRYP_KeyInit(&keyInit);
310
311
        /* set direction and mode */
312
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
313
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
314
        CRYP_Init(&cryptInit);
315
316
        /* enable crypto processor */
317
        CRYP_Cmd(ENABLE);
318
319
        /* flush IN/OUT FIFOs */
320
        CRYP_FIFOFlush();
321
322
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
323
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
324
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
325
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
326
327
        /* wait until the complete message has been processed */
328
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
329
330
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
331
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
332
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
333
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
334
335
        /* disable crypto processor */
336
        CRYP_Cmd(DISABLE);
337
    #endif /* WOLFSSL_STM32_CUBEMX */
338
        wolfSSL_CryptHwMutexUnLock();
339
        wc_Stm32_Aes_Cleanup();
340
341
        return ret;
342
    #endif /* !WOLFSSL_STM32_BARE */
343
    }
344
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
345
346
#ifdef HAVE_AES_DECRYPT
347
    #if defined(WOLFSSL_AES_DIRECT)
348
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
349
        Aes* aes, const byte* inBlock, byte* outBlock)
350
    {
351
    #ifdef WOLFSSL_STM32_BARE
352
        /* DHUK is routed via the crypto-callback framework, not here. */
353
        return wc_Stm32_Aes_Ecb(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE, 0);
354
    #else
355
        int ret = 0;
356
    #ifdef WOLFSSL_STM32_CUBEMX
357
        CRYP_HandleTypeDef hcryp;
358
    #else
359
        CRYP_InitTypeDef cryptInit;
360
        CRYP_KeyInitTypeDef keyInit;
361
    #endif
362
363
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
364
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
365
        if (ret < 0)
366
            return ret;
367
#endif
368
369
    #if defined(WOLFSSL_STM32_CUBEMX)
370
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
371
        if (ret != 0)
372
            return ret;
373
374
        ret = wolfSSL_CryptHwMutexLock();
375
        if (ret != 0)
376
            return ret;
377
378
    #if defined(STM32_HAL_V2)
379
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
380
    #elif defined(STM32_CRYPTO_AES_ONLY)
381
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
382
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
383
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
384
    #endif
385
        HAL_CRYP_Init(&hcryp);
386
387
    #if defined(STM32_HAL_V2)
388
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
389
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
390
    #elif defined(STM32_CRYPTO_AES_ONLY)
391
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
392
            outBlock, STM32_HAL_TIMEOUT);
393
    #else
394
        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
395
            outBlock, STM32_HAL_TIMEOUT);
396
    #endif
397
        if (ret != HAL_OK) {
398
            ret = WC_TIMEOUT_E;
399
        }
400
        HAL_CRYP_DeInit(&hcryp);
401
402
    #else /* Standard Peripheral Library */
403
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
404
        if (ret != 0)
405
            return ret;
406
407
        ret = wolfSSL_CryptHwMutexLock();
408
        if (ret != 0)
409
            return ret;
410
411
        /* reset registers to their default values */
412
        CRYP_DeInit();
413
414
        /* set direction and key */
415
        CRYP_KeyInit(&keyInit);
416
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
417
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
418
        CRYP_Init(&cryptInit);
419
420
        /* enable crypto processor */
421
        CRYP_Cmd(ENABLE);
422
423
        /* wait until decrypt key has been initialized */
424
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
425
426
        /* set direction and mode */
427
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
428
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
429
        CRYP_Init(&cryptInit);
430
431
        /* enable crypto processor */
432
        CRYP_Cmd(ENABLE);
433
434
        /* flush IN/OUT FIFOs */
435
        CRYP_FIFOFlush();
436
437
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
438
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
439
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
440
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
441
442
        /* wait until the complete message has been processed */
443
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
444
445
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
446
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
447
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
448
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
449
450
        /* disable crypto processor */
451
        CRYP_Cmd(DISABLE);
452
    #endif /* WOLFSSL_STM32_CUBEMX */
453
        wolfSSL_CryptHwMutexUnLock();
454
        wc_Stm32_Aes_Cleanup();
455
456
        return ret;
457
    #endif /* !WOLFSSL_STM32_BARE */
458
    }
459
    #endif /* WOLFSSL_AES_DIRECT */
460
#endif /* HAVE_AES_DECRYPT */
461
462
#elif defined(HAVE_COLDFIRE_SEC)
463
    /* Freescale Coldfire SEC support for CBC mode.
464
     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
465
    #include "sec.h"
466
    #include "mcf5475_sec.h"
467
    #include "mcf5475_siu.h"
468
#elif defined(FREESCALE_LTC)
469
    #include "fsl_ltc.h"
470
    #if defined(FREESCALE_LTC_AES_GCM)
471
        #undef NEED_AES_TABLES
472
        #undef GCM_TABLE
473
    #endif
474
475
        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
476
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
477
            Aes* aes, const byte* inBlock, byte* outBlock)
478
        {
479
            word32 keySize = 0;
480
            byte* key = (byte*)aes->key;
481
            int ret = wc_AesGetKeySize(aes, &keySize);
482
            if (ret != 0)
483
                return ret;
484
485
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
486
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
487
            if (ret < 0)
488
                return ret;
489
#endif
490
491
            if (wolfSSL_CryptHwMutexLock() == 0) {
492
                LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
493
                    key, keySize);
494
                wolfSSL_CryptHwMutexUnLock();
495
            }
496
            return 0;
497
        }
498
        #ifdef HAVE_AES_DECRYPT
499
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
500
            Aes* aes, const byte* inBlock, byte* outBlock)
501
        {
502
            word32 keySize = 0;
503
            byte* key = (byte*)aes->key;
504
            int ret = wc_AesGetKeySize(aes, &keySize);
505
            if (ret != 0)
506
                return ret;
507
508
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
509
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
510
            if (ret < 0)
511
                return ret;
512
#endif
513
514
            if (wolfSSL_CryptHwMutexLock() == 0) {
515
                LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
516
                    key, keySize, kLTC_EncryptKey);
517
                wolfSSL_CryptHwMutexUnLock();
518
            }
519
            return 0;
520
        }
521
        #endif
522
523
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
524
525
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
526
527
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
528
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
529
        Aes* aes, const byte* inBlock, byte* outBlock)
530
    {
531
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
532
        {
533
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
534
            if (ret < 0)
535
                return ret;
536
        }
537
#endif
538
        /* Thread mutex protection handled in Pic32Crypto */
539
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
540
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
541
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
542
    }
543
    #endif
544
545
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
546
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
547
        Aes* aes, const byte* inBlock, byte* outBlock)
548
    {
549
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
550
        {
551
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
552
            if (ret < 0)
553
                return ret;
554
        }
555
#endif
556
        /* Thread mutex protection handled in Pic32Crypto */
557
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
558
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
559
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
560
    }
561
    #endif
562
563
#elif defined(WOLFSSL_NRF51_AES)
564
    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
565
    #include "wolfssl/wolfcrypt/port/nrf51.h"
566
567
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
568
        Aes* aes, const byte* inBlock, byte* outBlock)
569
    {
570
        int ret;
571
572
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
573
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
574
        if (ret < 0)
575
            return ret;
576
#endif
577
578
        ret = wolfSSL_CryptHwMutexLock();
579
        if (ret == 0) {
580
            ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds,
581
                                    outBlock);
582
            wolfSSL_CryptHwMutexUnLock();
583
        }
584
        return ret;
585
    }
586
587
    #ifdef HAVE_AES_DECRYPT
588
        #error nRF51 AES Hardware does not support decrypt
589
    #endif /* HAVE_AES_DECRYPT */
590
591
#elif defined(WOLFSSL_ESP32_CRYPT) && \
592
     !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
593
    #include <esp_log.h>
594
    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
595
    #define TAG "aes"
596
597
    /* We'll use SW for fallback:
598
     *   unsupported key lengths. (e.g. ESP32-S3)
599
     *   chipsets not implemented.
600
     *   hardware busy. */
601
    #define NEED_AES_TABLES
602
    #define NEED_AES_HW_FALLBACK
603
    #define NEED_SOFTWARE_AES_SETKEY
604
    #undef  WOLFSSL_AES_DIRECT
605
    #define WOLFSSL_AES_DIRECT
606
607
    /* Encrypt: If we choose to never have a fallback to SW: */
608
    #if !defined(NEED_AES_HW_FALLBACK) && \
609
        (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
610
    /* calling this one when NO_AES_192 is defined */
611
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
612
        Aes* aes, const byte* inBlock, byte* outBlock)
613
    {
614
        int ret;
615
616
    #ifdef WC_DEBUG_CIPHER_LIFECYCLE
617
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
618
        if (ret < 0)
619
            return ret;
620
    #endif
621
622
        /* Thread mutex protection handled in esp_aes_hw_InUse */
623
    #ifdef NEED_AES_HW_FALLBACK
624
        if (wc_esp32AesSupportedKeyLen(aes)) {
625
            ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
626
        }
627
    #else
628
        ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
629
    #endif
630
        return ret;
631
    }
632
    #endif
633
634
    /* Decrypt: If we choose to never have a fallback to SW: */
635
    #if !defined(NEED_AES_HW_FALLBACK) && \
636
        (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
637
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
638
        Aes* aes, const byte* inBlock, byte* outBlock)
639
    {
640
        int ret = 0;
641
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
642
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
643
        if (ret < 0)
644
            return ret;
645
#endif
646
        /* Thread mutex protection handled in esp_aes_hw_InUse */
647
    #ifdef NEED_AES_HW_FALLBACK
648
        if (wc_esp32AesSupportedKeyLen(aes)) {
649
            ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
650
        }
651
        else {
652
            ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
653
        }
654
    #else
655
        /* if we don't need fallback, always use HW */
656
        ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
657
    #endif
658
        return ret;
659
    }
660
    #endif
661
662
#elif defined(WOLFSSL_AESNI)
663
664
    #define NEED_AES_TABLES
665
666
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
667
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
668
     */
669
670
    #ifndef AESNI_ALIGN
671
        #define AESNI_ALIGN 16
672
    #endif
673
674
    /* Note that all write access to these static variables must be idempotent,
675
     * as arranged by Check_CPU_support_AES(), else they will be susceptible to
676
     * data races.  Don't use wolfSSL_Atomic_Uint here, to avoid atomic access
677
     * overhead on subsequent calls.
678
     */
679
    static int checkedAESNI = 0;
680
    static int haveAESNI = 0;
681
    static cpuid_flags_t intel_flags = WC_CPUID_INITIALIZER;
682
683
    static WARN_UNUSED_RESULT int Check_CPU_support_AES(void)
684
    {
685
        cpuid_get_flags_ex(&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_t cpuid_flags = WC_CPUID_INITIALIZER;
1090
1091
static void Check_CPU_support_HwCrypto(Aes* aes)
1092
{
1093
    if (cpuid_flags == WC_CPUID_INITIALIZER)
1094
        cpuid_get_flags_ex(&cpuid_flags);
1095
    aes->use_aes_hw_crypto = IS_AARCH64_AES(cpuid_flags);
1096
#ifdef HAVE_AESGCM
1097
    aes->use_pmull_hw_crypto = IS_AARCH64_PMULL(cpuid_flags);
1098
    aes->use_sha3_hw_crypto = IS_AARCH64_SHA3(cpuid_flags);
1099
#endif
1100
}
1101
#endif /* __aarch64__ && !WOLFSSL_ARMASM_NO_HW_CRYPTO */
1102
1103
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
1104
    defined(WOLFSSL_AESGCM_STREAM) || defined(WOLFSSL_AESGCM_SIV)
1105
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
1106
    byte* outBlock)
1107
{
1108
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
1109
#if !defined(__aarch64__)
1110
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1111
#else
1112
    if (aes->use_aes_hw_crypto) {
1113
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
1114
           (int)aes->rounds);
1115
    }
1116
    else
1117
#endif /* !__aarch64__ */
1118
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
1119
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
1120
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
1121
    {
1122
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
1123
            (const unsigned char*)aes->key, aes->rounds);
1124
    }
1125
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1126
    {
1127
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1128
            (int)aes->rounds);
1129
    }
1130
#endif
1131
1132
    return 0;
1133
}
1134
#endif
1135
1136
#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1137
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
1138
    byte* outBlock)
1139
{
1140
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
1141
#if !defined(__aarch64__)
1142
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1143
#else
1144
    if (aes->use_aes_hw_crypto) {
1145
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
1146
            (int)aes->rounds);
1147
    }
1148
    else
1149
#endif /* !__aarch64__ */
1150
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
1151
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
1152
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
1153
    {
1154
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
1155
            (byte*)aes->key, (int)aes->rounds);
1156
    }
1157
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1158
    {
1159
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1160
            (int)aes->rounds);
1161
    }
1162
#endif
1163
    return 0;
1164
}
1165
#endif /* HAVE_AES_DECRYPT && WOLFSSL_AES_DIRECT */
1166
1167
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
1168
1169
#if defined(WOLFSSL_PPC64_ASM) && defined(WOLFSSL_PPC64_ASM_CRYPTO)
1170
/* POWER8+ has vector AES (vcipher/vncipher...) instructions.  When built in,
1171
 * select the "_crypto" implementations at run time if the CPU supports them.
1172
 *
1173
 * A run-time flag with direct calls is used rather than a function pointer: an
1174
 * indirect call would require an ELFv1 function descriptor, whereas direct
1175
 * calls work under both the ELFv1 and ELFv2 ABIs.  The dispatch is expressed as
1176
 * self-referential macros - the base name inside each macro is not re-expanded
1177
 * (C99 6.10.3.4), so it names the real base function.  In a PPC build the ARM
1178
 * branches that also call these names are #if'd out, so only the live PPC call
1179
 * sites are redirected. */
1180
1181
/* Resolved dispatch decision (0 = base, 1 = vector-crypto).  The write here is
1182
 * idempotent so a benign concurrent double-write is harmless.  Avoid atomic for
1183
 * this, as for intel_flags above, to avoid unnecessary expensive reads. */
1184
static int aes_ppc64_use_crypto = 0;
1185
1186
/* True when the CPU supports the vector-crypto instructions. */
1187
#define AES_PPC64_USE_CRYPTO()   (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
    static cpuid_flags_t cpu_flags = WC_CPUID_INITIALIZER;
1194
    if (cpu_flags == WC_CPUID_INITIALIZER)
1195
        cpuid_get_flags_ex(&cpu_flags);
1196
    aes_ppc64_use_crypto = (IS_PPC64_VEC_CRYPTO(cpu_flags) != 0);
1197
}
1198
1199
#define AES_set_encrypt_key(key, len, ks)                                     \
1200
    (AES_PPC64_USE_CRYPTO() ?                                               \
1201
        AES_set_encrypt_key_crypto((key), (len), (ks)) :                      \
1202
        AES_set_encrypt_key((key), (len), (ks)))
1203
#define AES_invert_key(ks, rounds)                                            \
1204
    (AES_PPC64_USE_CRYPTO() ?                                               \
1205
        AES_invert_key_crypto((ks), (rounds)) :                              \
1206
        AES_invert_key((ks), (rounds)))
1207
#define AES_ECB_encrypt(in, out, len, ks, nr)                                 \
1208
    (AES_PPC64_USE_CRYPTO() ?                                               \
1209
        AES_ECB_encrypt_crypto((in), (out), (len), (ks), (nr)) :              \
1210
        AES_ECB_encrypt((in), (out), (len), (ks), (nr)))
1211
#define AES_ECB_decrypt(in, out, len, ks, nr)                                 \
1212
    (AES_PPC64_USE_CRYPTO() ?                                               \
1213
        AES_ECB_decrypt_crypto((in), (out), (len), (ks), (nr)) :              \
1214
        AES_ECB_decrypt((in), (out), (len), (ks), (nr)))
1215
#define AES_CBC_encrypt(in, out, len, ks, nr, iv)                             \
1216
    (AES_PPC64_USE_CRYPTO() ?                                               \
1217
        AES_CBC_encrypt_crypto((in), (out), (len), (ks), (nr), (iv)) :        \
1218
        AES_CBC_encrypt((in), (out), (len), (ks), (nr), (iv)))
1219
#define AES_CBC_decrypt(in, out, len, ks, nr, iv)                             \
1220
    (AES_PPC64_USE_CRYPTO() ?                                               \
1221
        AES_CBC_decrypt_crypto((in), (out), (len), (ks), (nr), (iv)) :        \
1222
        AES_CBC_decrypt((in), (out), (len), (ks), (nr), (iv)))
1223
#define AES_CTR_encrypt(in, out, len, ks, nr, ctr)                            \
1224
    (AES_PPC64_USE_CRYPTO() ?                                               \
1225
        AES_CTR_encrypt_crypto((in), (out), (len), (ks), (nr), (ctr)) :       \
1226
        AES_CTR_encrypt((in), (out), (len), (ks), (nr), (ctr)))
1227
#define AES_GCM_encrypt(in, out, len, ks, nr, ctr)                            \
1228
    (AES_PPC64_USE_CRYPTO() ?                                               \
1229
        AES_GCM_encrypt_crypto((in), (out), (len), (ks), (nr), (ctr)) :       \
1230
        AES_GCM_encrypt((in), (out), (len), (ks), (nr), (ctr)))
1231
#if defined(WOLFSSL_AES_XTS)
1232
#define AES_XTS_encrypt(in, out, sz, i, key, key2, tmp, nr)                   \
1233
    (AES_PPC64_USE_CRYPTO() ?                                               \
1234
        AES_XTS_encrypt_crypto((in), (out), (sz), (i), (key), (key2), (tmp),  \
1235
            (nr)) :                                                           \
1236
        AES_XTS_encrypt((in), (out), (sz), (i), (key), (key2), (tmp), (nr)))
1237
#define AES_XTS_decrypt(in, out, sz, i, key, key2, tmp, nr)                   \
1238
    (AES_PPC64_USE_CRYPTO() ?                                               \
1239
        AES_XTS_decrypt_crypto((in), (out), (sz), (i), (key), (key2), (tmp),  \
1240
            (nr)) :                                                           \
1241
        AES_XTS_decrypt((in), (out), (sz), (i), (key), (key2), (tmp), (nr)))
1242
#endif /* WOLFSSL_AES_XTS */
1243
#else
1244
#define Aes_SetCrypto()                 WC_DO_NOTHING
1245
#endif /* WOLFSSL_PPC64_ASM && WOLFSSL_PPC64_ASM_CRYPTO */
1246
1247
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
1248
    defined(WOLFSSL_AESGCM_STREAM) || defined(HAVE_AESGCM)
1249
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
1250
    byte* outBlock)
1251
{
1252
    AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1253
        (int)aes->rounds);
1254
1255
    return 0;
1256
}
1257
#endif
1258
1259
#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1260
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
1261
    byte* outBlock)
1262
{
1263
    AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1264
        (int)aes->rounds);
1265
    return 0;
1266
}
1267
#endif /* HAVE_AES_DECRYPT && WOLFSSL_AES_DIRECT */
1268
1269
#elif defined(FREESCALE_MMCAU)
1270
    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
1271
     * through the CAU/mmCAU library. Documentation located in
1272
     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
1273
     * Guide (See note in README). */
1274
    #ifdef FREESCALE_MMCAU_CLASSIC
1275
        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
1276
        #include "cau_api.h"
1277
    #else
1278
        #include "fsl_mmcau.h"
1279
    #endif
1280
1281
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1282
        Aes* aes, const byte* inBlock, byte* outBlock)
1283
    {
1284
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1285
        {
1286
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1287
            if (ret < 0)
1288
                return ret;
1289
        }
1290
#endif
1291
1292
        if (wolfSSL_CryptHwMutexLock() == 0) {
1293
        #ifdef FREESCALE_MMCAU_CLASSIC
1294
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1295
                WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
1296
                return BAD_ALIGN_E;
1297
            }
1298
            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1299
        #else
1300
            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1301
                                 outBlock);
1302
        #endif
1303
            wolfSSL_CryptHwMutexUnLock();
1304
        }
1305
        return 0;
1306
    }
1307
    #ifdef HAVE_AES_DECRYPT
1308
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1309
        Aes* aes, const byte* inBlock, byte* outBlock)
1310
    {
1311
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1312
        {
1313
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1314
            if (ret < 0)
1315
                return ret;
1316
        }
1317
#endif
1318
        if (wolfSSL_CryptHwMutexLock() == 0) {
1319
        #ifdef FREESCALE_MMCAU_CLASSIC
1320
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1321
                WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
1322
                return BAD_ALIGN_E;
1323
            }
1324
            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1325
        #else
1326
            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1327
                                 outBlock);
1328
        #endif
1329
            wolfSSL_CryptHwMutexUnLock();
1330
        }
1331
        return 0;
1332
    }
1333
    #endif /* HAVE_AES_DECRYPT */
1334
1335
#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
1336
        && !defined(WOLFSSL_QNX_CAAM)) || \
1337
      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
1338
        defined(HAVE_AESCCM))
1339
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1340
            Aes* aes, const byte* inBlock, byte* outBlock)
1341
        {
1342
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1343
            {
1344
                int ret =
1345
                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1346
                if (ret < 0)
1347
                    return ret;
1348
            }
1349
#endif
1350
            return wc_AesEncryptDirect(aes, outBlock, inBlock);
1351
        }
1352
1353
#elif defined(WOLFSSL_AFALG)
1354
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
1355
1356
#elif defined(WOLFSSL_DEVCRYPTO_AES)
1357
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
1358
1359
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
1360
    #include "hal_data.h"
1361
1362
    #ifndef WOLFSSL_SCE_AES256_HANDLE
1363
        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
1364
    #endif
1365
1366
    #ifndef WOLFSSL_SCE_AES192_HANDLE
1367
        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
1368
    #endif
1369
1370
    #ifndef WOLFSSL_SCE_AES128_HANDLE
1371
        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
1372
    #endif
1373
1374
    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
1375
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1376
    {
1377
        word32 ret;
1378
1379
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1380
                CRYPTO_WORD_ENDIAN_BIG) {
1381
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1382
        }
1383
1384
        switch (aes->keylen) {
1385
        #ifdef WOLFSSL_AES_128
1386
            case AES_128_KEY_SIZE:
1387
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
1388
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
1389
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1390
                        (word32*)outBlock);
1391
                break;
1392
        #endif
1393
        #ifdef WOLFSSL_AES_192
1394
            case AES_192_KEY_SIZE:
1395
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
1396
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
1397
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1398
                        (word32*)outBlock);
1399
                break;
1400
        #endif
1401
        #ifdef WOLFSSL_AES_256
1402
            case AES_256_KEY_SIZE:
1403
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
1404
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
1405
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
1406
                        (word32*)outBlock);
1407
                break;
1408
        #endif
1409
            default:
1410
                WOLFSSL_MSG("Unknown key size");
1411
                return BAD_FUNC_ARG;
1412
        }
1413
1414
        if (ret != SSP_SUCCESS) {
1415
            /* revert input */
1416
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1417
            return WC_HW_E;
1418
        }
1419
1420
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1421
                CRYPTO_WORD_ENDIAN_BIG) {
1422
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1423
            if (inBlock != outBlock) {
1424
                /* revert input */
1425
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1426
            }
1427
        }
1428
        return 0;
1429
    }
1430
1431
    #if defined(HAVE_AES_DECRYPT)
1432
    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
1433
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1434
    {
1435
        word32 ret;
1436
1437
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1438
                CRYPTO_WORD_ENDIAN_BIG) {
1439
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1440
        }
1441
1442
        switch (aes->keylen) {
1443
        #ifdef WOLFSSL_AES_128
1444
            case AES_128_KEY_SIZE:
1445
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
1446
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
1447
                        (sz / sizeof(word32)), (word32*)inBlock,
1448
                        (word32*)outBlock);
1449
                break;
1450
        #endif
1451
        #ifdef WOLFSSL_AES_192
1452
            case AES_192_KEY_SIZE:
1453
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
1454
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
1455
                        (sz / sizeof(word32)), (word32*)inBlock,
1456
                        (word32*)outBlock);
1457
                break;
1458
        #endif
1459
        #ifdef WOLFSSL_AES_256
1460
            case AES_256_KEY_SIZE:
1461
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
1462
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
1463
                        (sz / sizeof(word32)), (word32*)inBlock,
1464
                        (word32*)outBlock);
1465
                break;
1466
        #endif
1467
            default:
1468
                WOLFSSL_MSG("Unknown key size");
1469
                return BAD_FUNC_ARG;
1470
        }
1471
        if (ret != SSP_SUCCESS) {
1472
            return WC_HW_E;
1473
        }
1474
1475
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1476
                CRYPTO_WORD_ENDIAN_BIG) {
1477
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
1478
            if (inBlock != outBlock) {
1479
                /* revert input */
1480
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
1481
            }
1482
        }
1483
1484
        return 0;
1485
    }
1486
    #endif /* HAVE_AES_DECRYPT */
1487
1488
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
1489
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1490
        Aes* aes, const byte* inBlock, byte* outBlock)
1491
    {
1492
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1493
        {
1494
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1495
            if (ret < 0)
1496
                return ret;
1497
        }
1498
#endif
1499
        return AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1500
    }
1501
    #endif
1502
1503
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1504
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1505
        Aes* aes, const byte* inBlock, byte* outBlock)
1506
    {
1507
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1508
        {
1509
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1510
            if (ret < 0)
1511
                return ret;
1512
        }
1513
#endif
1514
        return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1515
    }
1516
    #endif
1517
1518
#elif defined(WOLFSSL_KCAPI_AES)
1519
    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
1520
    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
1521
        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1522
        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
1523
        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
1524
        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
1525
1526
        #define NEED_AES_TABLES
1527
    #endif
1528
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
1529
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
1530
1531
#elif defined(WOLFSSL_RISCV_ASM)
1532
/* Block cipher implemented by the generated RISC-V assembly
1533
 * (riscv-64-aes-asm.S / _c.c). The key schedule is wired in wc_AesSetKeyLocal.
1534
 * Vector-crypto overrides the bulk modes (ECB/CBC/CTR/GCM/XTS) with asm; scalar
1535
 * and base run the common-C modes over these single-block primitives, so the
1536
 * block routine is needed whenever a common-C mode (or Direct/CCM/GCM-stream)
1537
 * is built. */
1538
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
1539
    defined(WOLFSSL_AESGCM_STREAM) || defined(HAVE_AESGCM) || \
1540
    defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) || \
1541
    defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_XTS) || \
1542
    defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1543
    defined(WOLFSSL_AES_CFB)
1544
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
1545
    byte* outBlock)
1546
{
1547
    AES_encrypt_RISCV64(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1548
    return 0;
1549
}
1550
#endif
1551
1552
#if defined(HAVE_AES_DECRYPT) && (defined(WOLFSSL_AES_DIRECT) || \
1553
    defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
1554
    defined(WOLFSSL_AES_XTS) || defined(HAVE_AESCCM))
1555
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
1556
    byte* outBlock)
1557
{
1558
    AES_decrypt_RISCV64(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1559
    return 0;
1560
}
1561
#endif
1562
1563
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1564
/* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
1565
1566
#elif defined(WOLFSSL_PSOC6_CRYPTO)
1567
1568
    #if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
1569
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1570
            Aes* aes, const byte* inBlock, byte* outBlock)
1571
        {
1572
            return wc_Psoc6_Aes_Encrypt(aes, inBlock, outBlock);
1573
        }
1574
    #endif
1575
1576
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1577
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
1578
            Aes* aes, const byte* inBlock, byte* outBlock)
1579
        {
1580
            return wc_Psoc6_Aes_Decrypt(aes, inBlock, outBlock);
1581
        }
1582
1583
    #endif
1584
#elif defined(WOLF_CRYPTO_CB_ONLY_AES)
1585
    /* No software implementation AES T-tables, S-box, Rcon and the C key
1586
     * schedule are stripped. */
1587
#else
1588
1589
    /* using wolfCrypt software implementation */
1590
    #define NEED_AES_TABLES
1591
#endif
1592
1593
1594
1595
#if defined(WC_AES_BITSLICED) && !defined(HAVE_AES_ECB)
1596
    #error "When WC_AES_BITSLICED is defined, HAVE_AES_ECB is needed."
1597
#endif
1598
1599
#ifdef NEED_AES_TABLES
1600
1601
#ifndef WC_AES_BITSLICED
1602
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1603
#if !defined(WOLFSSL_ESP32_CRYPT) || \
1604
    (defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
1605
     defined(NEED_AES_HW_FALLBACK))
1606
#ifndef WOLFSSL_PPC64_ASM
1607
static const FLASH_QUALIFIER word32 rcon[] = {
1608
    0x01000000, 0x02000000, 0x04000000, 0x08000000,
1609
    0x10000000, 0x20000000, 0x40000000, 0x80000000,
1610
    0x1B000000, 0x36000000,
1611
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1612
};
1613
#endif
1614
#endif /* ESP32 */
1615
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1616
1617
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
1618
      defined(HAVE_AESCCM)
1619
#ifndef WOLFSSL_AES_SMALL_TABLES
1620
static const FLASH_QUALIFIER word32 Te[4][256] = {
1621
{
1622
    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1623
    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1624
    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1625
    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1626
    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1627
    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1628
    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1629
    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1630
    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1631
    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1632
    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1633
    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1634
    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1635
    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1636
    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1637
    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1638
    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1639
    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1640
    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1641
    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1642
    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1643
    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1644
    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1645
    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1646
    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1647
    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1648
    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1649
    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1650
    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1651
    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1652
    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1653
    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1654
    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1655
    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1656
    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1657
    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1658
    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1659
    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1660
    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1661
    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1662
    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1663
    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1664
    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1665
    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1666
    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1667
    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1668
    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1669
    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1670
    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1671
    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1672
    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1673
    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1674
    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1675
    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1676
    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1677
    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1678
    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1679
    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1680
    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1681
    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1682
    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1683
    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1684
    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1685
    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1686
},
1687
{
1688
    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1689
    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1690
    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1691
    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1692
    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1693
    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1694
    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1695
    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1696
    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1697
    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1698
    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1699
    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1700
    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1701
    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1702
    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1703
    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1704
    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1705
    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1706
    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1707
    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1708
    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1709
    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1710
    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1711
    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1712
    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1713
    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1714
    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1715
    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1716
    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1717
    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1718
    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1719
    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1720
    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1721
    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1722
    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1723
    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1724
    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1725
    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1726
    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1727
    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1728
    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1729
    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1730
    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1731
    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1732
    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1733
    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1734
    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1735
    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1736
    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1737
    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1738
    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1739
    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1740
    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1741
    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1742
    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1743
    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1744
    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1745
    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1746
    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1747
    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1748
    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1749
    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1750
    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1751
    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1752
},
1753
{
1754
    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1755
    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1756
    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1757
    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1758
    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1759
    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1760
    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1761
    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1762
    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1763
    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1764
    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1765
    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1766
    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1767
    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1768
    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1769
    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1770
    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1771
    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1772
    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1773
    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1774
    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1775
    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1776
    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1777
    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1778
    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1779
    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1780
    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1781
    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1782
    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1783
    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1784
    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1785
    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1786
    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1787
    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1788
    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1789
    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1790
    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1791
    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1792
    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1793
    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1794
    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1795
    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1796
    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1797
    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1798
    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1799
    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1800
    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1801
    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1802
    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1803
    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1804
    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1805
    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1806
    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1807
    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1808
    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1809
    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1810
    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1811
    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1812
    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1813
    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1814
    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1815
    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1816
    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1817
    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1818
},
1819
{
1820
    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1821
    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1822
    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1823
    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1824
    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1825
    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1826
    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1827
    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1828
    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1829
    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1830
    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1831
    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1832
    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1833
    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1834
    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1835
    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1836
    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1837
    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1838
    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1839
    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1840
    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1841
    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1842
    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1843
    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1844
    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1845
    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1846
    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1847
    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1848
    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1849
    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1850
    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1851
    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1852
    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1853
    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1854
    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1855
    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1856
    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1857
    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1858
    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1859
    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1860
    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1861
    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1862
    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1863
    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1864
    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1865
    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1866
    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1867
    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1868
    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1869
    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1870
    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1871
    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1872
    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1873
    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1874
    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1875
    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1876
    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1877
    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1878
    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1879
    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1880
    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1881
    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1882
    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1883
    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1884
}
1885
};
1886
1887
#ifdef HAVE_AES_DECRYPT
1888
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1889
static const FLASH_QUALIFIER word32 Td[4][256] = {
1890
{
1891
    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1892
    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1893
    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1894
    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1895
    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1896
    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1897
    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1898
    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1899
    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1900
    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1901
    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1902
    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1903
    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1904
    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1905
    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1906
    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1907
    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1908
    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1909
    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1910
    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1911
    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1912
    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1913
    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1914
    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1915
    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1916
    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1917
    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1918
    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1919
    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1920
    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1921
    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1922
    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1923
    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1924
    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1925
    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1926
    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1927
    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1928
    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1929
    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1930
    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1931
    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1932
    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1933
    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1934
    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1935
    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1936
    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1937
    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1938
    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1939
    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1940
    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1941
    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1942
    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1943
    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1944
    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1945
    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1946
    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1947
    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1948
    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1949
    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1950
    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1951
    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1952
    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1953
    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1954
    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1955
},
1956
{
1957
    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
1958
    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
1959
    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
1960
    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
1961
    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
1962
    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
1963
    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
1964
    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
1965
    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
1966
    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
1967
    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
1968
    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
1969
    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
1970
    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
1971
    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
1972
    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
1973
    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
1974
    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
1975
    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
1976
    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
1977
    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
1978
    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
1979
    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
1980
    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
1981
    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
1982
    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
1983
    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
1984
    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
1985
    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
1986
    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
1987
    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
1988
    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
1989
    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
1990
    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
1991
    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
1992
    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
1993
    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
1994
    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
1995
    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
1996
    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
1997
    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
1998
    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
1999
    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
2000
    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
2001
    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
2002
    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
2003
    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
2004
    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
2005
    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
2006
    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
2007
    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
2008
    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
2009
    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
2010
    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
2011
    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
2012
    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
2013
    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
2014
    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
2015
    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
2016
    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
2017
    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
2018
    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
2019
    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
2020
    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
2021
},
2022
{
2023
    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
2024
    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
2025
    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
2026
    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
2027
    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
2028
    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
2029
    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
2030
    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
2031
    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
2032
    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
2033
    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
2034
    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
2035
    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
2036
    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
2037
    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
2038
    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
2039
    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
2040
    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
2041
    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
2042
    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
2043
2044
    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
2045
    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
2046
    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
2047
    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
2048
    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
2049
    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
2050
    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
2051
    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
2052
    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
2053
    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
2054
    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
2055
    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
2056
    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
2057
    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
2058
    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
2059
    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
2060
    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
2061
    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
2062
    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
2063
    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
2064
    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
2065
    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
2066
    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
2067
    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
2068
    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
2069
    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
2070
    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
2071
    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
2072
    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
2073
    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
2074
    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
2075
    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
2076
    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
2077
    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
2078
    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
2079
    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
2080
    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
2081
    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
2082
    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
2083
    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
2084
    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
2085
    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
2086
    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
2087
    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
2088
},
2089
{
2090
    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
2091
    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
2092
    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
2093
    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
2094
    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
2095
    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
2096
    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
2097
    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
2098
    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
2099
    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
2100
    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
2101
    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
2102
    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
2103
    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
2104
    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
2105
    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
2106
    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
2107
    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
2108
    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
2109
    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
2110
    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
2111
    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
2112
    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
2113
    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
2114
    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
2115
    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
2116
    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
2117
    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
2118
    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
2119
    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
2120
    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
2121
    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
2122
    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
2123
    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
2124
    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
2125
    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
2126
    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
2127
    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
2128
    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
2129
    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
2130
    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
2131
    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
2132
    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
2133
    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
2134
    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
2135
    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
2136
    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
2137
    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
2138
    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
2139
    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
2140
    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
2141
    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
2142
    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
2143
    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
2144
    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
2145
    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
2146
    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
2147
    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
2148
    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
2149
    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
2150
    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
2151
    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
2152
    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
2153
    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
2154
}
2155
};
2156
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
2157
#endif /* HAVE_AES_DECRYPT */
2158
#endif /* WOLFSSL_AES_SMALL_TABLES */
2159
2160
#ifdef HAVE_AES_DECRYPT
2161
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
2162
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)
2163
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
2164
static const FLASH_QUALIFIER byte Td4[256] =
2165
{
2166
    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
2167
    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
2168
    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
2169
    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
2170
    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
2171
    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
2172
    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
2173
    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
2174
    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
2175
    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
2176
    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
2177
    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
2178
    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
2179
    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
2180
    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
2181
    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
2182
    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
2183
    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
2184
    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
2185
    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
2186
    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
2187
    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
2188
    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
2189
    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
2190
    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
2191
    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
2192
    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
2193
    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
2194
    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
2195
    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
2196
    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
2197
    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
2198
};
2199
#endif
2200
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
2201
#endif /* HAVE_AES_DECRYPT */
2202
2203
#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
2204
2205
#ifdef WOLFSSL_AES_SMALL_TABLES
2206
static const byte Tsbox[256] = {
2207
    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
2208
    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
2209
    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
2210
    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
2211
    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
2212
    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
2213
    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
2214
    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
2215
    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
2216
    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
2217
    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
2218
    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
2219
    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
2220
    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
2221
    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
2222
    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
2223
    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
2224
    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
2225
    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
2226
    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
2227
    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
2228
    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
2229
    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
2230
    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
2231
    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
2232
    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
2233
    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
2234
    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
2235
    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
2236
    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
2237
    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
2238
    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
2239
};
2240
2241
#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
2242
2243
static WARN_UNUSED_RESULT word32 col_mul(
2244
    word32 t, int i2, int i3, int ia, int ib)
2245
{
2246
    byte t3 = GETBYTE(t, i3);
2247
    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
2248
2249
    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
2250
}
2251
2252
#if defined(HAVE_AES_DECRYPT) && \
2253
    (defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
2254
     defined(WOLFSSL_AES_DIRECT))
2255
static WARN_UNUSED_RESULT word32 inv_col_mul(
2256
    word32 t, int i9, int ib, int id, int ie)
2257
{
2258
    byte t9 = GETBYTE(t, i9);
2259
    byte tb = GETBYTE(t, ib);
2260
    byte td = GETBYTE(t, id);
2261
    byte te = GETBYTE(t, ie);
2262
    byte t0 = t9 ^ tb ^ td;
2263
    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
2264
}
2265
#endif /* HAVE_AES_DECRYPT && (HAVE_AES_CBC || HAVE_AES_ECB || WOLFSSL_AES_DIRECT) */
2266
#endif /* WOLFSSL_AES_SMALL_TABLES */
2267
#endif
2268
#endif
2269
2270
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
2271
                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
2272
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
2273
      defined(HAVE_AESCCM)
2274
2275
2276
#ifndef WC_AES_BITSLICED
2277
2278
#ifndef WC_CACHE_LINE_SZ
2279
    #if defined(__x86_64__) || defined(_M_X64) || \
2280
       (defined(__ILP32__) && (__ILP32__ >= 1))
2281
1.51M
        #define WC_CACHE_LINE_SZ 64
2282
    #else
2283
        /* default cache line size */
2284
        #define WC_CACHE_LINE_SZ 32
2285
    #endif
2286
#endif
2287
2288
#ifndef WC_NO_CACHE_RESISTANT
2289
2290
#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
2291
    #define WOLFSSL_AES_TOUCH_LINES
2292
#endif
2293
2294
#ifndef WOLFSSL_AES_SMALL_TABLES
2295
/* load 4 Te Tables into cache by cache line stride */
2296
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
2297
22.7k
{
2298
22.7k
#ifndef WOLFSSL_AES_TOUCH_LINES
2299
22.7k
    volatile word32 x = 0;
2300
22.7k
    int i;
2301
22.7k
    int j;
2302
2303
113k
    for (i = 0; i < 4; i++) {
2304
        /* 256 elements, each one is 4 bytes */
2305
1.54M
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
2306
1.45M
            x &= Te[i][j];
2307
1.45M
        }
2308
90.9k
    }
2309
2310
22.7k
    return x;
2311
#else
2312
    return 0;
2313
#endif
2314
22.7k
}
2315
#else
2316
/* load sbox into cache by cache line stride */
2317
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
2318
{
2319
#ifndef WOLFSSL_AES_TOUCH_LINES
2320
    volatile word32 x = 0;
2321
    int i;
2322
2323
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
2324
        x &= Tsbox[i];
2325
    }
2326
2327
    return x;
2328
#else
2329
    return 0;
2330
#endif
2331
}
2332
#endif
2333
#endif
2334
2335
#ifdef WOLFSSL_AES_TOUCH_LINES
2336
#if WC_CACHE_LINE_SZ == 128
2337
    #define WC_CACHE_LINE_BITS      5
2338
    #define WC_CACHE_LINE_MASK_HI   0xe0
2339
    #define WC_CACHE_LINE_MASK_LO   0x1f
2340
    #define WC_CACHE_LINE_ADD       0x20
2341
#elif WC_CACHE_LINE_SZ == 64
2342
    #define WC_CACHE_LINE_BITS      4
2343
    #define WC_CACHE_LINE_MASK_HI   0xf0
2344
    #define WC_CACHE_LINE_MASK_LO   0x0f
2345
    #define WC_CACHE_LINE_ADD       0x10
2346
#elif WC_CACHE_LINE_SZ == 32
2347
    #define WC_CACHE_LINE_BITS      3
2348
    #define WC_CACHE_LINE_MASK_HI   0xf8
2349
    #define WC_CACHE_LINE_MASK_LO   0x07
2350
    #define WC_CACHE_LINE_ADD       0x08
2351
#elif WC_CACHE_LINE_SZ == 16
2352
    #define WC_CACHE_LINE_BITS      2
2353
    #define WC_CACHE_LINE_MASK_HI   0xfc
2354
    #define WC_CACHE_LINE_MASK_LO   0x03
2355
    #define WC_CACHE_LINE_ADD       0x04
2356
#else
2357
    #error Cache line size not supported
2358
#endif
2359
2360
#ifndef WOLFSSL_AES_SMALL_TABLES
2361
static word32 GetTable(const word32* t, byte o)
2362
{
2363
#if WC_CACHE_LINE_SZ == 64
2364
    word32 e;
2365
    byte hi = o & 0xf0;
2366
    byte lo = o & 0x0f;
2367
2368
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2369
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2370
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2371
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2372
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2373
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2374
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2375
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2376
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2377
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2378
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2379
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2380
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2381
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2382
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2383
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2384
2385
    return e;
2386
#else
2387
    word32 e = 0;
2388
    int i;
2389
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2390
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2391
2392
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2393
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2394
        hi -= WC_CACHE_LINE_ADD;
2395
    }
2396
2397
    return e;
2398
#endif
2399
}
2400
#endif
2401
2402
#ifdef WOLFSSL_AES_SMALL_TABLES
2403
static byte GetTable8(const byte* t, byte o)
2404
{
2405
#if WC_CACHE_LINE_SZ == 64
2406
    byte e;
2407
    byte hi = o & 0xf0;
2408
    byte lo = o & 0x0f;
2409
2410
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2411
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2412
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2413
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2414
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2415
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2416
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2417
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2418
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2419
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2420
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2421
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2422
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2423
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2424
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2425
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2426
2427
    return e;
2428
#else
2429
    byte e = 0;
2430
    int i;
2431
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2432
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2433
2434
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2435
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2436
        hi -= WC_CACHE_LINE_ADD;
2437
    }
2438
2439
    return e;
2440
#endif
2441
}
2442
#endif
2443
2444
#ifndef WOLFSSL_AES_SMALL_TABLES
2445
static void GetTable_Multi(const word32* t, word32* t0, byte o0,
2446
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2447
{
2448
    word32 e0 = 0;
2449
    word32 e1 = 0;
2450
    word32 e2 = 0;
2451
    word32 e3 = 0;
2452
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2453
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2454
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2455
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2456
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2457
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2458
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2459
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2460
    int i;
2461
2462
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2463
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2464
        hi0 -= WC_CACHE_LINE_ADD;
2465
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2466
        hi1 -= WC_CACHE_LINE_ADD;
2467
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2468
        hi2 -= WC_CACHE_LINE_ADD;
2469
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2470
        hi3 -= WC_CACHE_LINE_ADD;
2471
    }
2472
    *t0 = e0;
2473
    *t1 = e1;
2474
    *t2 = e2;
2475
    *t3 = e3;
2476
}
2477
static void XorTable_Multi(const word32* t, word32* t0, byte o0,
2478
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2479
{
2480
    word32 e0 = 0;
2481
    word32 e1 = 0;
2482
    word32 e2 = 0;
2483
    word32 e3 = 0;
2484
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2485
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2486
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2487
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2488
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2489
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2490
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2491
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2492
    int i;
2493
2494
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2495
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2496
        hi0 -= WC_CACHE_LINE_ADD;
2497
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2498
        hi1 -= WC_CACHE_LINE_ADD;
2499
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2500
        hi2 -= WC_CACHE_LINE_ADD;
2501
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2502
        hi3 -= WC_CACHE_LINE_ADD;
2503
    }
2504
    *t0 ^= e0;
2505
    *t1 ^= e1;
2506
    *t2 ^= e2;
2507
    *t3 ^= e3;
2508
}
2509
static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
2510
{
2511
    word32 e = 0;
2512
    int i;
2513
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2514
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2515
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2516
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2517
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2518
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2519
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2520
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2521
2522
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2523
        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
2524
             << 24;
2525
        hi0 -= WC_CACHE_LINE_ADD;
2526
        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
2527
             << 16;
2528
        hi1 -= WC_CACHE_LINE_ADD;
2529
        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
2530
             <<  8;
2531
        hi2 -= WC_CACHE_LINE_ADD;
2532
        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
2533
             <<  0;
2534
        hi3 -= WC_CACHE_LINE_ADD;
2535
    }
2536
2537
    return e;
2538
}
2539
#endif
2540
#else
2541
2542
28.5M
#define GetTable(t, o)  t[o]
2543
#define GetTable8(t, o) t[o]
2544
#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2545
    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
2546
#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2547
    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
2548
#define GetTable8_4(t, o0, o1, o2, o3) \
2549
91.4k
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
2550
91.4k
     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
2551
#endif
2552
2553
#ifndef HAVE_CUDA
2554
/* Encrypt a block using AES.
2555
 *
2556
 * @param [in]  aes       AES object.
2557
 * @param [in]  inBlock   Block to encrypt.
2558
 * @param [out] outBlock  Encrypted block.
2559
 * @param [in]  r         Rounds divided by 2.
2560
 */
2561
#define WC_AES_HAVE_PREFETCH_ARG
2562
static int always_prefetch = 0;
2563
WC_MAYBE_UNUSED static int never_prefetch = 1;
2564
WC_ARGS_NOT_NULL((1, 2, 3, 5))
2565
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2566
        word32 r, int *prefetch_ptr)
2567
132k
{
2568
132k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
2569
132k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
2570
132k
    const word32* rk;
2571
2572
#ifdef WC_C_DYNAMIC_FALLBACK
2573
    rk = aes->key_C_fallback;
2574
#else
2575
132k
    rk = aes->key;
2576
132k
#endif
2577
2578
    /*
2579
     * map byte array block to cipher state
2580
     * and add initial round key:
2581
     */
2582
132k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
2583
132k
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
2584
132k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
2585
132k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
2586
2587
132k
#ifdef LITTLE_ENDIAN_ORDER
2588
132k
    s0 = ByteReverseWord32(s0);
2589
132k
    s1 = ByteReverseWord32(s1);
2590
132k
    s2 = ByteReverseWord32(s2);
2591
132k
    s3 = ByteReverseWord32(s3);
2592
132k
#endif
2593
2594
    /* AddRoundKey */
2595
132k
    s0 ^= rk[0];
2596
132k
    s1 ^= rk[1];
2597
132k
    s2 ^= rk[2];
2598
132k
    s3 ^= rk[3];
2599
2600
132k
#ifndef WOLFSSL_AES_SMALL_TABLES
2601
2602
132k
#ifndef WC_NO_CACHE_RESISTANT
2603
132k
    if (*prefetch_ptr == 0) {
2604
22.7k
        s0 |= PreFetchTe();
2605
22.7k
        if (prefetch_ptr != &always_prefetch)
2606
2.93k
            *prefetch_ptr = 1;
2607
22.7k
    }
2608
#else
2609
    (void)prefetch_ptr;
2610
#endif
2611
2612
132k
#ifndef WOLFSSL_AES_TOUCH_LINES
2613
132k
#define ENC_ROUND_T_S(o)                                                       \
2614
768k
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
2615
768k
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
2616
768k
         rk[(o)+4];                                                            \
2617
768k
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
2618
768k
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
2619
768k
         rk[(o)+5];                                                            \
2620
768k
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
2621
768k
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
2622
768k
         rk[(o)+6];                                                            \
2623
768k
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
2624
768k
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
2625
768k
         rk[(o)+7]
2626
132k
#define ENC_ROUND_S_T(o)                                                       \
2627
636k
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
2628
636k
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
2629
636k
         rk[(o)+0];                                                            \
2630
636k
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
2631
636k
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
2632
636k
         rk[(o)+1];                                                            \
2633
636k
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
2634
636k
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
2635
636k
         rk[(o)+2];                                                            \
2636
636k
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
2637
636k
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
2638
636k
         rk[(o)+3]
2639
#else
2640
#define ENC_ROUND_T_S(o)                                                       \
2641
    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
2642
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
2643
    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
2644
                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
2645
    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
2646
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
2647
    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
2648
                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
2649
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
2650
2651
#define ENC_ROUND_S_T(o)                                                       \
2652
    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
2653
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
2654
    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
2655
                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
2656
    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
2657
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2658
    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
2659
                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
2660
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2661
#endif
2662
2663
132k
#ifndef WOLFSSL_AES_NO_UNROLL
2664
/* Unroll the loop. */
2665
132k
                       ENC_ROUND_T_S( 0);
2666
132k
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2667
132k
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2668
132k
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2669
132k
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2670
132k
    if (r > 5) {
2671
63.1k
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2672
63.1k
        if (r > 6) {
2673
43.9k
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2674
43.9k
        }
2675
63.1k
    }
2676
132k
    rk += r * 8;
2677
#else
2678
    /*
2679
     * Nr - 1 full rounds:
2680
     */
2681
2682
    for (;;) {
2683
        ENC_ROUND_T_S(0);
2684
2685
        rk += 8;
2686
        if (--r == 0) {
2687
            break;
2688
        }
2689
2690
        ENC_ROUND_S_T(0);
2691
    }
2692
#endif
2693
2694
    /*
2695
     * apply last round and
2696
     * map cipher state to byte array block:
2697
     */
2698
2699
132k
#ifndef WOLFSSL_AES_TOUCH_LINES
2700
132k
    s0 =
2701
132k
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2702
132k
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2703
132k
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2704
132k
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2705
132k
        rk[0];
2706
132k
    s1 =
2707
132k
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2708
132k
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2709
132k
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2710
132k
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2711
132k
        rk[1];
2712
132k
    s2 =
2713
132k
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2714
132k
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2715
132k
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2716
132k
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2717
132k
        rk[2];
2718
132k
    s3 =
2719
132k
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2720
132k
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2721
132k
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2722
132k
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2723
132k
        rk[3];
2724
#else
2725
{
2726
    word32 u0;
2727
    word32 u1;
2728
    word32 u2;
2729
    word32 u3;
2730
2731
    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
2732
    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
2733
                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
2734
    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
2735
    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
2736
    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
2737
                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
2738
    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
2739
    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
2740
    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
2741
                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
2742
    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
2743
    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
2744
    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
2745
                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
2746
    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
2747
    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
2748
}
2749
#endif
2750
2751
#else /* WOLFSSL_AES_SMALL_TABLES */
2752
2753
#ifndef WC_NO_CACHE_RESISTANT
2754
    if (*prefetch_ptr == 0) {
2755
        s0 |= PreFetchSBox();
2756
        if (prefetch_ptr != &always_prefetch)
2757
            *prefetch_ptr = 1;
2758
    }
2759
#else
2760
    (void)prefetch_ptr;
2761
#endif
2762
2763
    r *= 2;
2764
    /* Two rounds at a time */
2765
    for (rk += 4; r > 1; r--, rk += 4) {
2766
        t0 =
2767
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2768
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2769
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2770
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2771
        t1 =
2772
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2773
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2774
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2775
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2776
        t2 =
2777
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2778
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2779
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2780
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2781
        t3 =
2782
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2783
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2784
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2785
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2786
2787
        s0 =
2788
            (col_mul(t0, 3, 2, 0, 1) << 24) ^
2789
            (col_mul(t0, 2, 1, 0, 3) << 16) ^
2790
            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
2791
            (col_mul(t0, 0, 3, 2, 1)      ) ^
2792
            rk[0];
2793
        s1 =
2794
            (col_mul(t1, 3, 2, 0, 1) << 24) ^
2795
            (col_mul(t1, 2, 1, 0, 3) << 16) ^
2796
            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
2797
            (col_mul(t1, 0, 3, 2, 1)      ) ^
2798
            rk[1];
2799
        s2 =
2800
            (col_mul(t2, 3, 2, 0, 1) << 24) ^
2801
            (col_mul(t2, 2, 1, 0, 3) << 16) ^
2802
            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
2803
            (col_mul(t2, 0, 3, 2, 1)      ) ^
2804
            rk[2];
2805
        s3 =
2806
            (col_mul(t3, 3, 2, 0, 1) << 24) ^
2807
            (col_mul(t3, 2, 1, 0, 3) << 16) ^
2808
            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
2809
            (col_mul(t3, 0, 3, 2, 1)      ) ^
2810
            rk[3];
2811
    }
2812
2813
    t0 =
2814
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2815
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2816
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2817
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2818
    t1 =
2819
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2820
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2821
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2822
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2823
    t2 =
2824
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2825
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2826
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2827
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2828
    t3 =
2829
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2830
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2831
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2832
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2833
    s0 = t0 ^ rk[0];
2834
    s1 = t1 ^ rk[1];
2835
    s2 = t2 ^ rk[2];
2836
    s3 = t3 ^ rk[3];
2837
2838
#endif /* WOLFSSL_AES_SMALL_TABLES */
2839
2840
    /* write out */
2841
132k
#ifdef LITTLE_ENDIAN_ORDER
2842
132k
    s0 = ByteReverseWord32(s0);
2843
132k
    s1 = ByteReverseWord32(s1);
2844
132k
    s2 = ByteReverseWord32(s2);
2845
132k
    s3 = ByteReverseWord32(s3);
2846
132k
#endif
2847
2848
132k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2849
132k
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2850
132k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2851
132k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2852
132k
}
2853
2854
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2855
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
2856
    !defined(MAX3266X_AES)
2857
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
2858
/* Encrypt a number of blocks using AES.
2859
 *
2860
 * @param [in]  aes  AES object.
2861
 * @param [in]  in   Block to encrypt.
2862
 * @param [out] out  Encrypted block.
2863
 * @param [in]  sz   Number of blocks to encrypt.
2864
 */
2865
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2866
711
{
2867
711
    word32 i;
2868
711
    int did_prefetches = 0;
2869
2870
17.9k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
2871
17.2k
        AesEncrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
2872
17.2k
        in += WC_AES_BLOCK_SIZE;
2873
17.2k
        out += WC_AES_BLOCK_SIZE;
2874
17.2k
    }
2875
711
}
2876
#endif
2877
#endif
2878
#else
2879
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2880
        word32 r);
2881
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2882
#endif /* HAVE_CUDA */
2883
2884
#else
2885
2886
/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
2887
 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
2888
 */
2889
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
2890
static void bs_sub_bytes(bs_word u[8])
2891
{
2892
    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
2893
    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
2894
    bs_word y20, y21;
2895
    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
2896
    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
2897
    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
2898
    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
2899
    bs_word t40, t41, t42, t43, t44, t45;
2900
    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
2901
    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
2902
    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
2903
    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
2904
    bs_word tc20, tc21, tc26;
2905
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
2906
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
2907
2908
    U0 = u[7];
2909
    U1 = u[6];
2910
    U2 = u[5];
2911
    U3 = u[4];
2912
    U4 = u[3];
2913
    U5 = u[2];
2914
    U6 = u[1];
2915
    U7 = u[0];
2916
2917
    y14 = U3 ^ U5;
2918
    y13 = U0 ^ U6;
2919
    y9 = U0 ^ U3;
2920
    y8 = U0 ^ U5;
2921
    t0 = U1 ^ U2;
2922
    y1 = t0 ^ U7;
2923
    y4 = y1 ^ U3;
2924
    y12 = y13 ^ y14;
2925
    y2 = y1 ^ U0;
2926
    y5 = y1 ^ U6;
2927
    y3 = y5 ^ y8;
2928
    t1 = U4 ^ y12;
2929
    y15 = t1 ^ U5;
2930
    y20 = t1 ^ U1;
2931
    y6 = y15 ^ U7;
2932
    y10 = y15 ^ t0;
2933
    y11 = y20 ^ y9;
2934
    y7 = U7 ^ y11;
2935
    y17 = y10 ^ y11;
2936
    y19 = y10 ^ y8;
2937
    y16 = t0 ^ y11;
2938
    y21 = y13 ^ y16;
2939
    y18 = U0 ^ y16;
2940
    t2 = y12 & y15;
2941
    t3 = y3 & y6;
2942
    t4 = t3 ^ t2;
2943
    t5 = y4 & U7;
2944
    t6 = t5 ^ t2;
2945
    t7 = y13 & y16;
2946
    t8 = y5 & y1;
2947
    t9 = t8 ^ t7;
2948
    t10 = y2 & y7;
2949
    t11 = t10 ^ t7;
2950
    t12 = y9 & y11;
2951
    t13 = y14 & y17;
2952
    t14 = t13 ^ t12;
2953
    t15 = y8 & y10;
2954
    t16 = t15 ^ t12;
2955
    t17 = t4 ^ y20;
2956
    t18 = t6 ^ t16;
2957
    t19 = t9 ^ t14;
2958
    t20 = t11 ^ t16;
2959
    t21 = t17 ^ t14;
2960
    t22 = t18 ^ y19;
2961
    t23 = t19 ^ y21;
2962
    t24 = t20 ^ y18;
2963
    t25 = t21 ^ t22;
2964
    t26 = t21 & t23;
2965
    t27 = t24 ^ t26;
2966
    t28 = t25 & t27;
2967
    t29 = t28 ^ t22;
2968
    t30 = t23 ^ t24;
2969
    t31 = t22 ^ t26;
2970
    t32 = t31 & t30;
2971
    t33 = t32 ^ t24;
2972
    t34 = t23 ^ t33;
2973
    t35 = t27 ^ t33;
2974
    t36 = t24 & t35;
2975
    t37 = t36 ^ t34;
2976
    t38 = t27 ^ t36;
2977
    t39 = t29 & t38;
2978
    t40 = t25 ^ t39;
2979
    t41 = t40 ^ t37;
2980
    t42 = t29 ^ t33;
2981
    t43 = t29 ^ t40;
2982
    t44 = t33 ^ t37;
2983
    t45 = t42 ^ t41;
2984
    z0 = t44 & y15;
2985
    z1 = t37 & y6;
2986
    z2 = t33 & U7;
2987
    z3 = t43 & y16;
2988
    z4 = t40 & y1;
2989
    z5 = t29 & y7;
2990
    z6 = t42 & y11;
2991
    z7 = t45 & y17;
2992
    z8 = t41 & y10;
2993
    z9 = t44 & y12;
2994
    z10 = t37 & y3;
2995
    z11 = t33 & y4;
2996
    z12 = t43 & y13;
2997
    z13 = t40 & y5;
2998
    z14 = t29 & y2;
2999
    z15 = t42 & y9;
3000
    z16 = t45 & y14;
3001
    z17 = t41 & y8;
3002
    tc1 = z15 ^ z16;
3003
    tc2 = z10 ^ tc1;
3004
    tc3 = z9 ^ tc2;
3005
    tc4 = z0 ^ z2;
3006
    tc5 = z1 ^ z0;
3007
    tc6 = z3 ^ z4;
3008
    tc7 = z12 ^ tc4;
3009
    tc8 = z7 ^ tc6;
3010
    tc9 = z8 ^ tc7;
3011
    tc10 = tc8 ^ tc9;
3012
    tc11 = tc6 ^ tc5;
3013
    tc12 = z3 ^ z5;
3014
    tc13 = z13 ^ tc1;
3015
    tc14 = tc4 ^ tc12;
3016
    S3 = tc3 ^ tc11;
3017
    tc16 = z6 ^ tc8;
3018
    tc17 = z14 ^ tc10;
3019
    tc18 = tc13 ^ tc14;
3020
    S7 = ~(z12 ^ tc18);
3021
    tc20 = z15 ^ tc16;
3022
    tc21 = tc2 ^ z11;
3023
    S0 = tc3 ^ tc16;
3024
    S6 = ~(tc10 ^ tc18);
3025
    S4 = tc14 ^ S3;
3026
    S1 = ~(S3 ^ tc16);
3027
    tc26 = tc17 ^ tc20;
3028
    S2 = ~(tc26 ^ z17);
3029
    S5 = tc21 ^ tc17;
3030
3031
    u[0] = S7;
3032
    u[1] = S6;
3033
    u[2] = S5;
3034
    u[3] = S4;
3035
    u[4] = S3;
3036
    u[5] = S2;
3037
    u[6] = S1;
3038
    u[7] = S0;
3039
}
3040
3041
#define BS_MASK_BIT_SET(w, j, bmask) \
3042
    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
3043
3044
#define BS_TRANS_8(t, o, w, bmask, s)                   \
3045
    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
3046
    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
3047
    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
3048
    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
3049
    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
3050
    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
3051
    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
3052
    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
3053
3054
static void bs_transpose(bs_word* t, bs_word* blocks)
3055
{
3056
    bs_word bmask = 1;
3057
    int i;
3058
3059
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
3060
3061
    for (i = 0; i < BS_WORD_SIZE; i++) {
3062
        int j;
3063
        int o = 0;
3064
        for (j = 0; j < BS_BLOCK_WORDS; j++) {
3065
        #ifdef LITTLE_ENDIAN_ORDER
3066
            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
3067
        #else
3068
            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
3069
        #endif
3070
    #ifdef WOLFSSL_AES_NO_UNROLL
3071
            int k;
3072
            for (k = 0; k < BS_WORD_SIZE; k++) {
3073
                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
3074
            }
3075
    #else
3076
            BS_TRANS_8(t, o, w, bmask,  0);
3077
        #if BS_WORD_SIZE >= 16
3078
            BS_TRANS_8(t, o, w, bmask,  8);
3079
        #endif
3080
        #if BS_WORD_SIZE >= 32
3081
            BS_TRANS_8(t, o, w, bmask, 16);
3082
            BS_TRANS_8(t, o, w, bmask, 24);
3083
        #endif
3084
        #if BS_WORD_SIZE >= 64
3085
            BS_TRANS_8(t, o, w, bmask, 32);
3086
            BS_TRANS_8(t, o, w, bmask, 40);
3087
            BS_TRANS_8(t, o, w, bmask, 48);
3088
            BS_TRANS_8(t, o, w, bmask, 56);
3089
        #endif
3090
    #endif
3091
            o += BS_WORD_SIZE;
3092
        }
3093
        bmask <<= 1;
3094
    }
3095
}
3096
3097
#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
3098
    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
3099
    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
3100
    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
3101
    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
3102
    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
3103
    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
3104
    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
3105
    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
3106
3107
static void bs_inv_transpose(bs_word* t, bs_word* blocks)
3108
{
3109
    int o;
3110
3111
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
3112
3113
    for (o = 0; o < BS_BLOCK_WORDS; o++) {
3114
        int i;
3115
        for (i = 0; i < BS_WORD_SIZE; i++) {
3116
        #ifdef LITTLE_ENDIAN_ORDER
3117
            bs_word bmask = (bs_word)1 << i;
3118
        #else
3119
            bs_word bmask = bs_bswap((bs_word)1 << i);
3120
        #endif
3121
            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
3122
    #ifdef WOLFSSL_AES_NO_UNROLL
3123
            int j;
3124
            for (j = 0; j < BS_WORD_SIZE; j++) {
3125
                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
3126
            }
3127
    #else
3128
            BS_INV_TRANS_8(t, o, w, bmask, 0);
3129
        #if BS_WORD_SIZE >= 16
3130
            BS_INV_TRANS_8(t, o, w, bmask, 8);
3131
        #endif
3132
        #if BS_WORD_SIZE >= 32
3133
            BS_INV_TRANS_8(t, o, w, bmask, 16);
3134
            BS_INV_TRANS_8(t, o, w, bmask, 24);
3135
        #endif
3136
        #if BS_WORD_SIZE >= 64
3137
            BS_INV_TRANS_8(t, o, w, bmask, 32);
3138
            BS_INV_TRANS_8(t, o, w, bmask, 40);
3139
            BS_INV_TRANS_8(t, o, w, bmask, 48);
3140
            BS_INV_TRANS_8(t, o, w, bmask, 56);
3141
        #endif
3142
    #endif
3143
        }
3144
    }
3145
}
3146
3147
#define BS_ROW_OFF_0    0
3148
#define BS_ROW_OFF_1    32
3149
#define BS_ROW_OFF_2    64
3150
#define BS_ROW_OFF_3    96
3151
3152
#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
3153
#define BS_IDX_MASK     0x7f
3154
3155
#define BS_ASSIGN_8(d, od, s, os)   \
3156
    d[(od) + 0] = s[(os) + 0];      \
3157
    d[(od) + 1] = s[(os) + 1];      \
3158
    d[(od) + 2] = s[(os) + 2];      \
3159
    d[(od) + 3] = s[(os) + 3];      \
3160
    d[(od) + 4] = s[(os) + 4];      \
3161
    d[(od) + 5] = s[(os) + 5];      \
3162
    d[(od) + 6] = s[(os) + 6];      \
3163
    d[(od) + 7] = s[(os) + 7]
3164
3165
static void bs_shift_rows(bs_word* t, bs_word* b)
3166
{
3167
    int i;
3168
3169
    for (i = 0; i < 128; i += 32) {
3170
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
3171
        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
3172
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
3173
        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
3174
    }
3175
}
3176
3177
#define BS_SHIFT_OFF_0  0
3178
#define BS_SHIFT_OFF_1  8
3179
#define BS_SHIFT_OFF_2  16
3180
#define BS_SHIFT_OFF_3  24
3181
3182
/* Shift rows and mix columns.
3183
 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
3184
 */
3185
3186
#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
3187
        of      = br0[7] ^ br1[7];                                  \
3188
        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
3189
        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
3190
        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
3191
        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
3192
        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
3193
        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
3194
        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
3195
        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
3196
3197
static void bs_shift_mix(bs_word* t, bs_word* b)
3198
{
3199
    int i;
3200
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
3201
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
3202
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
3203
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
3204
3205
    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
3206
        bs_word* br0 = b + or0;
3207
        bs_word* br1 = b + or1;
3208
        bs_word* br2 = b + or2;
3209
        bs_word* br3 = b + or3;
3210
        bs_word of;
3211
3212
        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
3213
        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
3214
        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
3215
        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
3216
3217
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3218
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3219
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3220
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3221
    }
3222
}
3223
3224
static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
3225
{
3226
    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
3227
}
3228
3229
static void bs_sub_bytes_blocks(bs_word* b)
3230
{
3231
    int i;
3232
3233
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
3234
        bs_sub_bytes(b + i);
3235
    }
3236
}
3237
3238
static const FLASH_QUALIFIER byte bs_rcon[] = {
3239
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
3240
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
3241
};
3242
3243
static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
3244
    bs_word block[AES_BLOCK_BITS];
3245
    bs_word trans[AES_BLOCK_BITS];
3246
3247
    XMEMSET(block, 0, sizeof(block));
3248
    XMEMCPY(block, in, 4);
3249
3250
    bs_transpose(trans, block);
3251
    bs_sub_bytes_blocks(trans);
3252
    bs_inv_transpose(block, trans);
3253
3254
    XMEMCPY(out, block, 4);
3255
}
3256
3257
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
3258
    /* Rotate the input 8 bits to the left */
3259
#ifdef LITTLE_ENDIAN_ORDER
3260
    *(word32*)out = rotrFixed(*(word32*)in, 8);
3261
#else
3262
    *(word32*)out = rotlFixed(*(word32*)in, 8);
3263
#endif
3264
    bs_ke_sub_bytes(out, out);
3265
    /* On just the first byte, add 2^i to the byte */
3266
    out[0] ^= bs_rcon[i];
3267
}
3268
3269
static void bs_expand_key(unsigned char *in, word32 sz) {
3270
    unsigned char t[4];
3271
    word32 o;
3272
    word8 i = 0;
3273
3274
    if (sz == 176) {
3275
        /* Total of 11 rounds - AES-128. */
3276
        for (o = 16; o < sz; o += 16) {
3277
            bs_ke_transform(t, in + o - 4, i);
3278
            i++;
3279
            *(word32*)(in + o +  0) = *(word32*)(in + o - 16) ^
3280
                                      *(word32*) t;
3281
            *(word32*)(in + o +  4) = *(word32*)(in + o - 12) ^
3282
                                      *(word32*)(in + o +  0);
3283
            *(word32*)(in + o +  8) = *(word32*)(in + o -  8) ^
3284
                                      *(word32*)(in + o +  4);
3285
            *(word32*)(in + o + 12) = *(word32*)(in + o -  4) ^
3286
                                      *(word32*)(in + o +  8);
3287
        }
3288
    }
3289
    else if (sz == 208) {
3290
        /* Total of 13 rounds - AES-192. */
3291
        for (o = 24; o < sz; o += 24) {
3292
            bs_ke_transform(t, in + o - 4, i);
3293
            i++;
3294
            *(word32*)(in + o +  0) = *(word32*)(in + o - 24) ^
3295
                                      *(word32*) t;
3296
            *(word32*)(in + o +  4) = *(word32*)(in + o - 20) ^
3297
                                      *(word32*)(in + o +  0);
3298
            *(word32*)(in + o +  8) = *(word32*)(in + o - 16) ^
3299
                                      *(word32*)(in + o +  4);
3300
            *(word32*)(in + o + 12) = *(word32*)(in + o - 12) ^
3301
                                      *(word32*)(in + o +  8);
3302
            *(word32*)(in + o + 16) = *(word32*)(in + o -  8) ^
3303
                                      *(word32*)(in + o + 12);
3304
            *(word32*)(in + o + 20) = *(word32*)(in + o -  4) ^
3305
                                      *(word32*)(in + o + 16);
3306
        }
3307
    }
3308
    else if (sz == 240) {
3309
        /* Total of 15 rounds - AES-256. */
3310
        for (o = 32; o < sz; o += 16) {
3311
            if ((o & 0x1f) == 0) {
3312
                bs_ke_transform(t, in + o - 4, i);
3313
                i++;
3314
            }
3315
            else {
3316
                bs_ke_sub_bytes(t, in + o - 4);
3317
            }
3318
            *(word32*)(in + o +  0) = *(word32*)(in + o - 32) ^
3319
                                      *(word32*) t;
3320
            *(word32*)(in + o +  4) = *(word32*)(in + o - 28) ^
3321
                                      *(word32*)(in + o +  0);
3322
            *(word32*)(in + o +  8) = *(word32*)(in + o - 24) ^
3323
                                      *(word32*)(in + o +  4);
3324
            *(word32*)(in + o + 12) = *(word32*)(in + o - 20) ^
3325
                                      *(word32*)(in + o +  8);
3326
        }
3327
    }
3328
}
3329
3330
static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
3331
    word32 rounds)
3332
{
3333
    int i;
3334
    byte bs_key[15 * WC_AES_BLOCK_SIZE];
3335
    int ksSz = (rounds + 1) * WC_AES_BLOCK_SIZE;
3336
    bs_word block[AES_BLOCK_BITS];
3337
3338
    /* Fist round. */
3339
    XMEMCPY(bs_key, key, keyLen);
3340
    bs_expand_key(bs_key, ksSz);
3341
3342
    for (i = 0; i < ksSz; i += WC_AES_BLOCK_SIZE) {
3343
        int k;
3344
3345
        XMEMCPY(block, bs_key + i, WC_AES_BLOCK_SIZE);
3346
        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
3347
            int l;
3348
            for (l = 0; l < BS_BLOCK_WORDS; l++) {
3349
                block[k + l] = block[l];
3350
            }
3351
        }
3352
        bs_transpose(rk, block);
3353
        rk += AES_BLOCK_BITS;
3354
    }
3355
}
3356
3357
static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
3358
{
3359
    word32 i;
3360
    bs_word trans[AES_BLOCK_BITS];
3361
3362
    bs_transpose(trans, state);
3363
3364
    bs_add_round_key(trans, trans, rk);
3365
    for (i = 1; i < r; i++) {
3366
        bs_sub_bytes_blocks(trans);
3367
        bs_shift_mix(state, trans);
3368
        rk += AES_BLOCK_BITS;
3369
        bs_add_round_key(trans, state, rk);
3370
    }
3371
    bs_sub_bytes_blocks(trans);
3372
    bs_shift_rows(state, trans);
3373
    rk += AES_BLOCK_BITS;
3374
    bs_add_round_key(trans, state, rk);
3375
    bs_inv_transpose(state, trans);
3376
}
3377
3378
#ifndef HAVE_CUDA
3379
/* Encrypt a block using AES.
3380
 *
3381
 * @param [in]  aes       AES object.
3382
 * @param [in]  inBlock   Block to encrypt.
3383
 * @param [out] outBlock  Encrypted block.
3384
 * @param [in]  r         Rounds divided by 2.
3385
 */
3386
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3387
        word32 r)
3388
{
3389
    bs_word state[AES_BLOCK_BITS];
3390
3391
    (void)r;
3392
3393
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
3394
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
3395
3396
    bs_encrypt(state, aes->bs_key, aes->rounds);
3397
3398
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
3399
}
3400
3401
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3402
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3403
/* Encrypt a number of blocks using AES.
3404
 *
3405
 * @param [in]  aes  AES object.
3406
 * @param [in]  in   Block to encrypt.
3407
 * @param [out] out  Encrypted block.
3408
 * @param [in]  sz   Number of blocks to encrypt.
3409
 */
3410
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3411
{
3412
    bs_word state[AES_BLOCK_BITS];
3413
3414
    while (sz >= BS_BLOCK_SIZE) {
3415
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3416
        bs_encrypt(state, aes->bs_key, aes->rounds);
3417
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3418
        sz  -= BS_BLOCK_SIZE;
3419
        in  += BS_BLOCK_SIZE;
3420
        out += BS_BLOCK_SIZE;
3421
    }
3422
    if (sz > 0) {
3423
        XMEMCPY(state, in, sz);
3424
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3425
        bs_encrypt(state, aes->bs_key, aes->rounds);
3426
        XMEMCPY(out, state, sz);
3427
    }
3428
}
3429
#endif
3430
#else
3431
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3432
        word32 r);
3433
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
3434
#endif /* HAVE_CUDA */
3435
3436
#endif /* !WC_AES_BITSLICED */
3437
3438
#ifdef WC_AES_HAVE_PREFETCH_ARG
3439
#define wc_AesEncrypt(aes, inBlock, outBlock) \
3440
5.95k
    AesEncrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
3441
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesEncrypt_preFetchOpt(
3442
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
3443
#else
3444
#define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
3445
    wc_AesEncrypt(aes, inBlock, outBlock)
3446
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesEncrypt(
3447
    Aes* aes, const byte* inBlock, byte* outBlock)
3448
#endif
3449
115k
{
3450
#if defined(MAX3266X_AES)
3451
    word32 keySize;
3452
#endif
3453
#if defined(MAX3266X_CB)
3454
    int ret_cb;
3455
#endif
3456
115k
    word32 r;
3457
3458
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3459
    {
3460
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3461
        if (ret < 0)
3462
            return ret;
3463
    }
3464
#endif
3465
3466
115k
    r = aes->rounds >> 1;
3467
3468
115k
    if (r > 7 || r == 0) {
3469
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3470
0
        return KEYUSAGE_E;
3471
0
    }
3472
3473
#ifdef WOLFSSL_AESNI
3474
    if (aes->use_aesni) {
3475
        ASSERT_SAVED_VECTOR_REGISTERS();
3476
3477
        #ifdef DEBUG_AESNI
3478
            printf("about to aes encrypt\n");
3479
            printf("in  = %p\n", inBlock);
3480
            printf("out = %p\n", outBlock);
3481
            printf("aes->key = %p\n", aes->key);
3482
            printf("aes->rounds = %d\n", aes->rounds);
3483
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
3484
        #endif
3485
3486
        /* check alignment, decrypt doesn't need alignment */
3487
        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
3488
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
3489
            byte* tmp = (byte*)XMALLOC(WC_AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
3490
                                                      DYNAMIC_TYPE_TMP_BUFFER);
3491
            byte* tmp_align;
3492
            if (tmp == NULL)
3493
                return MEMORY_E;
3494
3495
            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
3496
3497
            XMEMCPY(tmp_align, inBlock, WC_AES_BLOCK_SIZE);
3498
            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, WC_AES_BLOCK_SIZE,
3499
                    (byte*)aes->key, (int)aes->rounds);
3500
            XMEMCPY(outBlock, tmp_align, WC_AES_BLOCK_SIZE);
3501
            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3502
            return 0;
3503
        #else
3504
            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
3505
            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
3506
            return BAD_ALIGN_E;
3507
        #endif
3508
        }
3509
3510
        AES_ECB_encrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3511
                        (int)aes->rounds);
3512
3513
        return 0;
3514
    }
3515
    else {
3516
        #ifdef DEBUG_AESNI
3517
            printf("Skipping AES-NI\n");
3518
        #endif
3519
    }
3520
#elif defined(WOLFSSL_ARMASM)
3521
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
3522
#if !defined(__aarch64__)
3523
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
3524
#else
3525
    if (aes->use_aes_hw_crypto) {
3526
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3527
            (int)aes->rounds);
3528
    }
3529
    else
3530
#endif /* !__aarch64__ */
3531
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
3532
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
3533
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
3534
    {
3535
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3536
            (const unsigned char*)aes->key, aes->rounds);
3537
    }
3538
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
3539
    {
3540
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3541
            (const unsigned char*)aes->key, aes->rounds);
3542
    }
3543
#endif
3544
    return 0;
3545
#endif /* WOLFSSL_AESNI */
3546
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3547
    AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3548
    return 0;
3549
#endif
3550
3551
#if defined(WOLFSSL_IMXRT_DCP)
3552
    if (aes->keylen == 16) {
3553
        DCPAesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3554
        return 0;
3555
    }
3556
#endif
3557
3558
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3559
    if (aes->useSWCrypt == 0) {
3560
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3561
                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
3562
    }
3563
#endif
3564
3565
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3566
    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
3567
    if (wc_esp32AesSupportedKeyLen(aes)) {
3568
        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
3569
    }
3570
    else {
3571
        /* For example, the ESP32-S3 does not support HW for len = 24,
3572
         * so fall back to SW */
3573
    #ifdef DEBUG_WOLFSSL
3574
        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
3575
                      aes->keylen);
3576
    #endif
3577
    }
3578
#endif
3579
3580
#if defined(MAX3266X_AES)
3581
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3582
        return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3583
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3584
                                    outBlock, (unsigned int)keySize);
3585
    }
3586
#endif
3587
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3588
    #ifndef WOLF_CRYPTO_CB_FIND
3589
    if (aes->devId != INVALID_DEVID)
3590
    #endif
3591
    {
3592
        ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock,
3593
                                            WC_AES_BLOCK_SIZE);
3594
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3595
            return ret_cb;
3596
        /* fall-through when unavailable */
3597
    }
3598
#endif
3599
3600
115k
#ifdef WC_AES_HAVE_PREFETCH_ARG
3601
115k
    AesEncrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
3602
#else
3603
    AesEncrypt_C(aes, inBlock, outBlock, r);
3604
#endif
3605
3606
115k
    return 0;
3607
115k
} /* wc_AesEncrypt */
3608
#endif
3609
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
3610
3611
#if defined(HAVE_AES_DECRYPT)
3612
#if ((defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3613
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)) && \
3614
    (defined(__aarch64__) || !defined(WOLFSSL_ARMASM))
3615
3616
#ifndef WC_AES_BITSLICED
3617
#ifndef WC_NO_CACHE_RESISTANT
3618
#ifndef WOLFSSL_AES_SMALL_TABLES
3619
/* load 4 Td Tables into cache by cache line stride */
3620
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
3621
830
{
3622
830
    volatile word32 x = 0;
3623
830
    int i;
3624
830
    int j;
3625
3626
4.15k
    for (i = 0; i < 4; i++) {
3627
        /* 256 elements, each one is 4 bytes */
3628
56.4k
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
3629
53.1k
            x &= Td[i][j];
3630
53.1k
        }
3631
3.32k
    }
3632
3633
830
    return x;
3634
830
}
3635
#endif /* !WOLFSSL_AES_SMALL_TABLES */
3636
3637
/* load Td Table4 into cache by cache line stride */
3638
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
3639
830
{
3640
830
#ifndef WOLFSSL_AES_TOUCH_LINES
3641
830
    volatile word32 x = 0;
3642
830
    int i;
3643
3644
4.15k
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
3645
3.32k
        x &= (word32)Td4[i];
3646
3.32k
    }
3647
3648
830
    return x;
3649
#else
3650
    return 0;
3651
#endif
3652
830
}
3653
#endif /* !WC_NO_CACHE_RESISTANT */
3654
3655
/* Decrypt a block using AES.
3656
 *
3657
 * @param [in]  aes       AES object.
3658
 * @param [in]  inBlock   Block to encrypt.
3659
 * @param [out] outBlock  Encrypted block.
3660
 * @param [in]  r         Rounds divided by 2.
3661
 */
3662
#ifndef WC_AES_HAVE_PREFETCH_ARG
3663
    #define WC_AES_HAVE_PREFETCH_ARG
3664
    static int always_prefetch = 0;
3665
    WC_MAYBE_UNUSED static int never_prefetch = 1;
3666
#endif
3667
WC_ARGS_NOT_NULL((1, 2, 3, 5))
3668
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3669
    word32 r, int *prefetch_ptr)
3670
22.8k
{
3671
22.8k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
3672
22.8k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
3673
22.8k
    const word32* rk;
3674
3675
#ifdef WC_C_DYNAMIC_FALLBACK
3676
    rk = aes->key_C_fallback;
3677
#else
3678
22.8k
    rk = aes->key;
3679
22.8k
#endif
3680
3681
    /*
3682
     * map byte array block to cipher state
3683
     * and add initial round key:
3684
     */
3685
22.8k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
3686
22.8k
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
3687
22.8k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
3688
22.8k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
3689
3690
22.8k
#ifdef LITTLE_ENDIAN_ORDER
3691
22.8k
    s0 = ByteReverseWord32(s0);
3692
22.8k
    s1 = ByteReverseWord32(s1);
3693
22.8k
    s2 = ByteReverseWord32(s2);
3694
22.8k
    s3 = ByteReverseWord32(s3);
3695
22.8k
#endif
3696
3697
22.8k
    s0 ^= rk[0];
3698
22.8k
    s1 ^= rk[1];
3699
22.8k
    s2 ^= rk[2];
3700
22.8k
    s3 ^= rk[3];
3701
3702
22.8k
#ifndef WOLFSSL_AES_SMALL_TABLES
3703
3704
22.8k
#ifndef WC_NO_CACHE_RESISTANT
3705
22.8k
    if (*prefetch_ptr == 0) {
3706
830
        s0 |= PreFetchTd();
3707
        /* don't set the prefetched flag here -- PreFetchTd4() is called
3708
         * below.
3709
         */
3710
830
    }
3711
#else
3712
    (void)prefetch_ptr;
3713
#endif
3714
3715
22.8k
#ifndef WOLFSSL_AES_TOUCH_LINES
3716
/* Unroll the loop. */
3717
22.8k
#define DEC_ROUND_T_S(o)                                            \
3718
125k
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
3719
125k
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
3720
125k
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
3721
125k
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
3722
125k
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
3723
125k
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
3724
125k
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
3725
125k
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
3726
22.8k
#define DEC_ROUND_S_T(o)                                            \
3727
102k
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
3728
102k
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
3729
102k
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
3730
102k
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
3731
102k
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
3732
102k
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
3733
102k
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
3734
102k
         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
3735
#else
3736
#define DEC_ROUND_T_S(o)                                                       \
3737
    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
3738
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
3739
    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
3740
                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
3741
    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
3742
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
3743
    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
3744
                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
3745
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
3746
3747
#define DEC_ROUND_S_T(o)                                                       \
3748
    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
3749
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
3750
    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
3751
                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
3752
    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
3753
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
3754
    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
3755
                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
3756
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
3757
#endif
3758
3759
22.8k
#ifndef WOLFSSL_AES_NO_UNROLL
3760
22.8k
                       DEC_ROUND_T_S( 0);
3761
22.8k
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3762
22.8k
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3763
22.8k
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3764
22.8k
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3765
22.8k
    if (r > 5) {
3766
5.43k
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3767
5.43k
        if (r > 6) {
3768
5.38k
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3769
5.38k
        }
3770
5.43k
    }
3771
22.8k
    rk += r * 8;
3772
#else
3773
3774
    /*
3775
     * Nr - 1 full rounds:
3776
     */
3777
3778
    for (;;) {
3779
        DEC_ROUND_T_S(0);
3780
3781
        rk += 8;
3782
        if (--r == 0) {
3783
            break;
3784
        }
3785
3786
        DEC_ROUND_S_T(0);
3787
    }
3788
#endif
3789
    /*
3790
     * apply last round and
3791
     * map cipher state to byte array block:
3792
     */
3793
3794
22.8k
#ifndef WC_NO_CACHE_RESISTANT
3795
22.8k
    if (*prefetch_ptr == 0) {
3796
830
        t0 |= PreFetchTd4();
3797
830
        if (prefetch_ptr != &always_prefetch)
3798
608
            *prefetch_ptr = 1;
3799
830
    }
3800
#else
3801
    (void)prefetch_ptr;
3802
#endif
3803
3804
22.8k
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3805
22.8k
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3806
22.8k
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3807
22.8k
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3808
22.8k
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3809
22.8k
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3810
22.8k
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3811
22.8k
                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
3812
3813
#else /* WOLFSSL_AES_SMALL_TABLES */
3814
3815
#ifndef WC_NO_CACHE_RESISTANT
3816
    if (*prefetch_ptr == 0) {
3817
        s0 |= PreFetchTd4();
3818
        if (prefetch_ptr != &always_prefetch)
3819
            *prefetch_ptr = 1;
3820
    }
3821
#else
3822
    (void)prefetch_ptr;
3823
#endif
3824
3825
    r *= 2;
3826
    for (rk += 4; r > 1; r--, rk += 4) {
3827
        t0 =
3828
            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3829
            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3830
            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3831
            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
3832
            rk[0];
3833
        t1 =
3834
            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3835
            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3836
            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3837
            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
3838
            rk[1];
3839
        t2 =
3840
            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3841
            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3842
            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3843
            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
3844
            rk[2];
3845
        t3 =
3846
            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3847
            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3848
            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3849
            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
3850
            rk[3];
3851
3852
        s0 =
3853
            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
3854
            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
3855
            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
3856
            (inv_col_mul(t0, 1, 3, 2, 0)      );
3857
        s1 =
3858
            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
3859
            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
3860
            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
3861
            (inv_col_mul(t1, 1, 3, 2, 0)      );
3862
        s2 =
3863
            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
3864
            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
3865
            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
3866
            (inv_col_mul(t2, 1, 3, 2, 0)      );
3867
        s3 =
3868
            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
3869
            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
3870
            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
3871
            (inv_col_mul(t3, 1, 3, 2, 0)      );
3872
    }
3873
3874
    t0 =
3875
        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3876
        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3877
        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3878
        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
3879
    t1 =
3880
        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3881
        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3882
        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3883
        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
3884
    t2 =
3885
        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3886
        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3887
        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3888
        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
3889
    t3 =
3890
        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3891
        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3892
        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3893
        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
3894
    s0 = t0 ^ rk[0];
3895
    s1 = t1 ^ rk[1];
3896
    s2 = t2 ^ rk[2];
3897
    s3 = t3 ^ rk[3];
3898
3899
#endif /* WOLFSSL_AES_SMALL_TABLES */
3900
3901
    /* write out */
3902
22.8k
#ifdef LITTLE_ENDIAN_ORDER
3903
22.8k
    s0 = ByteReverseWord32(s0);
3904
22.8k
    s1 = ByteReverseWord32(s1);
3905
22.8k
    s2 = ByteReverseWord32(s2);
3906
22.8k
    s3 = ByteReverseWord32(s3);
3907
22.8k
#endif
3908
3909
22.8k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
3910
22.8k
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
3911
22.8k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
3912
22.8k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
3913
3914
22.8k
}
3915
3916
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3917
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
3918
    !defined(MAX3266X_AES)
3919
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
3920
/* Decrypt a number of blocks using AES.
3921
 *
3922
 * @param [in]  aes  AES object.
3923
 * @param [in]  in   Block to encrypt.
3924
 * @param [out] out  Encrypted block.
3925
 * @param [in]  sz   Number of blocks to encrypt.
3926
 */
3927
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3928
297
{
3929
297
    word32 i;
3930
297
    int did_prefetches = 0;
3931
3932
2.53k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
3933
2.24k
        AesDecrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
3934
2.24k
        in += WC_AES_BLOCK_SIZE;
3935
2.24k
        out += WC_AES_BLOCK_SIZE;
3936
2.24k
    }
3937
297
}
3938
#endif
3939
#endif
3940
3941
#else /* WC_AES_BITSLICED */
3942
3943
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
3944
static void bs_inv_sub_bytes(bs_word u[8])
3945
{
3946
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
3947
    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
3948
    bs_word RTL0, RTL1, RTL2;
3949
    bs_word sa0, sa1;
3950
    bs_word sb0, sb1;
3951
    bs_word ab0, ab1, ab2, ab3;
3952
    bs_word ab20, ab21, ab22, ab23;
3953
    bs_word al, ah, aa, bl, bh, bb;
3954
    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
3955
    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
3956
    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
3957
    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
3958
    bs_word rr1, rr2;
3959
    bs_word r10, r11;
3960
    bs_word cp1, cp2, cp3, cp4;
3961
    bs_word vr1, vr2, vr3;
3962
    bs_word pr1, pr2, pr3;
3963
    bs_word wr1, wr2, wr3;
3964
    bs_word qr1, qr2, qr3;
3965
    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
3966
    bs_word tinv10, tinv11, tinv12, tinv13;
3967
    bs_word t01, t02;
3968
    bs_word d0, d1, d2, d3;
3969
    bs_word dl, dd, dh;
3970
    bs_word sd0, sd1;
3971
    bs_word p0, p1, p2, p3, p4, p6, p7;
3972
    bs_word X11, X13, X14, X16, X18, X19;
3973
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
3974
3975
    U0 = u[7];
3976
    U1 = u[6];
3977
    U2 = u[5];
3978
    U3 = u[4];
3979
    U4 = u[3];
3980
    U5 = u[2];
3981
    U6 = u[1];
3982
    U7 = u[0];
3983
3984
    Y0 = U0 ^ U3;
3985
    Y2 = ~(U1 ^ U3);
3986
    Y4 = U0 ^ Y2;
3987
    RTL0 = U6 ^ U7;
3988
    Y1 = Y2 ^ RTL0;
3989
    Y7 = ~(U2 ^ Y1);
3990
    RTL1 = U3 ^ U4;
3991
    Y6 = ~(U7 ^ RTL1);
3992
    Y3 = Y1 ^ RTL1;
3993
    RTL2 = ~(U0 ^ U2);
3994
    Y5 = U5 ^ RTL2;
3995
    sa1 = Y0 ^ Y2;
3996
    sa0 = Y1 ^ Y3;
3997
    sb1 = Y4 ^ Y6;
3998
    sb0 = Y5 ^ Y7;
3999
    ah = Y0 ^ Y1;
4000
    al = Y2 ^ Y3;
4001
    aa = sa0 ^ sa1;
4002
    bh = Y4 ^ Y5;
4003
    bl = Y6 ^ Y7;
4004
    bb = sb0 ^ sb1;
4005
    ab20 = sa0 ^ sb0;
4006
    ab22 = al ^ bl;
4007
    ab23 = Y3 ^ Y7;
4008
    ab21 = sa1 ^ sb1;
4009
    abcd1 = ah & bh;
4010
    rr1 = Y0 & Y4;
4011
    ph11 = ab20 ^ abcd1;
4012
    t01 = Y1 & Y5;
4013
    ph01 = t01 ^ abcd1;
4014
    abcd2 = al & bl;
4015
    r1 = Y2 & Y6;
4016
    pl11 = ab22 ^ abcd2;
4017
    r2 = Y3 & Y7;
4018
    pl01 = r2 ^ abcd2;
4019
    r3 = sa0 & sb0;
4020
    vr1 = aa & bb;
4021
    pr1 = vr1 ^ r3;
4022
    wr1 = sa1 & sb1;
4023
    qr1 = wr1 ^ r3;
4024
    ab0 = ph11 ^ rr1;
4025
    ab1 = ph01 ^ ab21;
4026
    ab2 = pl11 ^ r1;
4027
    ab3 = pl01 ^ qr1;
4028
    cp1 = ab0 ^ pr1;
4029
    cp2 = ab1 ^ qr1;
4030
    cp3 = ab2 ^ pr1;
4031
    cp4 = ab3 ^ ab23;
4032
    tinv1 = cp3 ^ cp4;
4033
    tinv2 = cp3 & cp1;
4034
    tinv3 = cp2 ^ tinv2;
4035
    tinv4 = cp1 ^ cp2;
4036
    tinv5 = cp4 ^ tinv2;
4037
    tinv6 = tinv5 & tinv4;
4038
    tinv7 = tinv3 & tinv1;
4039
    d2 = cp4 ^ tinv7;
4040
    d0 = cp2 ^ tinv6;
4041
    tinv8 = cp1 & cp4;
4042
    tinv9 = tinv4 & tinv8;
4043
    tinv10 = tinv4 ^ tinv2;
4044
    d1 = tinv9 ^ tinv10;
4045
    tinv11 = cp2 & cp3;
4046
    tinv12 = tinv1 & tinv11;
4047
    tinv13 = tinv1 ^ tinv2;
4048
    d3 = tinv12 ^ tinv13;
4049
    sd1 = d1 ^ d3;
4050
    sd0 = d0 ^ d2;
4051
    dl = d0 ^ d1;
4052
    dh = d2 ^ d3;
4053
    dd = sd0 ^ sd1;
4054
    abcd3 = dh & bh;
4055
    rr2 = d3 & Y4;
4056
    t02 = d2 & Y5;
4057
    abcd4 = dl & bl;
4058
    r4 = d1 & Y6;
4059
    r5 = d0 & Y7;
4060
    r6 = sd0 & sb0;
4061
    vr2 = dd & bb;
4062
    wr2 = sd1 & sb1;
4063
    abcd5 = dh & ah;
4064
    r7 = d3 & Y0;
4065
    r8 = d2 & Y1;
4066
    abcd6 = dl & al;
4067
    r9 = d1 & Y2;
4068
    r10 = d0 & Y3;
4069
    r11 = sd0 & sa0;
4070
    vr3 = dd & aa;
4071
    wr3 = sd1 & sa1;
4072
    ph12 = rr2 ^ abcd3;
4073
    ph02 = t02 ^ abcd3;
4074
    pl12 = r4 ^ abcd4;
4075
    pl02 = r5 ^ abcd4;
4076
    pr2 = vr2 ^ r6;
4077
    qr2 = wr2 ^ r6;
4078
    p0 = ph12 ^ pr2;
4079
    p1 = ph02 ^ qr2;
4080
    p2 = pl12 ^ pr2;
4081
    p3 = pl02 ^ qr2;
4082
    ph13 = r7 ^ abcd5;
4083
    ph03 = r8 ^ abcd5;
4084
    pl13 = r9 ^ abcd6;
4085
    pl03 = r10 ^ abcd6;
4086
    pr3 = vr3 ^ r11;
4087
    qr3 = wr3 ^ r11;
4088
    p4 = ph13 ^ pr3;
4089
    S7 = ph03 ^ qr3;
4090
    p6 = pl13 ^ pr3;
4091
    p7 = pl03 ^ qr3;
4092
    S3 = p1 ^ p6;
4093
    S6 = p2 ^ p6;
4094
    S0 = p3 ^ p6;
4095
    X11 = p0 ^ p2;
4096
    S5 = S0 ^ X11;
4097
    X13 = p4 ^ p7;
4098
    X14 = X11 ^ X13;
4099
    S1 = S3 ^ X14;
4100
    X16 = p1 ^ S7;
4101
    S2 = X14 ^ X16;
4102
    X18 = p0 ^ p4;
4103
    X19 = S5 ^ X16;
4104
    S4 = X18 ^ X19;
4105
4106
    u[0] = S7;
4107
    u[1] = S6;
4108
    u[2] = S5;
4109
    u[3] = S4;
4110
    u[4] = S3;
4111
    u[5] = S2;
4112
    u[6] = S1;
4113
    u[7] = S0;
4114
}
4115
4116
static void bs_inv_shift_rows(bs_word* b)
4117
{
4118
    bs_word t[AES_BLOCK_BITS];
4119
    int i;
4120
4121
    for (i = 0; i < 128; i += 32) {
4122
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
4123
        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
4124
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
4125
        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
4126
    }
4127
4128
    XMEMCPY(b, t, sizeof(t));
4129
}
4130
4131
#define O0  0
4132
#define O1  8
4133
#define O2  16
4134
#define O3  24
4135
4136
#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
4137
    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
4138
          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
4139
    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
4140
          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
4141
    of2 =                     b[O0+7] ^             b[O1+7] ^               \
4142
                    b[O2+7] ^ b[O3+7];                                      \
4143
                                                                            \
4144
    br[0] =                                                   b[O1+0] ^     \
4145
            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
4146
    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
4147
            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
4148
    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
4149
            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
4150
    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
4151
            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
4152
    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
4153
            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
4154
    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
4155
            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
4156
    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
4157
            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
4158
    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
4159
            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
4160
4161
/* Inverse mix columns and shift rows. */
4162
static void bs_inv_mix_shift(bs_word* t, bs_word* b)
4163
{
4164
    bs_word* bp = b;
4165
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
4166
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
4167
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
4168
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
4169
    int i;
4170
4171
    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
4172
        bs_word* br;
4173
        bs_word of0;
4174
        bs_word of1;
4175
        bs_word of2;
4176
4177
        br = t + or0;
4178
        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
4179
        br = t + or1;
4180
        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
4181
        br = t + or2;
4182
        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
4183
        br = t + or3;
4184
        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
4185
4186
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4187
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4188
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4189
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4190
4191
        bp += AES_BLOCK_BITS / 4;
4192
    }
4193
}
4194
4195
static void bs_inv_sub_bytes_blocks(bs_word* b)
4196
{
4197
    int i;
4198
4199
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
4200
        bs_inv_sub_bytes(b + i);
4201
    }
4202
}
4203
4204
static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
4205
{
4206
    int i;
4207
    bs_word trans[AES_BLOCK_BITS];
4208
4209
    bs_transpose(trans, state);
4210
4211
    rk += r * AES_BLOCK_BITS;
4212
    bs_add_round_key(trans, trans, rk);
4213
    bs_inv_shift_rows(trans);
4214
    bs_inv_sub_bytes_blocks(trans);
4215
    rk -= AES_BLOCK_BITS;
4216
    bs_add_round_key(trans, trans, rk);
4217
    for (i = (int)r - 2; i >= 0; i--) {
4218
        bs_inv_mix_shift(state, trans);
4219
        bs_inv_sub_bytes_blocks(state);
4220
        rk -= AES_BLOCK_BITS;
4221
        bs_add_round_key(trans, state, rk);
4222
    }
4223
4224
    bs_inv_transpose(state, trans);
4225
}
4226
4227
#ifdef WOLFSSL_AES_DIRECT
4228
/* Decrypt a block using AES.
4229
 *
4230
 * @param [in]  aes       AES object.
4231
 * @param [in]  inBlock   Block to encrypt.
4232
 * @param [out] outBlock  Encrypted block.
4233
 * @param [in]  r         Rounds divided by 2.
4234
 */
4235
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
4236
    word32 r)
4237
{
4238
    bs_word state[AES_BLOCK_BITS];
4239
4240
    (void)r;
4241
4242
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
4243
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
4244
4245
    bs_decrypt(state, aes->bs_key, aes->rounds);
4246
4247
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
4248
}
4249
#endif
4250
4251
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
4252
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
4253
/* Decrypt a number of blocks using AES.
4254
 *
4255
 * @param [in]  aes  AES object.
4256
 * @param [in]  in   Block to encrypt.
4257
 * @param [out] out  Encrypted block.
4258
 * @param [in]  sz   Number of blocks to encrypt.
4259
 */
4260
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
4261
{
4262
    bs_word state[AES_BLOCK_BITS];
4263
4264
    while (sz >= BS_BLOCK_SIZE) {
4265
        XMEMCPY(state, in, BS_BLOCK_SIZE);
4266
        bs_decrypt(state, aes->bs_key, aes->rounds);
4267
        XMEMCPY(out, state, BS_BLOCK_SIZE);
4268
        sz  -= BS_BLOCK_SIZE;
4269
        in  += BS_BLOCK_SIZE;
4270
        out += BS_BLOCK_SIZE;
4271
    }
4272
    if (sz > 0) {
4273
        XMEMCPY(state, in, sz);
4274
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
4275
        bs_decrypt(state, aes->bs_key, aes->rounds);
4276
        XMEMCPY(out, state, sz);
4277
    }
4278
}
4279
#endif
4280
4281
#endif /* !WC_AES_BITSLICED */
4282
#endif
4283
4284
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
4285
    defined(WOLFSSL_AES_DIRECT)
4286
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
4287
#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
4288
/* Software AES - ECB Decrypt */
4289
4290
#ifdef WC_AES_HAVE_PREFETCH_ARG
4291
#define wc_AesDecrypt(aes, inBlock, outBlock) \
4292
222
    AesDecrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
4293
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesDecrypt_preFetchOpt(
4294
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
4295
#else
4296
#define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
4297
    wc_AesDecrypt(aes, inBlock, outBlock)
4298
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
4299
    Aes* aes, const byte* inBlock, byte* outBlock)
4300
#endif
4301
20.6k
{
4302
#if defined(MAX3266X_AES)
4303
    word32 keySize;
4304
#endif
4305
#if defined(MAX3266X_CB)
4306
    int ret_cb;
4307
#endif
4308
20.6k
    word32 r;
4309
4310
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4311
    {
4312
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4313
        if (ret < 0)
4314
            return ret;
4315
    }
4316
#endif
4317
4318
20.6k
    r = aes->rounds >> 1;
4319
4320
20.6k
    if (r > 7 || r == 0) {
4321
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
4322
0
        return KEYUSAGE_E;
4323
0
    }
4324
4325
#ifdef WOLFSSL_AESNI
4326
    if (aes->use_aesni) {
4327
        ASSERT_SAVED_VECTOR_REGISTERS();
4328
4329
        #ifdef DEBUG_AESNI
4330
            printf("about to aes decrypt\n");
4331
            printf("in  = %p\n", inBlock);
4332
            printf("out = %p\n", outBlock);
4333
            printf("aes->key = %p\n", aes->key);
4334
            printf("aes->rounds = %d\n", aes->rounds);
4335
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
4336
        #endif
4337
4338
        /* if input and output same will overwrite input iv */
4339
        if ((const byte*)aes->tmp != inBlock)
4340
            XMEMCPY(aes->tmp, inBlock, WC_AES_BLOCK_SIZE);
4341
        AES_ECB_decrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
4342
                        (int)aes->rounds);
4343
        return 0;
4344
    }
4345
    else {
4346
        #ifdef DEBUG_AESNI
4347
            printf("Skipping AES-NI\n");
4348
        #endif
4349
    }
4350
#elif defined(WOLFSSL_ARMASM)
4351
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4352
#if !defined(__aarch64__)
4353
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
4354
#else
4355
    if (aes->use_aes_hw_crypto) {
4356
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
4357
            (int)aes->rounds);
4358
    }
4359
    else
4360
#endif /* !__aarch64__ */
4361
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
4362
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
4363
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
4364
    {
4365
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4366
            (const unsigned char*)aes->key, aes->rounds);
4367
    }
4368
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
4369
    {
4370
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4371
            (const unsigned char*)aes->key, aes->rounds);
4372
    }
4373
#endif
4374
    return 0;
4375
#endif /* WOLFSSL_AESNI */
4376
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
4377
    return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
4378
#endif
4379
#if defined(WOLFSSL_IMXRT_DCP)
4380
    if (aes->keylen == 16) {
4381
        DCPAesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4382
        return 0;
4383
    }
4384
#endif
4385
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
4386
    if (aes->useSWCrypt == 0) {
4387
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
4388
                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
4389
    }
4390
#endif
4391
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
4392
    if (wc_esp32AesSupportedKeyLen(aes)) {
4393
        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
4394
    }
4395
    else {
4396
        /* For example, the ESP32-S3 does not support HW for len = 24,
4397
         * so fall back to SW */
4398
    #ifdef DEBUG_WOLFSSL
4399
        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
4400
                        "unsupported keylen = %d", aes->keylen);
4401
    #endif
4402
    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
4403
#endif
4404
4405
#if defined(MAX3266X_AES)
4406
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
4407
        return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
4408
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
4409
                                    outBlock, (unsigned int)keySize);
4410
    }
4411
#endif
4412
4413
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
4414
    #ifndef WOLF_CRYPTO_CB_FIND
4415
    if (aes->devId != INVALID_DEVID)
4416
    #endif
4417
    {
4418
        ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock,
4419
                                            WC_AES_BLOCK_SIZE);
4420
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4421
            return ret_cb;
4422
        /* fall-through when unavailable */
4423
    }
4424
#endif
4425
4426
20.6k
#ifdef WC_AES_HAVE_PREFETCH_ARG
4427
20.6k
    AesDecrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
4428
#else
4429
    AesDecrypt_C(aes, inBlock, outBlock, r);
4430
#endif
4431
4432
20.6k
    return 0;
4433
20.6k
} /* wc_AesDecrypt[_SW]() */
4434
#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
4435
#endif
4436
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
4437
#endif /* HAVE_AES_DECRYPT */
4438
4439
#endif /* NEED_AES_TABLES */
4440
4441
#ifdef WOLF_CRYPTO_CB_ONLY_AES
4442
/* Under WOLF_CRYPTO_CB_ONLY_AES the per-block primitive is a thin shim over
4443
 * the cryptocb ECB callback. When the callback returns CRYPTOCB_UNAVAILABLE
4444
 * there is no software fallback, so the operation fails with NO_VALID_DEVID. */
4445
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
4446
    byte* outBlock)
4447
{
4448
    int ret;
4449
4450
    if (aes == NULL || inBlock == NULL || outBlock == NULL)
4451
        return BAD_FUNC_ARG;
4452
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4453
    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4454
    if (ret < 0)
4455
        return ret;
4456
#endif
4457
4458
    ret = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4459
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4460
        return ret;
4461
    return NO_VALID_DEVID;
4462
}
4463
4464
#ifdef HAVE_AES_DECRYPT
4465
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
4466
    byte* outBlock)
4467
{
4468
    int ret;
4469
4470
    if (aes == NULL || inBlock == NULL || outBlock == NULL)
4471
        return BAD_FUNC_ARG;
4472
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4473
    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4474
    if (ret < 0)
4475
        return ret;
4476
#endif
4477
4478
    ret = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4479
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4480
        return ret;
4481
    return NO_VALID_DEVID;
4482
}
4483
#endif /* HAVE_AES_DECRYPT */
4484
#endif /* WOLF_CRYPTO_CB_ONLY_AES */
4485
4486
#ifndef WC_AES_HAVE_PREFETCH_ARG
4487
    #ifndef AesEncrypt_preFetchOpt
4488
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4489
            wc_AesEncrypt(aes, inBlock, outBlock)
4490
    #endif
4491
    #ifndef AesDecrypt_preFetchOpt
4492
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4493
            wc_AesDecrypt(aes, inBlock, outBlock)
4494
    #endif
4495
#endif
4496
4497
/* wc_AesSetKey */
4498
#if defined(STM32_CRYPTO)
4499
4500
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4501
            const byte* iv, int dir)
4502
    {
4503
        word32 *rk;
4504
4505
        (void)dir;
4506
4507
        if (aes == NULL || (keylen != 16 &&
4508
        #ifdef WOLFSSL_AES_192
4509
            keylen != 24 &&
4510
        #endif
4511
            keylen != 32)) {
4512
            return BAD_FUNC_ARG;
4513
        }
4514
4515
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4516
        {
4517
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4518
            if (ret < 0)
4519
                return ret;
4520
        }
4521
#endif
4522
4523
        rk = aes->key;
4524
        aes->keylen = keylen;
4525
        aes->rounds = keylen/4 + 6;
4526
        XMEMCPY(rk, userKey, keylen);
4527
    #ifdef WOLF_CRYPTO_CB
4528
        /* Keep a raw (non-reversed) copy for crypto-callback offload, e.g. the
4529
         * DHUK device reads the seed from devKey. Mirrors the generic
4530
         * wc_AesSetKey cryptocb path. */
4531
        if (keylen <= sizeof(aes->devKey)) {
4532
            XMEMCPY(aes->devKey, userKey, keylen);
4533
        }
4534
    #endif
4535
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
4536
        ByteReverseWords(rk, rk, keylen);
4537
    #endif
4538
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4539
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4540
        defined(WOLFSSL_AES_CTS)
4541
        aes->left = 0;
4542
    #endif
4543
        return wc_AesSetIV(aes, iv);
4544
    }
4545
    #if defined(WOLFSSL_AES_DIRECT)
4546
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4547
                            const byte* iv, int dir)
4548
        {
4549
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4550
        }
4551
    #endif
4552
4553
#elif defined(HAVE_COLDFIRE_SEC)
4554
    #if defined (HAVE_THREADX)
4555
        #include "memory_pools.h"
4556
        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
4557
    #endif
4558
4559
    #define AES_BUFFER_SIZE (WC_AES_BLOCK_SIZE * 64)
4560
    static unsigned char *AESBuffIn = NULL;
4561
    static unsigned char *AESBuffOut = NULL;
4562
    static byte *secReg;
4563
    static byte *secKey;
4564
    static volatile SECdescriptorType *secDesc;
4565
4566
    static wolfSSL_Mutex Mutex_AesSEC;
4567
4568
    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
4569
    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
4570
4571
    extern volatile unsigned char __MBAR[];
4572
4573
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4574
        const byte* iv, int dir)
4575
    {
4576
        if (AESBuffIn == NULL) {
4577
        #if defined (HAVE_THREADX)
4578
            int s1, s2, s3, s4, s5;
4579
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
4580
                                  sizeof(SECdescriptorType), TX_NO_WAIT);
4581
            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
4582
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4583
            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
4584
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4585
            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
4586
                                  WC_AES_BLOCK_SIZE*2, TX_NO_WAIT);
4587
            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
4588
                                  WC_AES_BLOCK_SIZE, TX_NO_WAIT);
4589
4590
            if (s1 || s2 || s3 || s4 || s5)
4591
                return BAD_FUNC_ARG;
4592
        #else
4593
            #warning "Allocate non-Cache buffers"
4594
        #endif
4595
4596
            wc_InitMutex(&Mutex_AesSEC);
4597
        }
4598
4599
        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4600
            return BAD_FUNC_ARG;
4601
4602
        if (aes == NULL)
4603
            return BAD_FUNC_ARG;
4604
4605
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4606
        {
4607
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4608
            if (ret < 0)
4609
                return ret;
4610
        }
4611
#endif
4612
4613
        aes->keylen = keylen;
4614
        aes->rounds = keylen/4 + 6;
4615
        XMEMCPY(aes->key, userKey, keylen);
4616
4617
        if (iv)
4618
            XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4619
4620
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4621
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4622
        defined(WOLFSSL_AES_CTS)
4623
        aes->left = 0;
4624
    #endif
4625
4626
        return 0;
4627
    }
4628
#elif defined(FREESCALE_LTC)
4629
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
4630
        const byte* iv, int dir, int checkKeyLen)
4631
    {
4632
        if (aes == NULL)
4633
            return BAD_FUNC_ARG;
4634
4635
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4636
        {
4637
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4638
            if (ret < 0)
4639
                return ret;
4640
        }
4641
#endif
4642
4643
        if (checkKeyLen) {
4644
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4645
                return BAD_FUNC_ARG;
4646
        }
4647
        (void)dir;
4648
4649
        aes->rounds = keylen/4 + 6;
4650
        XMEMCPY(aes->key, userKey, keylen);
4651
4652
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4653
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4654
        defined(WOLFSSL_AES_CTS)
4655
        aes->left = 0;
4656
    #endif
4657
4658
        return wc_AesSetIV(aes, iv);
4659
    }
4660
4661
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4662
        const byte* iv, int dir)
4663
    {
4664
        if (aes == NULL || userKey == NULL) {
4665
            return BAD_FUNC_ARG;
4666
        }
4667
        if (keylen > sizeof(aes->key)) {
4668
            return BAD_FUNC_ARG;
4669
        }
4670
4671
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4672
    }
4673
4674
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4675
                        const byte* iv, int dir)
4676
    {
4677
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4678
    }
4679
#elif defined(WOLFSSL_NRF51_AES)
4680
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4681
        const byte* iv, int dir)
4682
    {
4683
        int ret;
4684
4685
        (void)dir;
4686
        (void)iv;
4687
4688
        if (aes == NULL || keylen != 16)
4689
            return BAD_FUNC_ARG;
4690
4691
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4692
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4693
        if (ret < 0)
4694
            return ret;
4695
#endif
4696
4697
        aes->keylen = keylen;
4698
        aes->rounds = keylen/4 + 6;
4699
        XMEMCPY(aes->key, userKey, keylen);
4700
        ret = nrf51_aes_set_key(userKey);
4701
4702
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4703
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4704
        defined(WOLFSSL_AES_CTS)
4705
        aes->left = 0;
4706
    #endif
4707
4708
        return ret;
4709
    }
4710
4711
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4712
                        const byte* iv, int dir)
4713
    {
4714
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4715
    }
4716
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4717
    /* This is the only definition for HW only.
4718
     * but needs to be renamed when fallback needed.
4719
     * See call in wc_AesSetKey() */
4720
    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
4721
        const byte* iv, int dir)
4722
    {
4723
        (void)dir;
4724
        (void)iv;
4725
        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
4726
        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
4727
            return BAD_FUNC_ARG;
4728
        }
4729
4730
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4731
        {
4732
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4733
            if (ret < 0)
4734
                return ret;
4735
        }
4736
#endif
4737
4738
    #if !defined(WOLFSSL_AES_128)
4739
        if (keylen == 16) {
4740
            return BAD_FUNC_ARG;
4741
        }
4742
    #endif
4743
4744
    #if !defined(WOLFSSL_AES_192)
4745
        if (keylen == 24) {
4746
            return BAD_FUNC_ARG;
4747
        }
4748
    #endif
4749
4750
    #if !defined(WOLFSSL_AES_256)
4751
        if (keylen == 32) {
4752
            return BAD_FUNC_ARG;
4753
        }
4754
    #endif
4755
4756
        aes->keylen = keylen;
4757
        aes->rounds = keylen/4 + 6;
4758
4759
        XMEMCPY(aes->key, userKey, keylen);
4760
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4761
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4762
            defined(WOLFSSL_AES_CTS)
4763
            aes->left = 0;
4764
        #endif
4765
        return wc_AesSetIV(aes, iv);
4766
    } /* wc_AesSetKey */
4767
4768
    /* end #elif ESP32 */
4769
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
4770
4771
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
4772
                    int dir)
4773
    {
4774
        SaSiError_t ret = SASI_OK;
4775
        SaSiAesIv_t iv_aes;
4776
4777
        if (aes == NULL ||
4778
           (keylen != AES_128_KEY_SIZE &&
4779
            keylen != AES_192_KEY_SIZE &&
4780
            keylen != AES_256_KEY_SIZE)) {
4781
            return BAD_FUNC_ARG;
4782
        }
4783
4784
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4785
        {
4786
            int ret2 =
4787
                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4788
            if (ret2 < 0)
4789
                return ret2;
4790
        }
4791
#endif
4792
4793
    #if defined(AES_MAX_KEY_SIZE)
4794
        if (keylen > (AES_MAX_KEY_SIZE/8)) {
4795
            return BAD_FUNC_ARG;
4796
        }
4797
    #endif
4798
        if (dir != AES_ENCRYPTION &&
4799
            dir != AES_DECRYPTION) {
4800
            return BAD_FUNC_ARG;
4801
        }
4802
4803
        if (dir == AES_ENCRYPTION) {
4804
            aes->ctx.mode = SASI_AES_ENCRYPT;
4805
            SaSi_AesInit(&aes->ctx.user_ctx,
4806
                         SASI_AES_ENCRYPT,
4807
                         SASI_AES_MODE_CBC,
4808
                         SASI_AES_PADDING_NONE);
4809
        }
4810
        else {
4811
            aes->ctx.mode = SASI_AES_DECRYPT;
4812
            SaSi_AesInit(&aes->ctx.user_ctx,
4813
                         SASI_AES_DECRYPT,
4814
                         SASI_AES_MODE_CBC,
4815
                         SASI_AES_PADDING_NONE);
4816
        }
4817
4818
        aes->keylen = keylen;
4819
        aes->rounds = keylen/4 + 6;
4820
        XMEMCPY(aes->key, userKey, keylen);
4821
4822
        aes->ctx.key.pKey = (byte*)aes->key;
4823
        aes->ctx.key.keySize= keylen;
4824
4825
        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
4826
                             SASI_AES_USER_KEY,
4827
                             &aes->ctx.key,
4828
                             sizeof(aes->ctx.key));
4829
        if (ret != SASI_OK) {
4830
            return BAD_FUNC_ARG;
4831
        }
4832
4833
        ret = wc_AesSetIV(aes, iv);
4834
4835
        if (iv)
4836
            XMEMCPY(iv_aes, iv, WC_AES_BLOCK_SIZE);
4837
        else
4838
            XMEMSET(iv_aes,  0, WC_AES_BLOCK_SIZE);
4839
4840
4841
        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
4842
        if (ret != SASI_OK) {
4843
            return ret;
4844
        }
4845
       return ret;
4846
    }
4847
    #if defined(WOLFSSL_AES_DIRECT)
4848
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4849
                            const byte* iv, int dir)
4850
        {
4851
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4852
        }
4853
    #endif
4854
4855
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
4856
    && !defined(WOLFSSL_QNX_CAAM)
4857
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4858
4859
#elif defined(WOLFSSL_AFALG)
4860
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4861
4862
#elif defined(WOLFSSL_DEVCRYPTO_AES)
4863
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
4864
4865
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4866
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
4867
4868
#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
4869
     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
4870
    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
4871
4872
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
4873
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4874
            const byte* iv, int dir)
4875
    {
4876
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4877
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4878
        defined(WOLFSSL_AES_CTS)
4879
        aes->left = 0;
4880
    #endif
4881
4882
        aes->keylen = (int)keylen;
4883
        aes->rounds = (keylen/4) + 6;
4884
4885
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4886
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
4887
#else
4888
        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
4889
4890
    #ifdef HAVE_AES_DECRYPT
4891
        if (dir == AES_DECRYPTION) {
4892
            AES_invert_key((byte*)aes->key, aes->rounds);
4893
        }
4894
    #else
4895
        (void)dir;
4896
    #endif
4897
#endif
4898
        return wc_AesSetIV(aes, iv);
4899
    }
4900
4901
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4902
            const byte* iv, int dir)
4903
    {
4904
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
4905
        int cbRet;
4906
#endif
4907
        if ((aes == NULL) || (userKey == NULL)) {
4908
            return BAD_FUNC_ARG;
4909
        }
4910
4911
        switch (keylen) {
4912
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4913
        defined(WOLFSSL_AES_128)
4914
        case 16:
4915
    #endif
4916
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4917
        defined(WOLFSSL_AES_192)
4918
        case 24:
4919
    #endif
4920
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4921
        defined(WOLFSSL_AES_256)
4922
        case 32:
4923
    #endif
4924
            break;
4925
        default:
4926
            return BAD_FUNC_ARG;
4927
        }
4928
4929
    #ifdef WOLF_CRYPTO_CB
4930
        if (aes->devId != INVALID_DEVID) {
4931
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
4932
            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
4933
            if (ret == 0) {
4934
                /* Callback succeeded - SE owns the key */
4935
                aes->keylen = (int)keylen;
4936
                if (iv != NULL)
4937
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4938
                else
4939
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
4940
                return 0;
4941
            }
4942
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
4943
                aes->devCtx = NULL;
4944
                return ret;
4945
            }
4946
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
4947
        #endif
4948
        #ifdef WOLF_CRYPTO_CB_SETKEY
4949
            cbRet = wc_CryptoCb_SetKey(aes->devId,
4950
                WC_SETKEY_AES, aes, (void*)userKey, keylen,
4951
                (void*)iv,
4952
                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
4953
            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4954
                return cbRet;
4955
            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
4956
        #endif /* WOLF_CRYPTO_CB_SETKEY */
4957
            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
4958
            if (keylen > sizeof(aes->devKey)) {
4959
                return BAD_FUNC_ARG;
4960
            }
4961
            XMEMCPY(aes->devKey, userKey, keylen);
4962
        }
4963
    #endif
4964
4965
        return AesSetKey(aes, userKey, keylen, iv, dir);
4966
    }
4967
4968
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
4969
        /* AES-CTR and AES-DIRECT need to use this for key setup */
4970
        /* This function allows key sizes that are not 128/192/256 bits */
4971
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4972
                           const byte* iv, int dir)
4973
    {
4974
        if (aes == NULL) {
4975
            return BAD_FUNC_ARG;
4976
        }
4977
        if (keylen > sizeof(aes->key)) {
4978
            return BAD_FUNC_ARG;
4979
        }
4980
4981
        return AesSetKey(aes, userKey, keylen, iv, dir);
4982
    }
4983
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
4984
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
4985
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4986
            const byte* iv, int dir)
4987
    {
4988
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4989
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4990
        defined(WOLFSSL_AES_CTS)
4991
        aes->left = 0;
4992
    #endif
4993
4994
        aes->keylen = (int)keylen;
4995
        aes->rounds = (keylen/4) + 6;
4996
4997
        /* Determine base vs vector-crypto before the (dispatched) key setup so
4998
         * the schedule matches the mode functions that later consume it. */
4999
        Aes_SetCrypto();
5000
        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5001
5002
    #ifdef HAVE_AES_DECRYPT
5003
        if (dir == AES_DECRYPTION) {
5004
            AES_invert_key((byte*)aes->key, aes->rounds);
5005
        }
5006
    #else
5007
        (void)dir;
5008
    #endif
5009
        return wc_AesSetIV(aes, iv);
5010
    }
5011
5012
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5013
            const byte* iv, int dir)
5014
    {
5015
        if ((aes == NULL) || (userKey == NULL)) {
5016
            return BAD_FUNC_ARG;
5017
        }
5018
5019
        switch (keylen) {
5020
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5021
        defined(WOLFSSL_AES_128)
5022
        case 16:
5023
    #endif
5024
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5025
        defined(WOLFSSL_AES_192)
5026
        case 24:
5027
    #endif
5028
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5029
        defined(WOLFSSL_AES_256)
5030
        case 32:
5031
    #endif
5032
            break;
5033
        default:
5034
            return BAD_FUNC_ARG;
5035
        }
5036
5037
    #ifdef WOLF_CRYPTO_CB
5038
        if (aes->devId != INVALID_DEVID) {
5039
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5040
            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5041
            if (ret == 0) {
5042
                /* Callback succeeded - SE owns the key */
5043
                aes->keylen = (int)keylen;
5044
                if (iv != NULL)
5045
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5046
                else
5047
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5048
                return 0;
5049
            }
5050
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5051
                aes->devCtx = NULL;
5052
                return ret;
5053
            }
5054
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5055
        #endif
5056
            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
5057
            if (keylen > sizeof(aes->devKey)) {
5058
                return BAD_FUNC_ARG;
5059
            }
5060
            XMEMCPY(aes->devKey, userKey, keylen);
5061
        }
5062
    #endif
5063
5064
        return AesSetKey(aes, userKey, keylen, iv, dir);
5065
    }
5066
5067
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5068
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5069
        /* This function allows key sizes that are not 128/192/256 bits */
5070
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5071
                           const byte* iv, int dir)
5072
    {
5073
        if (aes == NULL) {
5074
            return BAD_FUNC_ARG;
5075
        }
5076
        if (keylen > sizeof(aes->key)) {
5077
            return BAD_FUNC_ARG;
5078
        }
5079
5080
        return AesSetKey(aes, userKey, keylen, iv, dir);
5081
    }
5082
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5083
#elif defined(FREESCALE_MMCAU)
5084
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
5085
        const byte* iv, int dir, int checkKeyLen)
5086
    {
5087
        int ret;
5088
        byte* rk;
5089
        byte* tmpKey = (byte*)userKey;
5090
        int tmpKeyDynamic = 0;
5091
        word32 alignOffset = 0;
5092
5093
        (void)dir;
5094
5095
        if (aes == NULL)
5096
            return BAD_FUNC_ARG;
5097
5098
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5099
        {
5100
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5101
            if (ret < 0)
5102
                return ret;
5103
        }
5104
#endif
5105
5106
        if (checkKeyLen) {
5107
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
5108
                return BAD_FUNC_ARG;
5109
        }
5110
5111
        rk = (byte*)aes->key;
5112
        if (rk == NULL)
5113
            return BAD_FUNC_ARG;
5114
5115
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5116
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5117
        defined(WOLFSSL_AES_CTS)
5118
        aes->left = 0;
5119
    #endif
5120
5121
        aes->rounds = keylen/4 + 6;
5122
5123
    #ifdef FREESCALE_MMCAU_CLASSIC
5124
        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
5125
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
5126
            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
5127
                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5128
            if (tmp == NULL) {
5129
                return MEMORY_E;
5130
            }
5131
            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
5132
                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
5133
            tmpKey = tmp + alignOffset;
5134
            XMEMCPY(tmpKey, userKey, keylen);
5135
            tmpKeyDynamic = 1;
5136
        #else
5137
            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
5138
            return BAD_ALIGN_E;
5139
        #endif
5140
        }
5141
    #endif
5142
5143
        ret = wolfSSL_CryptHwMutexLock();
5144
        if(ret == 0) {
5145
        #ifdef FREESCALE_MMCAU_CLASSIC
5146
            cau_aes_set_key(tmpKey, keylen*8, rk);
5147
        #else
5148
            MMCAU_AES_SetKey(tmpKey, keylen, rk);
5149
        #endif
5150
            wolfSSL_CryptHwMutexUnLock();
5151
5152
            ret = wc_AesSetIV(aes, iv);
5153
        }
5154
5155
        if (tmpKeyDynamic == 1) {
5156
            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5157
        }
5158
5159
        return ret;
5160
    }
5161
5162
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5163
        const byte* iv, int dir)
5164
    {
5165
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
5166
    }
5167
5168
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5169
                        const byte* iv, int dir)
5170
    {
5171
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
5172
    }
5173
5174
#elif defined(WOLFSSL_PSOC6_CRYPTO)
5175
5176
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5177
        const byte* iv, int dir)
5178
    {
5179
        return wc_Psoc6_Aes_SetKey(aes, userKey, keylen, iv, dir);
5180
    }
5181
5182
    #if defined(WOLFSSL_AES_DIRECT)
5183
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5184
                            const byte* iv, int dir)
5185
        {
5186
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
5187
        }
5188
    #endif /* WOLFSSL_AES_DIRECT */
5189
#else
5190
    #define NEED_SOFTWARE_AES_SETKEY
5191
#endif
5192
5193
/* Either we fell though with no HW support at all,
5194
 * or perhaps there's HW support for *some* keylengths
5195
 * and we need both HW and SW. */
5196
#ifdef NEED_SOFTWARE_AES_SETKEY
5197
5198
#ifdef NEED_AES_TABLES
5199
5200
#ifndef WC_AES_BITSLICED
5201
#if !defined(WOLFSSL_ARMASM)
5202
/* Set the AES key and expand.
5203
 *
5204
 * @param [in]  aes    AES object.
5205
 * @param [in]  key    Block to encrypt.
5206
 * @param [in]  keySz  Number of bytes in key.
5207
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
5208
 */
5209
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
5210
4.19k
{
5211
#ifdef WC_C_DYNAMIC_FALLBACK
5212
    word32* rk = aes->key_C_fallback;
5213
#else
5214
4.19k
    word32* rk = aes->key;
5215
4.19k
#endif
5216
4.19k
    word32 temp;
5217
4.19k
    unsigned int i = 0;
5218
5219
4.19k
    XMEMCPY(rk, key, keySz);
5220
4.19k
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
5221
4.19k
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
5222
4.19k
    !defined(MAX3266X_AES)
5223
    /* Always reverse words when using only SW */
5224
4.19k
    {
5225
4.19k
        ByteReverseWords(rk, rk, keySz);
5226
4.19k
    }
5227
#else
5228
    /* Sometimes reverse words when using supported HW */
5229
    #if defined(WOLFSSL_ESPIDF)
5230
        /* Some platforms may need SW fallback (e.g. AES192) */
5231
        #if defined(NEED_AES_HW_FALLBACK)
5232
        {
5233
            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
5234
            if (wc_esp32AesSupportedKeyLen(aes)) {
5235
                /* don't reverse for HW supported key lengths */
5236
            }
5237
            else {
5238
                ByteReverseWords(rk, rk, keySz);
5239
            }
5240
        }
5241
        #else
5242
            /* If we don't need SW fallback, don't need to reverse words. */
5243
        #endif /* NEED_AES_HW_FALLBACK */
5244
    #endif /* WOLFSSL_ESPIDF */
5245
#endif /* LITTLE_ENDIAN_ORDER, etc */
5246
5247
4.19k
    switch (keySz) {
5248
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
5249
0
        defined(WOLFSSL_AES_128)
5250
2.47k
    case 16:
5251
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5252
        temp = (word32)-1;
5253
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5254
    #endif
5255
24.7k
        while (1)
5256
24.7k
        {
5257
24.7k
            temp  = rk[3];
5258
24.7k
            rk[4] = rk[0] ^
5259
24.7k
        #ifndef WOLFSSL_AES_SMALL_TABLES
5260
24.7k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5261
24.7k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5262
24.7k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5263
24.7k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5264
        #else
5265
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5266
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5267
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5268
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5269
        #endif
5270
24.7k
                rcon[i];
5271
24.7k
            rk[5] = rk[1] ^ rk[4];
5272
24.7k
            rk[6] = rk[2] ^ rk[5];
5273
24.7k
            rk[7] = rk[3] ^ rk[6];
5274
24.7k
            if (++i == 10)
5275
2.47k
                break;
5276
22.2k
            rk += 4;
5277
22.2k
        }
5278
2.47k
        break;
5279
0
#endif /* 128 */
5280
5281
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
5282
0
        defined(WOLFSSL_AES_192)
5283
539
    case 24:
5284
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5285
        temp = (word32)-1;
5286
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5287
    #endif
5288
        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
5289
4.31k
        while (1)
5290
4.31k
        {
5291
4.31k
            temp = rk[ 5];
5292
4.31k
            rk[ 6] = rk[ 0] ^
5293
4.31k
        #ifndef WOLFSSL_AES_SMALL_TABLES
5294
4.31k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5295
4.31k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5296
4.31k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5297
4.31k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5298
        #else
5299
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5300
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5301
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5302
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5303
        #endif
5304
4.31k
                rcon[i];
5305
4.31k
            rk[ 7] = rk[ 1] ^ rk[ 6];
5306
4.31k
            rk[ 8] = rk[ 2] ^ rk[ 7];
5307
4.31k
            rk[ 9] = rk[ 3] ^ rk[ 8];
5308
4.31k
            if (++i == 8)
5309
539
                break;
5310
3.77k
            rk[10] = rk[ 4] ^ rk[ 9];
5311
3.77k
            rk[11] = rk[ 5] ^ rk[10];
5312
3.77k
            rk += 6;
5313
3.77k
        }
5314
539
        break;
5315
0
#endif /* 192 */
5316
5317
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
5318
0
        defined(WOLFSSL_AES_256)
5319
1.18k
    case 32:
5320
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5321
        temp = (word32)-1;
5322
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5323
    #endif
5324
8.30k
        while (1)
5325
8.30k
        {
5326
8.30k
            temp = rk[ 7];
5327
8.30k
            rk[ 8] = rk[ 0] ^
5328
8.30k
        #ifndef WOLFSSL_AES_SMALL_TABLES
5329
8.30k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5330
8.30k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5331
8.30k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5332
8.30k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5333
        #else
5334
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5335
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5336
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5337
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5338
        #endif
5339
8.30k
                rcon[i];
5340
8.30k
            rk[ 9] = rk[ 1] ^ rk[ 8];
5341
8.30k
            rk[10] = rk[ 2] ^ rk[ 9];
5342
8.30k
            rk[11] = rk[ 3] ^ rk[10];
5343
8.30k
            if (++i == 7)
5344
1.18k
                break;
5345
7.11k
            temp = rk[11];
5346
7.11k
            rk[12] = rk[ 4] ^
5347
7.11k
        #ifndef WOLFSSL_AES_SMALL_TABLES
5348
7.11k
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
5349
7.11k
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
5350
7.11k
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
5351
7.11k
                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
5352
        #else
5353
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
5354
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
5355
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
5356
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
5357
        #endif
5358
7.11k
            rk[13] = rk[ 5] ^ rk[12];
5359
7.11k
            rk[14] = rk[ 6] ^ rk[13];
5360
7.11k
            rk[15] = rk[ 7] ^ rk[14];
5361
5362
7.11k
            rk += 8;
5363
7.11k
        }
5364
1.18k
        break;
5365
4.19k
#endif /* 256 */
5366
4.19k
    } /* switch */
5367
4.19k
    ForceZero(&temp, sizeof(temp));
5368
5369
4.19k
#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
5370
4.19k
    if (dir == AES_DECRYPTION) {
5371
659
        unsigned int j;
5372
5373
#ifdef WC_C_DYNAMIC_FALLBACK
5374
        rk = aes->key_C_fallback;
5375
#else
5376
659
        rk = aes->key;
5377
659
#endif
5378
5379
        /* invert the order of the round keys: */
5380
4.31k
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
5381
3.65k
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
5382
3.65k
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
5383
3.65k
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
5384
3.65k
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
5385
3.65k
        }
5386
659
        ForceZero(&temp, sizeof(temp));
5387
659
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
5388
        /* apply the inverse MixColumn transform to all round keys but the
5389
           first and the last: */
5390
7.30k
        for (i = 1; i < aes->rounds; i++) {
5391
6.64k
            rk += 4;
5392
6.64k
            rk[0] =
5393
6.64k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
5394
6.64k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
5395
6.64k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
5396
6.64k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
5397
6.64k
            rk[1] =
5398
6.64k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
5399
6.64k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
5400
6.64k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
5401
6.64k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
5402
6.64k
            rk[2] =
5403
6.64k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
5404
6.64k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
5405
6.64k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
5406
6.64k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
5407
6.64k
            rk[3] =
5408
6.64k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
5409
6.64k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
5410
6.64k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
5411
6.64k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
5412
6.64k
        }
5413
659
    #endif
5414
659
    }
5415
#else
5416
    (void)dir;
5417
#endif /* HAVE_AES_DECRYPT */
5418
5419
#ifdef WOLFSSL_CHECK_MEM_ZERO
5420
    wc_MemZero_Check(&temp, sizeof(temp));
5421
#else
5422
4.19k
    (void)temp;
5423
4.19k
#endif
5424
4.19k
}
5425
#endif
5426
#else /* WC_AES_BITSLICED */
5427
/* Set the AES key and expand.
5428
 *
5429
 * @param [in]  aes    AES object.
5430
 * @param [in]  key    Block to encrypt.
5431
 * @param [in]  keySz  Number of bytes in key.
5432
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
5433
 */
5434
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
5435
{
5436
    /* No need to invert when decrypting. */
5437
    (void)dir;
5438
5439
    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
5440
}
5441
#endif /* WC_AES_BITSLICED */
5442
5443
#endif /* NEED_AES_TABLES */
5444
5445
    /* AES - SetKey (block schedule via generated asm on RISC-V) */
5446
    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
5447
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
5448
        int checkKeyLen)
5449
4.19k
    {
5450
4.19k
        int ret;
5451
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
5452
        int cbRet;
5453
#endif
5454
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5455
        byte   local[32];
5456
        word32 localSz = 32;
5457
    #endif
5458
5459
4.19k
        if (aes == NULL)
5460
0
            return BAD_FUNC_ARG;
5461
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5462
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5463
        if (ret < 0)
5464
            return ret;
5465
#endif
5466
5467
4.19k
        switch (keylen) {
5468
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5469
0
        defined(WOLFSSL_AES_128)
5470
2.47k
        case 16:
5471
2.47k
    #endif
5472
2.47k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5473
2.47k
        defined(WOLFSSL_AES_192)
5474
3.00k
        case 24:
5475
3.00k
    #endif
5476
3.00k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5477
3.00k
        defined(WOLFSSL_AES_256)
5478
4.19k
        case 32:
5479
4.19k
    #endif
5480
4.19k
            break;
5481
0
        default:
5482
0
            return BAD_FUNC_ARG;
5483
4.19k
        }
5484
5485
4.19k
    #ifdef WOLF_CRYPTO_CB
5486
4.19k
        #ifndef WOLF_CRYPTO_CB_FIND
5487
4.19k
        if (aes->devId != INVALID_DEVID)
5488
990
        #endif
5489
990
        {
5490
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5491
            ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5492
            if (ret == 0) {
5493
                /* Callback succeeded - SE owns the key */
5494
                aes->keylen = (int)keylen;
5495
                if (iv != NULL)
5496
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5497
                else
5498
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5499
                return 0;
5500
            }
5501
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5502
                aes->devCtx = NULL;
5503
                return ret;
5504
            }
5505
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5506
        #endif
5507
        #ifdef WOLF_CRYPTO_CB_SETKEY
5508
            cbRet = wc_CryptoCb_SetKey(aes->devId,
5509
                WC_SETKEY_AES, aes, (void*)userKey, keylen,
5510
                (void*)iv,
5511
                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
5512
            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5513
                return cbRet;
5514
            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
5515
        #endif /* WOLF_CRYPTO_CB_SETKEY */
5516
            /* Standard CryptoCB path - copy key to devKey */
5517
990
            if (keylen > sizeof(aes->devKey)) {
5518
0
                return BAD_FUNC_ARG;
5519
0
            }
5520
990
            XMEMCPY(aes->devKey, userKey, keylen);
5521
990
        }
5522
4.19k
    #endif
5523
5524
    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
5525
        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
5526
            return WC_HW_E;
5527
        }
5528
    #endif
5529
5530
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5531
        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
5532
            keylen == (24 + WC_CAAM_BLOB_SZ) ||
5533
            keylen == (32 + WC_CAAM_BLOB_SZ)) {
5534
            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
5535
                return BAD_FUNC_ARG;
5536
            }
5537
5538
            /* set local values */
5539
            userKey = local;
5540
            keylen = localSz;
5541
        }
5542
    #endif
5543
5544
    #ifdef WOLFSSL_SECO_CAAM
5545
        /* if set to use hardware than import the key */
5546
        if (aes->devId == WOLFSSL_SECO_DEVID) {
5547
            int keyGroup = 1; /* group one was chosen arbitrarily */
5548
            unsigned int keyIdOut;
5549
            byte importiv[GCM_NONCE_MID_SZ];
5550
            int importivSz = GCM_NONCE_MID_SZ;
5551
            int keyType = 0;
5552
            WC_RNG rng;
5553
5554
            if (wc_InitRng(&rng) != 0) {
5555
                WOLFSSL_MSG("RNG init for IV failed");
5556
                return WC_HW_E;
5557
            }
5558
5559
            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
5560
                WOLFSSL_MSG("Generate IV failed");
5561
                wc_FreeRng(&rng);
5562
                return WC_HW_E;
5563
            }
5564
            wc_FreeRng(&rng);
5565
5566
            if (iv)
5567
                XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5568
            else
5569
                XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5570
5571
            switch (keylen) {
5572
                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
5573
                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
5574
                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
5575
            }
5576
5577
            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
5578
                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
5579
            if (keyIdOut == 0) {
5580
                return WC_HW_E;
5581
            }
5582
            aes->blackKey = keyIdOut;
5583
            return 0;
5584
        }
5585
    #endif
5586
5587
4.19k
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
5588
4.19k
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
5589
4.19k
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) || \
5590
4.19k
        defined(WOLFSSL_NXP_HASHCRYPT_AES)
5591
4.19k
        #ifdef WOLF_CRYPTO_CB
5592
4.19k
        #ifndef WOLF_CRYPTO_CB_FIND
5593
4.19k
        if (aes->devId != INVALID_DEVID)
5594
990
        #endif
5595
990
        #endif
5596
990
        {
5597
990
            if (keylen > sizeof(aes->devKey)) {
5598
0
                return BAD_FUNC_ARG;
5599
0
            }
5600
990
            XMEMCPY(aes->devKey, userKey, keylen);
5601
990
        }
5602
4.19k
    #endif
5603
5604
    #ifdef WOLF_CRYPTO_CB_ONLY_AES
5605
        /* No software AES schedule under CB_ONLY: aes->key[] (round keys) are
5606
         * unused because the static wc_AesEncrypt/wc_AesDecrypt are cryptocb-
5607
         * ECB shims. aes->rounds is still populated because wc_AesGetKeySize()
5608
         * reads it as the source of truth for the configured key size. */
5609
        aes->keylen = (int)keylen;
5610
        aes->rounds = (keylen / 4) + 6;
5611
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5612
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5613
            defined(WOLFSSL_AES_CTS)
5614
        aes->left = 0;
5615
        #endif
5616
        (void)dir;
5617
        return wc_AesSetIV(aes, iv);
5618
    #endif
5619
5620
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
5621
        if (checkKeyLen) {
5622
            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
5623
             * all key sizes. Otherwise this condition is never true. */
5624
            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
5625
                return BAD_FUNC_ARG;
5626
            }
5627
        }
5628
    #else
5629
4.19k
        (void) checkKeyLen;
5630
4.19k
    #endif
5631
5632
4.19k
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5633
4.19k
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5634
4.19k
        defined(WOLFSSL_AES_CTS)
5635
4.19k
        aes->left = 0;
5636
4.19k
    #endif
5637
5638
4.19k
        aes->keylen = (int)keylen;
5639
4.19k
        aes->rounds = (keylen/4) + 6;
5640
4.19k
        ret = wc_AesSetIV(aes, iv);
5641
4.19k
        if (ret != 0)
5642
0
            return ret;
5643
5644
#ifdef WC_C_DYNAMIC_FALLBACK
5645
#ifdef NEED_AES_TABLES
5646
        AesSetKey_C(aes, userKey, keylen, dir);
5647
#endif /* NEED_AES_TABLES */
5648
#endif /* WC_C_DYNAMIC_FALLBACK */
5649
5650
    #ifdef WOLFSSL_AESNI
5651
5652
       /* The dynamics for determining whether AES-NI will be used are tricky.
5653
        *
5654
        * First, we check for CPU support and cache the result -- if AES-NI is
5655
        * missing, we always shortcut to the AesSetKey_C() path.
5656
        *
5657
        * Second, if the CPU supports AES-NI, we confirm on a per-call basis
5658
        * that it's safe to use in the caller context, using
5659
        * SAVE_VECTOR_REGISTERS2().  This is an always-true no-op in user-space
5660
        * builds, but has substantive logic behind it in kernel module builds.
5661
        *
5662
        * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on
5663
        * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with
5664
        * success but with AES-NI disabled (the earlier AesSetKey_C() allows
5665
        * future encrypt/decrypt calls to succeed), otherwise we fail.
5666
        *
5667
        * Upon successful return, aes->use_aesni will have a zero value if
5668
        * AES-NI is disabled, and a nonzero value if it's enabled.
5669
        *
5670
        * An additional, optional semantic is available via
5671
        * WC_FLAG_DONT_USE_VECTOR_OPS, and is used in some kernel module builds
5672
        * to let the caller inhibit AES-NI.  When this macro is defined,
5673
        * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of
5674
        * uninitialized data in aes->use_aesni.  That's why support for
5675
        * WC_FLAG_DONT_USE_VECTOR_OPS must remain optional -- wc_AesInit() was
5676
        * only added in release 3.11.0, so legacy applications inevitably call
5677
        * wc_AesSetKey() on uninitialized Aes contexts.  This must continue to
5678
        * function correctly with default build settings.
5679
        */
5680
5681
        if (checkedAESNI == 0) {
5682
            haveAESNI = Check_CPU_support_AES();
5683
            checkedAESNI = 1;
5684
        }
5685
        if (haveAESNI
5686
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS) && !defined(WC_C_DYNAMIC_FALLBACK)
5687
            && (aes->use_aesni != WC_FLAG_DONT_USE_VECTOR_OPS)
5688
#endif
5689
            )
5690
        {
5691
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS)
5692
            if (aes->use_aesni == WC_FLAG_DONT_USE_VECTOR_OPS) {
5693
                aes->use_aesni = 0;
5694
                return 0;
5695
            }
5696
#endif
5697
            aes->use_aesni = 0;
5698
            #ifdef WOLFSSL_KERNEL_MODE
5699
            /* runtime alignment check */
5700
            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
5701
                ret = BAD_ALIGN_E;
5702
            }
5703
            else
5704
            #endif /* WOLFSSL_KERNEL_MODE */
5705
            {
5706
                ret = SAVE_VECTOR_REGISTERS2();
5707
            }
5708
            if (ret == 0) {
5709
                if (dir == AES_ENCRYPTION)
5710
                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5711
#ifdef HAVE_AES_DECRYPT
5712
                else
5713
                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5714
#endif
5715
5716
                RESTORE_VECTOR_REGISTERS();
5717
5718
                if (ret == 0)
5719
                    aes->use_aesni = 1;
5720
                else {
5721
#ifdef WC_C_DYNAMIC_FALLBACK
5722
                    ret = 0;
5723
#endif
5724
                }
5725
                return ret;
5726
            } else {
5727
#ifdef WC_C_DYNAMIC_FALLBACK
5728
                return 0;
5729
#else
5730
                return ret;
5731
#endif
5732
            }
5733
        }
5734
        else {
5735
            aes->use_aesni = 0;
5736
#ifdef WC_C_DYNAMIC_FALLBACK
5737
            /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C()
5738
             * above.
5739
             */
5740
            return 0;
5741
#endif
5742
        }
5743
    #endif /* WOLFSSL_AESNI */
5744
5745
4.19k
#ifndef WC_C_DYNAMIC_FALLBACK
5746
5747
#if defined(WOLFSSL_RISCV_ASM)
5748
        /* Generated RISC-V assembly key schedule (all paths). aes->rounds /
5749
         * aes->keylen were set above. */
5750
        AES_set_key_RISCV64(userKey, (int)keylen, (byte*)aes->key, dir);
5751
        return 0;
5752
#elif defined(WOLFSSL_ARMASM)
5753
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5754
    #ifndef __aarch64__
5755
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5756
    #else
5757
        Check_CPU_support_HwCrypto(aes);
5758
        if (aes->use_aes_hw_crypto) {
5759
            AES_set_key_AARCH64(userKey, keylen, (byte*)aes->key, dir);
5760
        }
5761
        else
5762
    #endif /* __aarch64__ */
5763
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
5764
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
5765
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
5766
        {
5767
            AES_set_encrypt_key_NEON(userKey, keylen * 8, (byte*)aes->key);
5768
        #ifdef HAVE_AES_DECRYPT
5769
            if (dir == AES_DECRYPTION) {
5770
                AES_invert_key_NEON((byte*)aes->key, aes->rounds);
5771
            }
5772
        #else
5773
            (void)dir;
5774
        #endif
5775
        }
5776
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5777
        {
5778
            AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5779
        #ifdef HAVE_AES_DECRYPT
5780
            if (dir == AES_DECRYPTION) {
5781
                AES_invert_key((byte*)aes->key, aes->rounds);
5782
            }
5783
        #else
5784
            (void)dir;
5785
        #endif
5786
        }
5787
    #endif
5788
        return 0;
5789
#else
5790
5791
    #ifdef WOLFSSL_KCAPI_AES
5792
        XMEMCPY(aes->devKey, userKey, keylen);
5793
        if (aes->init != 0) {
5794
            kcapi_cipher_destroy(aes->handle);
5795
            aes->handle = NULL;
5796
            aes->init = 0;
5797
        }
5798
        (void)dir;
5799
    #endif
5800
5801
4.19k
        if (keylen > sizeof(aes->key)) {
5802
0
            return BAD_FUNC_ARG;
5803
0
        }
5804
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
5805
        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
5806
                                  ((psa_algorithm_t)0), dir);
5807
#endif
5808
5809
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
5810
        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
5811
         * instead of SE05x crypto by setting useSWCrypt */
5812
        if (aes->useSWCrypt == 0) {
5813
            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
5814
            if (ret == 0) {
5815
                ret = wc_AesSetIV(aes, iv);
5816
            }
5817
            return ret;
5818
        }
5819
#endif
5820
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
5821
        if (keylen == TA_KEY_TYPE_AES128_SIZE) {
5822
            ret = wc_Microchip_aes_set_key(aes, userKey, keylen, iv, dir);
5823
            if (ret != 0) {
5824
                return ret;
5825
            }
5826
            ret = wc_AesSetIV(aes, iv);
5827
            if (ret != 0) {
5828
                return ret;
5829
            }
5830
        }
5831
#endif
5832
4.19k
        XMEMCPY(aes->key, userKey, keylen);
5833
5834
4.19k
#ifndef WC_AES_BITSLICED
5835
4.19k
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
5836
4.19k
        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
5837
4.19k
        && !defined(MAX3266X_AES)
5838
5839
        /* software */
5840
4.19k
        ByteReverseWords(aes->key, aes->key, keylen);
5841
5842
    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
5843
        if (wc_esp32AesSupportedKeyLen(aes)) {
5844
            /* supported lengths don't get reversed */
5845
            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
5846
        }
5847
        else {
5848
            word32* rk = aes->key;
5849
5850
            /* For example, the ESP32-S3 does not support HW for len = 24,
5851
             * so fall back to SW */
5852
        #ifdef DEBUG_WOLFSSL
5853
            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
5854
        #endif
5855
            XMEMCPY(rk, userKey, keylen);
5856
            /* When not ESP32 HW, we need to reverse endianness */
5857
            ByteReverseWords(rk, rk, keylen);
5858
        }
5859
    #endif
5860
5861
    #ifdef WOLFSSL_IMXRT_DCP
5862
        {
5863
            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
5864
            word32 temp = 0;
5865
            if (keylen == 16)
5866
                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
5867
            if (temp != 0)
5868
                return WC_HW_E;
5869
        }
5870
    #endif
5871
4.19k
#endif /* !WC_AES_BITSLICED */
5872
5873
4.19k
#ifdef NEED_AES_TABLES
5874
4.19k
        AesSetKey_C(aes, userKey, keylen, dir);
5875
4.19k
#endif /* NEED_AES_TABLES */
5876
5877
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
5878
        XMEMCPY((byte*)aes->key, userKey, keylen);
5879
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
5880
            ByteReverseWords(aes->key, aes->key, 32);
5881
        }
5882
#endif
5883
5884
    #if defined(WOLFSSL_DEVCRYPTO) && \
5885
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
5886
        aes->ctx.cfd = -1;
5887
    #endif
5888
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5889
        ForceZero(local, sizeof(local));
5890
    #endif
5891
4.19k
        return ret;
5892
4.19k
#endif
5893
5894
4.19k
#endif /* !WC_C_DYNAMIC_FALLBACK */
5895
5896
4.19k
    } /* wc_AesSetKeyLocal */
5897
5898
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5899
            const byte* iv, int dir)
5900
3.75k
    {
5901
3.75k
        if (aes == NULL) {
5902
0
            return BAD_FUNC_ARG;
5903
0
        }
5904
3.75k
        if (keylen > sizeof(aes->key)) {
5905
0
            return BAD_FUNC_ARG;
5906
0
        }
5907
5908
    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
5909
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
5910
        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
5911
        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
5912
            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
5913
            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
5914
        }
5915
        else {
5916
        #if  defined(WOLFSSL_HW_METRICS)
5917
            /* It is interesting to know how many times we could not complete
5918
             * AES in hardware due to unsupported lengths. */
5919
            wc_esp32AesUnupportedLengthCountAdd();
5920
        #endif
5921
        #ifdef DEBUG_WOLFSSL
5922
            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
5923
                           keylen);
5924
        #endif
5925
        }
5926
    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
5927
5928
3.75k
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
5929
5930
3.75k
    } /* wc_AesSetKey() */
5931
5932
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5933
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5934
        /* This function allows key sizes that are not 128/192/256 bits */
5935
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5936
                           const byte* iv, int dir)
5937
439
    {
5938
439
        if (aes == NULL) {
5939
0
            return BAD_FUNC_ARG;
5940
0
        }
5941
439
        if (keylen > sizeof(aes->key)) {
5942
0
            return BAD_FUNC_ARG;
5943
0
        }
5944
5945
439
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
5946
439
    }
5947
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5948
#endif /* wc_AesSetKey block */
5949
5950
5951
/* wc_AesSetIV is shared between software and hardware */
5952
int wc_AesSetIV(Aes* aes, const byte* iv)
5953
4.69k
{
5954
4.69k
    if (aes == NULL)
5955
0
        return BAD_FUNC_ARG;
5956
5957
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5958
    {
5959
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5960
        if (ret < 0)
5961
            return ret;
5962
    }
5963
#endif
5964
5965
4.69k
    if (iv)
5966
3.02k
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5967
1.66k
    else
5968
1.66k
        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
5969
5970
4.69k
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5971
4.69k
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5972
4.69k
    defined(WOLFSSL_AES_CTS)
5973
    /* Clear any unused bytes from last cipher op. */
5974
4.69k
    aes->left = 0;
5975
4.69k
#endif
5976
5977
4.69k
    return 0;
5978
4.69k
}
5979
5980
#ifdef WOLFSSL_AESNI
5981
5982
#ifdef WC_C_DYNAMIC_FALLBACK
5983
5984
#define VECTOR_REGISTERS_PUSH {                                      \
5985
        int orig_use_aesni = aes->use_aesni;                         \
5986
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
5987
            aes->use_aesni = 0;                                      \
5988
        }                                                            \
5989
        WC_DO_NOTHING
5990
5991
#define VECTOR_REGISTERS_PUSH2(fail_clause) {                        \
5992
        int orig_use_aesni = aes->use_aesni;                         \
5993
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
5994
            aes->use_aesni = 0;                                      \
5995
        }                                                            \
5996
        WC_DO_NOTHING
5997
5998
5999
#define VECTOR_REGISTERS_POP                                         \
6000
        if (aes->use_aesni)                                          \
6001
            RESTORE_VECTOR_REGISTERS();                              \
6002
        else                                                         \
6003
            aes->use_aesni = orig_use_aesni;                         \
6004
    }                                                                \
6005
    WC_DO_NOTHING
6006
6007
#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
6008
6009
#define VECTOR_REGISTERS_PUSH { \
6010
        WC_DO_NOTHING
6011
6012
#define VECTOR_REGISTERS_PUSH2(fail_clause) { \
6013
        WC_DO_NOTHING
6014
6015
#define VECTOR_REGISTERS_POP                                         \
6016
    }                                                                \
6017
    WC_DO_NOTHING
6018
6019
#else
6020
6021
#define VECTOR_REGISTERS_PUSH {                                          \
6022
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
6023
            return ret;                                                  \
6024
        }                                                                \
6025
        WC_DO_NOTHING
6026
6027
#define VECTOR_REGISTERS_PUSH2(fail_clause) {                            \
6028
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
6029
            { fail_clause }                                              \
6030
            return ret;                                                  \
6031
        }                                                                \
6032
        WC_DO_NOTHING
6033
6034
#define VECTOR_REGISTERS_POP \
6035
        if (aes->use_aesni) {                                            \
6036
            RESTORE_VECTOR_REGISTERS();                                  \
6037
        }                                                                \
6038
    }                                                                    \
6039
    WC_DO_NOTHING
6040
6041
#endif
6042
6043
#else /* !WOLFSSL_AESNI */
6044
6045
7.01k
#define VECTOR_REGISTERS_PUSH WC_DO_NOTHING
6046
#define VECTOR_REGISTERS_PUSH2(fail_clause) WC_DO_NOTHING
6047
7.01k
#define VECTOR_REGISTERS_POP WC_DO_NOTHING
6048
6049
#endif /* !WOLFSSL_AESNI */
6050
6051
6052
/* AES-DIRECT */
6053
#if defined(WOLFSSL_AES_DIRECT)
6054
    #if defined(HAVE_COLDFIRE_SEC)
6055
        #error "Coldfire SEC doesn't yet support AES direct"
6056
6057
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6058
        !defined(WOLFSSL_QNX_CAAM)
6059
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6060
6061
    #elif defined(WOLFSSL_AFALG)
6062
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6063
6064
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
6065
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6066
6067
    #else
6068
6069
        /* Allow direct access to one block encrypt */
6070
        /* Note, the in and out args are swapped compared to wc_AesEncrypt(). */
6071
        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
6072
230
        {
6073
230
            int ret;
6074
6075
230
            if (aes == NULL || out == NULL || in == NULL)
6076
0
                return BAD_FUNC_ARG;
6077
230
            VECTOR_REGISTERS_PUSH;
6078
230
            ret = wc_AesEncrypt(aes, in, out);
6079
230
            VECTOR_REGISTERS_POP;
6080
230
            return ret;
6081
230
        }
6082
6083
        /* vector reg save/restore is explicit in all below calls to
6084
         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
6085
         * macro.
6086
         */
6087
667
        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
6088
6089
        #ifdef HAVE_AES_DECRYPT
6090
        /* Allow direct access to one block decrypt */
6091
        /* Note, the in and out args are swapped compared to wc_AesDecrypt(). */
6092
        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
6093
0
        {
6094
0
            int ret;
6095
6096
0
            if (aes == NULL)
6097
0
                return BAD_FUNC_ARG;
6098
0
            VECTOR_REGISTERS_PUSH;
6099
0
            ret = wc_AesDecrypt(aes, in, out);
6100
0
            VECTOR_REGISTERS_POP;
6101
0
            return ret;
6102
0
        }
6103
6104
222
        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
6105
6106
        #endif /* HAVE_AES_DECRYPT */
6107
    #endif /* AES direct block */
6108
#endif /* WOLFSSL_AES_DIRECT */
6109
6110
6111
/* AES-CBC */
6112
#ifdef HAVE_AES_CBC
6113
#if defined(STM32_CRYPTO)
6114
6115
#ifdef WOLFSSL_STM32_BARE
6116
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6117
    {
6118
    #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6119
        if (sz % WC_AES_BLOCK_SIZE) {
6120
            return BAD_LENGTH_E;
6121
        }
6122
    #endif
6123
        if (sz == 0) {
6124
            return 0;
6125
        }
6126
    #ifdef WOLF_CRYPTO_CB
6127
        #ifndef WOLF_CRYPTO_CB_FIND
6128
        if (aes->devId != INVALID_DEVID)
6129
        #endif
6130
        {
6131
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6132
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6133
                return crypto_cb_ret;
6134
            /* fall-through when unavailable (normal-keyed Aes) */
6135
        }
6136
    #endif
6137
        /* DHUK / any crypto-callback device is routed above. wc_Stm32_Aes_Cbc
6138
         * processes whole blocks and ignores any sub-block remainder, matching
6139
         * the SW / CUBEMX CBC backends; define WOLFSSL_AES_CBC_LENGTH_CHECKS
6140
         * (above) to reject a non-block-multiple length with BAD_LENGTH_E. */
6141
        return wc_Stm32_Aes_Cbc(aes, out, in, sz, 1);
6142
    }
6143
    #ifdef HAVE_AES_DECRYPT
6144
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6145
    {
6146
    #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6147
        if (sz % WC_AES_BLOCK_SIZE) {
6148
            return BAD_LENGTH_E;
6149
        }
6150
    #endif
6151
        if (sz == 0) {
6152
            return 0;
6153
        }
6154
    #ifdef WOLF_CRYPTO_CB
6155
        #ifndef WOLF_CRYPTO_CB_FIND
6156
        if (aes->devId != INVALID_DEVID)
6157
        #endif
6158
        {
6159
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6160
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6161
                return crypto_cb_ret;
6162
            /* fall-through when unavailable (normal-keyed Aes) */
6163
        }
6164
    #endif
6165
        /* DHUK / any crypto-callback device is routed above. */
6166
        return wc_Stm32_Aes_Cbc(aes, out, in, sz, 0);
6167
    }
6168
    #endif /* HAVE_AES_DECRYPT */
6169
#elif defined(WOLFSSL_STM32_CUBEMX)
6170
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6171
    {
6172
        int ret = 0;
6173
        CRYP_HandleTypeDef hcryp;
6174
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6175
6176
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6177
        if (sz % WC_AES_BLOCK_SIZE) {
6178
            return BAD_LENGTH_E;
6179
        }
6180
#endif
6181
        if (blocks == 0)
6182
            return 0;
6183
6184
    #ifdef WOLF_CRYPTO_CB
6185
        #ifndef WOLF_CRYPTO_CB_FIND
6186
        if (aes->devId != INVALID_DEVID)
6187
        #endif
6188
        {
6189
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6190
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6191
                return crypto_cb_ret;
6192
            /* fall-through when unavailable (normal-keyed Aes) */
6193
        }
6194
    #endif
6195
6196
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6197
        if (ret != 0)
6198
            return ret;
6199
6200
        ret = wolfSSL_CryptHwMutexLock();
6201
        if (ret != 0) {
6202
            return ret;
6203
        }
6204
6205
    #if defined(STM32_HAL_V2)
6206
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
6207
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
6208
    #elif defined(STM32_CRYPTO_AES_ONLY)
6209
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
6210
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
6211
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6212
    #endif
6213
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6214
        ret = HAL_CRYP_Init(&hcryp);
6215
6216
        if (ret == HAL_OK) {
6217
        #if defined(STM32_HAL_V2)
6218
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
6219
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6220
        #elif defined(STM32_CRYPTO_AES_ONLY)
6221
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
6222
                out, STM32_HAL_TIMEOUT);
6223
        #else
6224
            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
6225
                                        blocks * WC_AES_BLOCK_SIZE,
6226
                                        out, STM32_HAL_TIMEOUT);
6227
        #endif
6228
        }
6229
        if (ret != HAL_OK) {
6230
            ret = WC_TIMEOUT_E;
6231
        }
6232
6233
        /* store iv for next call */
6234
        XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6235
6236
        HAL_CRYP_DeInit(&hcryp);
6237
6238
        wolfSSL_CryptHwMutexUnLock();
6239
        wc_Stm32_Aes_Cleanup();
6240
6241
        return ret;
6242
    }
6243
    #ifdef HAVE_AES_DECRYPT
6244
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6245
    {
6246
        int ret = 0;
6247
        CRYP_HandleTypeDef hcryp;
6248
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6249
6250
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6251
        if (sz % WC_AES_BLOCK_SIZE) {
6252
            return BAD_LENGTH_E;
6253
        }
6254
#endif
6255
        if (blocks == 0)
6256
            return 0;
6257
6258
    #ifdef WOLF_CRYPTO_CB
6259
        #ifndef WOLF_CRYPTO_CB_FIND
6260
        if (aes->devId != INVALID_DEVID)
6261
        #endif
6262
        {
6263
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6264
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6265
                return crypto_cb_ret;
6266
            /* fall-through when unavailable (normal-keyed Aes) */
6267
        }
6268
    #endif
6269
6270
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6271
        if (ret != 0)
6272
            return ret;
6273
6274
        ret = wolfSSL_CryptHwMutexLock();
6275
        if (ret != 0) {
6276
            return ret;
6277
        }
6278
6279
        /* if input and output same will overwrite input iv */
6280
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6281
6282
    #if defined(STM32_HAL_V2)
6283
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
6284
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
6285
    #elif defined(STM32_CRYPTO_AES_ONLY)
6286
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
6287
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
6288
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6289
    #endif
6290
6291
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6292
        ret = HAL_CRYP_Init(&hcryp);
6293
6294
        if (ret == HAL_OK) {
6295
        #if defined(STM32_HAL_V2)
6296
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
6297
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6298
        #elif defined(STM32_CRYPTO_AES_ONLY)
6299
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
6300
                out, STM32_HAL_TIMEOUT);
6301
        #else
6302
            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
6303
                                        blocks * WC_AES_BLOCK_SIZE,
6304
                out, STM32_HAL_TIMEOUT);
6305
        #endif
6306
        }
6307
        if (ret != HAL_OK) {
6308
            ret = WC_TIMEOUT_E;
6309
        }
6310
6311
        /* store iv for next call */
6312
        XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6313
6314
        HAL_CRYP_DeInit(&hcryp);
6315
        wolfSSL_CryptHwMutexUnLock();
6316
        wc_Stm32_Aes_Cleanup();
6317
6318
        return ret;
6319
    }
6320
    #endif /* HAVE_AES_DECRYPT */
6321
6322
#else /* Standard Peripheral Library */
6323
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6324
    {
6325
        int ret;
6326
        word32 *iv;
6327
        CRYP_InitTypeDef cryptInit;
6328
        CRYP_KeyInitTypeDef keyInit;
6329
        CRYP_IVInitTypeDef ivInit;
6330
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6331
6332
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6333
        if (sz % WC_AES_BLOCK_SIZE) {
6334
            return BAD_LENGTH_E;
6335
        }
6336
#endif
6337
        if (blocks == 0)
6338
            return 0;
6339
6340
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6341
        if (ret != 0)
6342
            return ret;
6343
6344
        ret = wolfSSL_CryptHwMutexLock();
6345
        if (ret != 0) {
6346
            return ret;
6347
        }
6348
6349
        /* reset registers to their default values */
6350
        CRYP_DeInit();
6351
6352
        /* set key */
6353
        CRYP_KeyInit(&keyInit);
6354
6355
        /* set iv */
6356
        iv = aes->reg;
6357
        CRYP_IVStructInit(&ivInit);
6358
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
6359
        ivInit.CRYP_IV0Left  = iv[0];
6360
        ivInit.CRYP_IV0Right = iv[1];
6361
        ivInit.CRYP_IV1Left  = iv[2];
6362
        ivInit.CRYP_IV1Right = iv[3];
6363
        CRYP_IVInit(&ivInit);
6364
6365
        /* set direction and mode */
6366
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
6367
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
6368
        CRYP_Init(&cryptInit);
6369
6370
        /* enable crypto processor */
6371
        CRYP_Cmd(ENABLE);
6372
6373
        while (blocks--) {
6374
            /* flush IN/OUT FIFOs */
6375
            CRYP_FIFOFlush();
6376
6377
            CRYP_DataIn(*(uint32_t*)&in[0]);
6378
            CRYP_DataIn(*(uint32_t*)&in[4]);
6379
            CRYP_DataIn(*(uint32_t*)&in[8]);
6380
            CRYP_DataIn(*(uint32_t*)&in[12]);
6381
6382
            /* wait until the complete message has been processed */
6383
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6384
6385
            *(uint32_t*)&out[0]  = CRYP_DataOut();
6386
            *(uint32_t*)&out[4]  = CRYP_DataOut();
6387
            *(uint32_t*)&out[8]  = CRYP_DataOut();
6388
            *(uint32_t*)&out[12] = CRYP_DataOut();
6389
6390
            /* store iv for next call */
6391
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6392
6393
            sz  -= WC_AES_BLOCK_SIZE;
6394
            in  += WC_AES_BLOCK_SIZE;
6395
            out += WC_AES_BLOCK_SIZE;
6396
        }
6397
6398
        /* disable crypto processor */
6399
        CRYP_Cmd(DISABLE);
6400
        wolfSSL_CryptHwMutexUnLock();
6401
        wc_Stm32_Aes_Cleanup();
6402
6403
        return ret;
6404
    }
6405
6406
    #ifdef HAVE_AES_DECRYPT
6407
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6408
    {
6409
        int ret;
6410
        word32 *iv;
6411
        CRYP_InitTypeDef cryptInit;
6412
        CRYP_KeyInitTypeDef keyInit;
6413
        CRYP_IVInitTypeDef ivInit;
6414
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6415
6416
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6417
        if (sz % WC_AES_BLOCK_SIZE) {
6418
            return BAD_LENGTH_E;
6419
        }
6420
#endif
6421
        if (blocks == 0)
6422
            return 0;
6423
6424
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6425
        if (ret != 0)
6426
            return ret;
6427
6428
        ret = wolfSSL_CryptHwMutexLock();
6429
        if (ret != 0) {
6430
            return ret;
6431
        }
6432
6433
        /* if input and output same will overwrite input iv */
6434
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6435
6436
        /* reset registers to their default values */
6437
        CRYP_DeInit();
6438
6439
        /* set direction and key */
6440
        CRYP_KeyInit(&keyInit);
6441
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
6442
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
6443
        CRYP_Init(&cryptInit);
6444
6445
        /* enable crypto processor */
6446
        CRYP_Cmd(ENABLE);
6447
6448
        /* wait until key has been prepared */
6449
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6450
6451
        /* set direction and mode */
6452
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
6453
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
6454
        CRYP_Init(&cryptInit);
6455
6456
        /* set iv */
6457
        iv = aes->reg;
6458
        CRYP_IVStructInit(&ivInit);
6459
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
6460
        ivInit.CRYP_IV0Left  = iv[0];
6461
        ivInit.CRYP_IV0Right = iv[1];
6462
        ivInit.CRYP_IV1Left  = iv[2];
6463
        ivInit.CRYP_IV1Right = iv[3];
6464
        CRYP_IVInit(&ivInit);
6465
6466
        /* enable crypto processor */
6467
        CRYP_Cmd(ENABLE);
6468
6469
        while (blocks--) {
6470
            /* flush IN/OUT FIFOs */
6471
            CRYP_FIFOFlush();
6472
6473
            CRYP_DataIn(*(uint32_t*)&in[0]);
6474
            CRYP_DataIn(*(uint32_t*)&in[4]);
6475
            CRYP_DataIn(*(uint32_t*)&in[8]);
6476
            CRYP_DataIn(*(uint32_t*)&in[12]);
6477
6478
            /* wait until the complete message has been processed */
6479
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6480
6481
            *(uint32_t*)&out[0]  = CRYP_DataOut();
6482
            *(uint32_t*)&out[4]  = CRYP_DataOut();
6483
            *(uint32_t*)&out[8]  = CRYP_DataOut();
6484
            *(uint32_t*)&out[12] = CRYP_DataOut();
6485
6486
            /* store iv for next call */
6487
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6488
6489
            in  += WC_AES_BLOCK_SIZE;
6490
            out += WC_AES_BLOCK_SIZE;
6491
        }
6492
6493
        /* disable crypto processor */
6494
        CRYP_Cmd(DISABLE);
6495
        wolfSSL_CryptHwMutexUnLock();
6496
        wc_Stm32_Aes_Cleanup();
6497
6498
        return ret;
6499
    }
6500
    #endif /* HAVE_AES_DECRYPT */
6501
#endif /* WOLFSSL_STM32_CUBEMX */
6502
6503
#elif defined(HAVE_COLDFIRE_SEC)
6504
    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
6505
        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
6506
    {
6507
        #ifdef DEBUG_WOLFSSL
6508
            int i; int stat1, stat2; int ret;
6509
        #endif
6510
6511
        int size;
6512
        volatile int v;
6513
6514
        if ((pi == NULL) || (po == NULL))
6515
            return BAD_FUNC_ARG;    /*wrong pointer*/
6516
6517
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6518
        if (sz % WC_AES_BLOCK_SIZE) {
6519
            return BAD_LENGTH_E;
6520
        }
6521
#endif
6522
6523
        wc_LockMutex(&Mutex_AesSEC);
6524
6525
        /* Set descriptor for SEC */
6526
        secDesc->length1 = 0x0;
6527
        secDesc->pointer1 = NULL;
6528
6529
        secDesc->length2 = WC_AES_BLOCK_SIZE;
6530
        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
6531
6532
        switch(aes->rounds) {
6533
            case 10: secDesc->length3 = 16; break;
6534
            case 12: secDesc->length3 = 24; break;
6535
            case 14: secDesc->length3 = 32; break;
6536
        }
6537
        XMEMCPY(secKey, aes->key, secDesc->length3);
6538
6539
        secDesc->pointer3 = (byte *)secKey;
6540
        secDesc->pointer4 = AESBuffIn;
6541
        secDesc->pointer5 = AESBuffOut;
6542
        secDesc->length6 = 0x0;
6543
        secDesc->pointer6 = NULL;
6544
        secDesc->length7 = 0x0;
6545
        secDesc->pointer7 = NULL;
6546
        secDesc->nextDescriptorPtr = NULL;
6547
6548
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6549
        size = AES_BUFFER_SIZE;
6550
#endif
6551
        while (sz) {
6552
            secDesc->header = descHeader;
6553
            XMEMCPY(secReg, aes->reg, WC_AES_BLOCK_SIZE);
6554
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6555
            sz -= AES_BUFFER_SIZE;
6556
#else
6557
            if (sz < AES_BUFFER_SIZE) {
6558
                size = sz;
6559
                sz = 0;
6560
            } else {
6561
                size = AES_BUFFER_SIZE;
6562
                sz -= AES_BUFFER_SIZE;
6563
            }
6564
#endif
6565
6566
            secDesc->length4 = size;
6567
            secDesc->length5 = size;
6568
6569
            XMEMCPY(AESBuffIn, pi, size);
6570
            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
6571
                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-WC_AES_BLOCK_SIZE]),
6572
                        WC_AES_BLOCK_SIZE);
6573
            }
6574
6575
            /* Point SEC to the location of the descriptor */
6576
            MCF_SEC_FR0 = (uint32)secDesc;
6577
            /* Initialize SEC and wait for encryption to complete */
6578
            MCF_SEC_CCCR0 = 0x0000001a;
6579
            /* poll SISR to determine when channel is complete */
6580
            v=0;
6581
6582
            while ((secDesc->header>> 24) != 0xff) v++;
6583
6584
            #ifdef DEBUG_WOLFSSL
6585
                ret = MCF_SEC_SISRH;
6586
                stat1 = MCF_SEC_AESSR;
6587
                stat2 = MCF_SEC_AESISR;
6588
                if (ret & 0xe0000000) {
6589
                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
6590
                              "AESISR=%08x\n", i, ret, stat1, stat2);
6591
                }
6592
            #endif
6593
6594
            XMEMCPY(po, AESBuffOut, size);
6595
6596
            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
6597
                XMEMCPY((void*)aes->reg, (void*)&(po[size-WC_AES_BLOCK_SIZE]),
6598
                        WC_AES_BLOCK_SIZE);
6599
            } else {
6600
                XMEMCPY((void*)aes->reg, (void*)aes->tmp, WC_AES_BLOCK_SIZE);
6601
            }
6602
6603
            pi += size;
6604
            po += size;
6605
        }
6606
6607
        wc_UnLockMutex(&Mutex_AesSEC);
6608
        return 0;
6609
    }
6610
6611
    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6612
    {
6613
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
6614
    }
6615
6616
    #ifdef HAVE_AES_DECRYPT
6617
    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6618
    {
6619
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
6620
    }
6621
    #endif /* HAVE_AES_DECRYPT */
6622
6623
#elif defined(FREESCALE_LTC)
6624
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6625
    {
6626
        word32 keySize;
6627
        status_t status;
6628
        byte *iv, *enc_key;
6629
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6630
6631
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6632
        if (sz % WC_AES_BLOCK_SIZE) {
6633
            return BAD_LENGTH_E;
6634
        }
6635
#endif
6636
        if (blocks == 0)
6637
            return 0;
6638
6639
        iv      = (byte*)aes->reg;
6640
        enc_key = (byte*)aes->key;
6641
6642
        status = wc_AesGetKeySize(aes, &keySize);
6643
        if (status != 0) {
6644
            return status;
6645
        }
6646
6647
        status = wolfSSL_CryptHwMutexLock();
6648
        if (status != 0)
6649
            return status;
6650
        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6651
            iv, enc_key, keySize);
6652
        wolfSSL_CryptHwMutexUnLock();
6653
6654
        /* store iv for next call */
6655
        if (status == kStatus_Success) {
6656
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6657
        }
6658
6659
        return (status == kStatus_Success) ? 0 : -1;
6660
    }
6661
6662
    #ifdef HAVE_AES_DECRYPT
6663
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6664
    {
6665
        word32 keySize;
6666
        status_t status;
6667
        byte* iv, *dec_key;
6668
        byte temp_block[WC_AES_BLOCK_SIZE];
6669
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6670
6671
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6672
        if (sz % WC_AES_BLOCK_SIZE) {
6673
            return BAD_LENGTH_E;
6674
        }
6675
#endif
6676
        if (blocks == 0)
6677
            return 0;
6678
6679
        iv      = (byte*)aes->reg;
6680
        dec_key = (byte*)aes->key;
6681
6682
        status = wc_AesGetKeySize(aes, &keySize);
6683
        if (status != 0) {
6684
            return status;
6685
        }
6686
6687
        /* get IV for next call */
6688
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6689
6690
        status = wolfSSL_CryptHwMutexLock();
6691
        if (status != 0)
6692
            return status;
6693
        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6694
            iv, dec_key, keySize, kLTC_EncryptKey);
6695
        wolfSSL_CryptHwMutexUnLock();
6696
6697
        /* store IV for next call */
6698
        if (status == kStatus_Success) {
6699
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6700
        }
6701
6702
        return (status == kStatus_Success) ? 0 : -1;
6703
    }
6704
    #endif /* HAVE_AES_DECRYPT */
6705
6706
#elif defined(FREESCALE_MMCAU) && !defined(WOLFSSL_ARMASM)
6707
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6708
    {
6709
        int offset = 0;
6710
        byte *iv;
6711
        byte temp_block[WC_AES_BLOCK_SIZE];
6712
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6713
        int ret;
6714
6715
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6716
        if (sz % WC_AES_BLOCK_SIZE) {
6717
            return BAD_LENGTH_E;
6718
        }
6719
#endif
6720
        if (blocks == 0)
6721
            return 0;
6722
6723
        iv = (byte*)aes->reg;
6724
6725
        while (blocks--) {
6726
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
6727
6728
            /* XOR block with IV for CBC */
6729
            xorbuf(temp_block, iv, WC_AES_BLOCK_SIZE);
6730
6731
            ret = wc_AesEncrypt(aes, temp_block, out + offset);
6732
            if (ret != 0)
6733
                return ret;
6734
6735
            offset += WC_AES_BLOCK_SIZE;
6736
6737
            /* store IV for next block */
6738
            XMEMCPY(iv, out + offset - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6739
        }
6740
6741
        return 0;
6742
    }
6743
    #ifdef HAVE_AES_DECRYPT
6744
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6745
    {
6746
        int ret;
6747
        int offset = 0;
6748
        byte* iv;
6749
        byte temp_block[WC_AES_BLOCK_SIZE];
6750
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6751
6752
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6753
        if (sz % WC_AES_BLOCK_SIZE) {
6754
            return BAD_LENGTH_E;
6755
        }
6756
#endif
6757
        if (blocks == 0)
6758
            return 0;
6759
6760
        iv = (byte*)aes->reg;
6761
6762
        while (blocks--) {
6763
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
6764
6765
            ret = wc_AesDecrypt(aes, in + offset, out + offset);
6766
            if (ret != 0)
6767
                return ret;
6768
6769
            /* XOR block with IV for CBC */
6770
            xorbuf(out + offset, iv, WC_AES_BLOCK_SIZE);
6771
6772
            /* store IV for next block */
6773
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6774
6775
            offset += WC_AES_BLOCK_SIZE;
6776
        }
6777
        return 0;
6778
    }
6779
    #endif /* HAVE_AES_DECRYPT */
6780
6781
#elif defined(MAX3266X_AES)
6782
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6783
    {
6784
        word32 keySize;
6785
        int status;
6786
        byte *iv;
6787
6788
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
6789
            return BAD_FUNC_ARG;
6790
        }
6791
6792
        /* Always enforce a length check */
6793
        if (sz % WC_AES_BLOCK_SIZE) {
6794
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6795
            return BAD_LENGTH_E;
6796
        #else
6797
            return BAD_FUNC_ARG;
6798
        #endif
6799
        }
6800
        if (sz == 0) {
6801
            return 0;
6802
        }
6803
6804
        iv = (byte*)aes->reg;
6805
        status = wc_AesGetKeySize(aes, &keySize);
6806
        if (status != 0) {
6807
            return status;
6808
        }
6809
6810
        status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
6811
                                        MXC_TPU_MODE_CBC, sz, out,
6812
                                        (unsigned int)keySize);
6813
        /* store iv for next call */
6814
        if (status == 0) {
6815
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6816
        }
6817
        return (status == 0) ? 0 : -1;
6818
    }
6819
6820
    #ifdef HAVE_AES_DECRYPT
6821
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6822
    {
6823
        word32 keySize;
6824
        int status;
6825
        byte *iv;
6826
        byte temp_block[WC_AES_BLOCK_SIZE];
6827
6828
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
6829
            return BAD_FUNC_ARG;
6830
        }
6831
6832
        /* Always enforce a length check */
6833
        if (sz % WC_AES_BLOCK_SIZE) {
6834
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6835
            return BAD_LENGTH_E;
6836
        #else
6837
            return BAD_FUNC_ARG;
6838
        #endif
6839
        }
6840
        if (sz == 0) {
6841
            return 0;
6842
        }
6843
6844
        iv = (byte*)aes->reg;
6845
        status = wc_AesGetKeySize(aes, &keySize);
6846
        if (status != 0) {
6847
            return status;
6848
        }
6849
6850
        /* get IV for next call */
6851
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6852
        status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
6853
                                        MXC_TPU_MODE_CBC, sz, out,
6854
                                        keySize);
6855
6856
        /* store iv for next call */
6857
        if (status == 0) {
6858
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6859
        }
6860
        return (status == 0) ? 0 : -1;
6861
    }
6862
    #endif /* HAVE_AES_DECRYPT */
6863
6864
6865
6866
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
6867
6868
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6869
    {
6870
        int ret;
6871
6872
        if (sz == 0)
6873
            return 0;
6874
6875
        /* hardware fails on input that is not a multiple of AES block size */
6876
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6877
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6878
            return BAD_LENGTH_E;
6879
#else
6880
            return BAD_FUNC_ARG;
6881
#endif
6882
        }
6883
6884
        ret = wc_Pic32AesCrypt(
6885
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6886
            out, in, sz, PIC32_ENCRYPTION,
6887
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6888
6889
        /* store iv for next call */
6890
        if (ret == 0) {
6891
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6892
        }
6893
6894
        return ret;
6895
    }
6896
    #ifdef HAVE_AES_DECRYPT
6897
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6898
    {
6899
        int ret;
6900
        byte scratch[WC_AES_BLOCK_SIZE];
6901
6902
        if (sz == 0)
6903
            return 0;
6904
6905
        /* hardware fails on input that is not a multiple of AES block size */
6906
        if (sz % WC_AES_BLOCK_SIZE != 0) {
6907
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6908
            return BAD_LENGTH_E;
6909
#else
6910
            return BAD_FUNC_ARG;
6911
#endif
6912
        }
6913
        XMEMCPY(scratch, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6914
6915
        ret = wc_Pic32AesCrypt(
6916
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
6917
            out, in, sz, PIC32_DECRYPTION,
6918
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
6919
6920
        /* store iv for next call */
6921
        if (ret == 0) {
6922
            XMEMCPY((byte*)aes->reg, scratch, WC_AES_BLOCK_SIZE);
6923
        }
6924
6925
        return ret;
6926
    }
6927
    #endif /* HAVE_AES_DECRYPT */
6928
#elif defined(WOLFSSL_ESP32_CRYPT) && \
6929
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6930
6931
    /* We'll use SW for fall back:
6932
     *   unsupported key lengths
6933
     *   hardware busy */
6934
    #define NEED_SW_AESCBC
6935
    #define NEED_AESCBC_HW_FALLBACK
6936
6937
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
6938
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6939
    {
6940
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6941
    }
6942
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6943
    {
6944
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
6945
    }
6946
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6947
        !defined(WOLFSSL_QNX_CAAM)
6948
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6949
6950
#elif defined(WOLFSSL_AFALG)
6951
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6952
6953
#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
6954
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
6955
6956
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
6957
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6958
6959
#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
6960
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
6961
6962
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
6963
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
6964
6965
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6966
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
6967
6968
#elif defined(WOLFSSL_PSOC6_CRYPTO)
6969
6970
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6971
    {
6972
        return wc_Psoc6_Aes_CbcEncrypt(aes, out, in, sz);
6973
    }
6974
6975
    #if defined(HAVE_AES_DECRYPT)
6976
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6977
    {
6978
        return wc_Psoc6_Aes_CbcDecrypt(aes, out, in, sz);
6979
    }
6980
    #endif /* HAVE_AES_DECRYPT */
6981
6982
#else
6983
    /* Reminder: Some HW implementations may also define this as needed.
6984
     * (e.g. for unsupported key length fallback)  */
6985
    #define NEED_SW_AESCBC
6986
#endif
6987
6988
#ifdef NEED_SW_AESCBC
6989
    /* Software AES - CBC Encrypt */
6990
6991
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6992
438
    {
6993
438
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
6994
438
        word32 blocks;
6995
438
        int ret;
6996
438
#endif
6997
6998
438
        if (aes == NULL || out == NULL || in == NULL) {
6999
0
            return BAD_FUNC_ARG;
7000
0
        }
7001
7002
438
        if (sz == 0) {
7003
0
            return 0;
7004
0
        }
7005
7006
438
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7007
438
        blocks = sz / WC_AES_BLOCK_SIZE;
7008
438
#endif
7009
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7010
        if (sz % WC_AES_BLOCK_SIZE) {
7011
            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
7012
            return BAD_LENGTH_E;
7013
        }
7014
#endif
7015
7016
#if defined(WOLFSSL_RISCV_ASM)
7017
        AES_CBC_encrypt_RISCV64(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7018
            (int)aes->rounds);
7019
        (void)blocks;
7020
        (void)ret;
7021
        return 0;
7022
#endif
7023
7024
    #ifdef WOLFSSL_IMXRT_DCP
7025
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
7026
        if (aes->keylen == 16)
7027
            return DCPAesCbcEncrypt(aes, out, in, sz);
7028
    #endif
7029
7030
438
    #ifdef WOLF_CRYPTO_CB
7031
438
        #ifndef WOLF_CRYPTO_CB_FIND
7032
438
        if (aes->devId != INVALID_DEVID)
7033
0
        #endif
7034
0
        {
7035
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
7036
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7037
0
                return crypto_cb_ret;
7038
            /* fall-through when unavailable */
7039
0
        }
7040
438
    #endif
7041
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
7042
        /* if async and byte count above threshold */
7043
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
7044
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
7045
        #if defined(HAVE_CAVIUM)
7046
            return NitroxAesCbcEncrypt(aes, out, in, sz);
7047
        #elif defined(HAVE_INTEL_QA)
7048
            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
7049
                (const byte*)aes->devKey, aes->keylen,
7050
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7051
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
7052
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
7053
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
7054
                sw->aes.aes = aes;
7055
                sw->aes.out = out;
7056
                sw->aes.in = in;
7057
                sw->aes.sz = sz;
7058
                return WC_PENDING_E;
7059
            }
7060
        #endif
7061
        }
7062
    #endif /* WOLFSSL_ASYNC_CRYPT */
7063
7064
#if defined(WOLFSSL_ARMASM)
7065
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7066
    #if !defined(__aarch64__)
7067
        AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7068
            (int)aes->rounds);
7069
    #else
7070
        if (aes->use_aes_hw_crypto) {
7071
            AES_CBC_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7072
                (byte*)aes->key, (int)aes->rounds);
7073
        }
7074
        else
7075
    #endif /* __aarch64__ */
7076
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7077
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
7078
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7079
        {
7080
            AES_CBC_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
7081
                aes->rounds, (unsigned char*)aes->reg);
7082
        }
7083
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7084
        {
7085
            AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
7086
                aes->rounds, (unsigned char*)aes->reg);
7087
        }
7088
    #endif
7089
        return 0;
7090
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7091
        AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
7092
            aes->rounds, (unsigned char*)aes->reg);
7093
        return 0;
7094
#else
7095
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
7096
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
7097
        if (aes->useSWCrypt == 0) {
7098
            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
7099
                                   kAlgorithm_SSS_AES_CBC);
7100
        }
7101
        else
7102
    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
7103
        if (wc_esp32AesSupportedKeyLen(aes)) {
7104
            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
7105
            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
7106
        }
7107
        else {
7108
            /* For example, the ESP32-S3 does not support HW for len = 24,
7109
             * so fall back to SW */
7110
        #ifdef DEBUG_WOLFSSL
7111
            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
7112
                          "unsupported keylen = %d", aes->keylen);
7113
        #endif
7114
        }
7115
    #elif defined(WOLFSSL_AESNI)
7116
        VECTOR_REGISTERS_PUSH;
7117
        if (aes->use_aesni) {
7118
            #ifdef DEBUG_AESNI
7119
                printf("about to aes cbc encrypt\n");
7120
                printf("in  = %p\n", in);
7121
                printf("out = %p\n", out);
7122
                printf("aes->key = %p\n", aes->key);
7123
                printf("aes->reg = %p\n", aes->reg);
7124
                printf("aes->rounds = %d\n", aes->rounds);
7125
                printf("sz = %d\n", sz);
7126
            #endif
7127
7128
            /* check alignment, decrypt doesn't need alignment */
7129
            if ((wc_ptr_t)in % AESNI_ALIGN) {
7130
            #ifndef NO_WOLFSSL_ALLOC_ALIGN
7131
                byte* tmp = (byte*)XMALLOC(sz + WC_AES_BLOCK_SIZE + AESNI_ALIGN,
7132
                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
7133
                byte* tmp_align;
7134
                if (tmp == NULL)
7135
                    ret = MEMORY_E;
7136
                else {
7137
                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
7138
                    XMEMCPY(tmp_align, in, sz);
7139
                #ifdef WOLFSSL_X86_64_BUILD
7140
                    AesCbcEncryptBlocks(tmp_align, tmp_align, (byte*)aes->reg, sz,
7141
                                        (byte*)aes->key, (int)aes->rounds);
7142
                #else
7143
                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
7144
                                          (byte*)aes->key, (int)aes->rounds);
7145
                #endif
7146
                    /* store iv for next call */
7147
                    XMEMCPY(aes->reg, tmp_align + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7148
7149
                    XMEMCPY(out, tmp_align, sz);
7150
                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
7151
                    ret = 0;
7152
                }
7153
            #else
7154
                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
7155
                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
7156
                ret = BAD_ALIGN_E;
7157
            #endif
7158
            } else {
7159
            #ifdef WOLFSSL_X86_64_BUILD
7160
                AesCbcEncryptBlocks(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7161
                                    (int)aes->rounds);
7162
            #else
7163
                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7164
                                      (int)aes->rounds);
7165
            #endif
7166
                /* store iv for next call */
7167
                XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7168
7169
                ret = 0;
7170
            }
7171
        }
7172
        else
7173
    #endif
7174
438
        {
7175
438
#ifdef WC_AES_HAVE_PREFETCH_ARG
7176
438
            int did_prefetches = 0;
7177
438
#endif
7178
438
            ret = 0;
7179
3.22k
            while (blocks--) {
7180
2.79k
                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
7181
2.79k
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7182
2.79k
                                                (byte*)aes->reg,
7183
2.79k
                                                &did_prefetches);
7184
2.79k
                if (ret != 0)
7185
0
                    break;
7186
2.79k
                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
7187
7188
2.79k
                out += WC_AES_BLOCK_SIZE;
7189
2.79k
                in  += WC_AES_BLOCK_SIZE;
7190
2.79k
            }
7191
438
        }
7192
7193
    #ifdef WOLFSSL_AESNI
7194
        VECTOR_REGISTERS_POP;
7195
    #endif
7196
7197
438
        return ret;
7198
438
#endif
7199
438
    } /* wc_AesCbcEncrypt */
7200
7201
#ifdef HAVE_AES_DECRYPT
7202
    /* Software AES - CBC Decrypt */
7203
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7204
311
    {
7205
311
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7206
311
        word32 blocks;
7207
311
        int ret;
7208
311
#endif
7209
7210
311
        if (aes == NULL || out == NULL || in == NULL) {
7211
0
            return BAD_FUNC_ARG;
7212
0
        }
7213
7214
311
        if (sz == 0) {
7215
0
            return 0;
7216
0
        }
7217
7218
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
7219
        if (wc_esp32AesSupportedKeyLen(aes)) {
7220
            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
7221
            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
7222
        }
7223
        else {
7224
            /* For example, the ESP32-S3 does not support HW for len = 24,
7225
             * so fall back to SW */
7226
        #ifdef DEBUG_WOLFSSL
7227
            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
7228
                          "unsupported keylen = %d", aes->keylen);
7229
        #endif
7230
        }
7231
    #endif
7232
7233
311
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7234
311
        blocks = sz / WC_AES_BLOCK_SIZE;
7235
311
#endif
7236
311
        if (sz % WC_AES_BLOCK_SIZE) {
7237
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7238
            return BAD_LENGTH_E;
7239
#else
7240
0
            return BAD_FUNC_ARG;
7241
0
#endif
7242
0
        }
7243
7244
#if defined(WOLFSSL_RISCV_ASM)
7245
        AES_CBC_decrypt_RISCV64(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7246
            (int)aes->rounds);
7247
        (void)blocks;
7248
        (void)ret;
7249
        return 0;
7250
#endif
7251
7252
    #ifdef WOLFSSL_IMXRT_DCP
7253
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
7254
        if (aes->keylen == 16)
7255
            return DCPAesCbcDecrypt(aes, out, in, sz);
7256
    #endif
7257
7258
311
    #ifdef WOLF_CRYPTO_CB
7259
311
        #ifndef WOLF_CRYPTO_CB_FIND
7260
311
        if (aes->devId != INVALID_DEVID)
7261
0
        #endif
7262
0
        {
7263
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
7264
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7265
0
                return crypto_cb_ret;
7266
            /* fall-through when unavailable */
7267
0
        }
7268
311
    #endif
7269
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
7270
        /* if async and byte count above threshold */
7271
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
7272
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
7273
        #if defined(HAVE_CAVIUM)
7274
            return NitroxAesCbcDecrypt(aes, out, in, sz);
7275
        #elif defined(HAVE_INTEL_QA)
7276
            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
7277
                (const byte*)aes->devKey, aes->keylen,
7278
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7279
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
7280
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
7281
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
7282
                sw->aes.aes = aes;
7283
                sw->aes.out = out;
7284
                sw->aes.in = in;
7285
                sw->aes.sz = sz;
7286
                return WC_PENDING_E;
7287
            }
7288
        #endif
7289
        }
7290
    #endif
7291
7292
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
7293
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
7294
        if (aes->useSWCrypt == 0) {
7295
            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
7296
                                   kAlgorithm_SSS_AES_CBC);
7297
        }
7298
    #endif
7299
7300
#if defined(WOLFSSL_ARMASM)
7301
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7302
    #if !defined(__aarch64__)
7303
        AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7304
            (int)aes->rounds);
7305
    #else
7306
        if (aes->use_aes_hw_crypto) {
7307
            AES_CBC_decrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7308
                (byte*)aes->key, (int)aes->rounds);
7309
        }
7310
        else
7311
    #endif /* !__aarch64__ */
7312
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7313
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
7314
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7315
        if (sz >= 64)
7316
    #endif
7317
        {
7318
            AES_CBC_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
7319
                aes->rounds, (unsigned char*)aes->reg);
7320
        }
7321
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7322
        else
7323
    #endif
7324
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
7325
    #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7326
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7327
        {
7328
            AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
7329
                aes->rounds, (unsigned char*)aes->reg);
7330
        }
7331
    #endif
7332
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
7333
        return 0;
7334
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7335
        AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
7336
            aes->rounds, (unsigned char*)aes->reg);
7337
        return 0;
7338
#else
7339
311
        VECTOR_REGISTERS_PUSH;
7340
7341
    #ifdef WOLFSSL_AESNI
7342
        if (aes->use_aesni) {
7343
            #ifdef DEBUG_AESNI
7344
                printf("about to aes cbc decrypt\n");
7345
                printf("in  = %p\n", in);
7346
                printf("out = %p\n", out);
7347
                printf("aes->key = %p\n", aes->key);
7348
                printf("aes->reg = %p\n", aes->reg);
7349
                printf("aes->rounds = %d\n", aes->rounds);
7350
                printf("sz = %d\n", sz);
7351
            #endif
7352
7353
            /* if input and output same will overwrite input iv */
7354
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7355
            #if defined(WOLFSSL_X86_64_BUILD)
7356
            AesCbcDecryptBlocks(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7357
                            (int)aes->rounds);
7358
            #elif defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
7359
            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7360
                            aes->rounds);
7361
            #elif defined(WOLFSSL_AESNI_BY6)
7362
            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7363
                            aes->rounds);
7364
            #else /* WOLFSSL_AESNI_BYx */
7365
            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7366
                            (int)aes->rounds);
7367
            #endif /* WOLFSSL_AESNI_BYx */
7368
            /* store iv for next call */
7369
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7370
            ret = 0;
7371
        }
7372
        else
7373
    #endif
7374
311
        {
7375
311
            ret = 0;
7376
#ifdef WC_AES_BITSLICED
7377
            if (in != out) {
7378
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
7379
7380
                while (blocks > BS_WORD_SIZE) {
7381
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
7382
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7383
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
7384
                              WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
7385
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
7386
                            WC_AES_BLOCK_SIZE);
7387
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7388
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7389
                    blocks -= BS_WORD_SIZE;
7390
                }
7391
                if (blocks > 0) {
7392
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
7393
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7394
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
7395
                              WC_AES_BLOCK_SIZE * (blocks - 1));
7396
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (blocks - 1)),
7397
                            WC_AES_BLOCK_SIZE);
7398
                    blocks = 0;
7399
                }
7400
            }
7401
            else {
7402
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
7403
                int i;
7404
7405
                while (blocks > BS_WORD_SIZE) {
7406
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
7407
                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * WC_AES_BLOCK_SIZE,
7408
                            WC_AES_BLOCK_SIZE);
7409
                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
7410
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
7411
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
7412
                                  WC_AES_BLOCK_SIZE);
7413
                    }
7414
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7415
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7416
7417
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7418
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7419
                    blocks -= BS_WORD_SIZE;
7420
                }
7421
                if (blocks > 0) {
7422
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
7423
                    XMEMCPY(aes->tmp, in + (blocks - 1) * WC_AES_BLOCK_SIZE,
7424
                            WC_AES_BLOCK_SIZE);
7425
                    for (i = blocks-1; i >= 1; i--) {
7426
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
7427
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
7428
                                  WC_AES_BLOCK_SIZE);
7429
                    }
7430
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7431
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7432
7433
                    blocks = 0;
7434
                }
7435
            }
7436
#else
7437
311
#ifdef WC_AES_HAVE_PREFETCH_ARG
7438
311
            {
7439
311
            int did_prefetches = 0;
7440
311
#endif
7441
20.7k
            while (blocks--) {
7442
20.3k
                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
7443
20.3k
                ret = AesDecrypt_preFetchOpt(aes, in, out, &did_prefetches);
7444
20.3k
                if (ret != 0)
7445
0
                    return ret;
7446
20.3k
                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7447
                /* store iv for next call */
7448
20.3k
                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7449
7450
20.3k
                out += WC_AES_BLOCK_SIZE;
7451
20.3k
                in  += WC_AES_BLOCK_SIZE;
7452
20.3k
            }
7453
311
#ifdef WC_AES_HAVE_PREFETCH_ARG
7454
311
            }
7455
311
#endif
7456
311
#endif
7457
311
        }
7458
7459
311
        VECTOR_REGISTERS_POP;
7460
7461
311
        return ret;
7462
311
#endif
7463
311
    }
7464
#endif /* HAVE_AES_DECRYPT */
7465
7466
#endif /* AES-CBC block */
7467
#endif /* HAVE_AES_CBC */
7468
7469
/* AES-CTR */
7470
#if defined(WOLFSSL_AES_COUNTER)
7471
7472
    #ifdef STM32_CRYPTO
7473
        #define NEED_AES_CTR_SOFT
7474
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
7475
7476
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
7477
        {
7478
        #ifdef WOLFSSL_STM32_BARE
7479
            /* CTR per-block transform: produce out = in XOR AES_ECB(counter).
7480
             * ECB-encrypt the counter aes->reg into a keystream block, then XOR
7481
             * with the plaintext 'in'. The caller (XTRANSFORM_AESCTRBLOCK loop)
7482
             * does not XOR and increments aes->reg after this returns. */
7483
            byte ks[WC_AES_BLOCK_SIZE];
7484
            int  ret = wc_Stm32_Aes_Ecb(aes, ks, (const byte*)aes->reg,
7485
                                        WC_AES_BLOCK_SIZE, 1);
7486
            if (ret == 0) {
7487
                xorbufout(out, in, ks, WC_AES_BLOCK_SIZE);
7488
            }
7489
            else {
7490
                /* The CTR loop breaks on this non-zero return; zero the block
7491
                 * so a failed HW ECB does not leave stale/prior plaintext in
7492
                 * the output. */
7493
                ForceZero(out, WC_AES_BLOCK_SIZE);
7494
            }
7495
            ForceZero(ks, sizeof(ks));
7496
            return ret;
7497
        #else
7498
            int ret = 0;
7499
        #ifdef WOLFSSL_STM32_CUBEMX
7500
            CRYP_HandleTypeDef hcryp;
7501
            #ifdef STM32_HAL_V2
7502
            word32 iv[WC_AES_BLOCK_SIZE/sizeof(word32)];
7503
            #endif
7504
        #else
7505
            word32 *iv;
7506
            CRYP_InitTypeDef cryptInit;
7507
            CRYP_KeyInitTypeDef keyInit;
7508
            CRYP_IVInitTypeDef ivInit;
7509
        #endif
7510
7511
        #ifdef WOLFSSL_STM32_CUBEMX
7512
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
7513
            if (ret != 0) {
7514
                return ret;
7515
            }
7516
7517
            ret = wolfSSL_CryptHwMutexLock();
7518
            if (ret != 0) {
7519
                return ret;
7520
            }
7521
7522
        #if defined(STM32_HAL_V2)
7523
            hcryp.Init.Algorithm  = CRYP_AES_CTR;
7524
            ByteReverseWords(iv, aes->reg, WC_AES_BLOCK_SIZE);
7525
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
7526
        #elif defined(STM32_CRYPTO_AES_ONLY)
7527
            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
7528
            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
7529
            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
7530
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
7531
        #else
7532
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
7533
        #endif
7534
            HAL_CRYP_Init(&hcryp);
7535
7536
        #if defined(STM32_HAL_V2)
7537
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, WC_AES_BLOCK_SIZE,
7538
                (uint32_t*)out, STM32_HAL_TIMEOUT);
7539
        #elif defined(STM32_CRYPTO_AES_ONLY)
7540
            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
7541
                out, STM32_HAL_TIMEOUT);
7542
        #else
7543
            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
7544
                out, STM32_HAL_TIMEOUT);
7545
        #endif
7546
            if (ret != HAL_OK) {
7547
                ret = WC_TIMEOUT_E;
7548
            }
7549
            HAL_CRYP_DeInit(&hcryp);
7550
7551
        #else /* Standard Peripheral Library */
7552
            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
7553
            if (ret != 0) {
7554
                return ret;
7555
            }
7556
7557
            ret = wolfSSL_CryptHwMutexLock();
7558
            if (ret != 0) {
7559
                return ret;
7560
            }
7561
7562
            /* reset registers to their default values */
7563
            CRYP_DeInit();
7564
7565
            /* set key */
7566
            CRYP_KeyInit(&keyInit);
7567
7568
            /* set iv */
7569
            iv = aes->reg;
7570
            CRYP_IVStructInit(&ivInit);
7571
            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
7572
            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
7573
            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
7574
            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
7575
            CRYP_IVInit(&ivInit);
7576
7577
            /* set direction and mode */
7578
            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
7579
            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
7580
            CRYP_Init(&cryptInit);
7581
7582
            /* enable crypto processor */
7583
            CRYP_Cmd(ENABLE);
7584
7585
            /* flush IN/OUT FIFOs */
7586
            CRYP_FIFOFlush();
7587
7588
            CRYP_DataIn(*(uint32_t*)&in[0]);
7589
            CRYP_DataIn(*(uint32_t*)&in[4]);
7590
            CRYP_DataIn(*(uint32_t*)&in[8]);
7591
            CRYP_DataIn(*(uint32_t*)&in[12]);
7592
7593
            /* wait until the complete message has been processed */
7594
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
7595
7596
            *(uint32_t*)&out[0]  = CRYP_DataOut();
7597
            *(uint32_t*)&out[4]  = CRYP_DataOut();
7598
            *(uint32_t*)&out[8]  = CRYP_DataOut();
7599
            *(uint32_t*)&out[12] = CRYP_DataOut();
7600
7601
            /* disable crypto processor */
7602
            CRYP_Cmd(DISABLE);
7603
        #endif /* WOLFSSL_STM32_CUBEMX */
7604
7605
            wolfSSL_CryptHwMutexUnLock();
7606
            wc_Stm32_Aes_Cleanup();
7607
            return ret;
7608
        #endif /* !WOLFSSL_STM32_BARE */
7609
        }
7610
7611
7612
    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
7613
7614
        #define NEED_AES_CTR_SOFT
7615
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
7616
7617
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
7618
        {
7619
            word32 tmpIv[WC_AES_BLOCK_SIZE / sizeof(word32)];
7620
            XMEMCPY(tmpIv, aes->reg, WC_AES_BLOCK_SIZE);
7621
            return wc_Pic32AesCrypt(
7622
                aes->key, aes->keylen, tmpIv, WC_AES_BLOCK_SIZE,
7623
                out, in, WC_AES_BLOCK_SIZE,
7624
                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
7625
        }
7626
7627
    #elif defined(HAVE_COLDFIRE_SEC)
7628
        #error "Coldfire SEC doesn't currently support AES-CTR mode"
7629
7630
    #elif defined(FREESCALE_LTC)
7631
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7632
        {
7633
            int ret = 0;
7634
            word32 keySize;
7635
            byte *iv, *enc_key;
7636
            byte* tmp;
7637
7638
            if (aes == NULL || out == NULL || in == NULL) {
7639
                return BAD_FUNC_ARG;
7640
            }
7641
7642
            /* consume any unused bytes left in aes->tmp */
7643
            tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7644
            while (aes->left && sz) {
7645
                *(out++) = *(in++) ^ *(tmp++);
7646
                aes->left--;
7647
                sz--;
7648
            }
7649
7650
            if (sz) {
7651
                iv      = (byte*)aes->reg;
7652
                enc_key = (byte*)aes->key;
7653
7654
                ret = wc_AesGetKeySize(aes, &keySize);
7655
                if (ret != 0)
7656
                    return ret;
7657
7658
                ret = wolfSSL_CryptHwMutexLock();
7659
                if (ret != 0)
7660
                    return ret;
7661
                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
7662
                    iv, enc_key, keySize, (byte*)aes->tmp,
7663
                    (uint32_t*)&aes->left);
7664
                wolfSSL_CryptHwMutexUnLock();
7665
            }
7666
7667
            return ret;
7668
        }
7669
7670
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
7671
        !defined(WOLFSSL_QNX_CAAM)
7672
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
7673
7674
    #elif defined(WOLFSSL_AFALG)
7675
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
7676
7677
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
7678
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
7679
7680
    #elif defined(WOLFSSL_ESP32_CRYPT) && \
7681
        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
7682
        /* esp32 doesn't support CRT mode by hw.     */
7683
        /* use aes ecnryption plus sw implementation */
7684
        #define NEED_AES_CTR_SOFT
7685
7686
    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
7687
        /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
7688
7689
    #elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
7690
        /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
7691
7692
    #else
7693
7694
        /* Use software based AES counter */
7695
        #define NEED_AES_CTR_SOFT
7696
    #endif
7697
7698
    #ifdef NEED_AES_CTR_SOFT
7699
        #ifndef WOLFSSL_ARMASM
7700
        /* Increment AES counter */
7701
        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
7702
2.84k
        {
7703
            /* in network byte order so start at end and work back */
7704
2.84k
            int i;
7705
3.40k
            for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
7706
3.40k
                if (++inOutCtr[i])  /* we're done unless we overflow */
7707
2.84k
                    return;
7708
3.40k
            }
7709
2.84k
        }
7710
        #endif
7711
7712
        /* Software AES - CTR Encrypt */
7713
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7714
762
        {
7715
762
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
7716
762
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7717
762
            byte scratch[WC_AES_BLOCK_SIZE];
7718
762
    #endif
7719
762
    #if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7720
762
            int ret = 0;
7721
762
    #endif
7722
762
            word32 processed;
7723
762
#ifdef WC_AES_HAVE_PREFETCH_ARG
7724
762
            int did_prefetches = 0;
7725
762
#endif
7726
7727
762
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
7728
762
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
7729
762
            XMEMSET(scratch, 0, sizeof(scratch));
7730
762
    #endif
7731
7732
762
            if (aes == NULL || out == NULL || in == NULL) {
7733
0
                return BAD_FUNC_ARG;
7734
0
            }
7735
7736
762
        #ifdef WOLF_CRYPTO_CB
7737
762
            #ifndef WOLF_CRYPTO_CB_FIND
7738
762
            if (aes->devId != INVALID_DEVID)
7739
0
            #endif
7740
0
            {
7741
0
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
7742
0
                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7743
0
                    return crypto_cb_ret;
7744
                /* fall-through when unavailable */
7745
0
            }
7746
762
        #endif
7747
7748
            /* consume any unused bytes left in aes->tmp */
7749
762
            processed = min(aes->left, sz);
7750
762
            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
7751
762
                      processed);
7752
762
            out += processed;
7753
762
            in += processed;
7754
762
            aes->left -= processed;
7755
762
            sz -= processed;
7756
7757
    #if defined(WOLFSSL_RISCV_ASM)
7758
            if (sz > 0) {
7759
                AES_CTR_encrypt_RISCV64(in, out, sz, (byte*)aes->reg,
7760
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left,
7761
                    (int)aes->rounds);
7762
            }
7763
            (void)scratch;
7764
            (void)ret;
7765
            return 0;
7766
    #endif
7767
7768
    #if defined(WOLFSSL_ARMASM)
7769
        #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7770
            #ifndef __aarch64__
7771
            AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
7772
                (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
7773
            #else
7774
            if (aes->use_aes_hw_crypto) {
7775
                AES_CTR_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7776
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
7777
                return 0;
7778
            }
7779
            else
7780
            #endif /* !__aarch64__ */
7781
        #endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7782
        #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
7783
            {
7784
                word32 numBlocks;
7785
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7786
                /* consume any unused bytes left in aes->tmp */
7787
                while ((aes->left != 0) && (sz != 0)) {
7788
                   *(out++) = *(in++) ^ *(tmp++);
7789
                   aes->left--;
7790
                   sz--;
7791
                }
7792
7793
                /* do as many block size ops as possible */
7794
                numBlocks = sz / WC_AES_BLOCK_SIZE;
7795
                if (numBlocks > 0) {
7796
                #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
7797
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7798
                    if (sz >= 32)
7799
                #endif
7800
                    {
7801
                        AES_CTR_encrypt_NEON(in, out,
7802
                            numBlocks * WC_AES_BLOCK_SIZE, (byte*)aes->key,
7803
                            aes->rounds, (byte*)aes->reg);
7804
                    }
7805
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7806
                    else
7807
                #endif
7808
                #endif
7809
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7810
                    {
7811
                        AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
7812
                            (byte*)aes->key, aes->rounds, (byte*)aes->reg);
7813
                    }
7814
                #endif
7815
7816
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
7817
                    out += numBlocks * WC_AES_BLOCK_SIZE;
7818
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
7819
                }
7820
7821
                /* handle non block size remaining */
7822
                if (sz) {
7823
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
7824
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
7825
7826
                #if defined(__aarch64__) && \
7827
                    !defined(WOLFSSL_ARMASM_NO_NEON) && \
7828
                    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7829
                    {
7830
                        AES_CTR_encrypt_NEON(zeros, (byte*)aes->tmp,
7831
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7832
                            (byte*)aes->reg);
7833
                    }
7834
                #else
7835
                    {
7836
                        AES_CTR_encrypt(zeros, (byte*)aes->tmp,
7837
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7838
                            (byte*)aes->reg);
7839
                    }
7840
                #endif
7841
7842
                    aes->left = WC_AES_BLOCK_SIZE;
7843
                    tmp = (byte*)aes->tmp;
7844
7845
                    while (sz--) {
7846
                        *(out++) = *(in++) ^ *(tmp++);
7847
                        aes->left--;
7848
                    }
7849
                }
7850
            }
7851
        #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
7852
            return 0;
7853
    #elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7854
            {
7855
                word32 numBlocks;
7856
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7857
                /* consume any unused bytes left in aes->tmp */
7858
                while ((aes->left != 0) && (sz != 0)) {
7859
                   *(out++) = *(in++) ^ *(tmp++);
7860
                   aes->left--;
7861
                   sz--;
7862
                }
7863
7864
                /* do as many block size ops as possible */
7865
                numBlocks = sz / WC_AES_BLOCK_SIZE;
7866
                if (numBlocks > 0) {
7867
                    AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
7868
                        (byte*)aes->key, aes->rounds, (byte*)aes->reg);
7869
7870
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
7871
                    out += numBlocks * WC_AES_BLOCK_SIZE;
7872
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
7873
                }
7874
7875
                /* handle non block size remaining */
7876
                if (sz) {
7877
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
7878
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
7879
7880
                    AES_CTR_encrypt(zeros, (byte*)aes->tmp,
7881
                        WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
7882
                        (byte*)aes->reg);
7883
7884
                    aes->left = WC_AES_BLOCK_SIZE;
7885
                    tmp = (byte*)aes->tmp;
7886
7887
                    while (sz--) {
7888
                        *(out++) = *(in++) ^ *(tmp++);
7889
                        aes->left--;
7890
                    }
7891
                }
7892
            }
7893
            return 0;
7894
    #else
7895
762
            VECTOR_REGISTERS_PUSH;
7896
7897
        #if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
7898
            if (aes->use_aesni && sz >= WC_AES_BLOCK_SIZE) {
7899
                word32 ctrBlocks = sz / WC_AES_BLOCK_SIZE;
7900
                word32 ctrBytes  = ctrBlocks * WC_AES_BLOCK_SIZE;
7901
                AesCtrEncryptBlocks(in, out, ctrBytes, (byte*)aes->key,
7902
                                    (int)aes->rounds, (byte*)aes->reg);
7903
                in  += ctrBytes;
7904
                out += ctrBytes;
7905
                sz  -= ctrBytes;
7906
                aes->left = 0;
7907
            }
7908
        #endif
7909
7910
762
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
7911
762
            !defined(XTRANSFORM_AESCTRBLOCK)
7912
762
            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
7913
315
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
7914
315
                byte* counter = (byte*)aes->reg;
7915
315
                byte* c = out;
7916
2.24k
                while (blocks--) {
7917
1.92k
                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
7918
1.92k
                    c += WC_AES_BLOCK_SIZE;
7919
1.92k
                    IncrementAesCounter(counter);
7920
1.92k
                }
7921
7922
                /* reset number of blocks and then do encryption */
7923
315
                blocks = sz / WC_AES_BLOCK_SIZE;
7924
315
                wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
7925
315
                xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
7926
315
                in += WC_AES_BLOCK_SIZE * blocks;
7927
315
                out += WC_AES_BLOCK_SIZE * blocks;
7928
315
                sz -= blocks * WC_AES_BLOCK_SIZE;
7929
315
            }
7930
447
            else
7931
447
        #endif
7932
447
            {
7933
            #ifdef WOLFSSL_CHECK_MEM_ZERO
7934
                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
7935
                    WC_AES_BLOCK_SIZE);
7936
            #endif
7937
                /* do as many block size ops as possible */
7938
878
                while (sz >= WC_AES_BLOCK_SIZE) {
7939
                #ifdef XTRANSFORM_AESCTRBLOCK
7940
                    ret = XTRANSFORM_AESCTRBLOCK(aes, out, in);
7941
                    if (ret != 0)
7942
                        break;
7943
                #else
7944
431
                    ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7945
431
                                                    scratch,
7946
431
                                                    &did_prefetches);
7947
431
                    if (ret != 0)
7948
0
                        break;
7949
431
                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
7950
431
                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
7951
431
                #endif
7952
431
                    IncrementAesCounter((byte*)aes->reg);
7953
7954
431
                    out += WC_AES_BLOCK_SIZE;
7955
431
                    in  += WC_AES_BLOCK_SIZE;
7956
431
                    sz  -= WC_AES_BLOCK_SIZE;
7957
431
                    aes->left = 0;
7958
431
                }
7959
447
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
7960
447
            }
7961
7962
            /* handle non block size remaining and store unused byte count in left */
7963
762
            if ((ret == 0) && sz) {
7964
487
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7965
487
                                                (byte*)aes->tmp,
7966
487
                                                &did_prefetches);
7967
487
                if (ret == 0) {
7968
487
                    IncrementAesCounter((byte*)aes->reg);
7969
487
                    aes->left = WC_AES_BLOCK_SIZE - sz;
7970
487
                    xorbufout(out, in, aes->tmp, sz);
7971
487
                }
7972
487
            }
7973
7974
762
            if (ret < 0)
7975
0
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
7976
7977
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7978
            wc_MemZero_Check(scratch, WC_AES_BLOCK_SIZE);
7979
        #endif
7980
7981
762
            VECTOR_REGISTERS_POP;
7982
7983
762
            return ret;
7984
762
    #endif
7985
762
        }
7986
7987
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
7988
                                        const byte* iv, int dir)
7989
0
        {
7990
0
            if (aes == NULL) {
7991
0
                return BAD_FUNC_ARG;
7992
0
            }
7993
0
            if (len > sizeof(aes->key)) {
7994
0
                return BAD_FUNC_ARG;
7995
0
            }
7996
7997
0
            return wc_AesSetKey(aes, key, len, iv, dir);
7998
0
        }
7999
8000
    #endif /* NEED_AES_CTR_SOFT */
8001
8002
#endif /* WOLFSSL_AES_COUNTER */
8003
8004
#ifndef WC_AES_HAVE_PREFETCH_ARG
8005
    #ifndef AesEncrypt_preFetchOpt
8006
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
8007
            wc_AesEncrypt(aes, inBlock, outBlock)
8008
    #endif
8009
    #ifndef AesDecrypt_preFetchOpt
8010
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
8011
            wc_AesDecrypt(aes, inBlock, outBlock)
8012
    #endif
8013
#endif
8014
8015
/*
8016
 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
8017
 * of two parts in order:
8018
 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
8019
 *      to the implicit IV.
8020
 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
8021
 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
8022
 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
8023
 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
8024
 * block counter during the encryption.
8025
 */
8026
8027
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
8028
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
8029
1.34k
{
8030
1.34k
    int i;
8031
1.60k
    for (i = (int)ctrSz - 1; i >= 0; i--) {
8032
1.60k
        if (++ctr[i])
8033
1.34k
            break;
8034
1.60k
    }
8035
1.34k
}
8036
#endif /* HAVE_AESGCM || HAVE_AESCCM */
8037
8038
8039
#ifdef HAVE_AESGCM
8040
8041
#ifdef WOLFSSL_AESGCM_STREAM
8042
    /* Access initialization counter data. */
8043
358
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
8044
    /* Access counter data. */
8045
11.5k
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
8046
    /* Access tag data. */
8047
32.3k
    #define AES_TAG(aes)            ((aes)->streamData + 2 * WC_AES_BLOCK_SIZE)
8048
    /* Access last GHASH block. */
8049
    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE)
8050
    /* Access last encrypted block. */
8051
4.51k
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
8052
8053
16.1k
    #define GHASH_ONE_BLOCK     GHASH_ONE_BLOCK_SW
8054
#endif
8055
8056
#if defined(HAVE_COLDFIRE_SEC)
8057
    #error "Coldfire SEC doesn't currently support AES-GCM mode"
8058
8059
#endif
8060
8061
#if !defined(NO_INLINE) && defined(__GNUC__) && !defined(__cplusplus)
8062
/* Inline for callers here in aes.c, but a callable local function for outside
8063
 * callers.  Don't use WC_INLINE unconditionally, because we can't count on
8064
 * correct behavior beyond gcc/clang, and we don't want the the WC_MAYBE_UNUSED
8065
 * attribute in NO_INLINE builds.
8066
 */
8067
WC_INLINE
8068
#endif
8069
1.09k
int wc_local_AesGcmCheckTagSz(word32 authTagSz) {
8070
#ifdef WC_AES_GCM_ALLOW_NONSTANDARD_TAG_LENGTH
8071
    #ifdef HAVE_FIPS
8072
        #error WC_AES_GCM_ALLOW_NONSTANDARD_TAG_LENGTH not allowed with FIPS 140.
8073
    #endif
8074
    wc_static_assert(WOLFSSL_MIN_AUTH_TAG_SZ >= 4);
8075
    if ((authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) ||
8076
        (authTagSz > WC_AES_BLOCK_SIZE))
8077
    {
8078
        WOLFSSL_MSG("AES-GCM unsupported authTagSz");
8079
        return BAD_FUNC_ARG;
8080
    }
8081
    else
8082
        return 0;
8083
#else
8084
    /* A switch is actually better for the optimizer than most hand-rolled
8085
     * equivalents, because it hands the compiler the exact value set and lets
8086
     * it pick the best lowering per WOLFSSL_MIN_AUTH_TAG_SZ configuration.
8087
     */
8088
1.09k
    switch (authTagSz) {
8089
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 4
8090
    case 4:
8091
#endif
8092
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 8
8093
    case 8:
8094
#endif
8095
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 12
8096
0
    case 12:
8097
0
#endif
8098
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 13
8099
0
    case 13:
8100
0
#endif
8101
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 14
8102
0
    case 14:
8103
0
#endif
8104
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 15
8105
0
    case 15:
8106
0
#endif
8107
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 16
8108
1.08k
    case 16:
8109
1.08k
#endif
8110
1.08k
        return 0;
8111
11
    default:
8112
11
        WOLFSSL_MSG("AES-GCM unsupported authTagSz");
8113
11
        return BAD_FUNC_ARG;
8114
1.09k
    }
8115
1.09k
#endif
8116
1.09k
}
8117
8118
#if defined(WOLFSSL_AFALG)
8119
    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
8120
8121
#elif defined(WOLFSSL_KCAPI_AES)
8122
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
8123
8124
#elif defined(WOLFSSL_DEVCRYPTO_AES)
8125
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
8126
8127
#else /* software + AESNI implementation */
8128
8129
#if !defined(FREESCALE_LTC_AES_GCM)
8130
#if (!(defined(__aarch64__) && defined(WOLFSSL_ARMASM))) || \
8131
    defined(WOLFSSL_AESGCM_STREAM)
8132
static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
8133
40.3k
{
8134
40.3k
    int i;
8135
8136
    /* in network byte order so start at end and work back */
8137
40.4k
    for (i = WC_AES_BLOCK_SIZE - 1; i >= WC_AES_BLOCK_SIZE - CTR_SZ; i--) {
8138
40.4k
        if (++inOutCtr[i])  /* we're done unless we overflow */
8139
40.3k
            return;
8140
40.4k
    }
8141
40.3k
}
8142
#endif
8143
#endif /* !FREESCALE_LTC_AES_GCM */
8144
8145
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
8146
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8147
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8148
8149
static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
8150
2.17k
{
8151
    /* Multiply the sz by 8 */
8152
2.17k
    word32 szHi = (sz >> (8*sizeof(sz) - 3));
8153
2.17k
    sz <<= 3;
8154
8155
    /* copy over the words of the sz into the destination buffer */
8156
2.17k
    buf[0] = (byte)(szHi >> 24);
8157
2.17k
    buf[1] = (byte)(szHi >> 16);
8158
2.17k
    buf[2] = (byte)(szHi >>  8);
8159
2.17k
    buf[3] = (byte)szHi;
8160
2.17k
    buf[4] = (byte)(sz >> 24);
8161
2.17k
    buf[5] = (byte)(sz >> 16);
8162
2.17k
    buf[6] = (byte)(sz >>  8);
8163
2.17k
    buf[7] = (byte)sz;
8164
2.17k
}
8165
8166
8167
static WC_INLINE void RIGHTSHIFTX(byte* x)
8168
3.38k
{
8169
3.38k
    int i;
8170
3.38k
    int carryIn = 0;
8171
3.38k
    volatile byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
8172
8173
57.4k
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
8174
54.0k
        int carryOut = (x[i] & 0x01) << 7;
8175
54.0k
        x[i] = (byte) ((x[i] >> 1) | carryIn);
8176
54.0k
        carryIn = carryOut;
8177
54.0k
    }
8178
3.38k
    x[0] ^= borrow;
8179
3.38k
}
8180
8181
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
8182
8183
8184
#ifdef GCM_TABLE
8185
8186
void GenerateM0(Gcm* gcm)
8187
{
8188
    int i, j;
8189
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
8190
8191
    XMEMCPY(m[128], gcm->H, WC_AES_BLOCK_SIZE);
8192
8193
    for (i = 64; i > 0; i /= 2) {
8194
        XMEMCPY(m[i], m[i*2], WC_AES_BLOCK_SIZE);
8195
        RIGHTSHIFTX(m[i]);
8196
    }
8197
8198
    for (i = 2; i < 256; i *= 2) {
8199
        for (j = 1; j < i; j++) {
8200
            XMEMCPY(m[i+j], m[i], WC_AES_BLOCK_SIZE);
8201
            xorbuf(m[i+j], m[j], WC_AES_BLOCK_SIZE);
8202
        }
8203
    }
8204
8205
#if defined(WOLFSSL_PPC64_ASM)
8206
    for (i = 1; i < 256; i++) {
8207
        word64* m64 = (word64*)gcm->M0[i];
8208
        m64[0] = ByteReverseWord64(m64[0]);
8209
        m64[1] = ByteReverseWord64(m64[1]);
8210
    }
8211
#endif
8212
    XMEMSET(m[0], 0, WC_AES_BLOCK_SIZE);
8213
}
8214
8215
#elif defined(GCM_TABLE_4BIT)
8216
8217
#if !defined(WC_16BIT_CPU)
8218
static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
8219
18.0k
{
8220
18.0k
    int i;
8221
288k
    for (i = 15; i > 0; i--)
8222
270k
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
8223
18.0k
    r8[0] = (byte)(z8[0] >> 4);
8224
18.0k
}
8225
#endif
8226
8227
void GenerateM0(Gcm* gcm)
8228
1.12k
{
8229
1.12k
#if !defined(WC_16BIT_CPU)
8230
1.12k
    int i;
8231
1.12k
#endif
8232
1.12k
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
8233
8234
    /* 0 times -> 0x0 */
8235
1.12k
    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
8236
    /* 1 times -> 0x8 */
8237
1.12k
    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
8238
    /* 2 times -> 0x4 */
8239
1.12k
    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
8240
1.12k
    RIGHTSHIFTX(m[0x4]);
8241
    /* 4 times -> 0x2 */
8242
1.12k
    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
8243
1.12k
    RIGHTSHIFTX(m[0x2]);
8244
    /* 8 times -> 0x1 */
8245
1.12k
    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
8246
1.12k
    RIGHTSHIFTX(m[0x1]);
8247
8248
    /* 0x3 */
8249
1.12k
    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
8250
1.12k
    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
8251
8252
    /* 0x5 -> 0x7 */
8253
1.12k
    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
8254
1.12k
    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
8255
1.12k
    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
8256
1.12k
    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
8257
1.12k
    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
8258
1.12k
    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
8259
8260
    /* 0x9 -> 0xf */
8261
1.12k
    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
8262
1.12k
    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
8263
1.12k
    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
8264
1.12k
    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
8265
1.12k
    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
8266
1.12k
    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
8267
1.12k
    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
8268
1.12k
    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
8269
1.12k
    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
8270
1.12k
    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
8271
1.12k
    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
8272
1.12k
    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
8273
1.12k
    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
8274
1.12k
    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
8275
8276
1.12k
#if !defined(WC_16BIT_CPU)
8277
19.1k
    for (i = 0; i < 16; i++) {
8278
18.0k
        Shift4_M0(m[16+i], m[i]);
8279
18.0k
    }
8280
1.12k
#endif
8281
8282
#if defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8283
    for (i = 0; i < 32; i++) {
8284
    #if !defined(__aarch64__)
8285
        word32* m32 = (word32*)gcm->M0[i];
8286
        m32[0] = ByteReverseWord32(m32[0]);
8287
        m32[1] = ByteReverseWord32(m32[1]);
8288
        m32[2] = ByteReverseWord32(m32[2]);
8289
        m32[3] = ByteReverseWord32(m32[3]);
8290
    #else
8291
        word64* m64 = (word64*)gcm->M0[i];
8292
        m64[0] = ByteReverseWord64(m64[0]);
8293
        m64[1] = ByteReverseWord64(m64[1]);
8294
    #endif
8295
    }
8296
#endif
8297
1.12k
}
8298
8299
#endif /* GCM_TABLE */
8300
#endif
8301
8302
#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
8303
    #define HAVE_INTEL_AVX1
8304
    #ifndef NO_AVX2_SUPPORT
8305
        #define HAVE_INTEL_AVX2
8306
    #endif
8307
    #ifdef WOLFSSL_X86_64_BUILD
8308
        #ifndef NO_VAES_SUPPORT
8309
            #define HAVE_INTEL_VAES
8310
        #endif
8311
        #ifndef NO_AVX512_SUPPORT
8312
            #define HAVE_INTEL_AVX512
8313
        #endif
8314
    #endif
8315
#endif
8316
8317
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \
8318
    defined(WC_C_DYNAMIC_FALLBACK)
8319
void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m)
8320
                           XASM_LINK("GCM_generate_m0_aesni");
8321
#ifdef HAVE_INTEL_AVX1
8322
void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m)
8323
                          XASM_LINK("GCM_generate_m0_avx1");
8324
#endif
8325
#ifdef HAVE_INTEL_AVX2
8326
void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
8327
                          XASM_LINK("GCM_generate_m0_avx2");
8328
#endif
8329
#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */
8330
8331
/* Software AES - GCM SetKey */
8332
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
8333
1.12k
{
8334
1.12k
    int  ret;
8335
1.12k
    byte iv[WC_AES_BLOCK_SIZE];
8336
8337
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
8338
        byte   local[32];
8339
        word32 localSz = 32;
8340
8341
        if (len == (16 + WC_CAAM_BLOB_SZ) ||
8342
          len == (24 + WC_CAAM_BLOB_SZ) ||
8343
          len == (32 + WC_CAAM_BLOB_SZ)) {
8344
            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
8345
                 return BAD_FUNC_ARG;
8346
            }
8347
8348
            /* set local values */
8349
            key = local;
8350
            len = localSz;
8351
        }
8352
    #endif
8353
8354
1.12k
    if (!((len == 16) || (len == 24) || (len == 32)))
8355
0
        return BAD_FUNC_ARG;
8356
8357
1.12k
    if (aes == NULL || key == NULL) {
8358
#ifdef WOLFSSL_IMX6_CAAM_BLOB
8359
        ForceZero(local, sizeof(local));
8360
#endif
8361
0
        return BAD_FUNC_ARG;
8362
0
    }
8363
#ifdef OPENSSL_EXTRA
8364
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
8365
    aes->gcm.aadLen = 0;
8366
#endif
8367
1.12k
    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
8368
1.12k
    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
8369
#ifdef WOLF_CRYPTO_CB_ONLY_AES
8370
    /* do key scheduling so that ECB-only devices can still do GCM */
8371
    if (ret == 0) {
8372
        ret = wc_CryptoCb_AesEcbEncrypt(aes, aes->gcm.H, iv, WC_AES_BLOCK_SIZE);
8373
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8374
        if (ret == 0)
8375
            GenerateM0(&aes->gcm);
8376
#endif
8377
    }
8378
    return ret;
8379
#endif
8380
1.12k
#ifdef WOLFSSL_AESGCM_STREAM
8381
1.12k
    aes->gcmKeySet = 1;
8382
1.12k
#endif
8383
    #if defined(WOLFSSL_SECO_CAAM)
8384
        if (aes->devId == WOLFSSL_SECO_DEVID) {
8385
            return ret;
8386
        }
8387
    #endif /* WOLFSSL_SECO_CAAM */
8388
8389
    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
8390
        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
8391
        return ret;
8392
    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
8393
8394
/* GCM setup needs one AES block encrypt of the all-zero IV to generate
8395
 * the hash subkey H. STM32_CRYPTO stores only the raw key (no expanded
8396
 * key schedule), so the ARMASM AES_ECB_encrypt helpers used here cannot
8397
 * be used. Excluding STM32_CRYPTO from this block falls back to the
8398
 * non-ARMASM wc_AesEncrypt implementation, which on STM32 routes to
8399
 * CRYP. */
8400
#if defined(WOLFSSL_ARMASM) && !defined(STM32_CRYPTO)
8401
    if (ret == 0) {
8402
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
8403
    #if !defined(__aarch64__)
8404
        AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
8405
    #else
8406
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
8407
            AES_GCM_set_key_AARCH64(iv, (byte*)aes->key, aes->gcm.H,
8408
                aes->rounds);
8409
        }
8410
        else
8411
    #endif /* !__aarch64__ */
8412
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
8413
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
8414
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
8415
        {
8416
            AES_ECB_encrypt_NEON(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
8417
                (const unsigned char*)aes->key, aes->rounds);
8418
        }
8419
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8420
        {
8421
            AES_ECB_encrypt(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
8422
                (const unsigned char*)aes->key, aes->rounds);
8423
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8424
            GenerateM0(&aes->gcm);
8425
        #endif /* GCM_TABLE */
8426
        }
8427
#endif
8428
    }
8429
#else
8430
1.12k
#if !defined(FREESCALE_LTC_AES_GCM) && !defined(WOLFSSL_PSOC6_CRYPTO)
8431
8432
8433
#ifdef WOLF_CRYPTO_CB_AES_SETKEY
8434
    if ((ret == 0) && (aes->devId != INVALID_DEVID && aes->devCtx != NULL)) {
8435
        /* SE owns key - skip H and M table generation */
8436
    }
8437
    else
8438
#endif
8439
1.12k
    if (ret == 0) {
8440
1.12k
        VECTOR_REGISTERS_PUSH;
8441
8442
#if defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM) && \
8443
    !defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
8444
        /* Compute H reflected for the carryless-multiply GHASH; the scalar
8445
         * GHASH uses no M0 table.  (Vector crypto supersedes scalar and needs H
8446
         * unreflected, so it falls through to the generic E(0) path below.) */
8447
        AES_GCM_set_key_RISCV64(iv, (byte*)aes->key, aes->gcm.H,
8448
            (int)aes->rounds);
8449
#else
8450
        /* Generate H = AES_Encrypt(key, 0^128) */
8451
1.12k
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
8452
8453
1.12k
        if (ret == 0) {
8454
1.12k
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8455
    #if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT)
8456
            if (aes->use_aesni) {
8457
        #if defined(WC_C_DYNAMIC_FALLBACK)
8458
            #ifdef HAVE_INTEL_AVX2
8459
                if (IS_INTEL_AVX2(intel_flags)) {
8460
                    GCM_generate_m0_avx2(aes->gcm.H,
8461
                        (byte*)aes->gcm.M0);
8462
                }
8463
                else
8464
            #endif
8465
            #if defined(HAVE_INTEL_AVX1)
8466
                if (IS_INTEL_AVX1(intel_flags)) {
8467
                    GCM_generate_m0_avx1(aes->gcm.H,
8468
                        (byte*)aes->gcm.M0);
8469
                }
8470
                else
8471
            #endif
8472
                {
8473
                    GCM_generate_m0_aesni(aes->gcm.H,
8474
                        (byte*)aes->gcm.M0);
8475
                }
8476
        #endif /* WC_C_DYNAMIC_FALLBACK */
8477
            }
8478
            else
8479
    #endif /* AESNI */
8480
1.12k
            {
8481
1.12k
                GenerateM0(&aes->gcm);
8482
1.12k
            }
8483
1.12k
#endif /* GCM_TABLE || GCM_TABLE_4BIT */
8484
1.12k
        }
8485
1.12k
#endif /* WOLFSSL_RISCV_SCALAR_CRYPTO_ASM */
8486
8487
1.12k
        VECTOR_REGISTERS_POP;
8488
1.12k
    }
8489
1.12k
#endif /* !FREESCALE_LTC_AES_GCM && !WOLFSSL_PSOC6_CRYPTO */
8490
1.12k
#endif
8491
8492
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
8493
    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
8494
#endif
8495
8496
1.12k
#ifdef WOLF_CRYPTO_CB
8497
1.12k
    if (aes->devId != INVALID_DEVID) {
8498
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
8499
        if (aes->devCtx != NULL) {
8500
            /* SE owns key - don't copy to devKey */
8501
        }
8502
        else
8503
    #endif
8504
0
        {
8505
0
            XMEMCPY(aes->devKey, key, len);
8506
0
        }
8507
0
    }
8508
1.12k
#endif
8509
8510
#ifdef WOLFSSL_IMX6_CAAM_BLOB
8511
    ForceZero(local, sizeof(local));
8512
#endif
8513
1.12k
    return ret;
8514
1.12k
}
8515
8516
8517
#ifdef WOLFSSL_AESNI
8518
8519
void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
8520
                     const unsigned char* addt, const unsigned char* ivec,
8521
                     unsigned char *tag, word32 nbytes,
8522
                     word32 abytes, word32 ibytes,
8523
                     word32 tbytes, const unsigned char* key, int nr)
8524
                     XASM_LINK("AES_GCM_encrypt_aesni");
8525
#ifdef HAVE_INTEL_AVX1
8526
void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
8527
                          const unsigned char* addt, const unsigned char* ivec,
8528
                          unsigned char *tag, word32 nbytes,
8529
                          word32 abytes, word32 ibytes,
8530
                          word32 tbytes, const unsigned char* key,
8531
                          int nr)
8532
                          XASM_LINK("AES_GCM_encrypt_avx1");
8533
#ifdef HAVE_INTEL_AVX2
8534
void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
8535
                          const unsigned char* addt, const unsigned char* ivec,
8536
                          unsigned char *tag, word32 nbytes,
8537
                          word32 abytes, word32 ibytes,
8538
                          word32 tbytes, const unsigned char* key,
8539
                          int nr)
8540
                          XASM_LINK("AES_GCM_encrypt_avx2");
8541
#ifdef HAVE_INTEL_AVX512
8542
void AES_GCM_encrypt_avx512(const unsigned char *in, unsigned char *out,
8543
                          const unsigned char* addt, const unsigned char* ivec,
8544
                          unsigned char *tag, word32 nbytes,
8545
                          word32 abytes, word32 ibytes,
8546
                          word32 tbytes, const unsigned char* key,
8547
                          int nr)
8548
                          XASM_LINK("AES_GCM_encrypt_avx512");
8549
#endif
8550
#ifdef HAVE_INTEL_VAES
8551
void AES_GCM_encrypt_vaes(const unsigned char *in, unsigned char *out,
8552
                          const unsigned char* addt, const unsigned char* ivec,
8553
                          unsigned char *tag, word32 nbytes,
8554
                          word32 abytes, word32 ibytes,
8555
                          word32 tbytes, const unsigned char* key,
8556
                          int nr)
8557
                          XASM_LINK("AES_GCM_encrypt_vaes");
8558
#endif
8559
#endif /* HAVE_INTEL_AVX2 */
8560
#endif /* HAVE_INTEL_AVX1 */
8561
8562
#ifdef HAVE_AES_DECRYPT
8563
void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
8564
                     const unsigned char* addt, const unsigned char* ivec,
8565
                     const unsigned char *tag, word32 nbytes, word32 abytes,
8566
                     word32 ibytes, word32 tbytes, const unsigned char* key,
8567
                     int nr, int* res)
8568
                     XASM_LINK("AES_GCM_decrypt_aesni");
8569
#ifdef HAVE_INTEL_AVX1
8570
void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
8571
                          const unsigned char* addt, const unsigned char* ivec,
8572
                          const unsigned char *tag, word32 nbytes,
8573
                          word32 abytes, word32 ibytes, word32 tbytes,
8574
                          const unsigned char* key, int nr, int* res)
8575
                          XASM_LINK("AES_GCM_decrypt_avx1");
8576
#ifdef HAVE_INTEL_AVX2
8577
void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
8578
                          const unsigned char* addt, const unsigned char* ivec,
8579
                          const unsigned char *tag, word32 nbytes,
8580
                          word32 abytes, word32 ibytes, word32 tbytes,
8581
                          const unsigned char* key, int nr, int* res)
8582
                          XASM_LINK("AES_GCM_decrypt_avx2");
8583
#ifdef HAVE_INTEL_AVX512
8584
void AES_GCM_decrypt_avx512(const unsigned char *in, unsigned char *out,
8585
                          const unsigned char* addt, const unsigned char* ivec,
8586
                          const unsigned char *tag, word32 nbytes,
8587
                          word32 abytes, word32 ibytes, word32 tbytes,
8588
                          const unsigned char* key, int nr, int* res)
8589
                          XASM_LINK("AES_GCM_decrypt_avx512");
8590
#endif
8591
#ifdef HAVE_INTEL_VAES
8592
void AES_GCM_decrypt_vaes(const unsigned char *in, unsigned char *out,
8593
                          const unsigned char* addt, const unsigned char* ivec,
8594
                          const unsigned char *tag, word32 nbytes,
8595
                          word32 abytes, word32 ibytes, word32 tbytes,
8596
                          const unsigned char* key, int nr, int* res)
8597
                          XASM_LINK("AES_GCM_decrypt_vaes");
8598
#endif
8599
#endif /* HAVE_INTEL_AVX2 */
8600
#endif /* HAVE_INTEL_AVX1 */
8601
#endif /* HAVE_AES_DECRYPT */
8602
8603
#endif /* WOLFSSL_AESNI */
8604
8605
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
8606
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8607
#if defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM) && defined(HAVE_AESGCM) && \
8608
    !defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
8609
/* GHASH using the RISC-V scalar carryless-multiply (Zbc) helper.  Vector crypto
8610
 * supersedes it (fused vghsh/vgmul), so this scalar path yields when both are on.
8611
 *
8612
 * H is stored reflected by AES_GCM_set_key_RISCV64, which is the form
8613
 * GHASH_RISCV64 expects.  GHASH_RISCV64(x, h, in, blocks) computes, for each
8614
 * 16-byte block, x = (x ^ block) * H in GF(2^128) (reflecting x in/out so the
8615
 * caller sees the standard domain).  A single padded/length block is therefore
8616
 * just GHASH_RISCV64(x, h, block, 1) - no software GMULT or M0 table is needed.
8617
 *
8618
 * @param [in]  gcm  GCM object.
8619
 * @param [in]  a    Additional Authentication Data (AAD).
8620
 * @param [in]  aSz  Length of AAD in bytes.
8621
 * @param [in]  c    Cipher text.
8622
 * @param [in]  cSz  Length of cipher text in bytes.
8623
 * @param [out] s    Hash result.
8624
 * @param [in]  sSz  Number of bytes to output.
8625
 */
8626
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8627
    word32 cSz, byte* s, word32 sSz)
8628
{
8629
    ALIGN8 byte x[WC_AES_BLOCK_SIZE];
8630
    ALIGN8 byte scratch[WC_AES_BLOCK_SIZE];
8631
    word32 blocks, partial;
8632
    byte* h = gcm->H;
8633
8634
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
8635
8636
    /* Hash in A, the Additional Authentication Data */
8637
    if (aSz != 0 && a != NULL) {
8638
        blocks = aSz / WC_AES_BLOCK_SIZE;
8639
        partial = aSz % WC_AES_BLOCK_SIZE;
8640
        if (blocks > 0) {
8641
            GHASH_RISCV64(x, h, a, blocks);
8642
            a += blocks * WC_AES_BLOCK_SIZE;
8643
        }
8644
        if (partial != 0) {
8645
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8646
            XMEMCPY(scratch, a, partial);
8647
            GHASH_RISCV64(x, h, scratch, 1);
8648
        }
8649
    }
8650
8651
    /* Hash in C, the Ciphertext */
8652
    if (cSz != 0 && c != NULL) {
8653
        blocks = cSz / WC_AES_BLOCK_SIZE;
8654
        partial = cSz % WC_AES_BLOCK_SIZE;
8655
        if (blocks > 0) {
8656
            GHASH_RISCV64(x, h, c, blocks);
8657
            c += blocks * WC_AES_BLOCK_SIZE;
8658
        }
8659
        if (partial != 0) {
8660
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8661
            XMEMCPY(scratch, c, partial);
8662
            GHASH_RISCV64(x, h, scratch, 1);
8663
        }
8664
    }
8665
8666
    /* Hash in the lengths of A and C in bits */
8667
    FlattenSzInBits(&scratch[0], aSz);
8668
    FlattenSzInBits(&scratch[8], cSz);
8669
    GHASH_RISCV64(x, h, scratch, 1);
8670
8671
    /* Copy the result into s. */
8672
    XMEMCPY(s, x, sSz);
8673
}
8674
8675
#ifdef WOLFSSL_AESGCM_STREAM
8676
/* No extra initialization for the carryless-multiply implementation.
8677
 *
8678
 * @param [in] aes  AES GCM object.
8679
 */
8680
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8681
8682
/* GHASH one block of data into the streaming tag.
8683
 *
8684
 * x = (tag ^ block) * H using the carryless-multiply helper (reflected H).
8685
 *
8686
 * @param [in, out] aes    AES GCM object.
8687
 * @param [in]      block  Block of AAD or cipher text.
8688
 */
8689
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
8690
    GHASH_RISCV64(AES_TAG(aes), (aes)->gcm.H, block, 1)
8691
#endif /* WOLFSSL_AESGCM_STREAM */
8692
8693
#define HAVE_GHASH
8694
#elif defined(GCM_SMALL)
8695
static void GMULT(byte* X, byte* Y)
8696
{
8697
    byte Z[WC_AES_BLOCK_SIZE];
8698
    byte V[WC_AES_BLOCK_SIZE];
8699
    int i, j;
8700
8701
    XMEMSET(Z, 0, WC_AES_BLOCK_SIZE);
8702
    XMEMCPY(V, X, WC_AES_BLOCK_SIZE);
8703
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++)
8704
    {
8705
        byte y = Y[i];
8706
        for (j = 0; j < 8; j++)
8707
        {
8708
            if (y & 0x80) {
8709
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
8710
            }
8711
8712
            RIGHTSHIFTX(V);
8713
            y = y << 1;
8714
        }
8715
    }
8716
    XMEMCPY(X, Z, WC_AES_BLOCK_SIZE);
8717
}
8718
8719
8720
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
8721
    word32 cSz, byte* s, word32 sSz)
8722
{
8723
    byte x[WC_AES_BLOCK_SIZE];
8724
    byte scratch[WC_AES_BLOCK_SIZE];
8725
    word32 blocks, partial;
8726
    byte* h;
8727
8728
    h = gcm->H;
8729
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
8730
8731
    /* Hash in A, the Additional Authentication Data */
8732
    if (aSz != 0 && a != NULL) {
8733
        blocks = aSz / WC_AES_BLOCK_SIZE;
8734
        partial = aSz % WC_AES_BLOCK_SIZE;
8735
        while (blocks--) {
8736
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
8737
            GMULT(x, h);
8738
            a += WC_AES_BLOCK_SIZE;
8739
        }
8740
        if (partial != 0) {
8741
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8742
            XMEMCPY(scratch, a, partial);
8743
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8744
            GMULT(x, h);
8745
        }
8746
    }
8747
8748
    /* Hash in C, the Ciphertext */
8749
    if (cSz != 0 && c != NULL) {
8750
        blocks = cSz / WC_AES_BLOCK_SIZE;
8751
        partial = cSz % WC_AES_BLOCK_SIZE;
8752
        while (blocks--) {
8753
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
8754
            GMULT(x, h);
8755
            c += WC_AES_BLOCK_SIZE;
8756
        }
8757
        if (partial != 0) {
8758
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
8759
            XMEMCPY(scratch, c, partial);
8760
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8761
            GMULT(x, h);
8762
        }
8763
    }
8764
8765
    /* Hash in the lengths of A and C in bits */
8766
    FlattenSzInBits(&scratch[0], aSz);
8767
    FlattenSzInBits(&scratch[8], cSz);
8768
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
8769
    GMULT(x, h);
8770
8771
    /* Copy the result into s. */
8772
    XMEMCPY(s, x, sSz);
8773
}
8774
8775
#ifdef WOLFSSL_AESGCM_STREAM
8776
/* No extra initialization for small implementation.
8777
 *
8778
 * @param [in] aes  AES GCM object.
8779
 */
8780
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8781
8782
/* GHASH one block of data..
8783
 *
8784
 * XOR block into tag and GMULT with H.
8785
 *
8786
 * @param [in, out] aes    AES GCM object.
8787
 * @param [in]      block  Block of AAD or cipher text.
8788
 */
8789
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
8790
    do {                                                \
8791
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
8792
        GMULT(AES_TAG(aes), (aes)->gcm.H);              \
8793
    }                                                   \
8794
    while (0)
8795
#endif /* WOLFSSL_AESGCM_STREAM */
8796
8797
#if defined(WOLFSSL_ARMASM) && (!defined(__aarch64__) || \
8798
    defined(WOLFSSL_ARMASM_NO_NEON))
8799
static void GCM_gmult_len_armasm_C(
8800
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
8801
{
8802
    byte Z[AES_BLOCK_SIZE];
8803
    byte V[AES_BLOCK_SIZE];
8804
    int i;
8805
    int j;
8806
8807
    while (len >= AES_BLOCK_SIZE) {
8808
        xorbuf(x, a, AES_BLOCK_SIZE);
8809
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
8810
        XMEMCPY(V, x, AES_BLOCK_SIZE);
8811
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
8812
            byte y = h[i];
8813
            for (j = 0; j < 8; j++) {
8814
                if (y & 0x80) {
8815
                    xorbuf(Z, V, AES_BLOCK_SIZE);
8816
                }
8817
                RIGHTSHIFTX(V);
8818
                y = y << 1;
8819
            }
8820
        }
8821
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
8822
        len -= AES_BLOCK_SIZE;
8823
        a += AES_BLOCK_SIZE;
8824
    }
8825
}
8826
8827
#define GCM_GMULT_LEN(gcm, x, a, len) \
8828
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
8829
#elif defined(WOLFSSL_ARMASM)
8830
#define GCM_GMULT_LEN(gcm, x, a, len) \
8831
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
8832
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
8833
static void GCM_gmult_len_armasm_C(
8834
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
8835
{
8836
    byte Z[AES_BLOCK_SIZE];
8837
    byte V[AES_BLOCK_SIZE];
8838
    int i;
8839
    int j;
8840
8841
    while (len >= AES_BLOCK_SIZE) {
8842
        xorbuf(x, a, AES_BLOCK_SIZE);
8843
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
8844
        XMEMCPY(V, x, AES_BLOCK_SIZE);
8845
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
8846
            byte y = h[i];
8847
            for (j = 0; j < 8; j++) {
8848
                if (y & 0x80) {
8849
                    xorbuf(Z, V, AES_BLOCK_SIZE);
8850
                }
8851
                RIGHTSHIFTX(V);
8852
                y = y << 1;
8853
            }
8854
        }
8855
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
8856
        len -= AES_BLOCK_SIZE;
8857
        a += AES_BLOCK_SIZE;
8858
    }
8859
}
8860
8861
#define GCM_GMULT_LEN(gcm, x, a, len) \
8862
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
8863
#endif
8864
8865
#elif defined(GCM_TABLE)
8866
8867
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
8868
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8869
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
8870
#define GCM_GMULT_LEN(gcm, x, a, len) \
8871
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
8872
#else
8873
#define GCM_GMULT_LEN(gcm, x, a, len) \
8874
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
8875
#endif
8876
#elif defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
8877
#define GCM_GMULT_LEN(gcm, x, a, len) \
8878
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
8879
#else
8880
ALIGN16 static const byte R[256][2] = {
8881
    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
8882
    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
8883
    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
8884
    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
8885
    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
8886
    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
8887
    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
8888
    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
8889
    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
8890
    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
8891
    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
8892
    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
8893
    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
8894
    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
8895
    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
8896
    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
8897
    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
8898
    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
8899
    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
8900
    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
8901
    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
8902
    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
8903
    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
8904
    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
8905
    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
8906
    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
8907
    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
8908
    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
8909
    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
8910
    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
8911
    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
8912
    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
8913
    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
8914
    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
8915
    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
8916
    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
8917
    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
8918
    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
8919
    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
8920
    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
8921
    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
8922
    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
8923
    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
8924
    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
8925
    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
8926
    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
8927
    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
8928
    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
8929
    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
8930
    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
8931
    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
8932
    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
8933
    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
8934
    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
8935
    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
8936
    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
8937
    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
8938
    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
8939
    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
8940
    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
8941
    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
8942
    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
8943
    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
8944
    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
8945
8946
8947
static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE])
8948
{
8949
#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
8950
    int i, j;
8951
    byte Z[WC_AES_BLOCK_SIZE];
8952
    byte a;
8953
8954
    XMEMSET(Z, 0, sizeof(Z));
8955
8956
    for (i = 15; i > 0; i--) {
8957
        xorbuf(Z, m[x[i]], WC_AES_BLOCK_SIZE);
8958
        a = Z[15];
8959
8960
        for (j = 15; j > 0; j--) {
8961
            Z[j] = Z[j-1];
8962
        }
8963
8964
        Z[0]  = R[a][0];
8965
        Z[1] ^= R[a][1];
8966
    }
8967
    xorbuf(Z, m[x[0]], WC_AES_BLOCK_SIZE);
8968
8969
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
8970
#elif defined(WC_32BIT_CPU)
8971
#ifndef WOLFSSL_USE_ALIGN
8972
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
8973
    byte a;
8974
    word32* pZ;
8975
    word32* pm;
8976
    word32* px = (word32*)(x);
8977
    int i;
8978
8979
    pZ = (word32*)(Z + 15 + 1);
8980
    pm = (word32*)(m[x[15]]);
8981
    pZ[0] = pm[0];
8982
    pZ[1] = pm[1];
8983
    pZ[2] = pm[2];
8984
    pZ[3] = pm[3];
8985
    a = Z[16 + 15];
8986
    Z[15]  = R[a][0];
8987
    Z[16] ^= R[a][1];
8988
    for (i = 14; i > 0; i--) {
8989
        pZ = (word32*)(Z + i + 1);
8990
        pm = (word32*)(m[x[i]]);
8991
        pZ[0] ^= pm[0];
8992
        pZ[1] ^= pm[1];
8993
        pZ[2] ^= pm[2];
8994
        pZ[3] ^= pm[3];
8995
        a = Z[16 + i];
8996
        Z[i]    = R[a][0];
8997
        Z[i+1] ^= R[a][1];
8998
    }
8999
    pZ = (word32*)(Z + 1);
9000
    pm = (word32*)(m[x[0]]);
9001
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
9002
    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
9003
#else
9004
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
9005
    byte a;
9006
    int i;
9007
9008
    XMEMCPY(Z + 16, m[x[15]], WC_AES_BLOCK_SIZE);
9009
    a = Z[16 + 15];
9010
    Z[15]  = R[a][0];
9011
    Z[16] ^= R[a][1];
9012
    for (i = 14; i > 0; i--) {
9013
        xorbuf(Z + i + 1, m[x[i]], WC_AES_BLOCK_SIZE);
9014
        a = Z[16 + i];
9015
        Z[i]    = R[a][0];
9016
        Z[i+1] ^= R[a][1];
9017
    }
9018
    xorbuf(Z + 1, m[x[0]], WC_AES_BLOCK_SIZE);
9019
    XMEMCPY(x, Z + 1, WC_AES_BLOCK_SIZE);
9020
#endif
9021
#else
9022
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
9023
    byte a;
9024
    word64* pZ;
9025
    word64* pm;
9026
    word64* px = (word64*)(x);
9027
    int i;
9028
9029
    pZ = (word64*)(Z + 15 + 1);
9030
    pm = (word64*)(m[x[15]]);
9031
    pZ[0] = pm[0];
9032
    pZ[1] = pm[1];
9033
    a = Z[16 + 15];
9034
    Z[15]  = R[a][0];
9035
    Z[16] ^= R[a][1];
9036
    for (i = 14; i > 0; i--) {
9037
        pZ = (word64*)(Z + i + 1);
9038
        pm = (word64*)(m[x[i]]);
9039
        pZ[0] ^= pm[0];
9040
        pZ[1] ^= pm[1];
9041
        a = Z[16 + i];
9042
        Z[i]    = R[a][0];
9043
        Z[i+1] ^= R[a][1];
9044
    }
9045
    pZ = (word64*)(Z + 1);
9046
    pm = (word64*)(m[x[0]]);
9047
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
9048
#endif
9049
}
9050
#endif
9051
9052
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9053
    word32 cSz, byte* s, word32 sSz)
9054
{
9055
    byte x[WC_AES_BLOCK_SIZE];
9056
    byte scratch[WC_AES_BLOCK_SIZE];
9057
    word32 blocks, partial;
9058
9059
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9060
9061
    /* Hash in A, the Additional Authentication Data */
9062
    if (aSz != 0 && a != NULL) {
9063
        blocks = aSz / WC_AES_BLOCK_SIZE;
9064
        partial = aSz % WC_AES_BLOCK_SIZE;
9065
    #ifdef GCM_GMULT_LEN
9066
        if (blocks > 0) {
9067
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
9068
            a += blocks * WC_AES_BLOCK_SIZE;
9069
        }
9070
        if (partial != 0) {
9071
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9072
            XMEMCPY(scratch, a, partial);
9073
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9074
        }
9075
    #else
9076
        while (blocks--) {
9077
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
9078
            GMULT(x, gcm->M0);
9079
            a += WC_AES_BLOCK_SIZE;
9080
        }
9081
        if (partial != 0) {
9082
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9083
            XMEMCPY(scratch, a, partial);
9084
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9085
            GMULT(x, gcm->M0);
9086
        }
9087
    #endif
9088
    }
9089
9090
    /* Hash in C, the Ciphertext */
9091
    if (cSz != 0 && c != NULL) {
9092
        blocks = cSz / WC_AES_BLOCK_SIZE;
9093
        partial = cSz % WC_AES_BLOCK_SIZE;
9094
    #ifdef GCM_GMULT_LEN
9095
        if (blocks > 0) {
9096
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
9097
            c += blocks * WC_AES_BLOCK_SIZE;
9098
        }
9099
        if (partial != 0) {
9100
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9101
            XMEMCPY(scratch, c, partial);
9102
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9103
        }
9104
    #else
9105
        while (blocks--) {
9106
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
9107
            GMULT(x, gcm->M0);
9108
            c += WC_AES_BLOCK_SIZE;
9109
        }
9110
        if (partial != 0) {
9111
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9112
            XMEMCPY(scratch, c, partial);
9113
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9114
            GMULT(x, gcm->M0);
9115
        }
9116
    #endif
9117
    }
9118
9119
    /* Hash in the lengths of A and C in bits */
9120
    FlattenSzInBits(&scratch[0], aSz);
9121
    FlattenSzInBits(&scratch[8], cSz);
9122
#ifdef GCM_GMULT_LEN
9123
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9124
#else
9125
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9126
    GMULT(x, gcm->M0);
9127
#endif
9128
9129
    /* Copy the result into s. */
9130
    XMEMCPY(s, x, sSz);
9131
}
9132
9133
#ifdef WOLFSSL_AESGCM_STREAM
9134
/* No extra initialization for table implementation.
9135
 *
9136
 * @param [in] aes  AES GCM object.
9137
 */
9138
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9139
9140
/* GHASH one block of data..
9141
 *
9142
 * XOR block into tag and GMULT with H using pre-computed table.
9143
 *
9144
 * @param [in, out] aes    AES GCM object.
9145
 * @param [in]      block  Block of AAD or cipher text.
9146
 */
9147
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9148
    do {                                                \
9149
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
9150
        GMULT(AES_TAG(aes), aes->gcm.M0);               \
9151
    }                                                   \
9152
    while (0)
9153
#endif /* WOLFSSL_AESGCM_STREAM */
9154
/* end GCM_TABLE */
9155
#elif defined(GCM_TABLE_4BIT)
9156
/* ARM assembly */
9157
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
9158
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
9159
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
9160
#define GCM_GMULT_LEN(gcm, x, a, len) \
9161
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
9162
#define GMULT(x, m)                                                      \
9163
    GCM_gmult_NEON(x, (const byte**)m)
9164
#else
9165
#define GCM_GMULT_LEN(gcm, x, a, len) \
9166
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9167
#define GMULT(x, m)                                                      \
9168
    GCM_gmult(x, (const byte**)m)
9169
#endif
9170
9171
/* PPC64 assembly */
9172
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
9173
#define GCM_GMULT_LEN(gcm, x, a, len)                                    \
9174
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9175
#define GMULT(x, m)                                                      \
9176
    GCM_gmult(x, (const byte**)m)
9177
9178
#else
9179
/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
9180
 *  R shifts right a reverse bit pair of bytes such that:
9181
 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
9182
 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
9183
 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
9184
 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
9185
 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
9186
 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
9187
 *  To calculate te rest, XOR result for each bit.
9188
 *   e.g. 6 = 4 ^ 2 => 48,c0
9189
 *
9190
 * Second half is same values rotated by 4-bits.
9191
 */
9192
#if defined(WC_16BIT_CPU)
9193
static const byte R[16][2] = {
9194
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
9195
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
9196
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
9197
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
9198
};
9199
#elif defined(BIG_ENDIAN_ORDER)
9200
static const word16 R[32] = {
9201
          0x0000,       0x1c20,       0x3840,       0x2460,
9202
          0x7080,       0x6ca0,       0x48c0,       0x54e0,
9203
          0xe100,       0xfd20,       0xd940,       0xc560,
9204
          0x9180,       0x8da0,       0xa9c0,       0xb5e0,
9205
9206
          0x0000,       0x01c2,       0x0384,       0x0246,
9207
          0x0708,       0x06ca,       0x048c,       0x054e,
9208
          0x0e10,       0x0fd2,       0x0d94,       0x0c56,
9209
          0x0918,       0x08da,       0x0a9c,       0x0b5e,
9210
};
9211
#else
9212
static const word16 R[32] = {
9213
          0x0000,       0x201c,       0x4038,       0x6024,
9214
          0x8070,       0xa06c,       0xc048,       0xe054,
9215
          0x00e1,       0x20fd,       0x40d9,       0x60c5,
9216
          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
9217
9218
          0x0000,       0xc201,       0x8403,       0x4602,
9219
          0x0807,       0xca06,       0x8c04,       0x4e05,
9220
          0x100e,       0xd20f,       0x940d,       0x560c,
9221
          0x1809,       0xda08,       0x9c0a,       0x5e0b,
9222
};
9223
#endif
9224
9225
/* Multiply in GF(2^128) defined by polynomial:
9226
 *   x^128 + x^7 + x^2 + x^1 + 1.
9227
 *
9228
 * H: hash key = encrypt(key, 0)
9229
 * x = x * H in field
9230
 *
9231
 * x: cumulative result
9232
 * m: 4-bit table
9233
 *    [0..15] * H
9234
 */
9235
#if defined(WC_16BIT_CPU)
9236
static void GMULT(byte *x, byte m[16][WC_AES_BLOCK_SIZE])
9237
{
9238
    int i, j, n;
9239
    byte Z[WC_AES_BLOCK_SIZE];
9240
    byte a;
9241
9242
    XMEMSET(Z, 0, sizeof(Z));
9243
9244
    for (i = 15; i >= 0; i--) {
9245
        for (n = 0; n < 2; n++) {
9246
            if (n == 0)
9247
                xorbuf(Z, m[x[i] & 0xf], WC_AES_BLOCK_SIZE);
9248
            else {
9249
                xorbuf(Z, m[x[i] >> 4], WC_AES_BLOCK_SIZE);
9250
                if (i == 0)
9251
                    break;
9252
            }
9253
            a = Z[15] & 0xf;
9254
9255
            for (j = 15; j > 0; j--)
9256
                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
9257
            Z[0] >>= 4;
9258
9259
            Z[0] ^= R[a][0];
9260
            Z[1] ^= R[a][1];
9261
        }
9262
    }
9263
9264
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
9265
}
9266
#elif defined(WC_32BIT_CPU) && defined(BIG_ENDIAN_ORDER)
9267
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9268
{
9269
    int i;
9270
    word32 z8[4] = {0, 0, 0, 0};
9271
    byte a;
9272
    word32* x8 = (word32*)x;
9273
    word32* m8;
9274
    byte xi;
9275
9276
    for (i = 15; i > 0; i--) {
9277
        xi = x[i];
9278
9279
        /* XOR in (msn * H) */
9280
        m8 = (word32*)m[xi & 0xf];
9281
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9282
9283
        /* Cache top byte for remainder calculations - lost in rotate. */
9284
        a = (byte)(z8[3] & 0xff);
9285
9286
        /* Rotate Z by 8-bits */
9287
        z8[3] = (z8[2] << 24) | (z8[3] >> 8);
9288
        z8[2] = (z8[1] << 24) | (z8[2] >> 8);
9289
        z8[1] = (z8[0] << 24) | (z8[1] >> 8);
9290
        z8[0] >>= 8;
9291
9292
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9293
        z8[0] ^= ((word32)R[16 + (a & 0xf)]) << 16;
9294
9295
        xi >>= 4;
9296
        /* XOR in next significant nibble (XORed with H) * remainder */
9297
        m8 = (word32*)m[xi];
9298
        a ^= (byte)(m8[3] >> 12) & 0xf;
9299
        a ^= (byte)((m8[3] << 4) & 0xf0);
9300
        z8[0] ^= ((word32)R[a >> 4]) << 16;
9301
9302
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9303
        m8 = (word32*)m[16 + xi];
9304
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
9305
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
9306
    }
9307
9308
    xi = x[0];
9309
9310
    /* XOR in most significant nibble * H */
9311
    m8 = (word32*)m[xi & 0xf];
9312
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9313
9314
    /* Cache top byte for remainder calculations - lost in rotate. */
9315
    a = (byte)(z8[3] & 0x0f);
9316
9317
    z8[3] = (z8[2] << 28) | (z8[3] >> 4);
9318
    z8[2] = (z8[1] << 28) | (z8[2] >> 4);
9319
    z8[1] = (z8[0] << 28) | (z8[1] >> 4);
9320
    z8[0] >>= 4;
9321
9322
    /* XOR in most significant nibble * remainder */
9323
    z8[0] ^= ((word32)R[a]) << 16;
9324
    /* XOR in next significant nibble * H */
9325
    m8 = (word32*)m[xi >> 4];
9326
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9327
9328
    /* Write back result. */
9329
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
9330
}
9331
#elif defined(WC_32BIT_CPU)
9332
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9333
{
9334
    int i;
9335
    word32 z8[4] = {0, 0, 0, 0};
9336
    byte a;
9337
    word32* x8 = (word32*)x;
9338
    word32* m8;
9339
    byte xi;
9340
    word32 n7, n6, n5, n4, n3, n2, n1, n0;
9341
9342
    for (i = 15; i > 0; i--) {
9343
        xi = x[i];
9344
9345
        /* XOR in (msn * H) */
9346
        m8 = (word32*)m[xi & 0xf];
9347
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9348
9349
        /* Cache top byte for remainder calculations - lost in rotate. */
9350
        a = (byte)(z8[3] >> 24);
9351
9352
        /* Rotate Z by 8-bits */
9353
        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
9354
        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
9355
        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
9356
        z8[0] <<= 8;
9357
9358
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9359
        z8[0] ^= (word32)R[16 + (a & 0xf)];
9360
9361
        xi >>= 4;
9362
        /* XOR in next significant nibble (XORed with H) * remainder */
9363
        m8 = (word32*)m[xi];
9364
        a ^= (byte)(m8[3] >> 20);
9365
        z8[0] ^= (word32)R[a >> 4];
9366
9367
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9368
        m8 = (word32*)m[16 + xi];
9369
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
9370
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
9371
    }
9372
9373
    xi = x[0];
9374
9375
    /* XOR in most significant nibble * H */
9376
    m8 = (word32*)m[xi & 0xf];
9377
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9378
9379
    /* Cache top byte for remainder calculations - lost in rotate. */
9380
    a = (z8[3] >> 24) & 0xf;
9381
9382
    /* Rotate z by 4-bits */
9383
    n7 = z8[3] & 0xf0f0f0f0ULL;
9384
    n6 = z8[3] & 0x0f0f0f0fULL;
9385
    n5 = z8[2] & 0xf0f0f0f0ULL;
9386
    n4 = z8[2] & 0x0f0f0f0fULL;
9387
    n3 = z8[1] & 0xf0f0f0f0ULL;
9388
    n2 = z8[1] & 0x0f0f0f0fULL;
9389
    n1 = z8[0] & 0xf0f0f0f0ULL;
9390
    n0 = z8[0] & 0x0f0f0f0fULL;
9391
    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
9392
    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
9393
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
9394
    z8[0] = (n1 >> 4) | (n0 << 12);
9395
9396
    /* XOR in most significant nibble * remainder */
9397
    z8[0] ^= (word32)R[a];
9398
    /* XOR in next significant nibble * H */
9399
    m8 = (word32*)m[xi >> 4];
9400
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9401
9402
    /* Write back result. */
9403
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
9404
}
9405
#elif defined(WC_64BIT_CPU) && defined(BIG_ENDIAN_ORDER)
9406
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9407
{
9408
    int i;
9409
    word64 z8[2] = {0, 0};
9410
    byte a;
9411
    word64* x8 = (word64*)x;
9412
    word64* m8;
9413
    byte xi;
9414
9415
    for (i = 15; i > 0; i--) {
9416
        xi = x[i];
9417
9418
        /* XOR in (msn * H) */
9419
        m8 = (word64*)m[xi & 0xf];
9420
        z8[0] ^= m8[0];
9421
        z8[1] ^= m8[1];
9422
9423
        /* Cache top byte for remainder calculations - lost in rotate. */
9424
        a = (byte)(z8[1] & 0xff);
9425
9426
        /* Rotate Z by 8-bits */
9427
        z8[1] = (z8[0] << 56) | (z8[1] >> 8);
9428
        z8[0] >>= 8;
9429
9430
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9431
        m8 = (word64*)m[16 + (xi >> 4)];
9432
        z8[0] ^= m8[0];
9433
        z8[1] ^= m8[1];
9434
9435
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9436
        z8[0] ^= ((word64)R[16 + (a & 0xf)]) << 48;
9437
        /* XOR in next significant nibble (XORed with H) * remainder */
9438
        m8 = (word64*)m[xi >> 4];
9439
        a ^= (byte)(m8[1] >> 12) & 0xf;
9440
        a ^= (byte)((m8[1] << 4) & 0xf0);
9441
        z8[0] ^= ((word64)R[a >> 4]) << 48;
9442
    }
9443
9444
    xi = x[0];
9445
9446
    /* XOR in most significant nibble * H */
9447
    m8 = (word64*)m[xi & 0xf];
9448
    z8[0] ^= m8[0];
9449
    z8[1] ^= m8[1];
9450
9451
    /* Cache top byte for remainder calculations - lost in rotate. */
9452
    a = (byte)(z8[1] & 0x0f);
9453
9454
    /* Rotate z by 4-bits */
9455
    z8[1] = (z8[0] << 60) | (z8[1] >> 4);
9456
    z8[0] >>= 4;
9457
9458
    /* XOR in next significant nibble * H */
9459
    m8 = (word64*)m[xi >> 4];
9460
    z8[0] ^= m8[0];
9461
    z8[1] ^= m8[1];
9462
    /* XOR in most significant nibble * remainder */
9463
    z8[0] ^= ((word64)R[a]) << 48;
9464
9465
    /* Write back result. */
9466
    x8[0] = z8[0];
9467
    x8[1] = z8[1];
9468
}
9469
#else
9470
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9471
46.4k
{
9472
46.4k
    int i;
9473
46.4k
    word64 z8[2] = {0, 0};
9474
46.4k
    byte a;
9475
46.4k
    word64* x8 = (word64*)x;
9476
46.4k
    word64* m8;
9477
46.4k
    word64 n0, n1, n2, n3;
9478
46.4k
    byte xi;
9479
9480
743k
    for (i = 15; i > 0; i--) {
9481
697k
        xi = x[i];
9482
9483
        /* XOR in (msn * H) */
9484
697k
        m8 = (word64*)m[xi & 0xf];
9485
697k
        z8[0] ^= m8[0];
9486
697k
        z8[1] ^= m8[1];
9487
9488
        /* Cache top byte for remainder calculations - lost in rotate. */
9489
697k
        a = (byte)(z8[1] >> 56);
9490
9491
        /* Rotate Z by 8-bits */
9492
697k
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
9493
697k
        z8[0] <<= 8;
9494
9495
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9496
697k
        m8 = (word64*)m[16 + (xi >> 4)];
9497
697k
        z8[0] ^= m8[0];
9498
697k
        z8[1] ^= m8[1];
9499
9500
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9501
697k
        z8[0] ^= (word64)R[16 + (a & 0xf)];
9502
        /* XOR in next significant nibble (XORed with H) * remainder */
9503
697k
        m8 = (word64*)m[xi >> 4];
9504
697k
        a ^= (byte)(m8[1] >> 52);
9505
697k
        z8[0] ^= (word64)R[a >> 4];
9506
697k
    }
9507
9508
46.4k
    xi = x[0];
9509
9510
    /* XOR in most significant nibble * H */
9511
46.4k
    m8 = (word64*)m[xi & 0xf];
9512
46.4k
    z8[0] ^= m8[0];
9513
46.4k
    z8[1] ^= m8[1];
9514
9515
    /* Cache top byte for remainder calculations - lost in rotate. */
9516
46.4k
    a = (z8[1] >> 56) & 0xf;
9517
9518
    /* Rotate z by 4-bits */
9519
46.4k
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
9520
46.4k
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
9521
46.4k
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
9522
46.4k
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
9523
46.4k
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
9524
46.4k
    z8[0] = (n1 >> 4) | (n0 << 12);
9525
9526
    /* XOR in next significant nibble * H */
9527
46.4k
    m8 = (word64*)m[xi >> 4];
9528
46.4k
    z8[0] ^= m8[0];
9529
46.4k
    z8[1] ^= m8[1];
9530
    /* XOR in most significant nibble * remainder */
9531
46.4k
    z8[0] ^= (word64)R[a];
9532
9533
    /* Write back result. */
9534
46.4k
    x8[0] = z8[0];
9535
46.4k
    x8[1] = z8[1];
9536
46.4k
}
9537
#endif
9538
#endif
9539
9540
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9541
    word32 cSz, byte* s, word32 sSz)
9542
727
{
9543
727
    byte x[WC_AES_BLOCK_SIZE];
9544
727
    byte scratch[WC_AES_BLOCK_SIZE];
9545
727
    word32 blocks, partial;
9546
9547
727
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9548
9549
    /* Hash in A, the Additional Authentication Data */
9550
727
    if (aSz != 0 && a != NULL) {
9551
727
        blocks = aSz / WC_AES_BLOCK_SIZE;
9552
727
        partial = aSz % WC_AES_BLOCK_SIZE;
9553
    #ifdef GCM_GMULT_LEN
9554
        if (blocks > 0) {
9555
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
9556
            a += blocks * WC_AES_BLOCK_SIZE;
9557
        }
9558
        if (partial != 0) {
9559
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9560
            XMEMCPY(scratch, a, partial);
9561
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9562
        }
9563
    #else
9564
727
        while (blocks--) {
9565
0
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
9566
0
            GMULT(x, gcm->M0);
9567
0
            a += WC_AES_BLOCK_SIZE;
9568
0
        }
9569
727
        if (partial != 0) {
9570
727
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9571
727
            XMEMCPY(scratch, a, partial);
9572
727
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9573
727
            GMULT(x, gcm->M0);
9574
727
        }
9575
727
    #endif
9576
727
    }
9577
9578
    /* Hash in C, the Ciphertext */
9579
727
    if (cSz != 0 && c != NULL) {
9580
723
        blocks = cSz / WC_AES_BLOCK_SIZE;
9581
723
        partial = cSz % WC_AES_BLOCK_SIZE;
9582
    #ifdef GCM_GMULT_LEN
9583
        if (blocks > 0) {
9584
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
9585
            c += blocks * WC_AES_BLOCK_SIZE;
9586
        }
9587
        if (partial != 0) {
9588
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9589
            XMEMCPY(scratch, c, partial);
9590
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9591
        }
9592
    #else
9593
28.9k
        while (blocks--) {
9594
28.2k
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
9595
28.2k
            GMULT(x, gcm->M0);
9596
28.2k
            c += WC_AES_BLOCK_SIZE;
9597
28.2k
        }
9598
723
        if (partial != 0) {
9599
588
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9600
588
            XMEMCPY(scratch, c, partial);
9601
588
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9602
588
            GMULT(x, gcm->M0);
9603
588
        }
9604
723
    #endif
9605
723
    }
9606
9607
    /* Hash in the lengths of A and C in bits */
9608
727
    FlattenSzInBits(&scratch[0], aSz);
9609
727
    FlattenSzInBits(&scratch[8], cSz);
9610
#ifdef GCM_GMULT_LEN
9611
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9612
#else
9613
727
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9614
727
    GMULT(x, gcm->M0);
9615
727
#endif
9616
9617
    /* Copy the result into s. */
9618
727
    XMEMCPY(s, x, sSz);
9619
727
}
9620
9621
#ifdef WOLFSSL_AESGCM_STREAM
9622
/* No extra initialization for 4-bit table implementation.
9623
 *
9624
 * @param [in] aes  AES GCM object.
9625
 */
9626
1.42k
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9627
9628
#ifdef GCM_GMULT_LEN
9629
/* GHASH one block of data.
9630
 *
9631
 * @param [in, out] aes    AES GCM object.
9632
 * @param [in]      block  Block of AAD or cipher text.
9633
 */
9634
#define GHASH_ONE_BLOCK_SW(aes, block)                                  \
9635
   GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
9636
#else
9637
/* GHASH one block of data.
9638
 *
9639
 * XOR block into tag and GMULT with H using pre-computed table.
9640
 *
9641
 * @param [in, out] aes    AES GCM object.
9642
 * @param [in]      block  Block of AAD or cipher text.
9643
 */
9644
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9645
16.1k
    do {                                                \
9646
16.1k
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
9647
16.1k
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
9648
16.1k
    }                                                   \
9649
16.1k
    while (0)
9650
#endif
9651
#endif /* WOLFSSL_AESGCM_STREAM */
9652
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
9653
9654
#if !defined(FREESCALE_LTC_AES_GCM)
9655
static void GMULT(word64* X, word64* Y)
9656
{
9657
    word64 Z[2] = {0,0};
9658
    word64 V[2];
9659
    int i, j;
9660
    word64 v1;
9661
    V[0] = X[0];  V[1] = X[1];
9662
9663
    for (i = 0; i < 2; i++)
9664
    {
9665
        word64 y = Y[i];
9666
        for (j = 0; j < 64; j++)
9667
        {
9668
#ifndef AES_GCM_GMULT_NCT
9669
            word64 mask = 0 - (y >> 63);
9670
            Z[0] ^= V[0] & mask;
9671
            Z[1] ^= V[1] & mask;
9672
#else
9673
            if (y & 0x8000000000000000ULL) {
9674
                Z[0] ^= V[0];
9675
                Z[1] ^= V[1];
9676
            }
9677
#endif
9678
9679
            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
9680
            V[1] >>= 1;
9681
            V[1] |= V[0] << 63;
9682
            V[0] >>= 1;
9683
            V[0] ^= v1;
9684
            y <<= 1;
9685
        }
9686
    }
9687
    X[0] = Z[0];
9688
    X[1] = Z[1];
9689
}
9690
9691
9692
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9693
    word32 cSz, byte* s, word32 sSz)
9694
{
9695
    word64 x[2] = {0,0};
9696
    word32 blocks, partial;
9697
    word64 bigH[2];
9698
9699
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
9700
    #ifdef LITTLE_ENDIAN_ORDER
9701
        ByteReverseWords64(bigH, bigH, WC_AES_BLOCK_SIZE);
9702
    #endif
9703
9704
    /* Hash in A, the Additional Authentication Data */
9705
    if (aSz != 0 && a != NULL) {
9706
        word64 bigA[2];
9707
        blocks = aSz / WC_AES_BLOCK_SIZE;
9708
        partial = aSz % WC_AES_BLOCK_SIZE;
9709
        while (blocks--) {
9710
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
9711
            #ifdef LITTLE_ENDIAN_ORDER
9712
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
9713
            #endif
9714
            x[0] ^= bigA[0];
9715
            x[1] ^= bigA[1];
9716
            GMULT(x, bigH);
9717
            a += WC_AES_BLOCK_SIZE;
9718
        }
9719
        if (partial != 0) {
9720
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
9721
            XMEMCPY(bigA, a, partial);
9722
            #ifdef LITTLE_ENDIAN_ORDER
9723
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
9724
            #endif
9725
            x[0] ^= bigA[0];
9726
            x[1] ^= bigA[1];
9727
            GMULT(x, bigH);
9728
        }
9729
#ifdef OPENSSL_EXTRA
9730
        /* store AAD partial tag for next call */
9731
        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
9732
        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
9733
        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
9734
        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
9735
#endif
9736
    }
9737
9738
    /* Hash in C, the Ciphertext */
9739
    if (cSz != 0 && c != NULL) {
9740
        word64 bigC[2];
9741
        blocks = cSz / WC_AES_BLOCK_SIZE;
9742
        partial = cSz % WC_AES_BLOCK_SIZE;
9743
#ifdef OPENSSL_EXTRA
9744
        /* Start from last AAD partial tag */
9745
        if(gcm->aadLen) {
9746
            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
9747
            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
9748
         }
9749
#endif
9750
        while (blocks--) {
9751
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
9752
            #ifdef LITTLE_ENDIAN_ORDER
9753
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
9754
            #endif
9755
            x[0] ^= bigC[0];
9756
            x[1] ^= bigC[1];
9757
            GMULT(x, bigH);
9758
            c += WC_AES_BLOCK_SIZE;
9759
        }
9760
        if (partial != 0) {
9761
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
9762
            XMEMCPY(bigC, c, partial);
9763
            #ifdef LITTLE_ENDIAN_ORDER
9764
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
9765
            #endif
9766
            x[0] ^= bigC[0];
9767
            x[1] ^= bigC[1];
9768
            GMULT(x, bigH);
9769
        }
9770
    }
9771
9772
    /* Hash in the lengths in bits of A and C */
9773
    {
9774
        word64 len[2];
9775
        len[0] = aSz; len[1] = cSz;
9776
#ifdef OPENSSL_EXTRA
9777
        if (gcm->aadLen)
9778
            len[0] = (word64)gcm->aadLen;
9779
#endif
9780
        /* Lengths are in bytes. Convert to bits. */
9781
        len[0] *= 8;
9782
        len[1] *= 8;
9783
9784
        x[0] ^= len[0];
9785
        x[1] ^= len[1];
9786
        GMULT(x, bigH);
9787
    }
9788
    #ifdef LITTLE_ENDIAN_ORDER
9789
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
9790
    #endif
9791
    XMEMCPY(s, x, sSz);
9792
}
9793
#endif /* !FREESCALE_LTC_AES_GCM */
9794
9795
#ifdef WOLFSSL_AESGCM_STREAM
9796
9797
#ifdef LITTLE_ENDIAN_ORDER
9798
9799
/* No extra initialization for small implementation.
9800
 *
9801
 * @param [in] aes  AES GCM object.
9802
 */
9803
#define GHASH_INIT_EXTRA(aes)                                               \
9804
    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, WC_AES_BLOCK_SIZE)
9805
9806
/* GHASH one block of data..
9807
 *
9808
 * XOR block into tag and GMULT with H.
9809
 *
9810
 * @param [in, out] aes    AES GCM object.
9811
 * @param [in]      block  Block of AAD or cipher text.
9812
 */
9813
#define GHASH_ONE_BLOCK_SW(aes, block)                              \
9814
    do {                                                            \
9815
        word64* x = (word64*)AES_TAG(aes);                          \
9816
        word64* h = (word64*)aes->gcm.H;                            \
9817
        word64 block64[2];                                          \
9818
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);                 \
9819
        ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE);    \
9820
        x[0] ^= block64[0];                                         \
9821
        x[1] ^= block64[1];                                         \
9822
        GMULT(x, h);                                                \
9823
    }                                                               \
9824
    while (0)
9825
9826
#ifdef OPENSSL_EXTRA
9827
/* GHASH in AAD and cipher text lengths in bits.
9828
 *
9829
 * Convert tag back to little-endian.
9830
 *
9831
 * @param [in, out] aes  AES GCM object.
9832
 */
9833
#define GHASH_LEN_BLOCK(aes)                            \
9834
    do {                                                \
9835
        word64* x = (word64*)AES_TAG(aes);              \
9836
        word64* h = (word64*)aes->gcm.H;                \
9837
        word64 len[2];                                  \
9838
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9839
        if (aes->gcm.aadLen)                            \
9840
            len[0] = (word64)aes->gcm.aadLen;           \
9841
        /* Lengths are in bytes. Convert to bits. */    \
9842
        len[0] *= 8;                                    \
9843
        len[1] *= 8;                                    \
9844
                                                        \
9845
        x[0] ^= len[0];                                 \
9846
        x[1] ^= len[1];                                 \
9847
        GMULT(x, h);                                    \
9848
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
9849
    }                                                   \
9850
    while (0)
9851
#else
9852
/* GHASH in AAD and cipher text lengths in bits.
9853
 *
9854
 * Convert tag back to little-endian.
9855
 *
9856
 * @param [in, out] aes  AES GCM object.
9857
 */
9858
#define GHASH_LEN_BLOCK(aes)                            \
9859
    do {                                                \
9860
        word64* x = (word64*)AES_TAG(aes);              \
9861
        word64* h = (word64*)aes->gcm.H;                \
9862
        word64 len[2];                                  \
9863
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9864
        /* Lengths are in bytes. Convert to bits. */    \
9865
        len[0] *= 8;                                    \
9866
        len[1] *= 8;                                    \
9867
                                                        \
9868
        x[0] ^= len[0];                                 \
9869
        x[1] ^= len[1];                                 \
9870
        GMULT(x, h);                                    \
9871
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
9872
    }                                                   \
9873
    while (0)
9874
#endif
9875
9876
#else
9877
9878
/* No extra initialization for small implementation.
9879
 *
9880
 * @param [in] aes  AES GCM object.
9881
 */
9882
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9883
9884
/* GHASH one block of data..
9885
 *
9886
 * XOR block into tag and GMULT with H.
9887
 *
9888
 * @param [in, out] aes    AES GCM object.
9889
 * @param [in]      block  Block of AAD or cipher text.
9890
 */
9891
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9892
    do {                                                \
9893
        word64* x = (word64*)AES_TAG(aes);              \
9894
        word64* h = (word64*)aes->gcm.H;                \
9895
        word64 block64[2];                              \
9896
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);        \
9897
        x[0] ^= block64[0];                             \
9898
        x[1] ^= block64[1];                             \
9899
        GMULT(x, h);                                    \
9900
    }                                                   \
9901
    while (0)
9902
9903
#ifdef OPENSSL_EXTRA
9904
/* GHASH in AAD and cipher text lengths in bits.
9905
 *
9906
 * Convert tag back to little-endian.
9907
 *
9908
 * @param [in, out] aes  AES GCM object.
9909
 */
9910
#define GHASH_LEN_BLOCK(aes)                            \
9911
    do {                                                \
9912
        word64* x = (word64*)AES_TAG(aes);              \
9913
        word64* h = (word64*)aes->gcm.H;                \
9914
        word64 len[2];                                  \
9915
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9916
        if (aes->gcm.aadLen)                            \
9917
            len[0] = (word64)aes->gcm.aadLen;           \
9918
        /* Lengths are in bytes. Convert to bits. */    \
9919
        len[0] *= 8;                                    \
9920
        len[1] *= 8;                                    \
9921
                                                        \
9922
        x[0] ^= len[0];                                 \
9923
        x[1] ^= len[1];                                 \
9924
        GMULT(x, h);                                    \
9925
    }                                                   \
9926
    while (0)
9927
#else
9928
/* GHASH in AAD and cipher text lengths in bits.
9929
 *
9930
 * Convert tag back to little-endian.
9931
 *
9932
 * @param [in, out] aes  AES GCM object.
9933
 */
9934
#define GHASH_LEN_BLOCK(aes)                            \
9935
    do {                                                \
9936
        word64* x = (word64*)AES_TAG(aes);              \
9937
        word64* h = (word64*)aes->gcm.H;                \
9938
        word64 len[2];                                  \
9939
        len[0] = aes->aSz; len[1] = aes->cSz;           \
9940
        /* Lengths are in bytes. Convert to bits. */    \
9941
        len[0] *= 8;                                    \
9942
        len[1] *= 8;                                    \
9943
                                                        \
9944
        x[0] ^= len[0];                                 \
9945
        x[1] ^= len[1];                                 \
9946
        GMULT(x, h);                                    \
9947
    }                                                   \
9948
    while (0)
9949
#endif
9950
9951
#endif /* !LITTLE_ENDIAN_ORDER */
9952
9953
#endif /* WOLFSSL_AESGCM_STREAM */
9954
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
9955
#else /* GCM_WORD32 */
9956
9957
static void GMULT(word32* X, word32* Y)
9958
{
9959
    word32 Z[4] = {0,0,0,0};
9960
    word32 V[4];
9961
    int i, j;
9962
9963
    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
9964
9965
    for (i = 0; i < 4; i++)
9966
    {
9967
        word32 y = Y[i];
9968
        for (j = 0; j < 32; j++)
9969
        {
9970
            if (y & 0x80000000) {
9971
                Z[0] ^= V[0];
9972
                Z[1] ^= V[1];
9973
                Z[2] ^= V[2];
9974
                Z[3] ^= V[3];
9975
            }
9976
9977
            if (V[3] & 0x00000001) {
9978
                V[3] >>= 1;
9979
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
9980
                V[2] >>= 1;
9981
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
9982
                V[1] >>= 1;
9983
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
9984
                V[0] >>= 1;
9985
                V[0] ^= 0xE1000000;
9986
            } else {
9987
                V[3] >>= 1;
9988
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
9989
                V[2] >>= 1;
9990
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
9991
                V[1] >>= 1;
9992
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
9993
                V[0] >>= 1;
9994
            }
9995
            y <<= 1;
9996
        }
9997
    }
9998
    X[0] = Z[0];
9999
    X[1] = Z[1];
10000
    X[2] = Z[2];
10001
    X[3] = Z[3];
10002
}
10003
10004
10005
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
10006
    word32 cSz, byte* s, word32 sSz)
10007
{
10008
    word32 x[4] = {0,0,0,0};
10009
    word32 blocks, partial;
10010
    word32 bigH[4];
10011
10012
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
10013
    #ifdef LITTLE_ENDIAN_ORDER
10014
        ByteReverseWords(bigH, bigH, WC_AES_BLOCK_SIZE);
10015
    #endif
10016
10017
    /* Hash in A, the Additional Authentication Data */
10018
    if (aSz != 0 && a != NULL) {
10019
        word32 bigA[4];
10020
        blocks = aSz / WC_AES_BLOCK_SIZE;
10021
        partial = aSz % WC_AES_BLOCK_SIZE;
10022
        while (blocks--) {
10023
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
10024
            #ifdef LITTLE_ENDIAN_ORDER
10025
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
10026
            #endif
10027
            x[0] ^= bigA[0];
10028
            x[1] ^= bigA[1];
10029
            x[2] ^= bigA[2];
10030
            x[3] ^= bigA[3];
10031
            GMULT(x, bigH);
10032
            a += WC_AES_BLOCK_SIZE;
10033
        }
10034
        if (partial != 0) {
10035
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
10036
            XMEMCPY(bigA, a, partial);
10037
            #ifdef LITTLE_ENDIAN_ORDER
10038
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
10039
            #endif
10040
            x[0] ^= bigA[0];
10041
            x[1] ^= bigA[1];
10042
            x[2] ^= bigA[2];
10043
            x[3] ^= bigA[3];
10044
            GMULT(x, bigH);
10045
        }
10046
    }
10047
10048
    /* Hash in C, the Ciphertext */
10049
    if (cSz != 0 && c != NULL) {
10050
        word32 bigC[4];
10051
        blocks = cSz / WC_AES_BLOCK_SIZE;
10052
        partial = cSz % WC_AES_BLOCK_SIZE;
10053
        while (blocks--) {
10054
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
10055
            #ifdef LITTLE_ENDIAN_ORDER
10056
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
10057
            #endif
10058
            x[0] ^= bigC[0];
10059
            x[1] ^= bigC[1];
10060
            x[2] ^= bigC[2];
10061
            x[3] ^= bigC[3];
10062
            GMULT(x, bigH);
10063
            c += WC_AES_BLOCK_SIZE;
10064
        }
10065
        if (partial != 0) {
10066
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
10067
            XMEMCPY(bigC, c, partial);
10068
            #ifdef LITTLE_ENDIAN_ORDER
10069
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
10070
            #endif
10071
            x[0] ^= bigC[0];
10072
            x[1] ^= bigC[1];
10073
            x[2] ^= bigC[2];
10074
            x[3] ^= bigC[3];
10075
            GMULT(x, bigH);
10076
        }
10077
    }
10078
10079
    /* Hash in the lengths in bits of A and C */
10080
    {
10081
        word32 len[4];
10082
10083
        /* Lengths are in bytes. Convert to bits. */
10084
        len[0] = (aSz >> (8*sizeof(aSz) - 3));
10085
        len[1] = aSz << 3;
10086
        len[2] = (cSz >> (8*sizeof(cSz) - 3));
10087
        len[3] = cSz << 3;
10088
10089
        x[0] ^= len[0];
10090
        x[1] ^= len[1];
10091
        x[2] ^= len[2];
10092
        x[3] ^= len[3];
10093
        GMULT(x, bigH);
10094
    }
10095
    #ifdef LITTLE_ENDIAN_ORDER
10096
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
10097
    #endif
10098
    XMEMCPY(s, x, sSz);
10099
}
10100
10101
#ifdef WOLFSSL_AESGCM_STREAM
10102
#ifdef LITTLE_ENDIAN_ORDER
10103
/* Little-endian 32-bit word implementation requires byte reversal of H.
10104
 *
10105
 * H is all-zeros block encrypted with key.
10106
 *
10107
 * @param [in, out] aes  AES GCM object.
10108
 */
10109
#define GHASH_INIT_EXTRA(aes) \
10110
    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, WC_AES_BLOCK_SIZE)
10111
10112
/* GHASH one block of data..
10113
 *
10114
 * XOR block, in big-endian form, into tag and GMULT with H.
10115
 *
10116
 * @param [in, out] aes    AES GCM object.
10117
 * @param [in]      block  Block of AAD or cipher text.
10118
 */
10119
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
10120
    do {                                                        \
10121
        word32* x = (word32*)AES_TAG(aes);                      \
10122
        word32* h = (word32*)aes->gcm.H;                        \
10123
        word32 bigEnd[4];                                       \
10124
        XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE);              \
10125
        ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE);    \
10126
        x[0] ^= bigEnd[0];                                      \
10127
        x[1] ^= bigEnd[1];                                      \
10128
        x[2] ^= bigEnd[2];                                      \
10129
        x[3] ^= bigEnd[3];                                      \
10130
        GMULT(x, h);                                            \
10131
    }                                                           \
10132
    while (0)
10133
10134
/* GHASH in AAD and cipher text lengths in bits.
10135
 *
10136
 * Convert tag back to little-endian.
10137
 *
10138
 * @param [in, out] aes  AES GCM object.
10139
 */
10140
#define GHASH_LEN_BLOCK(aes)                                \
10141
    do {                                                    \
10142
        word32 len[4];                                      \
10143
        word32* x = (word32*)AES_TAG(aes);                  \
10144
        word32* h = (word32*)aes->gcm.H;                    \
10145
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
10146
        len[1] = aes->aSz << 3;                             \
10147
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
10148
        len[3] = aes->cSz << 3;                             \
10149
        x[0] ^= len[0];                                     \
10150
        x[1] ^= len[1];                                     \
10151
        x[2] ^= len[2];                                     \
10152
        x[3] ^= len[3];                                     \
10153
        GMULT(x, h);                                        \
10154
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);          \
10155
    }                                                       \
10156
    while (0)
10157
#else
10158
/* No extra initialization for 32-bit word implementation.
10159
 *
10160
 * @param [in] aes  AES GCM object.
10161
 */
10162
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
10163
10164
/* GHASH one block of data..
10165
 *
10166
 * XOR block into tag and GMULT with H.
10167
 *
10168
 * @param [in, out] aes    AES GCM object.
10169
 * @param [in]      block  Block of AAD or cipher text.
10170
 */
10171
#define GHASH_ONE_BLOCK_SW(aes, block)                      \
10172
    do {                                                    \
10173
        word32* x = (word32*)AES_TAG(aes);                  \
10174
        word32* h = (word32*)aes->gcm.H;                    \
10175
        word32 block32[4];                                  \
10176
        XMEMCPY(block32, block, WC_AES_BLOCK_SIZE);         \
10177
        x[0] ^= block32[0];                                 \
10178
        x[1] ^= block32[1];                                 \
10179
        x[2] ^= block32[2];                                 \
10180
        x[3] ^= block32[3];                                 \
10181
        GMULT(x, h);                                        \
10182
    }                                                       \
10183
    while (0)
10184
10185
/* GHASH in AAD and cipher text lengths in bits.
10186
 *
10187
 * @param [in, out] aes  AES GCM object.
10188
 */
10189
#define GHASH_LEN_BLOCK(aes)                                \
10190
    do {                                                    \
10191
        word32 len[4];                                      \
10192
        word32* x = (word32*)AES_TAG(aes);                  \
10193
        word32* h = (word32*)aes->gcm.H;                    \
10194
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
10195
        len[1] = aes->aSz << 3;                             \
10196
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
10197
        len[3] = aes->cSz << 3;                             \
10198
        x[0] ^= len[0];                                     \
10199
        x[1] ^= len[1];                                     \
10200
        x[2] ^= len[2];                                     \
10201
        x[3] ^= len[3];                                     \
10202
        GMULT(x, h);                                        \
10203
    }                                                       \
10204
    while (0)
10205
#endif /* LITTLE_ENDIAN_ORDER */
10206
#endif /* WOLFSSL_AESGCM_STREAM */
10207
#endif /* end GCM_WORD32 */
10208
#endif
10209
10210
#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
10211
#ifdef WOLFSSL_AESGCM_STREAM
10212
#ifndef GHASH_LEN_BLOCK
10213
/* Hash in the lengths of the AAD and cipher text in bits.
10214
 *
10215
 * Default implementation.
10216
 *
10217
 * @param [in, out] aes  AES GCM object.
10218
 */
10219
#define GHASH_LEN_BLOCK(aes)                      \
10220
358
    do {                                          \
10221
358
        byte scratch[WC_AES_BLOCK_SIZE];          \
10222
358
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
10223
358
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
10224
358
        GHASH_ONE_BLOCK(aes, scratch);            \
10225
358
    }                                             \
10226
358
    while (0)
10227
#endif
10228
10229
/* Initialize a GHASH for streaming operations.
10230
 *
10231
 * @param [in, out] aes  AES GCM object.
10232
 */
10233
1.07k
static void GHASH_INIT(Aes* aes) {
10234
    /* Set tag to all zeros as initial value. */
10235
1.07k
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
10236
    /* Reset counts of AAD and cipher text. */
10237
1.07k
    aes->aOver = 0;
10238
1.07k
    aes->cOver = 0;
10239
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10240
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10241
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10242
        ; /* Don't do extra initialization. */
10243
    }
10244
    else
10245
#endif
10246
1.07k
    {
10247
        /* Extra initialization based on implementation. */
10248
1.07k
        GHASH_INIT_EXTRA(aes);
10249
1.07k
    }
10250
1.07k
}
10251
10252
/* Update the GHASH with AAD and/or cipher text.
10253
 *
10254
 * @param [in,out] aes   AES GCM object.
10255
 * @param [in]     a     Additional authentication data buffer.
10256
 * @param [in]     aSz   Size of data in AAD buffer.
10257
 * @param [in]     c     Cipher text buffer.
10258
 * @param [in]     cSz   Size of data in cipher text buffer.
10259
 */
10260
static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
10261
    word32 cSz)
10262
6.33k
{
10263
6.33k
    word32 blocks;
10264
6.33k
    word32 partial;
10265
10266
    /* Hash in A, the Additional Authentication Data */
10267
6.33k
    if (aSz != 0 && a != NULL) {
10268
        /* Update count of AAD we have hashed. */
10269
509
        aes->aSz += aSz;
10270
        /* Check if we have unprocessed data. */
10271
509
        if (aes->aOver > 0) {
10272
            /* Calculate amount we can use - fill up the block. */
10273
320
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10274
320
            if (sz > aSz) {
10275
170
                sz = (byte)aSz;
10276
170
            }
10277
            /* Copy extra into last GHASH block array and update count. */
10278
320
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
10279
320
            aes->aOver = (byte)(aes->aOver + sz);
10280
320
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
10281
                /* We have filled up the block and can process. */
10282
150
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10283
                /* Reset count. */
10284
150
                aes->aOver = 0;
10285
150
            }
10286
            /* Used up some data. */
10287
320
            aSz -= sz;
10288
320
            a += sz;
10289
320
        }
10290
10291
        /* Calculate number of blocks of AAD and the leftover. */
10292
509
        blocks = aSz / WC_AES_BLOCK_SIZE;
10293
509
        partial = aSz % WC_AES_BLOCK_SIZE;
10294
        /* GHASH full blocks now. */
10295
4.49k
        while (blocks--) {
10296
3.98k
            GHASH_ONE_BLOCK(aes, a);
10297
3.98k
            a += WC_AES_BLOCK_SIZE;
10298
3.98k
        }
10299
509
        if (partial != 0) {
10300
            /* Cache the partial block. */
10301
310
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
10302
310
            aes->aOver = (byte)partial;
10303
310
        }
10304
509
    }
10305
6.33k
    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
10306
        /* No more AAD coming and we have a partial block. */
10307
        /* Fill the rest of the block with zeros. */
10308
60
        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10309
60
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
10310
        /* GHASH last AAD block. */
10311
60
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10312
        /* Clear partial count for next time through. */
10313
60
        aes->aOver = 0;
10314
60
    }
10315
10316
    /* Hash in C, the Ciphertext */
10317
6.33k
    if (cSz != 0 && c != NULL) {
10318
        /* Update count of cipher text we have hashed. */
10319
675
        aes->cSz += cSz;
10320
675
        if (aes->cOver > 0) {
10321
            /* Calculate amount we can use - fill up the block. */
10322
392
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
10323
392
            if (sz > cSz) {
10324
215
                sz = (byte)cSz;
10325
215
            }
10326
392
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
10327
            /* Update count of unused encrypted counter. */
10328
392
            aes->cOver = (byte)(aes->cOver + sz);
10329
392
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
10330
                /* We have filled up the block and can process. */
10331
177
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10332
                /* Reset count. */
10333
177
                aes->cOver = 0;
10334
177
            }
10335
            /* Used up some data. */
10336
392
            cSz -= sz;
10337
392
            c += sz;
10338
392
        }
10339
10340
        /* Calculate number of blocks of cipher text and the leftover. */
10341
675
        blocks = cSz / WC_AES_BLOCK_SIZE;
10342
675
        partial = cSz % WC_AES_BLOCK_SIZE;
10343
        /* GHASH full blocks now. */
10344
11.8k
        while (blocks--) {
10345
11.2k
            GHASH_ONE_BLOCK(aes, c);
10346
11.2k
            c += WC_AES_BLOCK_SIZE;
10347
11.2k
        }
10348
675
        if (partial != 0) {
10349
            /* Cache the partial block. */
10350
346
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
10351
346
            aes->cOver = (byte)partial;
10352
346
        }
10353
675
    }
10354
6.33k
}
10355
10356
/* Finalize the GHASH calculation.
10357
 *
10358
 * Complete hashing cipher text and hash the AAD and cipher text lengths.
10359
 *
10360
 * @param [in, out] aes  AES GCM object.
10361
 * @param [out]     s    Authentication tag.
10362
 * @param [in]      sSz  Size of authentication tag required.
10363
 */
10364
static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
10365
358
{
10366
    /* AAD block incomplete when > 0 */
10367
358
    byte over = aes->aOver;
10368
10369
358
    if (aes->cOver > 0) {
10370
        /* Cipher text block incomplete. */
10371
150
        over = aes->cOver;
10372
150
    }
10373
358
    if (over > 0) {
10374
        /* Zeroize the unused part of the block. */
10375
248
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
10376
248
            (size_t)WC_AES_BLOCK_SIZE - over);
10377
        /* Hash the last block of cipher text. */
10378
248
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10379
248
    }
10380
    /* Hash in the lengths of AAD and cipher text in bits */
10381
358
    GHASH_LEN_BLOCK(aes);
10382
    /* Copy the result into s. */
10383
358
    XMEMCPY(s, AES_TAG(aes), sSz);
10384
    /* reset aes->gcm.H in case of reuse */
10385
358
    GHASH_INIT_EXTRA(aes);
10386
358
}
10387
#endif /* WOLFSSL_AESGCM_STREAM */
10388
10389
10390
#ifdef FREESCALE_LTC_AES_GCM
10391
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10392
                   const byte* iv, word32 ivSz,
10393
                   byte* authTag, word32 authTagSz,
10394
                   const byte* authIn, word32 authInSz)
10395
{
10396
    status_t status;
10397
    word32 keySize;
10398
10399
    /* argument checks */
10400
    if (aes == NULL || ivSz == 0) {
10401
        return BAD_FUNC_ARG;
10402
    }
10403
10404
    status = wc_local_AesGcmCheckTagSz(authTagSz);
10405
    if (status != 0)
10406
        return status;
10407
10408
    status = wc_AesGetKeySize(aes, &keySize);
10409
    if (status)
10410
        return status;
10411
10412
    status = wolfSSL_CryptHwMutexLock();
10413
    if (status != 0)
10414
        return status;
10415
10416
    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
10417
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
10418
    wolfSSL_CryptHwMutexUnLock();
10419
10420
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
10421
}
10422
10423
#else
10424
10425
#ifdef STM32_CRYPTO_AES_GCM
10426
10427
/* this function supports inline encrypt */
10428
static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
10429
                                  Aes* aes, byte* out, const byte* in, word32 sz,
10430
                                  const byte* iv, word32 ivSz,
10431
                                  byte* authTag, word32 authTagSz,
10432
                                  const byte* authIn, word32 authInSz)
10433
{
10434
    int ret;
10435
#ifdef WOLFSSL_STM32_CUBEMX
10436
    CRYP_HandleTypeDef hcryp;
10437
#else
10438
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
10439
#endif
10440
    word32 keySize;
10441
#ifdef WOLFSSL_STM32_CUBEMX
10442
    int status = HAL_OK;
10443
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10444
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
10445
#else
10446
    int status = SUCCESS;
10447
#endif
10448
    word32 partial = sz % WC_AES_BLOCK_SIZE;
10449
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
10450
    word32 ctrInit[WC_AES_BLOCK_SIZE/sizeof(word32)];
10451
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10452
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10453
    byte* authInPadded = NULL;
10454
    int authPadSz, wasAlloc = 0, useSwGhash = 0;
10455
10456
    ret = wc_AesGetKeySize(aes, &keySize);
10457
    if (ret != 0)
10458
        return ret;
10459
10460
#ifdef WOLFSSL_STM32_CUBEMX
10461
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
10462
    if (ret != 0)
10463
        return ret;
10464
#endif
10465
10466
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
10467
    if (ivSz == GCM_NONCE_MID_SZ) {
10468
        byte* pCtr = (byte*)ctr;
10469
        XMEMCPY(ctr, iv, ivSz);
10470
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
10471
    }
10472
    else {
10473
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
10474
    }
10475
    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
10476
10477
    /* Authentication buffer */
10478
#if STM_CRYPT_HEADER_WIDTH == 1
10479
    authPadSz = 0; /* CubeHAL supports byte mode */
10480
#else
10481
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
10482
#endif
10483
#ifdef WOLFSSL_STM32MP13
10484
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
10485
     * minimum of 16 bytes for the auth */
10486
    if ((authInSz > 0) && (authInSz < 16)) {
10487
        authPadSz = 16 - authInSz;
10488
    }
10489
#endif
10490
    if (authPadSz != 0) {
10491
        if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) {
10492
            authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
10493
        }
10494
        if (authPadSz <= sizeof(authhdr)) {
10495
            authInPadded = (byte*)authhdr;
10496
        }
10497
        else {
10498
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
10499
                DYNAMIC_TYPE_TMP_BUFFER);
10500
            if (authInPadded == NULL) {
10501
                wolfSSL_CryptHwMutexUnLock();
10502
                return MEMORY_E;
10503
            }
10504
            wasAlloc = 1;
10505
        }
10506
        XMEMSET(authInPadded, 0, authPadSz);
10507
        XMEMCPY(authInPadded, authIn, authInSz);
10508
    } else {
10509
        authPadSz = authInSz;
10510
        authInPadded = (byte*)authIn;
10511
    }
10512
10513
    /* for cases where hardware cannot be used for authTag calculate it */
10514
    /* if IV is not 12 calculate GHASH using software */
10515
    if (ivSz != GCM_NONCE_MID_SZ
10516
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
10517
        /* or hardware that does not support partial block */
10518
        || sz == 0 || partial != 0
10519
    #endif
10520
    #if STM_CRYPT_HEADER_WIDTH == 4
10521
        /* or authIn is not a multiple of 4  */
10522
        || authPadSz != authInSz
10523
    #endif
10524
    ) {
10525
        useSwGhash = 1;
10526
    }
10527
10528
    /* Hardware requires counter + 1 */
10529
    IncrementGcmCounter((byte*)ctr);
10530
10531
    ret = wolfSSL_CryptHwMutexLock();
10532
    if (ret != 0) {
10533
        return ret;
10534
    }
10535
10536
#ifdef WOLFSSL_STM32_CUBEMX
10537
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10538
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
10539
10540
#if defined(STM32_HAL_V2)
10541
    hcryp.Init.Algorithm = CRYP_AES_GCM;
10542
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
10543
    #ifdef CRYP_KEYIVCONFIG_ONCE
10544
    /* allows repeated calls to HAL_CRYP_Encrypt */
10545
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
10546
    #endif
10547
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
10548
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10549
    HAL_CRYP_Init(&hcryp);
10550
10551
    #ifndef CRYP_KEYIVCONFIG_ONCE
10552
    /* GCM payload phase - can handle partial blocks */
10553
    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
10554
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
10555
    #else
10556
    /* GCM payload phase - blocks */
10557
    if (blocks) {
10558
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
10559
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
10560
    }
10561
    /* GCM payload phase - partial remainder */
10562
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10563
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10564
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10565
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
10566
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
10567
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10568
    }
10569
    #endif
10570
    if (status == HAL_OK && !useSwGhash) {
10571
        /* Compute the authTag */
10572
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
10573
            STM32_HAL_TIMEOUT);
10574
    }
10575
#elif defined(STM32_CRYPTO_AES_ONLY)
10576
    /* Set the CRYP parameters */
10577
    hcryp.Init.HeaderSize = authPadSz;
10578
    if (authPadSz == 0)
10579
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
10580
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
10581
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
10582
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
10583
    HAL_CRYP_Init(&hcryp);
10584
10585
    /* GCM init phase */
10586
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10587
    if (status == HAL_OK) {
10588
        /* GCM header phase */
10589
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
10590
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10591
    }
10592
    if (status == HAL_OK) {
10593
        /* GCM payload phase - blocks */
10594
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
10595
        if (blocks) {
10596
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
10597
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10598
        }
10599
    }
10600
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
10601
        /* GCM payload phase - partial remainder */
10602
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10603
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10604
        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
10605
                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
10606
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10607
    }
10608
    if (status == HAL_OK && !useSwGhash) {
10609
        /* GCM final phase */
10610
        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
10611
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
10612
    }
10613
#else
10614
    hcryp.Init.HeaderSize = authPadSz;
10615
    HAL_CRYP_Init(&hcryp);
10616
    if (blocks) {
10617
        /* GCM payload phase - blocks */
10618
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
10619
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10620
    }
10621
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10622
        /* GCM payload phase - partial remainder */
10623
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10624
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10625
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
10626
            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
10627
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10628
    }
10629
    if (status == HAL_OK && !useSwGhash) {
10630
        /* Compute the authTag */
10631
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
10632
    }
10633
#endif
10634
10635
    if (status != HAL_OK)
10636
        ret = AES_GCM_AUTH_E;
10637
    HAL_CRYP_DeInit(&hcryp);
10638
10639
#else /* Standard Peripheral Library */
10640
    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
10641
    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
10642
                         (uint8_t*)keyCopy,      keySize * 8,
10643
                         (uint8_t*)in,           sz,
10644
                         (uint8_t*)authInPadded, authInSz,
10645
                         (uint8_t*)out,          (uint8_t*)tag);
10646
    if (status != SUCCESS)
10647
        ret = AES_GCM_AUTH_E;
10648
#endif /* WOLFSSL_STM32_CUBEMX */
10649
    wolfSSL_CryptHwMutexUnLock();
10650
    wc_Stm32_Aes_Cleanup();
10651
10652
    if (ret == 0) {
10653
        /* return authTag */
10654
        if (authTag) {
10655
            if (useSwGhash) {
10656
                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
10657
                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
10658
                if (ret == 0) {
10659
                    xorbuf(authTag, tag, authTagSz);
10660
                }
10661
            }
10662
            else {
10663
                /* use hardware calculated tag */
10664
                XMEMCPY(authTag, tag, authTagSz);
10665
            }
10666
        }
10667
    }
10668
10669
    /* Free memory */
10670
    if (wasAlloc) {
10671
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
10672
    }
10673
10674
    return ret;
10675
}
10676
10677
#endif /* STM32_CRYPTO_AES_GCM */
10678
10679
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
10680
#ifdef WOLFSSL_AESNI
10681
/* For performance reasons, this code needs to be not inlined. */
10682
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
10683
                      Aes* aes, byte* out, const byte* in, word32 sz,
10684
                      const byte* iv, word32 ivSz,
10685
                      byte* authTag, word32 authTagSz,
10686
                      const byte* authIn, word32 authInSz);
10687
#else
10688
static
10689
#endif
10690
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
10691
                      Aes* aes, byte* out, const byte* in, word32 sz,
10692
                      const byte* iv, word32 ivSz,
10693
                      byte* authTag, word32 authTagSz,
10694
                      const byte* authIn, word32 authInSz)
10695
{
10696
    int ret = 0;
10697
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10698
    word32 partial = sz % WC_AES_BLOCK_SIZE;
10699
    const byte* p = in;
10700
    byte* c = out;
10701
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
10702
    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
10703
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
10704
#ifdef WC_AES_HAVE_PREFETCH_ARG
10705
    int did_prefetches = 0;
10706
#endif
10707
10708
    if (ivSz == GCM_NONCE_MID_SZ) {
10709
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
10710
        XMEMCPY(counter, iv, ivSz);
10711
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
10712
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
10713
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
10714
    }
10715
    else {
10716
        /* Counter is GHASH of IV. */
10717
#ifdef OPENSSL_EXTRA
10718
        word32 aadTemp = aes->gcm.aadLen;
10719
        aes->gcm.aadLen = 0;
10720
#endif
10721
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
10722
#ifdef OPENSSL_EXTRA
10723
        aes->gcm.aadLen = aadTemp;
10724
#endif
10725
    }
10726
    XMEMCPY(initialCounter, counter, WC_AES_BLOCK_SIZE);
10727
10728
#ifdef WOLFSSL_PIC32MZ_CRYPT
10729
    if (blocks) {
10730
        /* use initial IV for HW, but don't use it below */
10731
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
10732
10733
        ret = wc_Pic32AesCrypt(
10734
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
10735
            out, in, (blocks * WC_AES_BLOCK_SIZE),
10736
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
10737
        if (ret != 0)
10738
            return ret;
10739
    }
10740
    /* process remainder using partial handling */
10741
#endif
10742
10743
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
10744
    /* some hardware acceleration can gain performance from doing AES encryption
10745
     * of the whole buffer at once */
10746
    if (c != p && blocks > 0) { /* can not handle inline encryption */
10747
        while (blocks--) {
10748
            IncrementGcmCounter(counter);
10749
            XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
10750
            c += WC_AES_BLOCK_SIZE;
10751
        }
10752
10753
        /* reset number of blocks and then do encryption */
10754
        blocks = sz / WC_AES_BLOCK_SIZE;
10755
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
10756
        xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
10757
        p += WC_AES_BLOCK_SIZE * blocks;
10758
    }
10759
    else
10760
#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
10761
    {
10762
        while (blocks--) {
10763
            IncrementGcmCounter(counter);
10764
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
10765
            ret = AesEncrypt_preFetchOpt(aes, counter, scratch,
10766
                                            &did_prefetches);
10767
            if (ret != 0)
10768
                return ret;
10769
            xorbufout(c, scratch, p, WC_AES_BLOCK_SIZE);
10770
        #endif
10771
            p += WC_AES_BLOCK_SIZE;
10772
            c += WC_AES_BLOCK_SIZE;
10773
        }
10774
    }
10775
10776
    if (partial != 0) {
10777
        IncrementGcmCounter(counter);
10778
        ret = AesEncrypt_preFetchOpt(aes, counter, scratch, &did_prefetches);
10779
        if (ret != 0)
10780
            return ret;
10781
        xorbufout(c, scratch, p, partial);
10782
    }
10783
    if (authTag) {
10784
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
10785
        ret = AesEncrypt_preFetchOpt(aes, initialCounter, scratch,
10786
                                        &did_prefetches);
10787
        if (ret != 0)
10788
            return ret;
10789
        xorbuf(authTag, scratch, authTagSz);
10790
#ifdef OPENSSL_EXTRA
10791
        if (!in && !sz)
10792
            /* store AAD size for next call */
10793
            aes->gcm.aadLen = authInSz;
10794
#endif
10795
    }
10796
10797
    return ret;
10798
}
10799
#elif (defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
10800
      (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
10801
static int AES_GCM_encrypt_ASM(Aes* aes, byte* out, const byte* in,
10802
    word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
10803
    const byte* authIn, word32 authInSz)
10804
{
10805
    word32 blocks;
10806
    word32 partial;
10807
    byte counter[WC_AES_BLOCK_SIZE];
10808
    byte initialCounter[WC_AES_BLOCK_SIZE];
10809
    byte x[WC_AES_BLOCK_SIZE];
10810
    byte scratch[WC_AES_BLOCK_SIZE];
10811
10812
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
10813
    if (ivSz == GCM_NONCE_MID_SZ) {
10814
        XMEMCPY(initialCounter, iv, ivSz);
10815
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
10816
    }
10817
    else {
10818
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
10819
    }
10820
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
10821
10822
    /* Hash in the Additional Authentication Data */
10823
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
10824
    if (authInSz != 0 && authIn != NULL) {
10825
        blocks = authInSz / WC_AES_BLOCK_SIZE;
10826
        partial = authInSz % WC_AES_BLOCK_SIZE;
10827
        if (blocks > 0) {
10828
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
10829
            authIn += blocks * WC_AES_BLOCK_SIZE;
10830
        }
10831
        if (partial != 0) {
10832
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10833
            XMEMCPY(scratch, authIn, partial);
10834
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10835
        }
10836
    }
10837
10838
    /* do as many blocks as possible */
10839
    blocks = sz / WC_AES_BLOCK_SIZE;
10840
    partial = sz % WC_AES_BLOCK_SIZE;
10841
    if (blocks > 0) {
10842
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
10843
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10844
        if (sz >= 32)
10845
    #endif
10846
        {
10847
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
10848
                (const unsigned char*)aes->key, aes->rounds, counter);
10849
        }
10850
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10851
        else
10852
    #endif
10853
    #endif
10854
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10855
        {
10856
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
10857
                (const unsigned char*)aes->key, aes->rounds, counter);
10858
        }
10859
    #endif
10860
        GCM_GMULT_LEN(&aes->gcm, x, out, blocks * WC_AES_BLOCK_SIZE);
10861
        in += blocks * WC_AES_BLOCK_SIZE;
10862
        out += blocks * WC_AES_BLOCK_SIZE;
10863
    }
10864
    /* take care of partial block sizes leftover */
10865
    if (partial != 0) {
10866
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10867
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10868
        {
10869
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
10870
                (const unsigned char*)aes->key, aes->rounds, counter);
10871
        }
10872
    #else
10873
        {
10874
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
10875
                (const unsigned char*)aes->key, aes->rounds, counter);
10876
        }
10877
    #endif
10878
        XMEMCPY(out, scratch, partial);
10879
10880
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10881
        XMEMCPY(scratch, out, partial);
10882
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10883
    }
10884
10885
    /* Hash in the lengths of A and C in bits */
10886
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10887
    FlattenSzInBits(&scratch[0], authInSz);
10888
    FlattenSzInBits(&scratch[8], sz);
10889
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10890
    if (authTagSz > WC_AES_BLOCK_SIZE) {
10891
        XMEMCPY(authTag, x, WC_AES_BLOCK_SIZE);
10892
    }
10893
    else {
10894
        /* authTagSz can be smaller than WC_AES_BLOCK_SIZE */
10895
        XMEMCPY(authTag, x, authTagSz);
10896
    }
10897
10898
    /* Auth tag calculation. */
10899
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10900
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10901
    {
10902
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10903
            (const unsigned char*)aes->key, aes->rounds);
10904
    }
10905
#else
10906
    {
10907
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10908
            (const unsigned char*)aes->key, aes->rounds);
10909
    }
10910
#endif
10911
    xorbuf(authTag, scratch, authTagSz);
10912
10913
    return 0;
10914
}
10915
#endif
10916
10917
#if defined(WOLFSSL_RISCV_ASM)
10918
/* Pointer passed as "H" to the RISC-V GCM asm.  Scalar/vector crypto use the
10919
 * raw hash subkey gcm.H.  Base (software GHASH) uses the precomputed M0 table
10920
 * for GCM_TABLE/GCM_TABLE_4BIT, but gcm.H for the table-free GCM_WORD32/
10921
 * GCM_SMALL builds (which have no M0 member). */
10922
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) || \
10923
    defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
10924
    #define AES_GCM_H_PTR(aes) ((aes)->gcm.H)
10925
#elif defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
10926
    #define AES_GCM_H_PTR(aes) ((byte*)(aes)->gcm.M0)
10927
#else
10928
    #define AES_GCM_H_PTR(aes) ((byte*)(aes)->gcm.H)
10929
#endif
10930
#endif /* WOLFSSL_RISCV_ASM */
10931
10932
/* Software AES - GCM Encrypt */
10933
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10934
                   const byte* iv, word32 ivSz,
10935
                   byte* authTag, word32 authTagSz,
10936
                   const byte* authIn, word32 authInSz)
10937
600
{
10938
600
    int ret;
10939
10940
    /* argument checks */
10941
    /* If sz is non-zero, both in and out must be set; if sz is 0, in and
10942
     * out are don't cares (GMAC case), matching wc_AesGcmDecrypt. */
10943
600
    if (aes == NULL || iv == NULL || ivSz == 0 ||
10944
600
        (sz != 0 && (in == NULL || out == NULL)) ||
10945
600
        authTag == NULL ||
10946
600
        ((authInSz > 0) && (authIn == NULL)))
10947
0
    {
10948
0
        return BAD_FUNC_ARG;
10949
0
    }
10950
10951
600
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
10952
600
    if (ret != 0)
10953
0
        return ret;
10954
10955
600
#ifdef WOLF_CRYPTO_CB
10956
600
    #ifndef WOLF_CRYPTO_CB_FIND
10957
600
    if (aes->devId != INVALID_DEVID)
10958
0
    #endif
10959
0
    {
10960
0
        int crypto_cb_ret =
10961
0
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
10962
0
                                      authTagSz, authIn, authInSz);
10963
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
10964
0
            return crypto_cb_ret;
10965
        /* fall-through when unavailable */
10966
0
    }
10967
600
#endif
10968
10969
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
10970
    /* if async and byte count above threshold */
10971
    /* only 12-byte IV is supported in HW */
10972
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
10973
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
10974
    #if defined(HAVE_CAVIUM)
10975
        #ifdef HAVE_CAVIUM_V
10976
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
10977
            return NitroxAesGcmEncrypt(aes, out, in, sz,
10978
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10979
                authTag, authTagSz, authIn, authInSz);
10980
        }
10981
        #endif
10982
    #elif defined(HAVE_INTEL_QA)
10983
        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
10984
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10985
            authTag, authTagSz, authIn, authInSz);
10986
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
10987
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
10988
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
10989
            sw->aes.aes = aes;
10990
            sw->aes.out = out;
10991
            sw->aes.in = in;
10992
            sw->aes.sz = sz;
10993
            sw->aes.iv = iv;
10994
            sw->aes.ivSz = ivSz;
10995
            sw->aes.authTag = authTag;
10996
            sw->aes.authTagSz = authTagSz;
10997
            sw->aes.authIn = authIn;
10998
            sw->aes.authInSz = authInSz;
10999
            return WC_PENDING_E;
11000
        }
11001
    #endif
11002
    }
11003
#endif /* WOLFSSL_ASYNC_CRYPT */
11004
11005
#ifdef WOLFSSL_SILABS_SE_ACCEL
11006
    return wc_AesGcmEncrypt_silabs(
11007
        aes, out, in, sz,
11008
        iv, ivSz,
11009
        authTag, authTagSz,
11010
        authIn, authInSz);
11011
#endif
11012
11013
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
11014
#ifndef TA_AES_GCM_MAX_DATA_SIZE
11015
    #define TA_AES_GCM_MAX_DATA_SIZE 996u
11016
#endif
11017
    if (aes != NULL &&
11018
        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
11019
        ivSz == TA_AES_GCM_IV_LENGTH &&
11020
        authTagSz == TA_AES_GCM_TAG_LENGTH &&
11021
        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
11022
        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
11023
        return wc_Microchip_AesGcmEncrypt(
11024
            aes, out, in, sz,
11025
            iv, ivSz,
11026
            authTag, authTagSz,
11027
            authIn, authInSz);
11028
    }
11029
#endif
11030
11031
#if defined(WOLFSSL_STM32_BARE) && defined(STM32_CRYPTO)
11032
    ret = wc_Stm32_Aes_Gcm(aes, out, in, sz, iv, ivSz,
11033
                           authTag, authTagSz,
11034
                           authIn, authInSz, 1 /* enc */);
11035
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11036
        return ret;
11037
    /* fall through to SW GCM (still uses HW AES via wc_AesEncrypt) */
11038
#endif /* WOLFSSL_STM32_BARE && STM32_CRYPTO */
11039
11040
11041
#ifdef STM32_CRYPTO_AES_GCM
11042
    return wc_AesGcmEncrypt_STM32(
11043
        aes, out, in, sz, iv, ivSz,
11044
        authTag, authTagSz, authIn, authInSz);
11045
#endif /* STM32_CRYPTO_AES_GCM */
11046
11047
#if defined(WOLFSSL_PSOC6_CRYPTO)
11048
    return wc_Psoc6_Aes_GcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
11049
                                   authTagSz, authIn, authInSz);
11050
#endif /* WOLFSSL_PSOC6_CRYPTO */
11051
11052
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) || \
11053
    defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
11054
    AES_GCM_encrypt_RISCV64(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
11055
        authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
11056
        (int)aes->rounds);
11057
    return 0;
11058
#elif defined(WOLFSSL_RISCV_ASM)
11059
    AES_GCM_encrypt_RISCV64(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
11060
        authInSz, (byte*)aes->key, AES_GCM_H_PTR(aes), (byte*)aes->tmp,
11061
        (byte*)aes->reg, (int)aes->rounds);
11062
    return 0;
11063
#endif
11064
11065
600
    VECTOR_REGISTERS_PUSH;
11066
11067
#if defined(WOLFSSL_ARMASM)
11068
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
11069
#if !defined(__aarch64__)
11070
    AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
11071
        authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
11072
        aes->rounds);
11073
    ret = 0;
11074
#else
11075
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11076
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11077
        if (aes->use_sha3_hw_crypto) {
11078
            AES_GCM_encrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
11079
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11080
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
11081
        }
11082
        else
11083
    #endif
11084
        {
11085
            AES_GCM_encrypt_AARCH64(in, out, sz, iv, ivSz, authTag, authTagSz,
11086
                authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
11087
                (byte*)aes->reg, aes->rounds);
11088
        }
11089
        ret = 0;
11090
    }
11091
    else
11092
#endif /* !__aarch64__ */
11093
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
11094
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11095
    {
11096
        ret = AES_GCM_encrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
11097
            authTagSz, authIn, authInSz);
11098
    }
11099
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
11100
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11101
    ret = AES_GCM_encrypt_ASM(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11102
        authIn, authInSz);
11103
#else
11104
#ifdef WOLFSSL_AESNI
11105
    if (aes->use_aesni) {
11106
#ifdef HAVE_INTEL_AVX512
11107
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11108
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11109
            AES_GCM_encrypt_avx512(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11110
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11111
            ret = 0;
11112
        }
11113
        else
11114
#endif
11115
#ifdef HAVE_INTEL_VAES
11116
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11117
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11118
            AES_GCM_encrypt_vaes(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11119
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11120
            ret = 0;
11121
        }
11122
        else
11123
#endif
11124
#ifdef HAVE_INTEL_AVX2
11125
        if (IS_INTEL_AVX2(intel_flags)) {
11126
            AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11127
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11128
            ret = 0;
11129
        }
11130
        else
11131
#endif
11132
#if defined(HAVE_INTEL_AVX1)
11133
        if (IS_INTEL_AVX1(intel_flags)) {
11134
            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11135
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11136
            ret = 0;
11137
        } else
11138
#endif
11139
        {
11140
            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11141
                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
11142
            ret = 0;
11143
        }
11144
    }
11145
    else
11146
#endif /* WOLFSSL_AESNI */
11147
600
    {
11148
600
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11149
600
                                authIn, authInSz);
11150
600
    }
11151
600
#endif
11152
11153
600
    VECTOR_REGISTERS_POP;
11154
11155
600
    return ret;
11156
600
}
11157
#endif
11158
11159
11160
/* AES GCM Decrypt */
11161
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
11162
#ifdef FREESCALE_LTC_AES_GCM
11163
int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
11164
                   const byte* iv, word32 ivSz,
11165
                   const byte* authTag, word32 authTagSz,
11166
                   const byte* authIn, word32 authInSz)
11167
{
11168
    int ret;
11169
    word32 keySize;
11170
    status_t status;
11171
11172
    /* argument checks */
11173
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
11174
     * in and out are don't cares, as this is is the GMAC case. */
11175
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
11176
        authTag == NULL || ivSz == 0 ||
11177
        ((authInSz > 0) && (authIn == NULL)))
11178
    {
11179
        return BAD_FUNC_ARG;
11180
    }
11181
11182
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
11183
    if (ret != 0)
11184
        return ret;
11185
11186
    ret = wc_AesGetKeySize(aes, &keySize);
11187
    if (ret != 0) {
11188
        return ret;
11189
    }
11190
11191
    status = wolfSSL_CryptHwMutexLock();
11192
    if (status != 0)
11193
        return status;
11194
11195
    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
11196
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
11197
    wolfSSL_CryptHwMutexUnLock();
11198
11199
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
11200
}
11201
11202
#else
11203
11204
#ifdef STM32_CRYPTO_AES_GCM
11205
/* this function supports inline decrypt */
11206
static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
11207
                                  Aes* aes, byte* out,
11208
                                  const byte* in, word32 sz,
11209
                                  const byte* iv, word32 ivSz,
11210
                                  const byte* authTag, word32 authTagSz,
11211
                                  const byte* authIn, word32 authInSz)
11212
{
11213
    int ret;
11214
#ifdef WOLFSSL_STM32_CUBEMX
11215
    int status = HAL_OK;
11216
    CRYP_HandleTypeDef hcryp;
11217
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
11218
#else
11219
    int status = SUCCESS;
11220
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
11221
#endif
11222
    word32 keySize;
11223
    word32 partial = sz % WC_AES_BLOCK_SIZE;
11224
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
11225
    word32 tagExpected[WC_AES_BLOCK_SIZE/sizeof(word32)];
11226
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
11227
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
11228
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
11229
    byte* authInPadded = NULL;
11230
    int authPadSz, wasAlloc = 0, tagComputed = 0;
11231
11232
    ret = wc_AesGetKeySize(aes, &keySize);
11233
    if (ret != 0)
11234
        return ret;
11235
11236
#ifdef WOLFSSL_STM32_CUBEMX
11237
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
11238
    if (ret != 0)
11239
        return ret;
11240
#endif
11241
11242
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
11243
    if (ivSz == GCM_NONCE_MID_SZ) {
11244
        byte* pCtr = (byte*)ctr;
11245
        XMEMCPY(ctr, iv, ivSz);
11246
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
11247
    }
11248
    else {
11249
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
11250
    }
11251
11252
    /* Make copy of expected authTag, which could get corrupted in some
11253
     * Cube HAL versions without proper partial block support.
11254
     * For TLS blocks the authTag is after the output buffer, so save it */
11255
    XMEMCPY(tagExpected, authTag, authTagSz);
11256
11257
    /* Authentication buffer */
11258
#if STM_CRYPT_HEADER_WIDTH == 1
11259
    authPadSz = 0; /* CubeHAL supports byte mode */
11260
#else
11261
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
11262
#endif
11263
#ifdef WOLFSSL_STM32MP13
11264
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
11265
     * minimum of 16 bytes for the auth */
11266
    if ((authInSz > 0) && (authInSz < 16)) {
11267
        authPadSz = 16 - authInSz;
11268
    }
11269
#else
11270
    if (authPadSz != 0) {
11271
        authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
11272
    }
11273
    else {
11274
        authPadSz = authInSz;
11275
    }
11276
#endif
11277
11278
    /* for cases where hardware cannot be used for authTag calculate it */
11279
    /* if IV is not 12 calculate GHASH using software */
11280
    if (ivSz != GCM_NONCE_MID_SZ
11281
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
11282
        /* or hardware that does not support partial block */
11283
        || sz == 0 || partial != 0
11284
    #endif
11285
    #if STM_CRYPT_HEADER_WIDTH == 4
11286
        /* or authIn is not a multiple of 4  */
11287
        || authPadSz != authInSz
11288
    #endif
11289
    ) {
11290
        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
11291
        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
11292
        if (ret != 0)
11293
            return ret;
11294
        xorbuf(tag, partialBlock, sizeof(tag));
11295
        tagComputed = 1;
11296
    }
11297
11298
    /* if using hardware for authentication tag make sure its aligned and zero padded */
11299
    if (authPadSz != authInSz && !tagComputed) {
11300
        if (authPadSz <= sizeof(authhdr)) {
11301
            authInPadded = (byte*)authhdr;
11302
        }
11303
        else {
11304
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
11305
                DYNAMIC_TYPE_TMP_BUFFER);
11306
            if (authInPadded == NULL) {
11307
                wolfSSL_CryptHwMutexUnLock();
11308
                return MEMORY_E;
11309
            }
11310
            wasAlloc = 1;
11311
        }
11312
        XMEMSET(authInPadded, 0, authPadSz);
11313
        XMEMCPY(authInPadded, authIn, authInSz);
11314
    } else {
11315
        authInPadded = (byte*)authIn;
11316
    }
11317
11318
    /* Hardware requires counter + 1 */
11319
    IncrementGcmCounter((byte*)ctr);
11320
11321
    ret = wolfSSL_CryptHwMutexLock();
11322
    if (ret != 0) {
11323
        if (wasAlloc) {
11324
            XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11325
        }
11326
        return ret;
11327
    }
11328
11329
#ifdef WOLFSSL_STM32_CUBEMX
11330
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11331
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
11332
11333
#if defined(STM32_HAL_V2)
11334
    hcryp.Init.Algorithm = CRYP_AES_GCM;
11335
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
11336
    #ifdef CRYP_KEYIVCONFIG_ONCE
11337
    /* allows repeated calls to HAL_CRYP_Decrypt */
11338
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
11339
    #endif
11340
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
11341
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11342
    HAL_CRYP_Init(&hcryp);
11343
11344
    #ifndef CRYP_KEYIVCONFIG_ONCE
11345
    /* GCM payload phase - can handle partial blocks */
11346
    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
11347
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
11348
    #else
11349
    /* GCM payload phase - blocks */
11350
    if (blocks) {
11351
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
11352
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
11353
    }
11354
    /* GCM payload phase - partial remainder */
11355
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11356
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11357
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11358
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
11359
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
11360
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11361
    }
11362
    #endif
11363
    if (status == HAL_OK && !tagComputed) {
11364
        /* Compute the authTag */
11365
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
11366
            STM32_HAL_TIMEOUT);
11367
    }
11368
#elif defined(STM32_CRYPTO_AES_ONLY)
11369
    /* Set the CRYP parameters */
11370
    hcryp.Init.HeaderSize = authPadSz;
11371
    if (authPadSz == 0)
11372
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
11373
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
11374
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
11375
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
11376
    HAL_CRYP_Init(&hcryp);
11377
11378
    /* GCM init phase */
11379
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11380
    if (status == HAL_OK) {
11381
        /* GCM header phase */
11382
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
11383
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11384
    }
11385
    if (status == HAL_OK) {
11386
        /* GCM payload phase - blocks */
11387
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
11388
        if (blocks) {
11389
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
11390
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11391
        }
11392
    }
11393
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
11394
        /* GCM payload phase - partial remainder */
11395
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11396
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11397
        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
11398
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
11399
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11400
    }
11401
    if (status == HAL_OK && tagComputed == 0) {
11402
        /* GCM final phase */
11403
        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
11404
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
11405
    }
11406
#else
11407
    hcryp.Init.HeaderSize = authPadSz;
11408
    HAL_CRYP_Init(&hcryp);
11409
    if (blocks) {
11410
        /* GCM payload phase - blocks */
11411
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
11412
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11413
    }
11414
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11415
        /* GCM payload phase - partial remainder */
11416
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11417
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11418
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
11419
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
11420
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11421
    }
11422
    if (status == HAL_OK && tagComputed == 0) {
11423
        /* Compute the authTag */
11424
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
11425
    }
11426
#endif
11427
11428
    if (status != HAL_OK)
11429
        ret = AES_GCM_AUTH_E;
11430
11431
    HAL_CRYP_DeInit(&hcryp);
11432
11433
#else /* Standard Peripheral Library */
11434
    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
11435
11436
    /* Input size and auth size need to be the actual sizes, even though
11437
     * they are not block aligned, because this length (in bits) is used
11438
     * in the final GHASH. */
11439
    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
11440
    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
11441
                         (uint8_t*)keyCopy,      keySize * 8,
11442
                         (uint8_t*)in,           sz,
11443
                         (uint8_t*)authInPadded, authInSz,
11444
                         (uint8_t*)out,          (uint8_t*)partialBlock);
11445
    if (status != SUCCESS)
11446
        ret = AES_GCM_AUTH_E;
11447
    if (tagComputed == 0)
11448
        XMEMCPY(tag, partialBlock, authTagSz);
11449
#endif /* WOLFSSL_STM32_CUBEMX */
11450
    wolfSSL_CryptHwMutexUnLock();
11451
    wc_Stm32_Aes_Cleanup();
11452
11453
    /* Check authentication tag */
11454
    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
11455
        ret = AES_GCM_AUTH_E;
11456
    }
11457
11458
    /* Free memory */
11459
    if (wasAlloc) {
11460
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11461
    }
11462
11463
    return ret;
11464
}
11465
11466
#endif /* STM32_CRYPTO_AES_GCM */
11467
11468
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11469
#ifdef WOLFSSL_AESNI
11470
/* For performance reasons, this code needs to be not inlined. */
11471
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
11472
                      Aes* aes, byte* out, const byte* in, word32 sz,
11473
                      const byte* iv, word32 ivSz,
11474
                      const byte* authTag, word32 authTagSz,
11475
                      const byte* authIn, word32 authInSz);
11476
#else
11477
static
11478
#endif
11479
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
11480
                      Aes* aes, byte* out, const byte* in, word32 sz,
11481
                      const byte* iv, word32 ivSz,
11482
                      const byte* authTag, word32 authTagSz,
11483
                      const byte* authIn, word32 authInSz)
11484
0
{
11485
0
    int ret;
11486
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
11487
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
11488
0
    const byte* c = in;
11489
0
    byte* p = out;
11490
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
11491
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
11492
0
    ALIGN16 byte Tprime[WC_AES_BLOCK_SIZE];
11493
0
    ALIGN16 byte EKY0[WC_AES_BLOCK_SIZE];
11494
0
    volatile sword32 res;
11495
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
11496
0
    byte mask;
11497
0
    word32 i;
11498
0
#endif
11499
11500
0
    if (ivSz == GCM_NONCE_MID_SZ) {
11501
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
11502
0
        XMEMCPY(counter, iv, ivSz);
11503
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
11504
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
11505
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
11506
0
    }
11507
0
    else {
11508
        /* Counter is GHASH of IV. */
11509
#ifdef OPENSSL_EXTRA
11510
        word32 aadTemp = aes->gcm.aadLen;
11511
        aes->gcm.aadLen = 0;
11512
#endif
11513
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
11514
#ifdef OPENSSL_EXTRA
11515
        aes->gcm.aadLen = aadTemp;
11516
#endif
11517
0
    }
11518
11519
    /* Calc the authTag again using received auth data and the cipher text */
11520
0
    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
11521
0
    ret = wc_AesEncrypt(aes, counter, EKY0);
11522
0
    if (ret != 0)
11523
0
        return ret;
11524
0
    xorbuf(Tprime, EKY0, sizeof(Tprime));
11525
#ifdef WC_AES_GCM_DEC_AUTH_EARLY
11526
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
11527
     * the pairwise bytes in the strings.
11528
     */
11529
    res = ConstantCompare(authTag, Tprime, authTagSz);
11530
    /* convert positive retval from ConstantCompare() to all-1s word, in
11531
     * constant time.
11532
     */
11533
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
11534
    ret = res & AES_GCM_AUTH_E;
11535
    if (ret != 0)
11536
        return ret;
11537
#endif
11538
11539
#ifdef OPENSSL_EXTRA
11540
    if (!out) {
11541
        /* authenticated, non-confidential data */
11542
        /* store AAD size for next call */
11543
        aes->gcm.aadLen = authInSz;
11544
    }
11545
#endif
11546
11547
#if defined(WOLFSSL_PIC32MZ_CRYPT)
11548
    if (blocks) {
11549
        /* use initial IV for HW, but don't use it below */
11550
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
11551
11552
        ret = wc_Pic32AesCrypt(
11553
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
11554
            out, in, (blocks * WC_AES_BLOCK_SIZE),
11555
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
11556
        if (ret != 0)
11557
            return ret;
11558
    }
11559
    /* process remainder using partial handling */
11560
#endif
11561
11562
0
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
11563
    /* some hardware acceleration can gain performance from doing AES encryption
11564
     * of the whole buffer at once */
11565
0
    if (c != p && blocks > 0) { /* can not handle inline decryption */
11566
0
        while (blocks--) {
11567
0
            IncrementGcmCounter(counter);
11568
0
            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
11569
0
            p += WC_AES_BLOCK_SIZE;
11570
0
        }
11571
11572
        /* reset number of blocks and then do encryption */
11573
0
        blocks = sz / WC_AES_BLOCK_SIZE;
11574
11575
0
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
11576
0
        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
11577
0
        c += WC_AES_BLOCK_SIZE * blocks;
11578
0
    }
11579
0
    else
11580
0
#endif /* HAVE_AES_ECB && !PIC32MZ */
11581
0
    {
11582
0
        while (blocks--) {
11583
0
            IncrementGcmCounter(counter);
11584
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
11585
0
            ret = wc_AesEncrypt(aes, counter, scratch);
11586
0
            if (ret != 0)
11587
0
                return ret;
11588
0
            xorbufout(p, scratch, c, WC_AES_BLOCK_SIZE);
11589
0
        #endif
11590
0
            p += WC_AES_BLOCK_SIZE;
11591
0
            c += WC_AES_BLOCK_SIZE;
11592
0
        }
11593
0
    }
11594
11595
0
    if (partial != 0) {
11596
0
        IncrementGcmCounter(counter);
11597
0
        ret = wc_AesEncrypt(aes, counter, scratch);
11598
0
        if (ret != 0)
11599
0
            return ret;
11600
0
        xorbuf(scratch, c, partial);
11601
0
        XMEMCPY(p, scratch, partial);
11602
0
    }
11603
11604
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
11605
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
11606
     * the pairwise bytes in the strings.
11607
     */
11608
0
    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
11609
    /* convert positive retval from ConstantCompare() to all-1s word, in
11610
     * constant time.
11611
     */
11612
0
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
11613
    /* now use res as a mask for constant time return of ret, unless tag
11614
     * mismatch, whereupon AES_GCM_AUTH_E is returned.
11615
     */
11616
0
    ret = (ret & ~res);
11617
0
    ret |= (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
11618
    /* Mask the output on auth failure instead of branching, to keep the tag
11619
     * compare constant time. res is all-ones on mismatch, zero on match. A
11620
     * single vectorizable pass is cheaper than folding the mask into the
11621
     * decrypt loop. Not needed for WC_AES_GCM_DEC_AUTH_EARLY: there the tag is
11622
     * checked before decryption, so out is never written on a mismatch. */
11623
0
    mask = (byte)res;
11624
0
    for (i = 0; i < sz; i++) {
11625
0
        out[i] &= (byte)~mask;
11626
0
    }
11627
0
#endif
11628
0
    return ret;
11629
0
}
11630
#elif (defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
11631
      (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11632
static int AES_GCM_decrypt_ASM(Aes* aes, byte* out, const byte* in,
11633
    word32 sz, const byte* iv, word32 ivSz, const byte* authTag,
11634
    word32 authTagSz, const byte* authIn, word32 authInSz)
11635
{
11636
    word32 blocks;
11637
    word32 partial;
11638
    byte counter[WC_AES_BLOCK_SIZE];
11639
    byte initialCounter[WC_AES_BLOCK_SIZE];
11640
    byte scratch[WC_AES_BLOCK_SIZE];
11641
    byte x[WC_AES_BLOCK_SIZE];
11642
11643
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
11644
    if (ivSz == GCM_NONCE_MID_SZ) {
11645
        XMEMCPY(initialCounter, iv, ivSz);
11646
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
11647
    }
11648
    else {
11649
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
11650
    }
11651
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
11652
11653
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
11654
    /* Hash in the Additional Authentication Data */
11655
    if (authInSz != 0 && authIn != NULL) {
11656
        blocks = authInSz / WC_AES_BLOCK_SIZE;
11657
        partial = authInSz % WC_AES_BLOCK_SIZE;
11658
        if (blocks > 0) {
11659
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
11660
            authIn += blocks * WC_AES_BLOCK_SIZE;
11661
        }
11662
        if (partial != 0) {
11663
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11664
            XMEMCPY(scratch, authIn, partial);
11665
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11666
        }
11667
    }
11668
11669
    blocks = sz / WC_AES_BLOCK_SIZE;
11670
    partial = sz % WC_AES_BLOCK_SIZE;
11671
    /* do as many blocks as possible */
11672
    if (blocks > 0) {
11673
        GCM_GMULT_LEN(&aes->gcm, x, in, blocks * WC_AES_BLOCK_SIZE);
11674
11675
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
11676
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11677
        if (sz >= 32)
11678
    #endif
11679
        {
11680
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
11681
                (const unsigned char*)aes->key, aes->rounds, counter);
11682
        }
11683
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11684
        else
11685
    #endif
11686
    #endif
11687
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11688
        {
11689
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
11690
                (const unsigned char*)aes->key, aes->rounds, counter);
11691
        }
11692
    #endif
11693
        in += blocks * WC_AES_BLOCK_SIZE;
11694
        out += blocks * WC_AES_BLOCK_SIZE;
11695
    }
11696
    if (partial != 0) {
11697
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11698
        XMEMCPY(scratch, in, partial);
11699
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11700
11701
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
11702
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
11703
        {
11704
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
11705
                (const unsigned char*)aes->key, aes->rounds, counter);
11706
        }
11707
    #else
11708
        {
11709
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
11710
                (const unsigned char*)aes->key, aes->rounds, counter);
11711
        }
11712
    #endif
11713
        XMEMCPY(out, scratch, partial);
11714
    }
11715
11716
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11717
    FlattenSzInBits(&scratch[0], authInSz);
11718
    FlattenSzInBits(&scratch[8], sz);
11719
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11720
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
11721
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
11722
    {
11723
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
11724
            (const unsigned char*)aes->key, aes->rounds);
11725
    }
11726
#else
11727
    {
11728
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
11729
            (const unsigned char*)aes->key, aes->rounds);
11730
    }
11731
#endif
11732
    xorbuf(x, scratch, authTagSz);
11733
    if (authTag != NULL) {
11734
        if (ConstantCompare(authTag, x, authTagSz) != 0) {
11735
            return AES_GCM_AUTH_E;
11736
        }
11737
    }
11738
11739
    return 0;
11740
}
11741
#endif
11742
11743
/* Software AES - GCM Decrypt */
11744
int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
11745
                     const byte* iv, word32 ivSz,
11746
                     const byte* authTag, word32 authTagSz,
11747
                     const byte* authIn, word32 authInSz)
11748
127
{
11749
127
    int ret;
11750
#ifdef WOLFSSL_AESNI
11751
    int res = WC_NO_ERR_TRACE(AES_GCM_AUTH_E);
11752
#endif
11753
11754
    /* argument checks */
11755
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
11756
     * in and out are don't cares, as this is is the GMAC case. */
11757
127
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
11758
127
        authTag == NULL || ivSz == 0)
11759
0
    {
11760
0
        return BAD_FUNC_ARG;
11761
0
    }
11762
11763
127
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
11764
127
    if (ret != 0)
11765
0
        return ret;
11766
11767
127
#ifdef WOLF_CRYPTO_CB
11768
127
    #ifndef WOLF_CRYPTO_CB_FIND
11769
127
    if (aes->devId != INVALID_DEVID)
11770
0
    #endif
11771
0
    {
11772
0
        int crypto_cb_ret =
11773
0
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
11774
0
                                      authTag, authTagSz, authIn, authInSz);
11775
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11776
0
            return crypto_cb_ret;
11777
        /* fall-through when unavailable */
11778
0
    }
11779
127
#endif
11780
11781
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
11782
    /* if async and byte count above threshold */
11783
    /* only 12-byte IV is supported in HW */
11784
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
11785
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
11786
    #if defined(HAVE_CAVIUM)
11787
        #ifdef HAVE_CAVIUM_V
11788
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
11789
            return NitroxAesGcmDecrypt(aes, out, in, sz,
11790
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
11791
                authTag, authTagSz, authIn, authInSz);
11792
        }
11793
        #endif
11794
    #elif defined(HAVE_INTEL_QA)
11795
        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
11796
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
11797
            authTag, authTagSz, authIn, authInSz);
11798
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
11799
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
11800
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
11801
            sw->aes.aes = aes;
11802
            sw->aes.out = out;
11803
            sw->aes.in = in;
11804
            sw->aes.sz = sz;
11805
            sw->aes.iv = iv;
11806
            sw->aes.ivSz = ivSz;
11807
            sw->aes.authTag = (byte*)authTag;
11808
            sw->aes.authTagSz = authTagSz;
11809
            sw->aes.authIn = authIn;
11810
            sw->aes.authInSz = authInSz;
11811
            return WC_PENDING_E;
11812
        }
11813
    #endif
11814
    }
11815
#endif /* WOLFSSL_ASYNC_CRYPT */
11816
11817
#ifdef WOLFSSL_SILABS_SE_ACCEL
11818
    return wc_AesGcmDecrypt_silabs(
11819
        aes, out, in, sz, iv, ivSz,
11820
        authTag, authTagSz, authIn, authInSz);
11821
11822
#endif
11823
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
11824
#ifndef TA_AES_GCM_MAX_DATA_SIZE
11825
    #define TA_AES_GCM_MAX_DATA_SIZE 996u
11826
#endif
11827
    if (aes != NULL &&
11828
        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
11829
        ivSz == TA_AES_GCM_IV_LENGTH &&
11830
        authTagSz == TA_AES_GCM_TAG_LENGTH &&
11831
        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
11832
        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
11833
        return wc_Microchip_AesGcmDecrypt(
11834
            aes, out, in, sz, iv, ivSz,
11835
            authTag, authTagSz, authIn, authInSz);
11836
    }
11837
#endif
11838
11839
    /* BARE: GCM decrypt always uses SW path (with HW AES blocks via
11840
     * wc_AesEncrypt). Encrypt is HW-accelerated above; decrypt + tag
11841
     * verification stays in well-tested SW for now. */
11842
11843
#ifdef STM32_CRYPTO_AES_GCM
11844
    /* The STM standard peripheral library API's doesn't support partial blocks */
11845
    return wc_AesGcmDecrypt_STM32(
11846
        aes, out, in, sz, iv, ivSz,
11847
        authTag, authTagSz, authIn, authInSz);
11848
#endif /* STM32_CRYPTO_AES_GCM */
11849
11850
#if defined(WOLFSSL_PSOC6_CRYPTO)
11851
    return wc_Psoc6_Aes_GcmDecrypt(aes, out, in, sz, iv, ivSz, authTag,
11852
                                   authTagSz, authIn, authInSz);
11853
#endif /* WOLFSSL_PSOC6_CRYPTO */
11854
11855
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) || \
11856
    defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
11857
    return AES_GCM_decrypt_RISCV64((byte*)in, out, sz, iv, ivSz, authTag,
11858
        authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11859
        (byte*)aes->tmp, (byte*)aes->reg, (int)aes->rounds);
11860
#elif defined(WOLFSSL_RISCV_ASM)
11861
    return AES_GCM_decrypt_RISCV64((byte*)in, out, sz, iv, ivSz, authTag,
11862
        authTagSz, authIn, authInSz, (byte*)aes->key, AES_GCM_H_PTR(aes),
11863
        (byte*)aes->tmp, (byte*)aes->reg, (int)aes->rounds);
11864
#endif
11865
11866
127
    VECTOR_REGISTERS_PUSH;
11867
11868
#if defined(WOLFSSL_ARMASM)
11869
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
11870
#ifndef __aarch64__
11871
    {
11872
    #ifdef OPENSSL_EXTRA
11873
        word32 reg[WC_AES_BLOCK_SIZE / sizeof(word32)];
11874
        XMEMCPY(reg, aes->reg, sizeof(reg));
11875
    #endif
11876
        ret = AES_GCM_decrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
11877
            authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
11878
            (byte*)aes->reg, aes->rounds);
11879
    #ifdef OPENSSL_EXTRA
11880
        XMEMCPY(aes->reg, reg, sizeof(reg));
11881
    #endif
11882
    }
11883
#else
11884
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11885
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11886
        if (aes->use_sha3_hw_crypto) {
11887
            ret = AES_GCM_decrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
11888
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11889
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
11890
        }
11891
        else
11892
    #endif
11893
        {
11894
            ret = AES_GCM_decrypt_AARCH64(in, out, sz, iv, ivSz, authTag,
11895
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11896
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
11897
        }
11898
    }
11899
    else
11900
#endif /* !__aarch64__ */
11901
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
11902
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11903
    {
11904
        ret = AES_GCM_decrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
11905
            authTagSz, authIn, authInSz);
11906
    }
11907
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
11908
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11909
    {
11910
        ret = AES_GCM_decrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
11911
            authTagSz, authIn, authInSz);
11912
    }
11913
#else
11914
#ifdef WOLFSSL_AESNI
11915
    if (aes->use_aesni) {
11916
#ifdef HAVE_INTEL_AVX512
11917
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11918
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11919
            AES_GCM_decrypt_avx512(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11920
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11921
            if (res == 0)
11922
                ret = AES_GCM_AUTH_E;
11923
            else
11924
                ret = 0;
11925
        }
11926
        else
11927
#endif
11928
#ifdef HAVE_INTEL_VAES
11929
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11930
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11931
            AES_GCM_decrypt_vaes(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11932
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11933
            if (res == 0)
11934
                ret = AES_GCM_AUTH_E;
11935
            else
11936
                ret = 0;
11937
        }
11938
        else
11939
#endif
11940
#ifdef HAVE_INTEL_AVX2
11941
        if (IS_INTEL_AVX2(intel_flags)) {
11942
            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11943
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11944
            if (res == 0)
11945
                ret = AES_GCM_AUTH_E;
11946
            else
11947
                ret = 0;
11948
        }
11949
        else
11950
#endif
11951
#if defined(HAVE_INTEL_AVX1)
11952
        if (IS_INTEL_AVX1(intel_flags)) {
11953
            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11954
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11955
            if (res == 0)
11956
                ret = AES_GCM_AUTH_E;
11957
            else
11958
                ret = 0;
11959
        }
11960
        else
11961
#endif
11962
        {
11963
            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11964
                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11965
            if (res == 0)
11966
                ret = AES_GCM_AUTH_E;
11967
            else
11968
                ret = 0;
11969
        }
11970
    }
11971
    else
11972
#endif /* WOLFSSL_AESNI */
11973
127
    {
11974
127
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11975
127
                                                             authIn, authInSz);
11976
127
    }
11977
127
#endif
11978
11979
127
    VECTOR_REGISTERS_POP;
11980
11981
127
    return ret;
11982
127
}
11983
#endif
11984
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
11985
11986
#ifdef WOLFSSL_AESGCM_STREAM
11987
11988
/* Initialize the AES GCM cipher with an IV. C implementation.
11989
 *
11990
 * @param [in, out] aes   AES object.
11991
 * @param [in]      iv    IV/nonce buffer.
11992
 * @param [in]      ivSz  Length of IV/nonce data.
11993
 */
11994
static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
11995
1.07k
{
11996
1.07k
    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
11997
1.07k
    int ret;
11998
11999
1.07k
    if (ivSz == GCM_NONCE_MID_SZ) {
12000
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
12001
1.07k
        XMEMCPY(counter, iv, ivSz);
12002
1.07k
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
12003
1.07k
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
12004
1.07k
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
12005
1.07k
    }
12006
0
    else {
12007
        /* Counter is GHASH of IV. */
12008
    #ifdef OPENSSL_EXTRA
12009
        word32 aadTemp = aes->gcm.aadLen;
12010
        aes->gcm.aadLen = 0;
12011
    #endif
12012
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
12013
    #ifdef OPENSSL_EXTRA
12014
        aes->gcm.aadLen = aadTemp;
12015
    #endif
12016
0
    }
12017
12018
    /* Copy in the counter for use with cipher. */
12019
1.07k
    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
12020
    /* Encrypt initial counter into a buffer for GCM. */
12021
1.07k
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
12022
1.07k
    if (ret != 0)
12023
0
        return ret;
12024
    /* Reset state fields. */
12025
1.07k
    aes->over = 0;
12026
1.07k
    aes->aSz = 0;
12027
1.07k
    aes->cSz = 0;
12028
    /* Initialization for GHASH. */
12029
1.07k
    GHASH_INIT(aes);
12030
12031
1.07k
    return 0;
12032
1.07k
}
12033
12034
/* Update the AES GCM cipher with data. C implementation.
12035
 *
12036
 * Only enciphers data.
12037
 *
12038
 * @param [in, out] aes  AES object.
12039
 * @param [in]      out  Cipher text or plaintext buffer.
12040
 * @param [in]      in   Plaintext or cipher text buffer.
12041
 * @param [in]      sz   Length of data.
12042
 */
12043
static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
12044
    Aes* aes, byte* out, const byte* in, word32 sz)
12045
6.33k
{
12046
6.33k
    word32 blocks;
12047
6.33k
    word32 partial;
12048
6.33k
    int ret;
12049
12050
    /* Check if previous encrypted block was not used up. */
12051
6.33k
    if (aes->over > 0) {
12052
3.81k
        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
12053
3.81k
        if (pSz > sz) pSz = (byte)sz;
12054
12055
        /* Use some/all of last encrypted block. */
12056
3.81k
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
12057
3.81k
        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
12058
12059
        /* Some data used. */
12060
3.81k
        sz  -= pSz;
12061
3.81k
        in  += pSz;
12062
3.81k
        out += pSz;
12063
3.81k
    }
12064
12065
    /* Calculate the number of blocks needing to be encrypted and any leftover.
12066
     */
12067
6.33k
    blocks  = sz / WC_AES_BLOCK_SIZE;
12068
6.33k
    partial = sz & (WC_AES_BLOCK_SIZE - 1);
12069
12070
6.33k
#if defined(HAVE_AES_ECB)
12071
    /* Some hardware acceleration can gain performance from doing AES encryption
12072
     * of the whole buffer at once.
12073
     * Overwrites the cipher text before using plaintext - no inline encryption.
12074
     */
12075
6.33k
    if ((out != in) && blocks > 0) {
12076
161
        word32 b;
12077
        /* Place incrementing counter blocks into cipher text. */
12078
9.35k
        for (b = 0; b < blocks; b++) {
12079
9.19k
            IncrementGcmCounter(AES_COUNTER(aes));
12080
9.19k
            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
12081
9.19k
        }
12082
12083
        /* Encrypt counter blocks. */
12084
161
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
12085
        /* XOR in plaintext. */
12086
161
        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
12087
        /* Skip over processed data. */
12088
161
        in += WC_AES_BLOCK_SIZE * blocks;
12089
161
        out += WC_AES_BLOCK_SIZE * blocks;
12090
161
    }
12091
6.17k
    else
12092
6.17k
#endif /* HAVE_AES_ECB */
12093
6.17k
    {
12094
        /* Encrypt block by block. */
12095
8.18k
        while (blocks--) {
12096
2.01k
            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
12097
2.01k
            IncrementGcmCounter(AES_COUNTER(aes));
12098
            /* Encrypt counter into a buffer. */
12099
2.01k
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
12100
2.01k
            if (ret != 0)
12101
0
                return ret;
12102
            /* XOR plain text into encrypted counter into cipher text buffer. */
12103
2.01k
            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
12104
            /* Data complete. */
12105
2.01k
            in  += WC_AES_BLOCK_SIZE;
12106
2.01k
            out += WC_AES_BLOCK_SIZE;
12107
2.01k
        }
12108
6.17k
    }
12109
12110
6.33k
    if (partial != 0) {
12111
        /* Generate an extra block and use up as much as needed. */
12112
346
        IncrementGcmCounter(AES_COUNTER(aes));
12113
        /* Encrypt counter into cache. */
12114
346
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
12115
346
        if (ret != 0)
12116
0
            return ret;
12117
        /* XOR plain text into encrypted counter into cipher text buffer. */
12118
346
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
12119
        /* Keep amount of encrypted block used. */
12120
346
        aes->over = (byte)partial;
12121
346
    }
12122
12123
6.33k
    return 0;
12124
6.33k
}
12125
12126
/* Calculates authentication tag for AES GCM. C implementation.
12127
 *
12128
 * @param [in, out] aes        AES object.
12129
 * @param [out]     authTag    Buffer to store authentication tag in.
12130
 * @param [in]      authTagSz  Length of tag to create.
12131
 */
12132
static WARN_UNUSED_RESULT int AesGcmFinal_C(
12133
    Aes* aes, byte* authTag, word32 authTagSz)
12134
358
{
12135
    /* Calculate authentication tag. */
12136
358
    GHASH_FINAL(aes, authTag, authTagSz);
12137
    /* XOR in as much of encrypted counter as is required. */
12138
358
    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
12139
#ifdef OPENSSL_EXTRA
12140
    /* store AAD size for next call */
12141
    aes->gcm.aadLen = aes->aSz;
12142
#endif
12143
    /* Zeroize last block to protect sensitive data. */
12144
358
    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
12145
12146
358
    return 0;
12147
358
}
12148
12149
#ifdef WOLFSSL_AESNI
12150
12151
#ifdef __cplusplus
12152
    extern "C" {
12153
#endif
12154
12155
/* Assembly code implementations in: aes_gcm_asm.S */
12156
#ifdef HAVE_INTEL_AVX2
12157
extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
12158
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12159
    unsigned char* counter, unsigned char* initCtr);
12160
#ifdef HAVE_INTEL_AVX512
12161
extern void AES_GCM_init_avx512(const unsigned char* key, int nr,
12162
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12163
    unsigned char* counter, unsigned char* initCtr);
12164
#endif
12165
#ifdef HAVE_INTEL_VAES
12166
extern void AES_GCM_init_vaes(const unsigned char* key, int nr,
12167
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12168
    unsigned char* counter, unsigned char* initCtr);
12169
#endif
12170
extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
12171
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12172
#ifdef HAVE_INTEL_AVX512
12173
extern void AES_GCM_aad_update_avx512(const unsigned char* addt,
12174
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12175
#endif
12176
#ifdef HAVE_INTEL_VAES
12177
extern void AES_GCM_aad_update_vaes(const unsigned char* addt,
12178
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12179
#endif
12180
extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
12181
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12182
#ifdef HAVE_INTEL_AVX512
12183
extern void AES_GCM_encrypt_block_avx512(const unsigned char* key, int nr,
12184
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12185
#endif
12186
#ifdef HAVE_INTEL_VAES
12187
extern void AES_GCM_encrypt_block_vaes(const unsigned char* key, int nr,
12188
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12189
#endif
12190
extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
12191
    unsigned char* tag, unsigned char* h);
12192
#ifdef HAVE_INTEL_AVX512
12193
extern void AES_GCM_ghash_block_avx512(const unsigned char* data,
12194
    unsigned char* tag, unsigned char* h);
12195
#endif
12196
#ifdef HAVE_INTEL_VAES
12197
extern void AES_GCM_ghash_block_vaes(const unsigned char* data,
12198
    unsigned char* tag, unsigned char* h);
12199
#endif
12200
12201
extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
12202
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12203
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12204
#ifdef HAVE_INTEL_AVX512
12205
extern void AES_GCM_encrypt_update_avx512(const unsigned char* key, int nr,
12206
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12207
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12208
#endif
12209
#ifdef HAVE_INTEL_VAES
12210
extern void AES_GCM_encrypt_update_vaes(const unsigned char* key, int nr,
12211
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12212
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12213
#endif
12214
extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
12215
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12216
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12217
#ifdef HAVE_INTEL_AVX512
12218
extern void AES_GCM_encrypt_final_avx512(unsigned char* tag,
12219
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12220
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12221
#endif
12222
#ifdef HAVE_INTEL_VAES
12223
extern void AES_GCM_encrypt_final_vaes(unsigned char* tag,
12224
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12225
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12226
#endif
12227
#endif
12228
#ifdef HAVE_INTEL_AVX1
12229
extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
12230
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12231
    unsigned char* counter, unsigned char* initCtr);
12232
extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
12233
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12234
extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
12235
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12236
extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
12237
    unsigned char* tag, unsigned char* h);
12238
12239
extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
12240
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12241
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12242
extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
12243
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12244
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12245
#endif
12246
extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
12247
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12248
    unsigned char* counter, unsigned char* initCtr);
12249
extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
12250
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12251
extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
12252
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12253
extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
12254
    unsigned char* tag, unsigned char* h);
12255
12256
extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
12257
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12258
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12259
extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
12260
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12261
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12262
12263
#ifdef __cplusplus
12264
    } /* extern "C" */
12265
#endif
12266
12267
/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
12268
 *
12269
 * @param [in, out] aes   AES object.
12270
 * @param [in]      iv    IV/nonce buffer.
12271
 * @param [in]      ivSz  Length of IV/nonce data.
12272
 */
12273
static WARN_UNUSED_RESULT int AesGcmInit_aesni(
12274
    Aes* aes, const byte* iv, word32 ivSz)
12275
{
12276
    ASSERT_SAVED_VECTOR_REGISTERS();
12277
12278
    /* Reset state fields. */
12279
    aes->over = 0;
12280
    aes->aSz = 0;
12281
    aes->cSz = 0;
12282
    /* Set tag to all zeros as initial value. */
12283
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
12284
    /* Reset counts of AAD and cipher text. */
12285
    aes->aOver = 0;
12286
    aes->cOver = 0;
12287
12288
#ifdef HAVE_INTEL_AVX512
12289
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12290
        AES_GCM_init_avx512((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12291
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12292
    }
12293
    else
12294
#endif
12295
#ifdef HAVE_INTEL_VAES
12296
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12297
        AES_GCM_init_vaes((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12298
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12299
    }
12300
    else
12301
#endif
12302
#ifdef HAVE_INTEL_AVX2
12303
    if (IS_INTEL_AVX2(intel_flags)) {
12304
        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12305
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12306
    }
12307
    else
12308
#endif
12309
#ifdef HAVE_INTEL_AVX1
12310
    if (IS_INTEL_AVX1(intel_flags)) {
12311
        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12312
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12313
    }
12314
    else
12315
#endif
12316
    {
12317
        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12318
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12319
    }
12320
12321
    return 0;
12322
}
12323
12324
/* Update the AES GCM for encryption with authentication data.
12325
 *
12326
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
12327
 *
12328
 * @param [in, out] aes   AES object.
12329
 * @param [in]      a     Buffer holding authentication data.
12330
 * @param [in]      aSz   Length of authentication data in bytes.
12331
 * @param [in]      endA  Whether no more authentication data is expected.
12332
 */
12333
static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
12334
    Aes* aes, const byte* a, word32 aSz, int endA)
12335
{
12336
    word32 blocks;
12337
    int partial;
12338
12339
    ASSERT_SAVED_VECTOR_REGISTERS();
12340
12341
    if (aSz != 0 && a != NULL) {
12342
        /* Total count of AAD updated. */
12343
        aes->aSz += aSz;
12344
        /* Check if we have unprocessed data. */
12345
        if (aes->aOver > 0) {
12346
            /* Calculate amount we can use - fill up the block. */
12347
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
12348
            if (sz > aSz) {
12349
                sz = (byte)aSz;
12350
            }
12351
            /* Copy extra into last GHASH block array and update count. */
12352
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
12353
            aes->aOver = (byte)(aes->aOver + sz);
12354
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
12355
                /* We have filled up the block and can process. */
12356
#ifdef HAVE_INTEL_AVX512
12357
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12358
                    AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12359
                                             aes->gcm.H);
12360
                }
12361
                else
12362
#endif
12363
#ifdef HAVE_INTEL_VAES
12364
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12365
                    AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12366
                                             aes->gcm.H);
12367
                }
12368
                else
12369
#endif
12370
            #ifdef HAVE_INTEL_AVX2
12371
                if (IS_INTEL_AVX2(intel_flags)) {
12372
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12373
                                             aes->gcm.H);
12374
                }
12375
                else
12376
            #endif
12377
            #ifdef HAVE_INTEL_AVX1
12378
                if (IS_INTEL_AVX1(intel_flags)) {
12379
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
12380
                                             aes->gcm.H);
12381
                }
12382
                else
12383
            #endif
12384
                {
12385
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
12386
                                              aes->gcm.H);
12387
                }
12388
                /* Reset count. */
12389
                aes->aOver = 0;
12390
            }
12391
            /* Used up some data. */
12392
            aSz -= sz;
12393
            a += sz;
12394
        }
12395
12396
        /* Calculate number of blocks of AAD and the leftover. */
12397
        blocks = aSz / WC_AES_BLOCK_SIZE;
12398
        partial = aSz % WC_AES_BLOCK_SIZE;
12399
        if (blocks > 0) {
12400
            /* GHASH full blocks now. */
12401
#ifdef HAVE_INTEL_AVX512
12402
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12403
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12404
                AES_GCM_aad_update_avx512(a, blocks * WC_AES_BLOCK_SIZE,
12405
                                        AES_TAG(aes), aes->gcm.H);
12406
            }
12407
            else
12408
#endif
12409
#ifdef HAVE_INTEL_VAES
12410
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12411
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12412
                AES_GCM_aad_update_vaes(a, blocks * WC_AES_BLOCK_SIZE,
12413
                                        AES_TAG(aes), aes->gcm.H);
12414
            }
12415
            else
12416
#endif
12417
        #ifdef HAVE_INTEL_AVX2
12418
            if (IS_INTEL_AVX2(intel_flags)) {
12419
                AES_GCM_aad_update_avx2(a, blocks * WC_AES_BLOCK_SIZE,
12420
                                        AES_TAG(aes), aes->gcm.H);
12421
            }
12422
            else
12423
        #endif
12424
        #ifdef HAVE_INTEL_AVX1
12425
            if (IS_INTEL_AVX1(intel_flags)) {
12426
                AES_GCM_aad_update_avx1(a, blocks * WC_AES_BLOCK_SIZE,
12427
                                        AES_TAG(aes), aes->gcm.H);
12428
            }
12429
            else
12430
        #endif
12431
            {
12432
                AES_GCM_aad_update_aesni(a, blocks * WC_AES_BLOCK_SIZE,
12433
                                         AES_TAG(aes), aes->gcm.H);
12434
            }
12435
            /* Skip over to end of AAD blocks. */
12436
            a += blocks * WC_AES_BLOCK_SIZE;
12437
        }
12438
        if (partial != 0) {
12439
            /* Cache the partial block. */
12440
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
12441
            aes->aOver = (byte)partial;
12442
        }
12443
    }
12444
    if (endA && (aes->aOver > 0)) {
12445
        /* No more AAD coming and we have a partial block. */
12446
        /* Fill the rest of the block with zeros. */
12447
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
12448
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
12449
        /* GHASH last AAD block. */
12450
#ifdef HAVE_INTEL_AVX512
12451
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12452
            AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12453
                                     aes->gcm.H);
12454
        }
12455
        else
12456
#endif
12457
#ifdef HAVE_INTEL_VAES
12458
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12459
            AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12460
                                     aes->gcm.H);
12461
        }
12462
        else
12463
#endif
12464
    #ifdef HAVE_INTEL_AVX2
12465
        if (IS_INTEL_AVX2(intel_flags)) {
12466
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12467
                                     aes->gcm.H);
12468
        }
12469
        else
12470
    #endif
12471
    #ifdef HAVE_INTEL_AVX1
12472
        if (IS_INTEL_AVX1(intel_flags)) {
12473
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
12474
                                     aes->gcm.H);
12475
        }
12476
        else
12477
    #endif
12478
        {
12479
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
12480
                                      aes->gcm.H);
12481
        }
12482
        /* Clear partial count for next time through. */
12483
        aes->aOver = 0;
12484
    }
12485
12486
    return 0;
12487
}
12488
12489
/* Update the AES GCM for encryption with data and/or authentication data.
12490
 *
12491
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
12492
 *
12493
 * @param [in, out] aes  AES object.
12494
 * @param [out]     c    Buffer to hold cipher text.
12495
 * @param [in]      p    Buffer holding plaintext.
12496
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
12497
 * @param [in]      a    Buffer holding authentication data.
12498
 * @param [in]      aSz  Length of authentication data in bytes.
12499
 */
12500
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
12501
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
12502
{
12503
    word32 blocks;
12504
    int partial;
12505
    int ret;
12506
12507
    ASSERT_SAVED_VECTOR_REGISTERS();
12508
12509
    /* Hash in A, the Authentication Data */
12510
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
12511
    if (ret != 0)
12512
        return ret;
12513
12514
    /* Encrypt plaintext and Hash in C, the Cipher text */
12515
    if (cSz != 0 && c != NULL) {
12516
        /* Update count of cipher text we have hashed. */
12517
        aes->cSz += cSz;
12518
        if (aes->cOver > 0) {
12519
            /* Calculate amount we can use - fill up the block. */
12520
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
12521
            if (sz > cSz) {
12522
                sz = (byte)cSz;
12523
            }
12524
            /* Encrypt some of the plaintext. */
12525
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
12526
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
12527
            /* Update count of unused encrypted counter. */
12528
            aes->cOver = (byte)(aes->cOver + sz);
12529
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
12530
                /* We have filled up the block and can process. */
12531
#ifdef HAVE_INTEL_AVX512
12532
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12533
                    AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12534
                                             aes->gcm.H);
12535
                }
12536
                else
12537
#endif
12538
#ifdef HAVE_INTEL_VAES
12539
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12540
                    AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12541
                                             aes->gcm.H);
12542
                }
12543
                else
12544
#endif
12545
            #ifdef HAVE_INTEL_AVX2
12546
                if (IS_INTEL_AVX2(intel_flags)) {
12547
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12548
                                             aes->gcm.H);
12549
                }
12550
                else
12551
            #endif
12552
            #ifdef HAVE_INTEL_AVX1
12553
                if (IS_INTEL_AVX1(intel_flags)) {
12554
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
12555
                                             aes->gcm.H);
12556
                }
12557
                else
12558
            #endif
12559
                {
12560
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
12561
                                              aes->gcm.H);
12562
                }
12563
                /* Reset count. */
12564
                aes->cOver = 0;
12565
            }
12566
            /* Used up some data. */
12567
            cSz -= sz;
12568
            p += sz;
12569
            c += sz;
12570
        }
12571
12572
        /* Calculate number of blocks of plaintext and the leftover. */
12573
        blocks = cSz / WC_AES_BLOCK_SIZE;
12574
        partial = cSz % WC_AES_BLOCK_SIZE;
12575
        if (blocks > 0) {
12576
            /* Encrypt and GHASH full blocks now. */
12577
#ifdef HAVE_INTEL_AVX512
12578
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12579
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12580
                AES_GCM_encrypt_update_avx512((byte*)aes->key, (int)aes->rounds,
12581
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12582
                    AES_COUNTER(aes));
12583
            }
12584
            else
12585
#endif
12586
#ifdef HAVE_INTEL_VAES
12587
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12588
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12589
                AES_GCM_encrypt_update_vaes((byte*)aes->key, (int)aes->rounds,
12590
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12591
                    AES_COUNTER(aes));
12592
            }
12593
            else
12594
#endif
12595
        #ifdef HAVE_INTEL_AVX2
12596
            if (IS_INTEL_AVX2(intel_flags)) {
12597
                AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
12598
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12599
                    AES_COUNTER(aes));
12600
            }
12601
            else
12602
        #endif
12603
        #ifdef HAVE_INTEL_AVX1
12604
            if (IS_INTEL_AVX1(intel_flags)) {
12605
                AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
12606
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12607
                    AES_COUNTER(aes));
12608
            }
12609
            else
12610
        #endif
12611
            {
12612
                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
12613
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12614
                    AES_COUNTER(aes));
12615
            }
12616
            /* Skip over to end of blocks. */
12617
            p += blocks * WC_AES_BLOCK_SIZE;
12618
            c += blocks * WC_AES_BLOCK_SIZE;
12619
        }
12620
        if (partial != 0) {
12621
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
12622
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
12623
#ifdef HAVE_INTEL_AVX512
12624
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12625
                AES_GCM_encrypt_block_avx512((byte*)aes->key, (int)aes->rounds,
12626
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12627
            }
12628
            else
12629
#endif
12630
#ifdef HAVE_INTEL_VAES
12631
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12632
                AES_GCM_encrypt_block_vaes((byte*)aes->key, (int)aes->rounds,
12633
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12634
            }
12635
            else
12636
#endif
12637
        #ifdef HAVE_INTEL_AVX2
12638
            if (IS_INTEL_AVX2(intel_flags)) {
12639
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
12640
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12641
            }
12642
            else
12643
        #endif
12644
        #ifdef HAVE_INTEL_AVX1
12645
            if (IS_INTEL_AVX1(intel_flags)) {
12646
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
12647
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12648
            }
12649
            else
12650
        #endif
12651
            {
12652
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
12653
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12654
            }
12655
            /* XOR the remaining plaintext to calculate cipher text.
12656
             * Keep cipher text for GHASH of last partial block.
12657
             */
12658
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
12659
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
12660
            /* Update count of the block used. */
12661
            aes->cOver = (byte)partial;
12662
        }
12663
    }
12664
    return 0;
12665
}
12666
12667
/* Finalize the AES GCM for encryption and calculate the authentication tag.
12668
 *
12669
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
12670
 *
12671
 * @param [in, out] aes        AES object.
12672
 * @param [in]      authTag    Buffer to hold authentication tag.
12673
 * @param [in]      authTagSz  Length of authentication tag in bytes.
12674
 * @return  0 on success.
12675
 */
12676
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
12677
    Aes* aes, byte* authTag, word32 authTagSz)
12678
{
12679
    /* AAD block incomplete when > 0 */
12680
    byte over = aes->aOver;
12681
12682
    ASSERT_SAVED_VECTOR_REGISTERS();
12683
12684
    if (aes->cOver > 0) {
12685
        /* Cipher text block incomplete. */
12686
        over = aes->cOver;
12687
    }
12688
    if (over > 0) {
12689
        /* Fill the rest of the block with zeros. */
12690
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
12691
        /* GHASH last cipher block. */
12692
#ifdef HAVE_INTEL_AVX512
12693
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12694
            AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12695
                                     aes->gcm.H);
12696
        }
12697
        else
12698
#endif
12699
#ifdef HAVE_INTEL_VAES
12700
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12701
            AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12702
                                     aes->gcm.H);
12703
        }
12704
        else
12705
#endif
12706
    #ifdef HAVE_INTEL_AVX2
12707
        if (IS_INTEL_AVX2(intel_flags)) {
12708
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12709
                                     aes->gcm.H);
12710
        }
12711
        else
12712
    #endif
12713
    #ifdef HAVE_INTEL_AVX1
12714
        if (IS_INTEL_AVX1(intel_flags)) {
12715
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
12716
                                     aes->gcm.H);
12717
        }
12718
        else
12719
    #endif
12720
        {
12721
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
12722
                                      aes->gcm.H);
12723
        }
12724
    }
12725
    /* Calculate the authentication tag. */
12726
#ifdef HAVE_INTEL_AVX512
12727
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12728
        AES_GCM_encrypt_final_avx512(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12729
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12730
    }
12731
    else
12732
#endif
12733
#ifdef HAVE_INTEL_VAES
12734
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12735
        AES_GCM_encrypt_final_vaes(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12736
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12737
    }
12738
    else
12739
#endif
12740
#ifdef HAVE_INTEL_AVX2
12741
    if (IS_INTEL_AVX2(intel_flags)) {
12742
        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12743
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12744
    }
12745
    else
12746
#endif
12747
#ifdef HAVE_INTEL_AVX1
12748
    if (IS_INTEL_AVX1(intel_flags)) {
12749
        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12750
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12751
    }
12752
    else
12753
#endif
12754
    {
12755
        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
12756
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12757
    }
12758
12759
    return 0;
12760
}
12761
12762
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
12763
12764
#ifdef __cplusplus
12765
    extern "C" {
12766
#endif
12767
12768
/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
12769
#ifdef HAVE_INTEL_AVX2
12770
extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
12771
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12772
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12773
#ifdef HAVE_INTEL_AVX512
12774
extern void AES_GCM_decrypt_update_avx512(const unsigned char* key, int nr,
12775
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12776
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12777
#endif
12778
#ifdef HAVE_INTEL_VAES
12779
extern void AES_GCM_decrypt_update_vaes(const unsigned char* key, int nr,
12780
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12781
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12782
#endif
12783
extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
12784
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12785
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12786
#ifdef HAVE_INTEL_AVX512
12787
extern void AES_GCM_decrypt_final_avx512(unsigned char* tag,
12788
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12789
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12790
#endif
12791
#ifdef HAVE_INTEL_VAES
12792
extern void AES_GCM_decrypt_final_vaes(unsigned char* tag,
12793
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12794
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12795
#endif
12796
#endif
12797
#ifdef HAVE_INTEL_AVX1
12798
extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
12799
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12800
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12801
extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
12802
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12803
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12804
#endif
12805
extern void AES_GCM_decrypt_update_aesni(const unsigned char* key, int nr,
12806
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12807
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12808
extern void AES_GCM_decrypt_final_aesni(unsigned char* tag,
12809
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12810
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
12811
12812
#ifdef __cplusplus
12813
    } /* extern "C" */
12814
#endif
12815
12816
/* Update the AES GCM for decryption with data and/or authentication data.
12817
 *
12818
 * @param [in, out] aes  AES object.
12819
 * @param [out]     p    Buffer to hold plaintext.
12820
 * @param [in]      c    Buffer holding cipher text.
12821
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
12822
 * @param [in]      a    Buffer holding authentication data.
12823
 * @param [in]      aSz  Length of authentication data in bytes.
12824
 */
12825
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
12826
    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
12827
{
12828
    word32 blocks;
12829
    int partial;
12830
    int ret;
12831
12832
    ASSERT_SAVED_VECTOR_REGISTERS();
12833
12834
    /* Hash in A, the Authentication Data */
12835
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
12836
    if (ret != 0)
12837
        return ret;
12838
12839
    /* Hash in C, the Cipher text, and decrypt. */
12840
    if (cSz != 0 && p != NULL) {
12841
        /* Update count of cipher text we have hashed. */
12842
        aes->cSz += cSz;
12843
        if (aes->cOver > 0) {
12844
            /* Calculate amount we can use - fill up the block. */
12845
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
12846
            if (sz > cSz) {
12847
                sz = (byte)cSz;
12848
            }
12849
            /* Keep a copy of the cipher text for GHASH. */
12850
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
12851
            /* Decrypt some of the cipher text. */
12852
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
12853
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
12854
            /* Update count of unused encrypted counter. */
12855
            aes->cOver = (byte)(aes->cOver + sz);
12856
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
12857
                /* We have filled up the block and can process. */
12858
#ifdef HAVE_INTEL_AVX512
12859
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12860
                    AES_GCM_ghash_block_avx512(AES_LASTBLOCK(aes), AES_TAG(aes),
12861
                                             aes->gcm.H);
12862
                }
12863
                else
12864
#endif
12865
#ifdef HAVE_INTEL_VAES
12866
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12867
                    AES_GCM_ghash_block_vaes(AES_LASTBLOCK(aes), AES_TAG(aes),
12868
                                             aes->gcm.H);
12869
                }
12870
                else
12871
#endif
12872
            #ifdef HAVE_INTEL_AVX2
12873
                if (IS_INTEL_AVX2(intel_flags)) {
12874
                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
12875
                                             aes->gcm.H);
12876
                }
12877
                else
12878
            #endif
12879
            #ifdef HAVE_INTEL_AVX1
12880
                if (IS_INTEL_AVX1(intel_flags)) {
12881
                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
12882
                                             aes->gcm.H);
12883
                }
12884
                else
12885
            #endif
12886
                {
12887
                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
12888
                                              aes->gcm.H);
12889
                }
12890
                /* Reset count. */
12891
                aes->cOver = 0;
12892
            }
12893
            /* Used up some data. */
12894
            cSz -= sz;
12895
            c += sz;
12896
            p += sz;
12897
        }
12898
12899
        /* Calculate number of blocks of plaintext and the leftover. */
12900
        blocks = cSz / WC_AES_BLOCK_SIZE;
12901
        partial = cSz % WC_AES_BLOCK_SIZE;
12902
        if (blocks > 0) {
12903
            /* Decrypt and GHASH full blocks now. */
12904
#ifdef HAVE_INTEL_AVX512
12905
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12906
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12907
                AES_GCM_decrypt_update_avx512((byte*)aes->key, (int)aes->rounds,
12908
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12909
                    AES_COUNTER(aes));
12910
            }
12911
            else
12912
#endif
12913
#ifdef HAVE_INTEL_VAES
12914
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
12915
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12916
                AES_GCM_decrypt_update_vaes((byte*)aes->key, (int)aes->rounds,
12917
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12918
                    AES_COUNTER(aes));
12919
            }
12920
            else
12921
#endif
12922
        #ifdef HAVE_INTEL_AVX2
12923
            if (IS_INTEL_AVX2(intel_flags)) {
12924
                AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
12925
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12926
                    AES_COUNTER(aes));
12927
            }
12928
            else
12929
        #endif
12930
        #ifdef HAVE_INTEL_AVX1
12931
            if (IS_INTEL_AVX1(intel_flags)) {
12932
                AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
12933
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12934
                    AES_COUNTER(aes));
12935
            }
12936
            else
12937
        #endif
12938
            {
12939
                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
12940
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
12941
                    AES_COUNTER(aes));
12942
            }
12943
            /* Skip over to end of blocks. */
12944
            c += blocks * WC_AES_BLOCK_SIZE;
12945
            p += blocks * WC_AES_BLOCK_SIZE;
12946
        }
12947
        if (partial != 0) {
12948
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
12949
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
12950
#ifdef HAVE_INTEL_AVX512
12951
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12952
                AES_GCM_encrypt_block_avx512((byte*)aes->key, (int)aes->rounds,
12953
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12954
            }
12955
            else
12956
#endif
12957
#ifdef HAVE_INTEL_VAES
12958
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12959
                AES_GCM_encrypt_block_vaes((byte*)aes->key, (int)aes->rounds,
12960
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12961
            }
12962
            else
12963
#endif
12964
        #ifdef HAVE_INTEL_AVX2
12965
            if (IS_INTEL_AVX2(intel_flags)) {
12966
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
12967
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12968
            }
12969
            else
12970
        #endif
12971
        #ifdef HAVE_INTEL_AVX1
12972
            if (IS_INTEL_AVX1(intel_flags)) {
12973
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
12974
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12975
            }
12976
            else
12977
        #endif
12978
            {
12979
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
12980
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12981
            }
12982
            /* Keep cipher text for GHASH of last partial block. */
12983
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
12984
            /* XOR the remaining cipher text to calculate plaintext. */
12985
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
12986
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
12987
            /* Update count of the block used. */
12988
            aes->cOver = (byte)partial;
12989
        }
12990
    }
12991
12992
    return 0;
12993
}
12994
12995
/* Finalize the AES GCM for decryption and check the authentication tag.
12996
 *
12997
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
12998
 *
12999
 * @param [in, out] aes        AES object.
13000
 * @param [in]      authTag    Buffer holding authentication tag.
13001
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13002
 * @return  0 on success.
13003
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
13004
 *          value.
13005
 */
13006
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
13007
    Aes* aes, const byte* authTag, word32 authTagSz)
13008
{
13009
    int ret = 0;
13010
    int res;
13011
    /* AAD block incomplete when > 0 */
13012
    byte over = aes->aOver;
13013
    byte *lastBlock = AES_LASTGBLOCK(aes);
13014
13015
    ASSERT_SAVED_VECTOR_REGISTERS();
13016
13017
    if (aes->cOver > 0) {
13018
        /* Cipher text block incomplete. */
13019
        over = aes->cOver;
13020
        lastBlock = AES_LASTBLOCK(aes);
13021
    }
13022
    if (over > 0) {
13023
        /* Zeroize the unused part of the block. */
13024
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
13025
        /* Hash the last block of cipher text. */
13026
#ifdef HAVE_INTEL_AVX512
13027
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13028
            AES_GCM_ghash_block_avx512(lastBlock, AES_TAG(aes), aes->gcm.H);
13029
        }
13030
        else
13031
#endif
13032
#ifdef HAVE_INTEL_VAES
13033
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13034
            AES_GCM_ghash_block_vaes(lastBlock, AES_TAG(aes), aes->gcm.H);
13035
        }
13036
        else
13037
#endif
13038
    #ifdef HAVE_INTEL_AVX2
13039
        if (IS_INTEL_AVX2(intel_flags)) {
13040
            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
13041
        }
13042
        else
13043
    #endif
13044
    #ifdef HAVE_INTEL_AVX1
13045
        if (IS_INTEL_AVX1(intel_flags)) {
13046
            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
13047
        }
13048
        else
13049
    #endif
13050
        {
13051
            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
13052
        }
13053
    }
13054
    /* Calculate and compare the authentication tag. */
13055
#ifdef HAVE_INTEL_AVX512
13056
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13057
        AES_GCM_decrypt_final_avx512(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13058
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13059
    }
13060
    else
13061
#endif
13062
#ifdef HAVE_INTEL_VAES
13063
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13064
        AES_GCM_decrypt_final_vaes(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13065
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13066
    }
13067
    else
13068
#endif
13069
#ifdef HAVE_INTEL_AVX2
13070
    if (IS_INTEL_AVX2(intel_flags)) {
13071
        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13072
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13073
    }
13074
    else
13075
#endif
13076
#ifdef HAVE_INTEL_AVX1
13077
    if (IS_INTEL_AVX1(intel_flags)) {
13078
        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13079
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13080
    }
13081
    else
13082
#endif
13083
    {
13084
        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13085
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13086
    }
13087
13088
    /* Return error code when calculated doesn't match input. */
13089
    if (res == 0) {
13090
        ret = AES_GCM_AUTH_E;
13091
    }
13092
    return ret;
13093
}
13094
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
13095
#endif /* WOLFSSL_AESNI */
13096
13097
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13098
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13099
/* Initialize the AES GCM cipher with an IV. Aarch64 HW Crypto implementations.
13100
 *
13101
 * @param [in, out] aes   AES object.
13102
 * @param [in]      iv    IV/nonce buffer.
13103
 * @param [in]      ivSz  Length of IV/nonce data.
13104
 */
13105
static WARN_UNUSED_RESULT int AesGcmInit_AARCH64(Aes* aes, const byte* iv,
13106
    word32 ivSz)
13107
{
13108
    /* Reset state fields. */
13109
    aes->over = 0;
13110
    aes->aSz = 0;
13111
    aes->cSz = 0;
13112
    /* Set tag to all zeros as initial value. */
13113
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
13114
    /* Reset counts of AAD and cipher text. */
13115
    aes->aOver = 0;
13116
    aes->cOver = 0;
13117
13118
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13119
    if (aes->use_sha3_hw_crypto) {
13120
        AES_GCM_init_AARCH64_EOR3((byte*)aes->key, (int)aes->rounds, iv, ivSz,
13121
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
13122
    }
13123
    else
13124
#endif
13125
    {
13126
        AES_GCM_init_AARCH64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
13127
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
13128
    }
13129
13130
    return 0;
13131
}
13132
13133
/* Update the AES GCM for encryption with authentication data.
13134
 *
13135
 * Implementation uses AARCH64 optimized assembly code.
13136
 *
13137
 * @param [in, out] aes   AES object.
13138
 * @param [in]      a     Buffer holding authentication data.
13139
 * @param [in]      aSz   Length of authentication data in bytes.
13140
 * @param [in]      endA  Whether no more authentication data is expected.
13141
 */
13142
static WARN_UNUSED_RESULT int AesGcmAadUpdate_AARCH64(
13143
    Aes* aes, const byte* a, word32 aSz, int endA)
13144
{
13145
    word32 blocks;
13146
    int partial;
13147
13148
    if (aSz != 0 && a != NULL) {
13149
        /* Total count of AAD updated. */
13150
        aes->aSz += aSz;
13151
        /* Check if we have unprocessed data. */
13152
        if (aes->aOver > 0) {
13153
            /* Calculate amount we can use - fill up the block. */
13154
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
13155
            if (sz > aSz) {
13156
                sz = (byte)aSz;
13157
            }
13158
            /* Copy extra into last GHASH block array and update count. */
13159
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
13160
            aes->aOver = (byte)(aes->aOver + sz);
13161
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
13162
                /* We have filled up the block and can process. */
13163
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13164
                if (aes->use_sha3_hw_crypto) {
13165
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13166
                        AES_TAG(aes), aes->gcm.H);
13167
                }
13168
                else
13169
            #endif
13170
                {
13171
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13172
                        AES_TAG(aes), aes->gcm.H);
13173
                }
13174
                /* Reset count. */
13175
                aes->aOver = 0;
13176
            }
13177
            /* Used up some data. */
13178
            aSz -= sz;
13179
            a += sz;
13180
        }
13181
13182
        /* Calculate number of blocks of AAD and the leftover. */
13183
        blocks = aSz / WC_AES_BLOCK_SIZE;
13184
        partial = aSz % WC_AES_BLOCK_SIZE;
13185
        if (blocks > 0) {
13186
            /* GHASH full blocks now. */
13187
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13188
            if (aes->use_sha3_hw_crypto) {
13189
                AES_GCM_aad_update_AARCH64_EOR3(a, blocks * WC_AES_BLOCK_SIZE,
13190
                    AES_TAG(aes), aes->gcm.H);
13191
            }
13192
            else
13193
        #endif
13194
            {
13195
                AES_GCM_aad_update_AARCH64(a, blocks * WC_AES_BLOCK_SIZE,
13196
                    AES_TAG(aes), aes->gcm.H);
13197
            }
13198
            /* Skip over to end of AAD blocks. */
13199
            a += blocks * WC_AES_BLOCK_SIZE;
13200
        }
13201
        if (partial != 0) {
13202
            /* Cache the partial block. */
13203
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
13204
            aes->aOver = (byte)partial;
13205
        }
13206
    }
13207
    if (endA && (aes->aOver > 0)) {
13208
        /* No more AAD coming and we have a partial block. */
13209
        /* Fill the rest of the block with zeros. */
13210
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
13211
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
13212
        /* GHASH last AAD block. */
13213
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13214
        if (aes->use_sha3_hw_crypto) {
13215
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13216
                AES_TAG(aes), aes->gcm.H);
13217
        }
13218
        else
13219
    #endif
13220
        {
13221
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13222
                AES_TAG(aes), aes->gcm.H);
13223
        }
13224
        /* Clear partial count for next time through. */
13225
        aes->aOver = 0;
13226
    }
13227
13228
    return 0;
13229
}
13230
13231
/* Update the AES GCM for encryption with data and/or authentication data.
13232
 *
13233
 * Implementation uses AARCH64 optimized assembly code.
13234
 *
13235
 * @param [in, out] aes  AES object.
13236
 * @param [out]     c    Buffer to hold cipher text.
13237
 * @param [in]      p    Buffer holding plaintext.
13238
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13239
 * @param [in]      a    Buffer holding authentication data.
13240
 * @param [in]      aSz  Length of authentication data in bytes.
13241
 */
13242
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_AARCH64(
13243
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
13244
{
13245
    word32 blocks;
13246
    int partial;
13247
    int ret;
13248
13249
    /* Hash in A, the Authentication Data */
13250
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, (cSz > 0) && (c != NULL));
13251
    if (ret != 0)
13252
        return ret;
13253
13254
    /* Encrypt plaintext and Hash in C, the Cipher text */
13255
    if (cSz != 0 && c != NULL) {
13256
        /* Update count of cipher text we have hashed. */
13257
        aes->cSz += cSz;
13258
        if (aes->cOver > 0) {
13259
            /* Calculate amount we can use - fill up the block. */
13260
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13261
            if (sz > cSz) {
13262
                sz = (byte)cSz;
13263
            }
13264
            /* Encrypt some of the plaintext. */
13265
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
13266
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13267
            /* Update count of unused encrypted counter. */
13268
            aes->cOver = (byte)(aes->cOver + sz);
13269
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13270
                /* We have filled up the block and can process. */
13271
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13272
                if (aes->use_sha3_hw_crypto) {
13273
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13274
                        AES_TAG(aes), aes->gcm.H);
13275
                }
13276
                else
13277
            #endif
13278
                {
13279
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13280
                        AES_TAG(aes), aes->gcm.H);
13281
                }
13282
                /* Reset count. */
13283
                aes->cOver = 0;
13284
            }
13285
            /* Used up some data. */
13286
            cSz -= sz;
13287
            p += sz;
13288
            c += sz;
13289
        }
13290
13291
        /* Calculate number of blocks of plaintext and the leftover. */
13292
        blocks = cSz / WC_AES_BLOCK_SIZE;
13293
        partial = cSz % WC_AES_BLOCK_SIZE;
13294
        if (blocks > 0) {
13295
            /* Encrypt and GHASH full blocks now. */
13296
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13297
            if (aes->use_sha3_hw_crypto) {
13298
                AES_GCM_encrypt_update_AARCH64_EOR3((byte*)aes->key,
13299
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
13300
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13301
            }
13302
            else
13303
        #endif
13304
            {
13305
                AES_GCM_encrypt_update_AARCH64((byte*)aes->key,
13306
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
13307
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13308
            }
13309
            /* Skip over to end of blocks. */
13310
            p += blocks * WC_AES_BLOCK_SIZE;
13311
            c += blocks * WC_AES_BLOCK_SIZE;
13312
        }
13313
        if (partial != 0) {
13314
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
13315
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13316
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13317
            if (aes->use_sha3_hw_crypto) {
13318
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
13319
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
13320
                    AES_COUNTER(aes));
13321
            }
13322
            else
13323
        #endif
13324
            {
13325
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
13326
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13327
            }
13328
            /* XOR the remaining plaintext to calculate cipher text.
13329
             * Keep cipher text for GHASH of last partial block.
13330
             */
13331
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
13332
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
13333
            /* Update count of the block used. */
13334
            aes->cOver = (byte)partial;
13335
        }
13336
    }
13337
    return 0;
13338
}
13339
13340
/* Finalize the AES GCM for encryption and calculate the authentication tag.
13341
 *
13342
 * Calls ARCH64 optimized assembly code.
13343
 *
13344
 * @param [in, out] aes        AES object.
13345
 * @param [in]      authTag    Buffer to hold authentication tag.
13346
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13347
 * @return  0 on success.
13348
 */
13349
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_AARCH64(Aes* aes,
13350
    byte* authTag, word32 authTagSz)
13351
{
13352
    /* AAD block incomplete when > 0 */
13353
    byte over = aes->aOver;
13354
13355
    ASSERT_SAVED_VECTOR_REGISTERS();
13356
13357
    if (aes->cOver > 0) {
13358
        /* Cipher text block incomplete. */
13359
        over = aes->cOver;
13360
    }
13361
    if (over > 0) {
13362
        /* Fill the rest of the block with zeros. */
13363
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
13364
            (size_t)WC_AES_BLOCK_SIZE - over);
13365
        /* GHASH last cipher block. */
13366
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13367
        if (aes->use_sha3_hw_crypto) {
13368
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes), AES_TAG(aes),
13369
                aes->gcm.H);
13370
        }
13371
        else
13372
    #endif
13373
        {
13374
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes), AES_TAG(aes),
13375
                aes->gcm.H);
13376
        }
13377
    }
13378
    /* Calculate the authentication tag. */
13379
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13380
    if (aes->use_sha3_hw_crypto) {
13381
        AES_GCM_encrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
13382
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13383
    }
13384
    else
13385
#endif
13386
    {
13387
        AES_GCM_encrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
13388
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13389
    }
13390
13391
    return 0;
13392
}
13393
13394
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
13395
/* Update the AES GCM for decryption with data and/or authentication data.
13396
 *
13397
 * @param [in, out] aes  AES object.
13398
 * @param [out]     p    Buffer to hold plaintext.
13399
 * @param [in]      c    Buffer holding cipher text.
13400
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13401
 * @param [in]      a    Buffer holding authentication data.
13402
 * @param [in]      aSz  Length of authentication data in bytes.
13403
 */
13404
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_AARCH64(Aes* aes, byte* p,
13405
    const byte* c, word32 cSz, const byte* a, word32 aSz)
13406
{
13407
    word32 blocks;
13408
    int partial;
13409
    int ret;
13410
13411
    /* Hash in A, the Authentication Data */
13412
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, cSz > 0);
13413
    if (ret != 0)
13414
        return ret;
13415
13416
    /* Hash in C, the Cipher text, and decrypt. */
13417
    if (cSz != 0 && p != NULL) {
13418
        /* Update count of cipher text we have hashed. */
13419
        aes->cSz += cSz;
13420
        if (aes->cOver > 0) {
13421
            /* Calculate amount we can use - fill up the block. */
13422
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13423
            if (sz > cSz) {
13424
                sz = (byte)cSz;
13425
            }
13426
            /* Keep a copy of the cipher text for GHASH. */
13427
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
13428
            /* Decrypt some of the cipher text. */
13429
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
13430
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13431
            /* Update count of unused encrypted counter. */
13432
            aes->cOver = (byte)(aes->cOver + sz);
13433
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13434
                /* We have filled up the block and can process. */
13435
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13436
                if (aes->use_sha3_hw_crypto) {
13437
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTBLOCK(aes),
13438
                        AES_TAG(aes), aes->gcm.H);
13439
                }
13440
                else
13441
            #endif
13442
                {
13443
                    AES_GCM_ghash_block_AARCH64(AES_LASTBLOCK(aes),
13444
                        AES_TAG(aes), aes->gcm.H);
13445
                }
13446
                /* Reset count. */
13447
                aes->cOver = 0;
13448
            }
13449
            /* Used up some data. */
13450
            cSz -= sz;
13451
            c += sz;
13452
            p += sz;
13453
        }
13454
13455
        /* Calculate number of blocks of plaintext and the leftover. */
13456
        blocks = cSz / WC_AES_BLOCK_SIZE;
13457
        partial = cSz % WC_AES_BLOCK_SIZE;
13458
        if (blocks > 0) {
13459
            /* Decrypt and GHASH full blocks now. */
13460
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13461
            if (aes->use_sha3_hw_crypto) {
13462
                AES_GCM_decrypt_update_AARCH64_EOR3((byte*)aes->key,
13463
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
13464
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13465
            }
13466
            else
13467
        #endif
13468
            {
13469
                AES_GCM_decrypt_update_AARCH64((byte*)aes->key,
13470
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
13471
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13472
            }
13473
            /* Skip over to end of blocks. */
13474
            c += blocks * WC_AES_BLOCK_SIZE;
13475
            p += blocks * WC_AES_BLOCK_SIZE;
13476
        }
13477
        if (partial != 0) {
13478
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
13479
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13480
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13481
            if (aes->use_sha3_hw_crypto) {
13482
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
13483
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
13484
                    AES_COUNTER(aes));
13485
            }
13486
            else
13487
        #endif
13488
            {
13489
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
13490
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13491
            }
13492
            /* Keep cipher text for GHASH of last partial block. */
13493
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
13494
            /* XOR the remaining cipher text to calculate plaintext. */
13495
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
13496
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
13497
            /* Update count of the block used. */
13498
            aes->cOver = (byte)partial;
13499
        }
13500
    }
13501
13502
    return 0;
13503
}
13504
13505
/* Finalize the AES GCM for decryption and check the authentication tag.
13506
 *
13507
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
13508
 *
13509
 * @param [in, out] aes        AES object.
13510
 * @param [in]      authTag    Buffer holding authentication tag.
13511
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13512
 * @return  0 on success.
13513
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
13514
 *          value.
13515
 */
13516
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_AARCH64(
13517
    Aes* aes, const byte* authTag, word32 authTagSz)
13518
{
13519
    int ret = 0;
13520
    int res;
13521
    /* AAD block incomplete when > 0 */
13522
    byte over = aes->aOver;
13523
    byte *lastBlock = AES_LASTGBLOCK(aes);
13524
13525
    ASSERT_SAVED_VECTOR_REGISTERS();
13526
13527
    if (aes->cOver > 0) {
13528
        /* Cipher text block incomplete. */
13529
        over = aes->cOver;
13530
        lastBlock = AES_LASTBLOCK(aes);
13531
    }
13532
    if (over > 0) {
13533
        /* Zeroize the unused part of the block. */
13534
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
13535
        /* Hash the last block of cipher text. */
13536
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13537
        if (aes->use_sha3_hw_crypto) {
13538
            AES_GCM_ghash_block_AARCH64_EOR3(lastBlock, AES_TAG(aes),
13539
                aes->gcm.H);
13540
        }
13541
        else
13542
    #endif
13543
        {
13544
            AES_GCM_ghash_block_AARCH64(lastBlock, AES_TAG(aes), aes->gcm.H);
13545
        }
13546
    }
13547
    /* Calculate and compare the authentication tag. */
13548
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13549
    if (aes->use_sha3_hw_crypto) {
13550
        AES_GCM_decrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
13551
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13552
    }
13553
    else
13554
#endif
13555
    {
13556
        AES_GCM_decrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
13557
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13558
    }
13559
13560
    /* Return error code when calculated doesn't match input. */
13561
    if (res == 0) {
13562
        ret = AES_GCM_AUTH_E;
13563
    }
13564
    return ret;
13565
}
13566
#endif
13567
#endif
13568
13569
/* AES_GCM_H_PTR is defined earlier (before wc_AesGcmEncrypt). */
13570
#if defined(WOLFSSL_RISCV_ASM) && defined(WOLFSSL_AESGCM_STREAM)
13571
13572
static WARN_UNUSED_RESULT int AesGcmInit_RISCV64(Aes* aes, const byte* iv,
13573
    word32 ivSz)
13574
{
13575
    /* Reset state fields. */
13576
    aes->over = 0;
13577
    aes->aSz = 0;
13578
    aes->cSz = 0;
13579
    /* Set tag to all zeros as initial value. */
13580
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
13581
    /* Reset counts of AAD and cipher text. */
13582
    aes->aOver = 0;
13583
    aes->cOver = 0;
13584
13585
    {
13586
        AES_GCM_init_RISCV64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
13587
            AES_GCM_H_PTR(aes), AES_COUNTER(aes), AES_INITCTR(aes));
13588
    }
13589
13590
    return 0;
13591
}
13592
13593
/* Update the AES GCM for encryption with authentication data.
13594
 *
13595
 * Implementation uses RISC-V optimized assembly code.
13596
 *
13597
 * @param [in, out] aes   AES object.
13598
 * @param [in]      a     Buffer holding authentication data.
13599
 * @param [in]      aSz   Length of authentication data in bytes.
13600
 * @param [in]      endA  Whether no more authentication data is expected.
13601
 */
13602
static WARN_UNUSED_RESULT int AesGcmAadUpdate_RISCV64(
13603
    Aes* aes, const byte* a, word32 aSz, int endA)
13604
{
13605
    word32 blocks;
13606
    int partial;
13607
13608
    if (aSz != 0 && a != NULL) {
13609
        /* Total count of AAD updated. */
13610
        aes->aSz += aSz;
13611
        /* Check if we have unprocessed data. */
13612
        if (aes->aOver > 0) {
13613
            /* Calculate amount we can use - fill up the block. */
13614
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
13615
            if (sz > aSz) {
13616
                sz = (byte)aSz;
13617
            }
13618
            /* Copy extra into last GHASH block array and update count. */
13619
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
13620
            aes->aOver = (byte)(aes->aOver + sz);
13621
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
13622
                /* We have filled up the block and can process. */
13623
                {
13624
                    AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes),
13625
                        AES_TAG(aes), AES_GCM_H_PTR(aes));
13626
                }
13627
                /* Reset count. */
13628
                aes->aOver = 0;
13629
            }
13630
            /* Used up some data. */
13631
            aSz -= sz;
13632
            a += sz;
13633
        }
13634
13635
        /* Calculate number of blocks of AAD and the leftover. */
13636
        blocks = aSz / WC_AES_BLOCK_SIZE;
13637
        partial = aSz % WC_AES_BLOCK_SIZE;
13638
        if (blocks > 0) {
13639
            /* GHASH full blocks now. */
13640
            {
13641
                AES_GCM_aad_update_RISCV64(a, blocks * WC_AES_BLOCK_SIZE,
13642
                    AES_TAG(aes), AES_GCM_H_PTR(aes));
13643
            }
13644
            /* Skip over to end of AAD blocks. */
13645
            a += blocks * WC_AES_BLOCK_SIZE;
13646
        }
13647
        if (partial != 0) {
13648
            /* Cache the partial block. */
13649
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
13650
            aes->aOver = (byte)partial;
13651
        }
13652
    }
13653
    if (endA && (aes->aOver > 0)) {
13654
        /* No more AAD coming and we have a partial block. */
13655
        /* Fill the rest of the block with zeros. */
13656
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
13657
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
13658
        /* GHASH last AAD block. */
13659
        {
13660
            AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes),
13661
                AES_TAG(aes), AES_GCM_H_PTR(aes));
13662
        }
13663
        /* Clear partial count for next time through. */
13664
        aes->aOver = 0;
13665
    }
13666
13667
    return 0;
13668
}
13669
13670
/* Update the AES GCM for encryption with data and/or authentication data.
13671
 *
13672
 * Implementation uses RISC-V optimized assembly code.
13673
 *
13674
 * @param [in, out] aes  AES object.
13675
 * @param [out]     c    Buffer to hold cipher text.
13676
 * @param [in]      p    Buffer holding plaintext.
13677
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13678
 * @param [in]      a    Buffer holding authentication data.
13679
 * @param [in]      aSz  Length of authentication data in bytes.
13680
 */
13681
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_RISCV64(
13682
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
13683
{
13684
    word32 blocks;
13685
    int partial;
13686
    int ret;
13687
13688
    /* Hash in A, the Authentication Data */
13689
    ret = AesGcmAadUpdate_RISCV64(aes, a, aSz, (cSz > 0) && (c != NULL));
13690
    if (ret != 0)
13691
        return ret;
13692
13693
    /* Encrypt plaintext and Hash in C, the Cipher text */
13694
    if (cSz != 0 && c != NULL) {
13695
        /* Update count of cipher text we have hashed. */
13696
        aes->cSz += cSz;
13697
        if (aes->cOver > 0) {
13698
            /* Calculate amount we can use - fill up the block. */
13699
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13700
            if (sz > cSz) {
13701
                sz = (byte)cSz;
13702
            }
13703
            /* Encrypt some of the plaintext. */
13704
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
13705
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13706
            /* Update count of unused encrypted counter. */
13707
            aes->cOver = (byte)(aes->cOver + sz);
13708
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13709
                /* We have filled up the block and can process. */
13710
                {
13711
                    AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes),
13712
                        AES_TAG(aes), AES_GCM_H_PTR(aes));
13713
                }
13714
                /* Reset count. */
13715
                aes->cOver = 0;
13716
            }
13717
            /* Used up some data. */
13718
            cSz -= sz;
13719
            p += sz;
13720
            c += sz;
13721
        }
13722
13723
        /* Calculate number of blocks of plaintext and the leftover. */
13724
        blocks = cSz / WC_AES_BLOCK_SIZE;
13725
        partial = cSz % WC_AES_BLOCK_SIZE;
13726
        if (blocks > 0) {
13727
            /* Encrypt and GHASH full blocks now. */
13728
            {
13729
                AES_GCM_encrypt_update_RISCV64((byte*)aes->key,
13730
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
13731
                    AES_TAG(aes), AES_GCM_H_PTR(aes), AES_COUNTER(aes));
13732
            }
13733
            /* Skip over to end of blocks. */
13734
            p += blocks * WC_AES_BLOCK_SIZE;
13735
            c += blocks * WC_AES_BLOCK_SIZE;
13736
        }
13737
        if (partial != 0) {
13738
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
13739
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13740
            {
13741
                AES_GCM_encrypt_block_RISCV64((byte*)aes->key, (int)aes->rounds,
13742
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13743
            }
13744
            /* XOR the remaining plaintext to calculate cipher text.
13745
             * Keep cipher text for GHASH of last partial block.
13746
             */
13747
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
13748
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
13749
            /* Update count of the block used. */
13750
            aes->cOver = (byte)partial;
13751
        }
13752
    }
13753
    return 0;
13754
}
13755
13756
/* Finalize the AES GCM for encryption and calculate the authentication tag.
13757
 *
13758
 * Calls ARCH64 optimized assembly code.
13759
 *
13760
 * @param [in, out] aes        AES object.
13761
 * @param [in]      authTag    Buffer to hold authentication tag.
13762
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13763
 * @return  0 on success.
13764
 */
13765
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_RISCV64(Aes* aes,
13766
    byte* authTag, word32 authTagSz)
13767
{
13768
    /* AAD block incomplete when > 0 */
13769
    byte over = aes->aOver;
13770
13771
13772
    if (aes->cOver > 0) {
13773
        /* Cipher text block incomplete. */
13774
        over = aes->cOver;
13775
    }
13776
    if (over > 0) {
13777
        /* Fill the rest of the block with zeros. */
13778
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
13779
            (size_t)WC_AES_BLOCK_SIZE - over);
13780
        /* GHASH last cipher block. */
13781
        {
13782
            AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes), AES_TAG(aes),
13783
                AES_GCM_H_PTR(aes));
13784
        }
13785
    }
13786
    /* Calculate the authentication tag. */
13787
    {
13788
        AES_GCM_encrypt_final_RISCV64(AES_TAG(aes), authTag, authTagSz,
13789
            aes->cSz, aes->aSz, AES_GCM_H_PTR(aes), AES_INITCTR(aes));
13790
    }
13791
13792
    return 0;
13793
}
13794
13795
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
13796
/* Update the AES GCM for decryption with data and/or authentication data.
13797
 *
13798
 * @param [in, out] aes  AES object.
13799
 * @param [out]     p    Buffer to hold plaintext.
13800
 * @param [in]      c    Buffer holding cipher text.
13801
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13802
 * @param [in]      a    Buffer holding authentication data.
13803
 * @param [in]      aSz  Length of authentication data in bytes.
13804
 */
13805
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_RISCV64(Aes* aes, byte* p,
13806
    const byte* c, word32 cSz, const byte* a, word32 aSz)
13807
{
13808
    word32 blocks;
13809
    int partial;
13810
    int ret;
13811
13812
    /* Hash in A, the Authentication Data */
13813
    ret = AesGcmAadUpdate_RISCV64(aes, a, aSz, cSz > 0);
13814
    if (ret != 0)
13815
        return ret;
13816
13817
    /* Hash in C, the Cipher text, and decrypt. */
13818
    if (cSz != 0 && p != NULL) {
13819
        /* Update count of cipher text we have hashed. */
13820
        aes->cSz += cSz;
13821
        if (aes->cOver > 0) {
13822
            /* Calculate amount we can use - fill up the block. */
13823
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13824
            if (sz > cSz) {
13825
                sz = (byte)cSz;
13826
            }
13827
            /* Keep a copy of the cipher text for GHASH. */
13828
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
13829
            /* Decrypt some of the cipher text. */
13830
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
13831
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13832
            /* Update count of unused encrypted counter. */
13833
            aes->cOver = (byte)(aes->cOver + sz);
13834
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13835
                /* We have filled up the block and can process. */
13836
                {
13837
                    AES_GCM_ghash_block_RISCV64(AES_LASTBLOCK(aes),
13838
                        AES_TAG(aes), AES_GCM_H_PTR(aes));
13839
                }
13840
                /* Reset count. */
13841
                aes->cOver = 0;
13842
            }
13843
            /* Used up some data. */
13844
            cSz -= sz;
13845
            c += sz;
13846
            p += sz;
13847
        }
13848
13849
        /* Calculate number of blocks of plaintext and the leftover. */
13850
        blocks = cSz / WC_AES_BLOCK_SIZE;
13851
        partial = cSz % WC_AES_BLOCK_SIZE;
13852
        if (blocks > 0) {
13853
            /* Decrypt and GHASH full blocks now. */
13854
            {
13855
                AES_GCM_decrypt_update_RISCV64((byte*)aes->key,
13856
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
13857
                    AES_TAG(aes), AES_GCM_H_PTR(aes), AES_COUNTER(aes));
13858
            }
13859
            /* Skip over to end of blocks. */
13860
            c += blocks * WC_AES_BLOCK_SIZE;
13861
            p += blocks * WC_AES_BLOCK_SIZE;
13862
        }
13863
        if (partial != 0) {
13864
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
13865
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13866
            {
13867
                AES_GCM_encrypt_block_RISCV64((byte*)aes->key, (int)aes->rounds,
13868
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13869
            }
13870
            /* Keep cipher text for GHASH of last partial block. */
13871
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
13872
            /* XOR the remaining cipher text to calculate plaintext. */
13873
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
13874
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
13875
            /* Update count of the block used. */
13876
            aes->cOver = (byte)partial;
13877
        }
13878
    }
13879
13880
    return 0;
13881
}
13882
13883
/* Finalize the AES GCM for decryption and check the authentication tag.
13884
 *
13885
 * Implementation uses RISC-V optimized assembly code.
13886
 *
13887
 * @param [in, out] aes        AES object.
13888
 * @param [in]      authTag    Buffer holding authentication tag.
13889
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13890
 * @return  0 on success.
13891
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
13892
 *          value.
13893
 */
13894
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_RISCV64(
13895
    Aes* aes, const byte* authTag, word32 authTagSz)
13896
{
13897
    int ret = 0;
13898
    int res;
13899
    /* AAD block incomplete when > 0 */
13900
    byte over = aes->aOver;
13901
    byte *lastBlock = AES_LASTGBLOCK(aes);
13902
13903
13904
    if (aes->cOver > 0) {
13905
        /* Cipher text block incomplete. */
13906
        over = aes->cOver;
13907
        lastBlock = AES_LASTBLOCK(aes);
13908
    }
13909
    if (over > 0) {
13910
        /* Zeroize the unused part of the block. */
13911
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
13912
        /* Hash the last block of cipher text. */
13913
        {
13914
            AES_GCM_ghash_block_RISCV64(lastBlock, AES_TAG(aes), AES_GCM_H_PTR(aes));
13915
        }
13916
    }
13917
    /* Calculate and compare the authentication tag. */
13918
    {
13919
        AES_GCM_decrypt_final_RISCV64(AES_TAG(aes), authTag, authTagSz,
13920
            aes->cSz, aes->aSz, AES_GCM_H_PTR(aes), AES_INITCTR(aes), &res);
13921
    }
13922
13923
    /* Return error code when calculated doesn't match input. */
13924
    if (res == 0) {
13925
        ret = AES_GCM_AUTH_E;
13926
    }
13927
    return ret;
13928
}
13929
#endif
13930
#endif /* WOLFSSL_RISCV_ASM && WOLFSSL_AESGCM_STREAM */
13931
13932
/* Initialize an AES GCM cipher for encryption or decryption.
13933
 *
13934
 * Must call wc_AesInit() before calling this function.
13935
 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
13936
 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
13937
 *
13938
 * @param [in, out] aes   AES object.
13939
 * @param [in]      key   Buffer holding key.
13940
 * @param [in]      len   Length of key in bytes.
13941
 * @param [in]      iv    Buffer holding IV/nonce.
13942
 * @param [in]      ivSz  Length of IV/nonce in bytes.
13943
 * @return  0 on success.
13944
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
13945
 *          is NULL, or the IV is NULL and no previous IV has been set.
13946
 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
13947
 */
13948
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
13949
    word32 ivSz)
13950
1.07k
{
13951
1.07k
    int ret = 0;
13952
13953
    /* Check validity of parameters. */
13954
1.07k
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
13955
1.07k
            ((ivSz == 0) && (iv != NULL)) ||
13956
1.07k
            ((ivSz > 0) && (iv == NULL))) {
13957
0
        ret = BAD_FUNC_ARG;
13958
0
    }
13959
13960
1.07k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
13961
1.07k
    if ((ret == 0) && (aes->streamData == NULL)) {
13962
        /* Allocate buffers for streaming. */
13963
460
        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
13964
460
        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
13965
460
                                                              DYNAMIC_TYPE_AES);
13966
460
        if (aes->streamData == NULL) {
13967
0
            ret = MEMORY_E;
13968
0
        }
13969
460
    }
13970
1.07k
#endif
13971
13972
    /* Set the key if passed in. */
13973
1.07k
    if ((ret == 0) && (key != NULL)) {
13974
460
        ret = wc_AesGcmSetKey(aes, key, len);
13975
460
    }
13976
13977
1.07k
    if (ret == 0) {
13978
        /* Set the IV passed in if it is smaller than a block. */
13979
1.07k
        if ((iv != NULL) && (ivSz <= WC_AES_BLOCK_SIZE)) {
13980
1.07k
            XMEMMOVE((byte*)aes->reg, iv, ivSz);
13981
1.07k
            aes->nonceSz = ivSz;
13982
1.07k
        }
13983
        /* No IV passed in, check for cached IV. */
13984
1.07k
        if ((iv == NULL) && (aes->nonceSz != 0)) {
13985
            /* Use the cached copy. */
13986
0
            iv = (byte*)aes->reg;
13987
0
            ivSz = aes->nonceSz;
13988
0
        }
13989
13990
1.07k
        if (iv != NULL) {
13991
            /* Initialize with the IV. */
13992
13993
        #ifdef WOLFSSL_AESNI
13994
            if (aes->use_aesni) {
13995
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
13996
                ret = AesGcmInit_aesni(aes, iv, ivSz);
13997
                RESTORE_VECTOR_REGISTERS();
13998
            }
13999
            else
14000
        #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14001
              !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14002
            if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14003
                ret = AesGcmInit_AARCH64(aes, iv, ivSz);
14004
            }
14005
            else
14006
        #elif defined(WOLFSSL_RISCV_ASM)
14007
            ret = AesGcmInit_RISCV64(aes, iv, ivSz);
14008
            if (0)
14009
        #endif /* WOLFSSL_AESNI */
14010
1.07k
            {
14011
1.07k
                ret = AesGcmInit_C(aes, iv, ivSz);
14012
1.07k
            }
14013
14014
1.07k
            if (ret == 0)
14015
1.07k
                aes->nonceSet = 1;
14016
1.07k
        }
14017
1.07k
    }
14018
14019
1.07k
    return ret;
14020
1.07k
}
14021
14022
/* Initialize an AES GCM cipher for encryption.
14023
 *
14024
 * Must call wc_AesInit() before calling this function.
14025
 *
14026
 * @param [in, out] aes   AES object.
14027
 * @param [in]      key   Buffer holding key.
14028
 * @param [in]      len   Length of key in bytes.
14029
 * @param [in]      iv    Buffer holding IV/nonce.
14030
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14031
 * @return  0 on success.
14032
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
14033
 *          is NULL, or the IV is NULL and no previous IV has been set.
14034
 */
14035
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
14036
    word32 ivSz)
14037
0
{
14038
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
14039
0
}
14040
14041
/* Initialize an AES GCM cipher for encryption. Get IV.
14042
 *
14043
 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
14044
 * function.
14045
 * Must call wc_AesInit() before calling this function.
14046
 *
14047
 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
14048
 *
14049
 * @param [in, out] aes   AES object.
14050
 * @param [in]      key   Buffer holding key.
14051
 * @param [in]      len   Length of key in bytes.
14052
 * @param [in]      iv    Buffer holding IV/nonce.
14053
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14054
 * @return  0 on success.
14055
 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
14056
 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
14057
 *          nonce size.
14058
 */
14059
int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
14060
    word32 ivOutSz)
14061
0
{
14062
0
    int ret;
14063
14064
    /* Check validity of parameters. */
14065
0
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
14066
0
        ret = BAD_FUNC_ARG;
14067
0
    }
14068
0
    else {
14069
        /* Copy out the IV including generated part for decryption. */
14070
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
14071
        /* Initialize AES GCM cipher with key and cached Iv. */
14072
0
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
14073
0
    }
14074
14075
0
    return ret;
14076
0
}
14077
14078
/* Update the AES GCM for encryption with data and/or authentication data. */
14079
int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
14080
    const byte* authIn, word32 authInSz)
14081
4.46k
{
14082
4.46k
    int ret = 0;
14083
14084
    /* Check validity of parameters. */
14085
4.46k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
14086
645
            ((out == NULL) || (in == NULL)))) {
14087
0
        ret = BAD_FUNC_ARG;
14088
0
    }
14089
14090
    /* Check key has been set. */
14091
4.46k
    if ((ret == 0) && (!aes->gcmKeySet)) {
14092
0
        ret = MISSING_KEY;
14093
0
    }
14094
    /* Check IV has been set. */
14095
4.46k
    if ((ret == 0) && (!aes->nonceSet)) {
14096
0
        ret = MISSING_IV;
14097
0
    }
14098
14099
    /* Prevent overflow of aes->cSz and ->aSz.  Per NIST SP 800-38D section
14100
     * 5.2.1.1, the maximum allowed ciphertext limit is 2^32 - 2 blocks, but we
14101
     * currently pass around the cumulative sizes in bytes as word32s, so we
14102
     * can't currently support the maximum allowed.
14103
     */
14104
4.46k
    if ((ret == 0) &&
14105
4.46k
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
14106
4.46k
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
14107
0
    {
14108
0
        ret = AES_GCM_OVERFLOW_E;
14109
0
    }
14110
14111
4.46k
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
14112
294
        aes->invokeCtr[0]++;
14113
294
        if (aes->invokeCtr[0] == 0) {
14114
0
            aes->invokeCtr[1]++;
14115
0
            if (aes->invokeCtr[1] == 0)
14116
0
                ret = AES_GCM_OVERFLOW_E;
14117
0
        }
14118
294
    }
14119
14120
4.46k
    if (ret == 0) {
14121
        /* Encrypt with AAD and/or plaintext. */
14122
14123
    #ifdef WOLFSSL_AESNI
14124
        if (aes->use_aesni) {
14125
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14126
            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
14127
            RESTORE_VECTOR_REGISTERS();
14128
        }
14129
        else
14130
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14131
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14132
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14133
            ret = AesGcmEncryptUpdate_AARCH64(aes, out, in, sz, authIn,
14134
                authInSz);
14135
        }
14136
        else
14137
    #elif defined(WOLFSSL_RISCV_ASM)
14138
        ret = AesGcmEncryptUpdate_RISCV64(aes, out, in, sz, authIn, authInSz);
14139
        if (0)
14140
    #endif
14141
4.46k
        {
14142
            /* Encrypt the plaintext. */
14143
4.46k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
14144
4.46k
            if (ret == 0) {
14145
                /* Update the authentication tag with any authentication data and the
14146
                 * new cipher text. */
14147
4.46k
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
14148
4.46k
            }
14149
4.46k
        }
14150
4.46k
    }
14151
14152
4.46k
    return ret;
14153
4.46k
}
14154
14155
/* Finalize the AES GCM for encryption and return the authentication tag.
14156
 *
14157
 * Must set key and IV before calling this function.
14158
 * Must call wc_AesGcmInit() before calling this function.
14159
 *
14160
 * @param [in, out] aes        AES object.
14161
 * @param [out]     authTag    Buffer to hold authentication tag.
14162
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14163
 * @return  0 on success.
14164
 */
14165
int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
14166
240
{
14167
240
    int ret = 0;
14168
14169
    /* Check validity of parameters. */
14170
240
    if ((aes == NULL) || (authTag == NULL)) {
14171
0
        ret = BAD_FUNC_ARG;
14172
0
    }
14173
14174
240
    if (ret == 0)
14175
240
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
14176
14177
    /* Check key has been set. */
14178
240
    if ((ret == 0) && (!aes->gcmKeySet)) {
14179
0
        ret = MISSING_KEY;
14180
0
    }
14181
    /* Check IV has been set. */
14182
240
    if ((ret == 0) && (!aes->nonceSet)) {
14183
0
        ret = MISSING_IV;
14184
0
    }
14185
14186
240
    if (ret == 0) {
14187
        /* Calculate authentication tag. */
14188
    #ifdef WOLFSSL_AESNI
14189
        if (aes->use_aesni) {
14190
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14191
            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
14192
            RESTORE_VECTOR_REGISTERS();
14193
        }
14194
        else
14195
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14196
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14197
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14198
            ret = AesGcmEncryptFinal_AARCH64(aes, authTag, authTagSz);
14199
        }
14200
        else
14201
    #elif defined(WOLFSSL_RISCV_ASM)
14202
        ret = AesGcmEncryptFinal_RISCV64(aes, authTag, authTagSz);
14203
        if (0)
14204
    #endif
14205
240
        {
14206
240
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
14207
240
        }
14208
240
    }
14209
14210
240
    if ((ret == 0) && aes->ctrSet) {
14211
240
        IncCtr((byte*)aes->reg, aes->nonceSz);
14212
240
    }
14213
14214
240
    return ret;
14215
240
}
14216
14217
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
14218
/* Initialize an AES GCM cipher for decryption.
14219
 *
14220
 * Must call wc_AesInit() before calling this function.
14221
 *
14222
 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
14223
 * instead.
14224
 *
14225
 * @param [in, out] aes   AES object.
14226
 * @param [in]      key   Buffer holding key.
14227
 * @param [in]      len   Length of key in bytes.
14228
 * @param [in]      iv    Buffer holding IV/nonce.
14229
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14230
 * @return  0 on success.
14231
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
14232
 *          is NULL, or the IV is NULL and no previous IV has been set.
14233
 */
14234
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
14235
    word32 ivSz)
14236
0
{
14237
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
14238
0
}
14239
14240
/* Update the AES GCM for decryption with data and/or authentication data. */
14241
int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
14242
    const byte* authIn, word32 authInSz)
14243
1.87k
{
14244
1.87k
    int ret = 0;
14245
14246
    /* Check validity of parameters. */
14247
1.87k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
14248
30
            ((out == NULL) || (in == NULL)))) {
14249
0
        ret = BAD_FUNC_ARG;
14250
0
    }
14251
14252
    /* Check key has been set. */
14253
1.87k
    if ((ret == 0) && (!aes->gcmKeySet)) {
14254
0
        ret = MISSING_KEY;
14255
0
    }
14256
    /* Check IV has been set. */
14257
1.87k
    if ((ret == 0) && (!aes->nonceSet)) {
14258
0
        ret = MISSING_IV;
14259
0
    }
14260
14261
    /* Prevent overflow of aes->cSz and ->aSz.  Per NIST SP 800-38D section
14262
     * 5.2.1.1, the maximum allowed ciphertext limit is 2^32 - 2 blocks, but we
14263
     * currently pass around the cumulative sizes in bytes as word32s, so we
14264
     * can't currently support the maximum allowed.
14265
     */
14266
1.87k
    if ((ret == 0) &&
14267
1.87k
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
14268
1.87k
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
14269
0
    {
14270
0
        ret = AES_GCM_OVERFLOW_E;
14271
0
    }
14272
14273
1.87k
    if (ret == 0) {
14274
        /* Decrypt with AAD and/or cipher text. */
14275
    #ifdef WOLFSSL_AESNI
14276
        if (aes->use_aesni) {
14277
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14278
            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
14279
            RESTORE_VECTOR_REGISTERS();
14280
        }
14281
        else
14282
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14283
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14284
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14285
            ret = AesGcmDecryptUpdate_AARCH64(aes, out, in, sz, authIn,
14286
                authInSz);
14287
        }
14288
        else
14289
    #elif defined(WOLFSSL_RISCV_ASM)
14290
        ret = AesGcmDecryptUpdate_RISCV64(aes, out, in, sz, authIn, authInSz);
14291
        if (0)
14292
    #endif
14293
1.87k
        {
14294
            /* Update the authentication tag with any authentication data and
14295
             * cipher text. */
14296
1.87k
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
14297
            /* Decrypt the cipher text. */
14298
1.87k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
14299
1.87k
        }
14300
1.87k
    }
14301
14302
1.87k
    return ret;
14303
1.87k
}
14304
14305
/* Finalize the AES GCM for decryption and check the authentication tag.
14306
 *
14307
 * Must set key and IV before calling this function.
14308
 * Must call wc_AesGcmInit() before calling this function.
14309
 *
14310
 * @param [in, out] aes        AES object.
14311
 * @param [in]      authTag    Buffer holding authentication tag.
14312
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14313
 * @return  0 on success.
14314
 */
14315
int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
14316
129
{
14317
129
    int ret = 0;
14318
14319
    /* Check validity of parameters. */
14320
129
    if ((aes == NULL) || (authTag == NULL)) {
14321
0
        ret = BAD_FUNC_ARG;
14322
0
    }
14323
14324
129
    if (ret == 0)
14325
129
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
14326
14327
    /* Check key has been set. */
14328
129
    if ((ret == 0) && (!aes->gcmKeySet)) {
14329
0
        ret = MISSING_KEY;
14330
0
    }
14331
    /* Check IV has been set. */
14332
129
    if ((ret == 0) && (!aes->nonceSet)) {
14333
0
        ret = MISSING_IV;
14334
0
    }
14335
14336
129
    if (ret == 0) {
14337
        /* Calculate authentication tag and compare with one passed in.. */
14338
    #ifdef WOLFSSL_AESNI
14339
        if (aes->use_aesni) {
14340
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14341
            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
14342
            RESTORE_VECTOR_REGISTERS();
14343
        }
14344
        else
14345
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14346
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14347
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14348
            ret = AesGcmDecryptFinal_AARCH64(aes, authTag, authTagSz);
14349
        }
14350
        else
14351
    #elif defined(WOLFSSL_RISCV_ASM)
14352
        ret = AesGcmDecryptFinal_RISCV64(aes, authTag, authTagSz);
14353
        if (0)
14354
    #endif
14355
118
        {
14356
118
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
14357
            /* Calculate authentication tag. */
14358
118
            ret = AesGcmFinal_C(aes, calcTag, WC_AES_BLOCK_SIZE);
14359
118
            if (ret == 0) {
14360
                /* Check calculated tag matches the one passed in. */
14361
118
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
14362
117
                    ret = AES_GCM_AUTH_E;
14363
117
                }
14364
118
            }
14365
118
        }
14366
118
    }
14367
14368
129
    return ret;
14369
129
}
14370
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
14371
#endif /* WOLFSSL_AESGCM_STREAM */
14372
#endif /* WOLFSSL_XILINX_CRYPT */
14373
#endif /* end of block for AESGCM implementation selection */
14374
14375
14376
/* Common to all, abstract functions that build off of lower level AESGCM
14377
 * functions */
14378
#ifndef WC_NO_RNG
14379
14380
1.25k
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
14381
1.25k
    return (ivSz == GCM_NONCE_MIN_SZ ||
14382
1.25k
            ivSz == GCM_NONCE_MID_SZ ||
14383
0
            ivSz == GCM_NONCE_MAX_SZ);
14384
1.25k
}
14385
14386
14387
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
14388
1.12k
{
14389
1.12k
    int ret = 0;
14390
14391
1.12k
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
14392
0
        ret = BAD_FUNC_ARG;
14393
0
    }
14394
14395
1.12k
    if (ret == 0) {
14396
1.12k
        XMEMCPY((byte*)aes->reg, iv, ivSz);
14397
14398
        /* If the IV is 96, allow for a 2^64 invocation counter.
14399
         * For any other size for the nonce, limit the invocation
14400
         * counter to 32-bits. (SP 800-38D 8.3) */
14401
1.12k
        aes->invokeCtr[0] = 0;
14402
1.12k
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
14403
1.12k
    #ifdef WOLFSSL_AESGCM_STREAM
14404
1.12k
        aes->ctrSet = 1;
14405
1.12k
    #endif
14406
1.12k
        aes->nonceSz = ivSz;
14407
1.12k
    }
14408
14409
1.12k
    return ret;
14410
1.12k
}
14411
14412
14413
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
14414
                   const byte* ivFixed, word32 ivFixedSz,
14415
                   WC_RNG* rng)
14416
128
{
14417
128
    int ret = 0;
14418
14419
128
    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
14420
128
        (ivFixed == NULL && ivFixedSz != 0) ||
14421
128
        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
14422
14423
0
        ret = BAD_FUNC_ARG;
14424
0
    }
14425
14426
128
    if (ret == 0) {
14427
128
        byte* iv = (byte*)aes->reg;
14428
14429
128
        if (ivFixedSz)
14430
128
            XMEMCPY(iv, ivFixed, ivFixedSz);
14431
14432
128
        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
14433
128
    }
14434
14435
128
    if (ret == 0) {
14436
        /* If the IV is 96, allow for a 2^64 invocation counter.
14437
         * For any other size for the nonce, limit the invocation
14438
         * counter to 32-bits. (SP 800-38D 8.3) */
14439
126
        aes->invokeCtr[0] = 0;
14440
126
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
14441
126
    #ifdef WOLFSSL_AESGCM_STREAM
14442
126
        aes->ctrSet = 1;
14443
126
    #endif
14444
126
        aes->nonceSz = ivSz;
14445
126
    }
14446
14447
128
    return ret;
14448
128
}
14449
14450
14451
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
14452
                        byte* ivOut, word32 ivOutSz,
14453
                        byte* authTag, word32 authTagSz,
14454
                        const byte* authIn, word32 authInSz)
14455
600
{
14456
600
    int ret = 0;
14457
14458
600
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
14459
600
        ivOut == NULL || ivOutSz != aes->nonceSz ||
14460
600
        (authIn == NULL && authInSz != 0)) {
14461
14462
0
        ret = BAD_FUNC_ARG;
14463
0
    }
14464
14465
600
    if (ret == 0) {
14466
600
        aes->invokeCtr[0]++;
14467
600
        if (aes->invokeCtr[0] == 0) {
14468
0
            aes->invokeCtr[1]++;
14469
0
            if (aes->invokeCtr[1] == 0)
14470
0
                ret = AES_GCM_OVERFLOW_E;
14471
0
        }
14472
600
    }
14473
14474
600
    if (ret == 0) {
14475
600
        XMEMCPY(ivOut, aes->reg, ivOutSz);
14476
600
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
14477
600
                               (byte*)aes->reg, ivOutSz,
14478
600
                               authTag, authTagSz,
14479
600
                               authIn, authInSz);
14480
600
        if (ret == 0)
14481
600
            IncCtr((byte*)aes->reg, ivOutSz);
14482
600
    }
14483
14484
600
    return ret;
14485
600
}
14486
14487
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
14488
            const byte* authIn, word32 authInSz,
14489
            byte* authTag, word32 authTagSz, WC_RNG* rng)
14490
0
{
14491
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
14492
0
    int ret;
14493
14494
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
14495
0
        authTag == NULL || authTagSz == 0 || rng == NULL) {
14496
14497
0
        return BAD_FUNC_ARG;
14498
0
    }
14499
14500
0
#ifdef WOLFSSL_SMALL_STACK
14501
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
14502
#else
14503
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14504
#endif
14505
0
    if (ret != 0)
14506
0
        return ret;
14507
14508
0
    ret = wc_AesGcmSetKey(aes, key, keySz);
14509
0
    if (ret == 0)
14510
0
        ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
14511
0
    if (ret == 0)
14512
0
        ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
14513
0
                                  authTag, authTagSz, authIn, authInSz);
14514
14515
0
#ifdef WOLFSSL_SMALL_STACK
14516
0
    wc_AesDelete(aes, NULL);
14517
#else
14518
    wc_AesFree(aes);
14519
#endif
14520
14521
0
    return ret;
14522
0
}
14523
14524
int wc_GmacVerify(const byte* key, word32 keySz,
14525
                  const byte* iv, word32 ivSz,
14526
                  const byte* authIn, word32 authInSz,
14527
                  const byte* authTag, word32 authTagSz)
14528
0
{
14529
0
    int ret;
14530
0
#ifdef HAVE_AES_DECRYPT
14531
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
14532
14533
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
14534
0
        authTag == NULL || authTagSz == 0 || authTagSz > WC_AES_BLOCK_SIZE) {
14535
14536
0
        return BAD_FUNC_ARG;
14537
0
    }
14538
14539
0
#ifdef WOLFSSL_SMALL_STACK
14540
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
14541
#else
14542
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14543
#endif
14544
0
    if (ret == 0) {
14545
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
14546
0
        if (ret == 0)
14547
0
            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
14548
0
                                  authTag, authTagSz, authIn, authInSz);
14549
14550
0
    }
14551
0
#ifdef WOLFSSL_SMALL_STACK
14552
0
    wc_AesDelete(aes, NULL);
14553
#else
14554
    wc_AesFree(aes);
14555
#endif
14556
#else
14557
    (void)key;
14558
    (void)keySz;
14559
    (void)iv;
14560
    (void)ivSz;
14561
    (void)authIn;
14562
    (void)authInSz;
14563
    (void)authTag;
14564
    (void)authTagSz;
14565
    ret = NOT_COMPILED_IN;
14566
#endif
14567
0
    return ret;
14568
0
}
14569
14570
#endif /* WC_NO_RNG */
14571
14572
14573
int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
14574
0
{
14575
0
    if (gmac == NULL || key == NULL) {
14576
0
        return BAD_FUNC_ARG;
14577
0
    }
14578
0
    return wc_AesGcmSetKey(&gmac->aes, key, len);
14579
0
}
14580
14581
14582
/* Note, wc_GmacUpdate() is not a streaming API, it's a one-shot calculation of
14583
 * the authTag.
14584
 */
14585
int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
14586
                              const byte* authIn, word32 authInSz,
14587
                              byte* authTag, word32 authTagSz)
14588
0
{
14589
0
    if (gmac == NULL) {
14590
0
        return BAD_FUNC_ARG;
14591
0
    }
14592
14593
0
    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
14594
0
                                         authTag, authTagSz, authIn, authInSz);
14595
0
}
14596
14597
#endif /* HAVE_AESGCM */
14598
14599
#ifdef HAVE_AESCCM
14600
14601
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
14602
389
{
14603
389
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
14604
0
        return BAD_FUNC_ARG;
14605
14606
389
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
14607
389
}
14608
14609
14610
/* Checks if the tag size is an accepted value based on RFC 3610 section 2
14611
 * returns 0 if tag size is ok
14612
 */
14613
int wc_AesCcmCheckTagSize(int sz)
14614
589
{
14615
    /* values here are from RFC 3610 section 2 */
14616
589
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
14617
287
            && sz != 16) {
14618
0
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
14619
0
        return BAD_FUNC_ARG;
14620
0
    }
14621
589
    return 0;
14622
589
}
14623
14624
#if defined(HAVE_COLDFIRE_SEC)
14625
    #error "Coldfire SEC doesn't currently support AES-CCM mode"
14626
14627
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
14628
        !defined(WOLFSSL_QNX_CAAM)
14629
    /* implemented in wolfcrypt/src/port/caam_aes.c */
14630
14631
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
14632
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
14633
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14634
                   const byte* nonce, word32 nonceSz,
14635
                   byte* authTag, word32 authTagSz,
14636
                   const byte* authIn, word32 authInSz)
14637
{
14638
    return wc_AesCcmEncrypt_silabs(
14639
        aes, out, in, inSz,
14640
        nonce, nonceSz,
14641
        authTag, authTagSz,
14642
        authIn, authInSz);
14643
}
14644
14645
#ifdef HAVE_AES_DECRYPT
14646
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14647
                   const byte* nonce, word32 nonceSz,
14648
                   const byte* authTag, word32 authTagSz,
14649
                   const byte* authIn, word32 authInSz)
14650
{
14651
    return wc_AesCcmDecrypt_silabs(
14652
        aes, out, in, inSz,
14653
        nonce, nonceSz,
14654
        authTag, authTagSz,
14655
        authIn, authInSz);
14656
}
14657
#endif
14658
#elif defined(FREESCALE_LTC)
14659
14660
/* return 0 on success */
14661
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14662
                   const byte* nonce, word32 nonceSz,
14663
                   byte* authTag, word32 authTagSz,
14664
                   const byte* authIn, word32 authInSz)
14665
{
14666
    byte *key;
14667
    word32 keySize;
14668
    status_t status;
14669
14670
    /* sanity check on arguments */
14671
    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
14672
     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
14673
     * don't allow it here either.
14674
     */
14675
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
14676
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
14677
        return BAD_FUNC_ARG;
14678
    }
14679
14680
    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
14681
        return BAD_FUNC_ARG;
14682
    }
14683
14684
    key = (byte*)aes->key;
14685
14686
    status = wc_AesGetKeySize(aes, &keySize);
14687
    if (status != 0) {
14688
        return status;
14689
    }
14690
14691
    {
14692
        word32 lenSz = (word32)WC_AES_BLOCK_SIZE - 1U - nonceSz;
14693
        /* With a large nonce, B[] runs out of room to represent inSz, and beyond
14694
         * that, the counter itself can wrap.
14695
         */
14696
        if ((lenSz < sizeof(inSz)) &&
14697
            (inSz >= ((word32)1 << (lenSz * 8))))
14698
        {
14699
            return AES_CCM_OVERFLOW_E;
14700
        }
14701
    }
14702
14703
    status = wolfSSL_CryptHwMutexLock();
14704
    if (status != 0)
14705
        return status;
14706
14707
    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
14708
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
14709
    wolfSSL_CryptHwMutexUnLock();
14710
14711
    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
14712
}
14713
14714
#ifdef HAVE_AES_DECRYPT
14715
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14716
                   const byte* nonce, word32 nonceSz,
14717
                   const byte* authTag, word32 authTagSz,
14718
                   const byte* authIn, word32 authInSz)
14719
{
14720
    byte *key;
14721
    word32 keySize;
14722
    status_t status;
14723
14724
    /* sanity check on arguments */
14725
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
14726
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
14727
        return BAD_FUNC_ARG;
14728
    }
14729
14730
    key = (byte*)aes->key;
14731
14732
    status = wc_AesGetKeySize(aes, &keySize);
14733
    if (status != 0) {
14734
        return status;
14735
    }
14736
14737
    {
14738
        word32 lenSz = (word32)WC_AES_BLOCK_SIZE - 1U - nonceSz;
14739
        /* With a large nonce, B[] runs out of room to represent inSz, and beyond
14740
         * that, the counter itself can wrap.
14741
         */
14742
        if ((lenSz < sizeof(inSz)) &&
14743
            (inSz >= ((word32)1 << (lenSz * 8))))
14744
        {
14745
            return AES_CCM_OVERFLOW_E;
14746
        }
14747
    }
14748
14749
    status = wolfSSL_CryptHwMutexLock();
14750
    if (status != 0)
14751
        return status;
14752
    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
14753
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
14754
    wolfSSL_CryptHwMutexUnLock();
14755
14756
    if (status != kStatus_Success) {
14757
        XMEMSET(out, 0, inSz);
14758
        return AES_CCM_AUTH_E;
14759
    }
14760
    return 0;
14761
}
14762
#endif /* HAVE_AES_DECRYPT */
14763
14764
#else
14765
14766
/* Software CCM */
14767
static WARN_UNUSED_RESULT int roll_x(
14768
    Aes* aes, const byte* in, word32 inSz, byte* out)
14769
585
{
14770
585
    int ret;
14771
14772
    /* process the bulk of the data */
14773
22.4k
    while (inSz >= WC_AES_BLOCK_SIZE) {
14774
21.8k
        xorbuf(out, in, WC_AES_BLOCK_SIZE);
14775
21.8k
        in += WC_AES_BLOCK_SIZE;
14776
21.8k
        inSz -= WC_AES_BLOCK_SIZE;
14777
14778
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
14779
         * roll_x() after the AES cache lines are already hot -- no need to
14780
         * absorb additional prefetch overhead here.
14781
         */
14782
21.8k
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
14783
21.8k
        if (ret != 0)
14784
0
            return ret;
14785
21.8k
    }
14786
14787
    /* process remainder of the data */
14788
585
    if (inSz > 0) {
14789
498
        xorbuf(out, in, inSz);
14790
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
14791
         * roll_x() after the AES cache lines are already hot -- no need to
14792
         * absorb additional prefetch overhead here.
14793
         */
14794
498
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
14795
498
        if (ret != 0)
14796
0
            return ret;
14797
498
    }
14798
14799
585
    return 0;
14800
585
}
14801
14802
static WARN_UNUSED_RESULT int roll_auth(
14803
    Aes* aes, const byte* in, word32 inSz, byte* out)
14804
589
{
14805
589
    word32 authLenSz;
14806
589
    word32 remainder;
14807
589
    int ret;
14808
14809
    /* encode the length in */
14810
589
    if (inSz <= 0xFEFF) {
14811
589
        authLenSz = 2;
14812
589
        out[0] ^= (byte)(inSz >> 8);
14813
589
        out[1] ^= (byte)inSz;
14814
589
    }
14815
0
    else {
14816
0
        authLenSz = 6;
14817
0
        out[0] ^= 0xFF;
14818
0
        out[1] ^= 0xFE;
14819
0
        out[2] ^= (byte)(inSz >> 24);
14820
0
        out[3] ^= (byte)(inSz >> 16);
14821
0
        out[4] ^= (byte)(inSz >>  8);
14822
0
        out[5] ^= (byte)inSz;
14823
0
    }
14824
    /* Note, the protocol handles auth data up to 2^64, but we are
14825
     * using 32-bit sizes right now, so the bigger data isn't handled
14826
     * else {}
14827
     */
14828
14829
    /* start fill out the rest of the first block */
14830
589
    remainder = WC_AES_BLOCK_SIZE - authLenSz;
14831
589
    if (inSz >= remainder) {
14832
        /* plenty of bulk data to fill the remainder of this block */
14833
0
        xorbuf(out + authLenSz, in, remainder);
14834
0
        inSz -= remainder;
14835
0
        in += remainder;
14836
0
    }
14837
589
    else {
14838
        /* not enough bulk data, copy what is available, and pad zero */
14839
589
        xorbuf(out + authLenSz, in, inSz);
14840
589
        inSz = 0;
14841
589
    }
14842
    /* wc_AesCcmEncrypt() and wc_AesCcmDecrypt() only call roll_auth() after the
14843
     * AES cache lines are already hot -- no need to absorb additional prefetch
14844
     * overhead here.
14845
     */
14846
589
    ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
14847
14848
589
    if ((ret == 0) && (inSz > 0)) {
14849
0
        ret = roll_x(aes, in, inSz, out);
14850
0
    }
14851
14852
589
    return ret;
14853
589
}
14854
14855
14856
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
14857
21.8k
{
14858
21.8k
    word32 i;
14859
14860
21.9k
    for (i = 0; i < lenSz; i++) {
14861
21.9k
        if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
14862
21.9k
    }
14863
21.8k
}
14864
14865
#ifdef WOLFSSL_AESNI
14866
static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
14867
{
14868
    word32 i;
14869
14870
    /* B+1 = B */
14871
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 1, B, WC_AES_BLOCK_SIZE);
14872
    /* B+2,B+3 = B,B+1 */
14873
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 2, B, WC_AES_BLOCK_SIZE * 2);
14874
14875
    for (i = 0; i < lenSz; i++) {
14876
        if (++B[WC_AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
14877
    }
14878
    B[WC_AES_BLOCK_SIZE * 3 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 3 - 1] + 2U);
14879
    if (B[WC_AES_BLOCK_SIZE * 3 - 1] < 2U) {
14880
        for (i = 1; i < lenSz; i++) {
14881
            if (++B[WC_AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
14882
        }
14883
    }
14884
    B[WC_AES_BLOCK_SIZE * 4 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 4 - 1] + 3U);
14885
    if (B[WC_AES_BLOCK_SIZE * 4 - 1] < 3U) {
14886
        for (i = 1; i < lenSz; i++) {
14887
            if (++B[WC_AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
14888
        }
14889
    }
14890
}
14891
14892
static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
14893
{
14894
    word32 i;
14895
14896
    B[WC_AES_BLOCK_SIZE - 1] = (byte)(B[WC_AES_BLOCK_SIZE - 1] + 4U);
14897
    if (B[WC_AES_BLOCK_SIZE - 1] < 4U) {
14898
        for (i = 1; i < lenSz; i++) {
14899
            if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) break;
14900
        }
14901
    }
14902
}
14903
#endif
14904
14905
/* Software AES - CCM Encrypt */
14906
/* return 0 on success */
14907
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
14908
                   const byte* nonce, word32 nonceSz,
14909
                   byte* authTag, word32 authTagSz,
14910
                   const byte* authIn, word32 authInSz)
14911
505
{
14912
#ifdef WOLFSSL_AESNI
14913
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
14914
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
14915
#else
14916
505
    byte A[WC_AES_BLOCK_SIZE];
14917
505
    byte B[WC_AES_BLOCK_SIZE];
14918
505
#endif
14919
505
    byte lenSz;
14920
505
    word32 i;
14921
505
    byte mask = 0xFF;
14922
505
    const word32 wordSz = (word32)sizeof(word32);
14923
505
    int ret;
14924
14925
    /* sanity check on arguments */
14926
505
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
14927
505
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
14928
505
            authTagSz > WC_AES_BLOCK_SIZE)
14929
0
        return BAD_FUNC_ARG;
14930
14931
    /* Sanity check on authIn to prevent segfault in xorbuf() where
14932
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
14933
505
    if (authIn == NULL && authInSz > 0)
14934
0
        return BAD_FUNC_ARG;
14935
14936
    /* sanity check on tag size */
14937
505
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
14938
0
        return BAD_FUNC_ARG;
14939
0
    }
14940
14941
505
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
14942
14943
    /* With a large nonce, B[] runs out of room to represent inSz, and beyond
14944
     * that, the counter itself can wrap.
14945
     */
14946
505
    if ((lenSz < sizeof(inSz)) &&
14947
505
        (inSz >= ((word32)1 << (lenSz * 8))))
14948
0
    {
14949
0
        return AES_CCM_OVERFLOW_E;
14950
0
    }
14951
14952
505
#ifdef WOLF_CRYPTO_CB
14953
505
    #ifndef WOLF_CRYPTO_CB_FIND
14954
505
    if (aes->devId != INVALID_DEVID)
14955
0
    #endif
14956
0
    {
14957
0
        int crypto_cb_ret =
14958
0
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
14959
0
                                      authTag, authTagSz, authIn, authInSz);
14960
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
14961
0
            return crypto_cb_ret;
14962
        /* fall-through when unavailable */
14963
0
    }
14964
505
#endif
14965
14966
505
    XMEMSET(A, 0, sizeof(A));
14967
505
    XMEMCPY(B+1, nonce, nonceSz);
14968
14969
505
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
14970
505
                  + (8 * (((byte)authTagSz - 2) / 2))
14971
505
                  + (lenSz - 1));
14972
2.02k
    for (i = 0; i < lenSz; i++) {
14973
1.51k
        if (mask && i >= wordSz)
14974
0
            mask = 0x00;
14975
1.51k
        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
14976
1.51k
    }
14977
14978
#ifdef WOLFSSL_CHECK_MEM_ZERO
14979
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
14980
#endif
14981
14982
505
    VECTOR_REGISTERS_PUSH;
14983
    /* note this wc_AesEncrypt() will perform cache prefetches if needed, so
14984
     * that the later encrypt ops don't need to.
14985
     */
14986
505
    ret = wc_AesEncrypt(aes, B, A);
14987
#ifdef WOLFSSL_CHECK_MEM_ZERO
14988
    if (ret == 0)
14989
        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
14990
#endif
14991
14992
505
    if ((ret == 0) && (authInSz > 0))
14993
505
        ret = roll_auth(aes, authIn, authInSz, A);
14994
14995
505
    if ((ret == 0) && (inSz > 0))
14996
505
        ret = roll_x(aes, in, inSz, A);
14997
14998
505
    if (ret == 0) {
14999
505
        XMEMCPY(authTag, A, authTagSz);
15000
15001
505
        B[0] = (byte)(lenSz - 1U);
15002
2.02k
        for (i = 0; i < lenSz; i++)
15003
1.51k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15004
505
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15005
505
    }
15006
15007
505
    if (ret == 0) {
15008
505
        xorbuf(authTag, A, authTagSz);
15009
505
        B[15] = 1;
15010
505
    }
15011
#ifdef WOLFSSL_AESNI
15012
    if ((ret == 0) && aes->use_aesni) {
15013
        while (inSz >= WC_AES_BLOCK_SIZE * 4) {
15014
            AesCcmCtrIncSet4(B, lenSz);
15015
15016
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
15017
                            (int)aes->rounds);
15018
15019
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
15020
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE * 4);
15021
15022
            inSz -= WC_AES_BLOCK_SIZE * 4;
15023
            in += WC_AES_BLOCK_SIZE * 4;
15024
            out += WC_AES_BLOCK_SIZE * 4;
15025
15026
            AesCcmCtrInc4(B, lenSz);
15027
        }
15028
    }
15029
#endif
15030
505
    if (ret == 0) {
15031
15.8k
        while (inSz >= WC_AES_BLOCK_SIZE) {
15032
15.3k
            ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15033
15.3k
            if (ret != 0)
15034
0
                break;
15035
15.3k
            xorbuf(A, in, WC_AES_BLOCK_SIZE);
15036
15.3k
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
15037
15038
15.3k
            AesCcmCtrInc(B, lenSz);
15039
15.3k
            inSz -= WC_AES_BLOCK_SIZE;
15040
15.3k
            in += WC_AES_BLOCK_SIZE;
15041
15.3k
            out += WC_AES_BLOCK_SIZE;
15042
15.3k
        }
15043
505
    }
15044
505
    if ((ret == 0) && (inSz > 0)) {
15045
432
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15046
432
    }
15047
505
    if ((ret == 0) && (inSz > 0)) {
15048
432
        xorbuf(A, in, inSz);
15049
432
        XMEMCPY(out, A, inSz);
15050
432
    }
15051
15052
505
    ForceZero(A, sizeof(A));
15053
505
    ForceZero(B, sizeof(B));
15054
15055
#ifdef WOLFSSL_CHECK_MEM_ZERO
15056
    wc_MemZero_Check(A, sizeof(A));
15057
    wc_MemZero_Check(B, sizeof(B));
15058
#endif
15059
15060
505
    VECTOR_REGISTERS_POP;
15061
15062
505
    return ret;
15063
505
}
15064
15065
#ifdef HAVE_AES_DECRYPT
15066
/* Software AES - CCM Decrypt */
15067
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15068
                   const byte* nonce, word32 nonceSz,
15069
                   const byte* authTag, word32 authTagSz,
15070
                   const byte* authIn, word32 authInSz)
15071
84
{
15072
#ifdef WOLFSSL_AESNI
15073
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
15074
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
15075
#else
15076
84
    byte A[WC_AES_BLOCK_SIZE];
15077
84
    byte B[WC_AES_BLOCK_SIZE];
15078
84
#endif
15079
84
    byte* o;
15080
84
    byte lenSz;
15081
84
    word32 i, oSz;
15082
84
    byte mask = 0xFF;
15083
84
    const word32 wordSz = (word32)sizeof(word32);
15084
84
    int ret = 0;
15085
84
#ifdef WC_AES_HAVE_PREFETCH_ARG
15086
84
    int did_prefetches = 0;
15087
84
#endif
15088
15089
    /* sanity check on arguments */
15090
84
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
15091
84
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
15092
84
        authTagSz > WC_AES_BLOCK_SIZE)
15093
0
        return BAD_FUNC_ARG;
15094
15095
    /* Sanity check on authIn to prevent segfault in xorbuf() where
15096
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
15097
84
    if (authIn == NULL && authInSz > 0)
15098
0
        return BAD_FUNC_ARG;
15099
15100
    /* sanity check on tag size */
15101
84
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
15102
0
        return BAD_FUNC_ARG;
15103
0
    }
15104
15105
84
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
15106
15107
    /* With a large nonce, B[] runs out of room to represent inSz, and beyond
15108
     * that, the counter itself can wrap.
15109
     */
15110
84
    if ((lenSz < sizeof(inSz)) &&
15111
84
        (inSz >= ((word32)1 << (lenSz * 8))))
15112
0
    {
15113
0
        return AES_CCM_OVERFLOW_E;
15114
0
    }
15115
15116
84
#ifdef WOLF_CRYPTO_CB
15117
84
    #ifndef WOLF_CRYPTO_CB_FIND
15118
84
    if (aes->devId != INVALID_DEVID)
15119
0
    #endif
15120
0
    {
15121
0
        int crypto_cb_ret =
15122
0
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
15123
0
            authTag, authTagSz, authIn, authInSz);
15124
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15125
0
            return crypto_cb_ret;
15126
        /* fall-through when unavailable */
15127
0
    }
15128
84
#endif
15129
15130
84
    o = out;
15131
84
    oSz = inSz;
15132
84
    XMEMSET(A, 0, sizeof A);
15133
84
    XMEMCPY(B+1, nonce, nonceSz);
15134
15135
84
    B[0] = (byte)(lenSz - 1U);
15136
336
    for (i = 0; i < lenSz; i++)
15137
252
        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15138
84
    B[15] = 1;
15139
15140
#ifdef WOLFSSL_CHECK_MEM_ZERO
15141
    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
15142
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
15143
#endif
15144
15145
84
    VECTOR_REGISTERS_PUSH;
15146
15147
#ifdef WOLFSSL_AESNI
15148
    if (aes->use_aesni) {
15149
        while (oSz >= WC_AES_BLOCK_SIZE * 4) {
15150
            AesCcmCtrIncSet4(B, lenSz);
15151
15152
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
15153
                            (int)aes->rounds);
15154
15155
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
15156
            XMEMCPY(o, A, WC_AES_BLOCK_SIZE * 4);
15157
15158
            oSz -= WC_AES_BLOCK_SIZE * 4;
15159
            in += WC_AES_BLOCK_SIZE * 4;
15160
            o += WC_AES_BLOCK_SIZE * 4;
15161
15162
            AesCcmCtrInc4(B, lenSz);
15163
        }
15164
    }
15165
#endif
15166
15167
6.63k
    while (oSz >= WC_AES_BLOCK_SIZE) {
15168
6.55k
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15169
6.55k
        if (ret != 0)
15170
0
            break;
15171
6.55k
        xorbuf(A, in, WC_AES_BLOCK_SIZE);
15172
6.55k
        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
15173
6.55k
        AesCcmCtrInc(B, lenSz);
15174
6.55k
        oSz -= WC_AES_BLOCK_SIZE;
15175
6.55k
        in += WC_AES_BLOCK_SIZE;
15176
6.55k
        o += WC_AES_BLOCK_SIZE;
15177
6.55k
    }
15178
15179
84
    if ((ret == 0) && (inSz > 0))
15180
80
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15181
15182
84
    if ((ret == 0) && (inSz > 0)) {
15183
80
        xorbuf(A, in, oSz);
15184
80
        XMEMCPY(o, A, oSz);
15185
320
        for (i = 0; i < lenSz; i++)
15186
240
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15187
80
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15188
80
    }
15189
15190
84
    if (ret == 0) {
15191
84
        o = out;
15192
84
        oSz = inSz;
15193
15194
84
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
15195
84
                      + (8 * (((byte)authTagSz - 2) / 2))
15196
84
                      + (lenSz - 1));
15197
336
        for (i = 0; i < lenSz; i++) {
15198
252
            if (mask && i >= wordSz)
15199
0
                mask = 0x00;
15200
252
            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
15201
252
        }
15202
15203
84
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15204
84
    }
15205
15206
84
    if (ret == 0) {
15207
84
        if (authInSz > 0)
15208
84
            ret = roll_auth(aes, authIn, authInSz, A);
15209
84
    }
15210
84
    if ((ret == 0) && (inSz > 0))
15211
80
        ret = roll_x(aes, o, oSz, A);
15212
15213
84
    if (ret == 0) {
15214
84
        B[0] = (byte)(lenSz - 1U);
15215
336
        for (i = 0; i < lenSz; i++)
15216
252
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15217
84
        ret = AesEncrypt_preFetchOpt(aes, B, B, &did_prefetches);
15218
84
    }
15219
15220
84
    if (ret == 0)
15221
84
        xorbuf(A, B, authTagSz);
15222
15223
84
    if (ret == 0) {
15224
84
        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
15225
            /* If the authTag check fails, don't keep the decrypted data.
15226
             * Unfortunately, you need the decrypted data to calculate the
15227
             * check value. */
15228
            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
15229
                        defined(ACVP_VECTOR_TESTING)
15230
            WOLFSSL_MSG("Preserve output for vector responses");
15231
            #else
15232
84
            if (inSz > 0)
15233
80
                XMEMSET(out, 0, inSz);
15234
84
            #endif
15235
84
            ret = AES_CCM_AUTH_E;
15236
84
        }
15237
84
    }
15238
15239
84
    ForceZero(A, sizeof(A));
15240
84
    ForceZero(B, sizeof(B));
15241
84
    o = NULL;
15242
15243
#ifdef WOLFSSL_CHECK_MEM_ZERO
15244
    wc_MemZero_Check(A, sizeof(A));
15245
    wc_MemZero_Check(B, sizeof(B));
15246
#endif
15247
15248
84
    VECTOR_REGISTERS_POP;
15249
15250
84
    return ret;
15251
84
}
15252
15253
#endif /* HAVE_AES_DECRYPT */
15254
#endif /* software CCM */
15255
15256
/* abstract functions that call lower level AESCCM functions */
15257
#ifndef WC_NO_RNG
15258
15259
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
15260
466
{
15261
466
    int ret = 0;
15262
15263
466
    if (aes == NULL || nonce == NULL ||
15264
466
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
15265
15266
0
        ret = BAD_FUNC_ARG;
15267
0
    }
15268
15269
466
    if (ret == 0) {
15270
466
        XMEMCPY(aes->reg, nonce, nonceSz);
15271
466
        aes->nonceSz = nonceSz;
15272
15273
        /* Invocation counter should be 2^61 */
15274
466
        aes->invokeCtr[0] = 0;
15275
466
        aes->invokeCtr[1] = 0xE0000000;
15276
466
    }
15277
15278
466
    return ret;
15279
466
}
15280
15281
15282
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
15283
                        byte* ivOut, word32 ivOutSz,
15284
                        byte* authTag, word32 authTagSz,
15285
                        const byte* authIn, word32 authInSz)
15286
505
{
15287
505
    int ret = 0;
15288
15289
505
    if (aes == NULL || out == NULL ||
15290
505
        (in == NULL && sz != 0) ||
15291
505
        ivOut == NULL ||
15292
505
        (authIn == NULL && authInSz != 0) ||
15293
505
        (ivOutSz != aes->nonceSz)) {
15294
15295
0
        ret = BAD_FUNC_ARG;
15296
0
    }
15297
15298
505
    if (ret == 0) {
15299
505
        aes->invokeCtr[0]++;
15300
505
        if (aes->invokeCtr[0] == 0) {
15301
0
            aes->invokeCtr[1]++;
15302
0
            if (aes->invokeCtr[1] == 0)
15303
0
                ret = AES_CCM_OVERFLOW_E;
15304
0
        }
15305
505
    }
15306
15307
505
    if (ret == 0) {
15308
505
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
15309
505
                               (byte*)aes->reg, aes->nonceSz,
15310
505
                               authTag, authTagSz,
15311
505
                               authIn, authInSz);
15312
505
        if (ret == 0) {
15313
505
            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
15314
505
            IncCtr((byte*)aes->reg, aes->nonceSz);
15315
505
        }
15316
505
    }
15317
15318
505
    return ret;
15319
505
}
15320
15321
#endif /* WC_NO_RNG */
15322
15323
#endif /* HAVE_AESCCM */
15324
15325
#ifndef WC_NO_CONSTRUCTORS
15326
15327
0
#define AES_NEW_INIT_PLAIN  0
15328
#ifdef WOLF_PRIVATE_KEY_ID
15329
0
#define AES_NEW_INIT_ID     1
15330
0
#define AES_NEW_INIT_LABEL  2
15331
#endif
15332
15333
static Aes* _AesNew_common(void* heap, int devId, int *result_code,
15334
                            int aesInitType, unsigned char* id,
15335
                            int idLen, const char* label)
15336
0
{
15337
0
    int ret;
15338
0
    Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
15339
0
    if (aes == NULL) {
15340
0
        ret = MEMORY_E;
15341
0
    }
15342
0
    else {
15343
0
        switch (aesInitType) {
15344
0
#ifdef WOLF_PRIVATE_KEY_ID
15345
0
        case AES_NEW_INIT_ID:
15346
0
            if (id == NULL || idLen == 0 || label != NULL) {
15347
0
                ret = BAD_FUNC_ARG;
15348
0
            }
15349
0
            else {
15350
0
                ret = wc_AesInit_Id(aes, id, idLen, heap, devId);
15351
0
            }
15352
0
            break;
15353
0
        case AES_NEW_INIT_LABEL:
15354
0
            if (label == NULL || id != NULL || idLen != 0) {
15355
0
                ret = BAD_FUNC_ARG;
15356
0
            }
15357
0
            else {
15358
0
                ret = wc_AesInit_Label(aes, label, heap, devId);
15359
0
            }
15360
0
            break;
15361
0
#endif
15362
0
        default:
15363
0
            if (id != NULL || idLen != 0 || label != NULL) {
15364
0
                ret = BAD_FUNC_ARG;
15365
0
            }
15366
0
            else {
15367
0
                ret = wc_AesInit(aes, heap, devId);
15368
0
            }
15369
0
            break;
15370
0
        }
15371
0
        if (ret != 0) {
15372
0
            XFREE(aes, heap, DYNAMIC_TYPE_AES);
15373
0
            aes = NULL;
15374
0
        }
15375
0
    }
15376
0
    (void)aesInitType;
15377
0
    (void)id;
15378
0
    (void)idLen;
15379
0
    (void)label;
15380
15381
0
    if (result_code != NULL) {
15382
0
        *result_code = ret;
15383
0
    }
15384
15385
0
    return aes;
15386
0
}
15387
15388
Aes* wc_AesNew(void* heap, int devId, int *result_code)
15389
0
{
15390
0
    return _AesNew_common(heap, devId, result_code,
15391
0
                          AES_NEW_INIT_PLAIN, NULL, 0, NULL);
15392
0
}
15393
15394
#ifdef WOLF_PRIVATE_KEY_ID
15395
Aes* wc_AesNew_Id(unsigned char* id, int len, void* heap, int devId,
15396
                   int *result_code)
15397
0
{
15398
0
    return _AesNew_common(heap, devId, result_code,
15399
0
                          AES_NEW_INIT_ID, id, len, NULL);
15400
0
}
15401
15402
Aes* wc_AesNew_Label(const char* label, void* heap, int devId,
15403
                      int *result_code)
15404
0
{
15405
0
    return _AesNew_common(heap, devId, result_code,
15406
0
                          AES_NEW_INIT_LABEL, NULL, 0, label);
15407
0
}
15408
#endif /* WOLF_PRIVATE_KEY_ID */
15409
15410
int wc_AesDelete(Aes *aes, Aes** aes_p)
15411
0
{
15412
0
    void* heap;
15413
0
    if (aes == NULL)
15414
0
        return BAD_FUNC_ARG;
15415
0
    heap = aes->heap;
15416
0
    wc_AesFree(aes);
15417
0
    XFREE(aes, heap, DYNAMIC_TYPE_AES);
15418
0
    if (aes_p != NULL)
15419
0
        *aes_p = NULL;
15420
0
    return 0;
15421
0
}
15422
#endif /* !WC_NO_CONSTRUCTORS */
15423
15424
/* Initialize Aes */
15425
int wc_AesInit(Aes* aes, void* heap, int devId)
15426
4.61k
{
15427
4.61k
    int ret = 0;
15428
15429
4.61k
    if (aes == NULL)
15430
0
        return BAD_FUNC_ARG;
15431
15432
4.61k
    XMEMSET(aes, 0, sizeof(*aes));
15433
15434
4.61k
    aes->heap = heap;
15435
15436
4.61k
#if defined(WOLF_CRYPTO_CB)
15437
4.61k
    aes->devId = devId;
15438
4.61k
    aes->devCtx = NULL;
15439
#else
15440
    (void)devId;
15441
#endif
15442
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
15443
    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
15444
                                                        aes->heap, devId);
15445
#endif /* WOLFSSL_ASYNC_CRYPT */
15446
15447
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
15448
    aes->alFd = WC_SOCK_NOTSET;
15449
    aes->rdFd = WC_SOCK_NOTSET;
15450
#endif
15451
#if defined(WOLFSSL_DEVCRYPTO) && \
15452
   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
15453
    aes->ctx.cfd = -1;
15454
#endif
15455
#if defined(WOLFSSL_IMXRT_DCP)
15456
    DCPAesInit(aes);
15457
#endif
15458
15459
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
15460
    ret = wc_psa_aes_init(aes);
15461
#endif
15462
15463
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
15464
    if (ret == 0)
15465
        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
15466
#endif
15467
15468
4.61k
    return ret;
15469
4.61k
}
15470
15471
#ifdef WOLF_PRIVATE_KEY_ID
15472
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
15473
0
{
15474
0
    int ret = 0;
15475
15476
0
    if (aes == NULL)
15477
0
        ret = BAD_FUNC_ARG;
15478
0
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
15479
0
        ret = BUFFER_E;
15480
15481
0
    if (ret == 0)
15482
0
        ret = wc_AesInit(aes, heap, devId);
15483
0
    if (ret == 0) {
15484
0
        XMEMCPY(aes->id, id, (size_t)len);
15485
0
        aes->idLen = len;
15486
0
        aes->labelLen = 0;
15487
0
    }
15488
15489
0
    return ret;
15490
0
}
15491
15492
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
15493
0
{
15494
0
    int ret = 0;
15495
0
    size_t labelLen = 0;
15496
15497
0
    if (aes == NULL || label == NULL)
15498
0
        ret = BAD_FUNC_ARG;
15499
0
    if (ret == 0) {
15500
0
        labelLen = XSTRLEN(label);
15501
0
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
15502
0
            ret = BUFFER_E;
15503
0
    }
15504
15505
0
    if (ret == 0)
15506
0
        ret = wc_AesInit(aes, heap, devId);
15507
0
    if (ret == 0) {
15508
0
        XMEMCPY(aes->label, label, labelLen);
15509
0
        aes->labelLen = (int)labelLen;
15510
0
        aes->idLen = 0;
15511
0
    }
15512
15513
0
    return ret;
15514
0
}
15515
#endif
15516
15517
/* Free Aes resources */
15518
void wc_AesFree(Aes* aes)
15519
369k
{
15520
369k
    if (aes == NULL) {
15521
364k
        return;
15522
364k
    }
15523
15524
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
15525
    #ifndef WOLF_CRYPTO_CB_FIND
15526
    if (aes->devId != INVALID_DEVID)
15527
    #endif
15528
    {
15529
        int ret = wc_CryptoCb_Free(aes->devId, WC_ALGO_TYPE_CIPHER,
15530
                                   WC_CIPHER_AES, 0, aes);
15531
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
15532
        aes->devCtx = NULL;  /* Clear device context handle */
15533
    #endif
15534
        /* If callback wants standard free, it can set devId to INVALID_DEVID.
15535
         * Otherwise assume the callback handled cleanup. */
15536
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15537
            return;
15538
        /* fall-through when unavailable */
15539
    }
15540
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
15541
15542
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
15543
    (void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
15544
#endif
15545
15546
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
15547
    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
15548
#endif /* WOLFSSL_ASYNC_CRYPT */
15549
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
15550
    if (aes->rdFd > 0) { /* negative is error case */
15551
        close(aes->rdFd);
15552
        aes->rdFd = WC_SOCK_NOTSET;
15553
    }
15554
    if (aes->alFd > 0) {
15555
        close(aes->alFd);
15556
        aes->alFd = WC_SOCK_NOTSET;
15557
    }
15558
#endif /* WOLFSSL_AFALG */
15559
#ifdef WOLFSSL_KCAPI_AES
15560
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
15561
    if (aes->init == 1) {
15562
        kcapi_cipher_destroy(aes->handle);
15563
    }
15564
    aes->init = 0;
15565
    aes->handle = NULL;
15566
#endif
15567
#if defined(WOLFSSL_DEVCRYPTO) && \
15568
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
15569
    wc_DevCryptoFree(&aes->ctx);
15570
#endif
15571
4.61k
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
15572
4.61k
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
15573
4.61k
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
15574
4.61k
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
15575
4.61k
#endif
15576
#if defined(WOLFSSL_IMXRT_DCP)
15577
    DCPAesFree(aes);
15578
#endif
15579
4.61k
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
15580
4.61k
    !defined(WOLFSSL_AESNI)
15581
4.61k
    if (aes->streamData != NULL) {
15582
460
        ForceZero(aes->streamData, aes->streamData_sz);
15583
460
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
15584
460
        aes->streamData = NULL;
15585
460
    }
15586
4.61k
#endif
15587
15588
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
15589
    if (aes->useSWCrypt == 0) {
15590
        se050_aes_free(aes);
15591
    }
15592
#endif
15593
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
15594
    wc_Microchip_aes_free(aes);
15595
#endif
15596
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
15597
    wc_psa_aes_free(aes);
15598
#endif
15599
15600
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
15601
    wc_MAXQ10XX_AesFree(aes);
15602
#endif
15603
15604
#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
15605
    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
15606
    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
15607
    wc_fspsm_Aesfree(aes);
15608
#endif
15609
15610
4.61k
    ForceZero(aes, sizeof(Aes));
15611
15612
#ifdef WOLFSSL_CHECK_MEM_ZERO
15613
    wc_MemZero_Check(aes, sizeof(Aes));
15614
#endif
15615
4.61k
}
15616
15617
int wc_AesGetKeySize(Aes* aes, word32* keySize)
15618
0
{
15619
0
    int ret = 0;
15620
15621
0
    if (aes == NULL || keySize == NULL) {
15622
0
        return BAD_FUNC_ARG;
15623
0
    }
15624
15625
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
15626
    return wc_psa_aes_get_key_size(aes, keySize);
15627
#endif
15628
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
15629
    *keySize = aes->ctx.key.keySize;
15630
    return ret;
15631
#endif
15632
0
    switch (aes->rounds) {
15633
0
#ifdef WOLFSSL_AES_128
15634
0
    case 10:
15635
0
        *keySize = 16;
15636
0
        break;
15637
0
#endif
15638
0
#ifdef WOLFSSL_AES_192
15639
0
    case 12:
15640
0
        *keySize = 24;
15641
0
        break;
15642
0
#endif
15643
0
#ifdef WOLFSSL_AES_256
15644
0
    case 14:
15645
0
        *keySize = 32;
15646
0
        break;
15647
0
#endif
15648
0
    default:
15649
0
        *keySize = 0;
15650
0
        ret = BAD_FUNC_ARG;
15651
0
    }
15652
15653
0
    return ret;
15654
0
}
15655
15656
#endif /* !WOLFSSL_TI_CRYPT */
15657
15658
/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
15659
 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
15660
 */
15661
#ifndef VECTOR_REGISTERS_PUSH
15662
    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
15663
#endif
15664
#ifndef VECTOR_REGISTERS_POP
15665
    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
15666
#endif
15667
15668
#ifdef HAVE_AES_ECB
15669
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
15670
        !defined(WOLFSSL_QNX_CAAM)
15671
    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
15672
15673
#elif defined(WOLFSSL_AFALG)
15674
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
15675
15676
#elif defined(WOLFSSL_DEVCRYPTO_AES)
15677
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
15678
15679
#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
15680
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
15681
15682
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
15683
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
15684
15685
#elif defined(MAX3266X_AES)
15686
15687
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15688
{
15689
    int status;
15690
    word32 keySize;
15691
15692
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15693
        return BAD_FUNC_ARG;
15694
15695
    status = wc_AesGetKeySize(aes, &keySize);
15696
    if (status != 0) {
15697
        return status;
15698
    }
15699
15700
    status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key,
15701
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
15702
15703
    return status;
15704
}
15705
15706
#ifdef HAVE_AES_DECRYPT
15707
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15708
{
15709
    int status;
15710
    word32 keySize;
15711
15712
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15713
        return BAD_FUNC_ARG;
15714
15715
    status = wc_AesGetKeySize(aes, &keySize);
15716
    if (status != 0) {
15717
        return status;
15718
    }
15719
15720
    status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key,
15721
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
15722
15723
    return status;
15724
}
15725
#endif /* HAVE_AES_DECRYPT */
15726
15727
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
15728
15729
/* Software AES - ECB */
15730
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15731
{
15732
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15733
        return BAD_FUNC_ARG;
15734
15735
    return AES_ECB_encrypt(aes, in, out, sz);
15736
}
15737
15738
15739
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15740
{
15741
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15742
        return BAD_FUNC_ARG;
15743
15744
    return AES_ECB_decrypt(aes, in, out, sz);
15745
}
15746
15747
#elif defined(WOLFSSL_PSOC6_CRYPTO)
15748
15749
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15750
{
15751
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15752
        return BAD_FUNC_ARG;
15753
15754
    return wc_Psoc6_Aes_EcbEncrypt(aes, out, in, sz);
15755
}
15756
15757
#define _AesEcbEncrypt(aes, out, in, sz) wc_AesEcbEncrypt(aes, out, in, sz)
15758
15759
#ifdef HAVE_AES_DECRYPT
15760
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15761
{
15762
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15763
        return BAD_FUNC_ARG;
15764
15765
    return wc_Psoc6_Aes_EcbDecrypt(aes, out, in, sz);
15766
}
15767
15768
#define _AesEcbDecrypt(aes, out, in, sz) wc_AesEcbDecrypt(aes, out, in, sz)
15769
#endif /* HAVE_AES_DECRYPT */
15770
15771
#else
15772
15773
/* Software AES - ECB */
15774
static WARN_UNUSED_RESULT int _AesEcbEncrypt(
15775
    Aes* aes, byte* out, const byte* in, word32 sz)
15776
711
{
15777
711
    int ret = 0;
15778
15779
711
#ifdef WOLF_CRYPTO_CB
15780
711
    #ifndef WOLF_CRYPTO_CB_FIND
15781
711
    if (aes->devId != INVALID_DEVID)
15782
142
    #endif
15783
142
    {
15784
142
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
15785
142
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15786
0
            return ret;
15787
142
        ret = 0;
15788
        /* fall-through when unavailable */
15789
142
    }
15790
711
#endif
15791
#ifdef WOLF_CRYPTO_CB_ONLY_AES
15792
    /* No software fallback: the per-block loop below would only re-invoke
15793
     * cryptocb ECB and propagate UNAVAILABLE; short-circuit instead. */
15794
    return NO_VALID_DEVID;
15795
#endif
15796
#ifdef WOLFSSL_IMXRT_DCP
15797
    if (aes->keylen == 16)
15798
        return DCPAesEcbEncrypt(aes, out, in, sz);
15799
#endif
15800
15801
711
    VECTOR_REGISTERS_PUSH;
15802
15803
#if defined(WOLFSSL_RISCV_ASM)
15804
    AES_encrypt_blocks_RISCV64(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15805
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15806
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
15807
    AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15808
#else
15809
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
15810
#endif
15811
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15812
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15813
    if (aes->use_aes_hw_crypto) {
15814
        AES_encrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
15815
            (int)aes->rounds);
15816
    }
15817
    else
15818
#endif
15819
#if !defined(WOLFSSL_ARMASM_NO_NEON)
15820
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15821
    if (sz >= 32)
15822
#endif
15823
    {
15824
        AES_ECB_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
15825
            aes->rounds);
15826
    }
15827
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15828
    else
15829
#endif
15830
#endif
15831
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15832
    {
15833
        AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key,
15834
            aes->rounds);
15835
    }
15836
#endif
15837
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
15838
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
15839
    ret = 0;
15840
#else
15841
#ifdef WOLFSSL_AESNI
15842
    if (aes->use_aesni) {
15843
    #ifdef WOLFSSL_X86_64_BUILD
15844
        AesEcbEncryptBlocks(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15845
    #else
15846
        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15847
    #endif
15848
    }
15849
    else
15850
#endif
15851
711
    {
15852
711
#if defined(NEED_AES_TABLES)
15853
711
        AesEncryptBlocks_C(aes, in, out, sz);
15854
#else
15855
        word32 i;
15856
#ifdef WC_AES_HAVE_PREFETCH_ARG
15857
        int did_prefetches = 0;
15858
#endif
15859
15860
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
15861
            ret = AesEncrypt_preFetchOpt(aes, in, out, &did_prefetches);
15862
            if (ret != 0)
15863
                break;
15864
            in += WC_AES_BLOCK_SIZE;
15865
            out += WC_AES_BLOCK_SIZE;
15866
        }
15867
#endif
15868
711
    }
15869
711
#endif
15870
15871
711
    VECTOR_REGISTERS_POP;
15872
15873
711
    return ret;
15874
711
}
15875
15876
#ifdef HAVE_AES_DECRYPT
15877
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
15878
    Aes* aes, byte* out, const byte* in, word32 sz)
15879
297
{
15880
297
    int ret = 0;
15881
15882
297
#ifdef WOLF_CRYPTO_CB
15883
297
    #ifndef WOLF_CRYPTO_CB_FIND
15884
297
    if (aes->devId != INVALID_DEVID)
15885
281
    #endif
15886
281
    {
15887
281
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
15888
281
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15889
0
            return ret;
15890
281
        ret = 0;
15891
        /* fall-through when unavailable */
15892
281
    }
15893
297
#endif
15894
#ifdef WOLF_CRYPTO_CB_ONLY_AES
15895
    return NO_VALID_DEVID;
15896
#endif
15897
#ifdef WOLFSSL_IMXRT_DCP
15898
    if (aes->keylen == 16)
15899
        return DCPAesEcbDecrypt(aes, out, in, sz);
15900
#endif
15901
15902
297
    VECTOR_REGISTERS_PUSH;
15903
15904
#if defined(WOLFSSL_RISCV_ASM)
15905
    AES_decrypt_blocks_RISCV64(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15906
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15907
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
15908
    AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15909
#else
15910
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
15911
#endif
15912
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15913
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15914
    if (aes->use_aes_hw_crypto) {
15915
        AES_decrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
15916
            (int)aes->rounds);
15917
    }
15918
    else
15919
#endif
15920
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
15921
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15922
    if (sz >= 64)
15923
#endif
15924
    {
15925
        AES_ECB_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
15926
            aes->rounds);
15927
    }
15928
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15929
    else
15930
#endif
15931
#endif
15932
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15933
    {
15934
        AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key,
15935
            aes->rounds);
15936
    }
15937
#endif
15938
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
15939
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
15940
    ret = 0;
15941
#else
15942
#ifdef WOLFSSL_AESNI
15943
    if (aes->use_aesni) {
15944
    #ifdef WOLFSSL_X86_64_BUILD
15945
        AesEcbDecryptBlocks(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15946
    #else
15947
        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
15948
    #endif
15949
    }
15950
    else
15951
#endif
15952
297
    {
15953
297
#if defined(NEED_AES_TABLES)
15954
297
        AesDecryptBlocks_C(aes, in, out, sz);
15955
#else
15956
        word32 i;
15957
15958
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
15959
            ret = wc_AesDecryptDirect(aes, out, in);
15960
            if (ret != 0)
15961
                break;
15962
            in += WC_AES_BLOCK_SIZE;
15963
            out += WC_AES_BLOCK_SIZE;
15964
        }
15965
#endif
15966
297
    }
15967
297
#endif
15968
15969
297
    VECTOR_REGISTERS_POP;
15970
15971
297
    return ret;
15972
297
}
15973
#endif
15974
15975
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15976
569
{
15977
569
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15978
0
      return BAD_FUNC_ARG;
15979
569
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
15980
0
        return BAD_LENGTH_E;
15981
0
    }
15982
15983
569
    return _AesEcbEncrypt(aes, out, in, sz);
15984
569
}
15985
15986
#ifdef HAVE_AES_DECRYPT
15987
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
15988
16
{
15989
16
    if ((in == NULL) || (out == NULL) || (aes == NULL))
15990
0
      return BAD_FUNC_ARG;
15991
16
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
15992
0
        return BAD_LENGTH_E;
15993
0
    }
15994
15995
16
    return _AesEcbDecrypt(aes, out, in, sz);
15996
16
}
15997
#endif /* HAVE_AES_DECRYPT */
15998
#endif
15999
#endif /* HAVE_AES_ECB */
16000
16001
#if defined(WOLFSSL_AES_CFB)
16002
16003
#if defined(WOLFSSL_NXP_HASHCRYPT_AES)
16004
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
16005
16006
#elif defined(WOLFSSL_PSOC6_CRYPTO)
16007
16008
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16009
{
16010
    return wc_Psoc6_Aes_CfbEncrypt(aes, out, in, sz);
16011
}
16012
16013
#ifdef HAVE_AES_DECRYPT
16014
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16015
{
16016
    return wc_Psoc6_Aes_CfbDecrypt(aes, out, in, sz);
16017
}
16018
#endif /* HAVE_AES_DECRYPT */
16019
16020
#else
16021
/* Feedback AES mode
16022
 *
16023
 * aes structure holding key to use for encryption
16024
 * out buffer to hold result of encryption (must be at least as large as input
16025
 *     buffer)
16026
 * in  buffer to encrypt
16027
 * sz  size of input buffer
16028
 * mode flag to specify AES mode
16029
 *
16030
 * returns 0 on success and negative error values on failure
16031
 */
16032
/* Software AES - CFB Encrypt */
16033
static WARN_UNUSED_RESULT int AesCfbEncrypt_C(Aes* aes, byte* out,
16034
    const byte* in, word32 sz)
16035
0
{
16036
0
    int ret = 0;
16037
0
    word32 processed;
16038
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
16039
0
    int did_prefetches = 0;
16040
0
#endif
16041
16042
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16043
0
        return BAD_FUNC_ARG;
16044
0
    }
16045
0
    if (sz == 0) {
16046
0
        return 0;
16047
0
    }
16048
16049
0
    if (aes->left > 0) {
16050
        /* consume any unused bytes left in aes->tmp */
16051
0
        processed = min(aes->left, sz);
16052
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16053
0
            processed);
16054
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out,
16055
0
            processed);
16056
0
        aes->left -= processed;
16057
0
        out += processed;
16058
0
        in += processed;
16059
0
        sz -= processed;
16060
0
    }
16061
16062
0
    VECTOR_REGISTERS_PUSH;
16063
16064
0
    while (sz >= WC_AES_BLOCK_SIZE) {
16065
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
16066
0
                                        &did_prefetches);
16067
0
        if (ret != 0) {
16068
0
            break;
16069
0
        }
16070
0
        xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
16071
0
        XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
16072
0
        out += WC_AES_BLOCK_SIZE;
16073
0
        in  += WC_AES_BLOCK_SIZE;
16074
0
        sz  -= WC_AES_BLOCK_SIZE;
16075
0
    }
16076
16077
    /* encrypt left over data */
16078
0
    if ((ret == 0) && sz) {
16079
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16080
0
                                     &did_prefetches);
16081
0
        if (ret == 0) {
16082
0
            xorbufout(out, in, aes->tmp, sz);
16083
0
            XMEMCPY(aes->reg, out, sz);
16084
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
16085
0
        }
16086
0
    }
16087
16088
0
    VECTOR_REGISTERS_POP;
16089
16090
0
    return ret;
16091
0
}
16092
16093
16094
#if defined(HAVE_AES_DECRYPT)
16095
/* CFB 128
16096
 *
16097
 * aes structure holding key to use for decryption
16098
 * out buffer to hold result of decryption (must be at least as large as input
16099
 *     buffer)
16100
 * in  buffer to decrypt
16101
 * sz  size of input buffer
16102
 *
16103
 * returns 0 on success and negative error values on failure
16104
 */
16105
/* Software AES - CFB Decrypt */
16106
static WARN_UNUSED_RESULT int AesCfbDecrypt_C(Aes* aes, byte* out,
16107
    const byte* in, word32 sz, byte mode)
16108
0
{
16109
0
    int ret = 0;
16110
0
    word32 processed;
16111
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
16112
0
    int did_prefetches = 0;
16113
0
#endif
16114
0
#ifndef WC_AES_CFB_DEC_BUF_BLOCKS
16115
0
    #define WC_AES_CFB_DEC_BUF_BLOCKS 32
16116
#elif WC_AES_CFB_DEC_BUF_BLOCKS < 2
16117
    #error Invalid WC_AES_CFB_DEC_BUF_BLOCKS
16118
#endif
16119
0
#ifdef WOLFSSL_SMALL_STACK
16120
0
    byte *tmp = NULL;
16121
0
#endif
16122
16123
0
    (void)mode;
16124
16125
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16126
0
        return BAD_FUNC_ARG;
16127
0
    }
16128
0
    if (sz == 0) {
16129
0
        return 0;
16130
0
    }
16131
16132
0
    if (aes->left > 0) {
16133
        /* consume any unused bytes left in aes->tmp */
16134
0
        processed = min(aes->left, sz);
16135
        /* copy input over to aes->reg */
16136
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, processed);
16137
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16138
0
            processed);
16139
0
        aes->left -= processed;
16140
0
        out += processed;
16141
0
        in += processed;
16142
0
        sz -= processed;
16143
0
    }
16144
16145
#if defined(WOLFSSL_SMALL_STACK) && defined(HAVE_AES_ECB) &&    \
16146
    !defined(WOLFSSL_PIC32MZ_CRYPT) &&                          \
16147
    (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
16148
    /* Only suffer the heap overhead if sz is enough to warrant it.
16149
     *
16150
     * Allocate the working buffer before suspending interrupts, so that we can
16151
     * allocate with regular GFP_KERNEL.
16152
     */
16153
    if (sz >= WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE)
16154
        tmp = (byte *)XMALLOC(WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_AES);
16155
16156
    VECTOR_REGISTERS_PUSH2(XFREE(tmp, NULL, DYNAMIC_TYPE_AES););
16157
#else
16158
0
    VECTOR_REGISTERS_PUSH;
16159
0
#endif
16160
16161
    #if defined(HAVE_AES_ECB) && \
16162
        !defined(WOLFSSL_PIC32MZ_CRYPT) && \
16163
        (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
16164
#ifdef WOLFSSL_SMALL_STACK
16165
    if (tmp != NULL)
16166
#endif
16167
    {
16168
#ifndef WOLFSSL_SMALL_STACK
16169
        ALIGN16 byte tmp[WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE];
16170
#endif
16171
        if (sz >= 2 * WC_AES_BLOCK_SIZE) {
16172
            /* CFB-decrypt keystream block i is E(C_{i-1}): block 0 uses the
16173
             * feedback register, block i>=1 uses the previous cipher block.  So
16174
             * ECB the ciphertext straight out of 'in' (no shift-copy) to get
16175
             * E(C_0..C_{n-1}), XOR block i with the (i-1)th ECB output, and
16176
             * carry E(C_{n-1}) as the next chunk's block-0 keystream - E(reg)
16177
             * is computed only once here. */
16178
            ALIGN16 byte ks[WC_AES_BLOCK_SIZE];
16179
            ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, ks,
16180
                                         &did_prefetches);
16181
            while ((ret == 0) && (sz >= 2 * WC_AES_BLOCK_SIZE)) {
16182
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
16183
                word32 nbytes;
16184
                if (blocks > WC_AES_CFB_DEC_BUF_BLOCKS)
16185
                    blocks = WC_AES_CFB_DEC_BUF_BLOCKS;
16186
                nbytes = blocks * WC_AES_BLOCK_SIZE;
16187
                /* tmp[i] = E(C_i), read directly from the input. Already inside
16188
                 * VECTOR_REGISTERS_PUSH, so use the inner ECB (no nested
16189
                 * save/restore or re-dispatch) where available. */
16190
            #if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
16191
                if (aes->use_aesni) {
16192
                    AesEcbEncryptBlocks(in, tmp, nbytes, (byte*)aes->key,
16193
                                        (int)aes->rounds);
16194
                }
16195
                else
16196
            #endif
16197
                {
16198
                    ret = wc_AesEcbEncrypt(aes, tmp, in, nbytes);
16199
                    if (ret != 0)
16200
                        break;
16201
                }
16202
                /* Feedback for the tail = last cipher block; save it before the
16203
                 * XOR can overwrite 'in' (in == out case). */
16204
                XMEMCPY((byte*)aes->reg, in + nbytes - WC_AES_BLOCK_SIZE,
16205
                        WC_AES_BLOCK_SIZE);
16206
                /* P_0 = C_0 ^ E(feedback); P_i = C_i ^ E(C_{i-1}) =
16207
                 *       C_i ^ tmp[i-1]. */
16208
                xorbufout(out, in, ks, WC_AES_BLOCK_SIZE);
16209
                xorbufout(out + WC_AES_BLOCK_SIZE, in + WC_AES_BLOCK_SIZE, tmp,
16210
                          nbytes - WC_AES_BLOCK_SIZE);
16211
                /* Carry E(last cipher block) as the next chunk's block-0 KS. */
16212
                XMEMCPY(ks, tmp + nbytes - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
16213
                out += nbytes;
16214
                in  += nbytes;
16215
                sz  -= nbytes;
16216
            }
16217
        }
16218
    }
16219
    #endif
16220
0
    while (sz >= WC_AES_BLOCK_SIZE) {
16221
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16222
0
                                        &did_prefetches);
16223
0
        if (ret != 0) {
16224
0
            break;
16225
0
        }
16226
0
        XMEMCPY((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
16227
0
        xorbufout(out, in, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
16228
0
        out += WC_AES_BLOCK_SIZE;
16229
0
        in  += WC_AES_BLOCK_SIZE;
16230
0
        sz  -= WC_AES_BLOCK_SIZE;
16231
0
    }
16232
16233
    /* decrypt left over data */
16234
0
    if ((ret == 0) && sz) {
16235
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16236
0
                                        &did_prefetches);
16237
0
        if (ret == 0) {
16238
0
            XMEMCPY(aes->reg, in, sz);
16239
0
            xorbufout(out, in, aes->tmp, sz);
16240
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
16241
0
        }
16242
0
    }
16243
16244
0
    VECTOR_REGISTERS_POP;
16245
16246
0
#ifdef WOLFSSL_SMALL_STACK
16247
    /* Free tmp after restoring interrupts, so that GFP_KERNEL is usable. */
16248
0
    XFREE(tmp, NULL, DYNAMIC_TYPE_AES);
16249
0
#endif
16250
16251
0
    return ret;
16252
0
}
16253
#endif /* HAVE_AES_DECRYPT */
16254
16255
/* CFB 128
16256
 *
16257
 * aes structure holding key to use for encryption
16258
 * out buffer to hold result of encryption (must be at least as large as input
16259
 *     buffer)
16260
 * in  buffer to encrypt
16261
 * sz  size of input buffer
16262
 *
16263
 * returns 0 on success and negative error values on failure
16264
 */
16265
/* Software AES - CFB Encrypt */
16266
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16267
0
{
16268
0
#ifdef WOLF_CRYPTO_CB
16269
0
    if (aes == NULL)
16270
0
        return BAD_FUNC_ARG;
16271
0
    #ifndef WOLF_CRYPTO_CB_FIND
16272
0
    if (aes->devId != INVALID_DEVID)
16273
0
    #endif
16274
0
    {
16275
0
        int crypto_cb_ret = wc_CryptoCb_AesCfbEncrypt(aes, out, in, sz);
16276
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16277
0
            return crypto_cb_ret;
16278
        /* fall-through when unavailable */
16279
0
    }
16280
0
#endif
16281
0
    return AesCfbEncrypt_C(aes, out, in, sz);
16282
0
}
16283
16284
16285
#ifdef HAVE_AES_DECRYPT
16286
/* CFB 128
16287
 *
16288
 * aes structure holding key to use for decryption
16289
 * out buffer to hold result of decryption (must be at least as large as input
16290
 *     buffer)
16291
 * in  buffer to decrypt
16292
 * sz  size of input buffer
16293
 *
16294
 * returns 0 on success and negative error values on failure
16295
 */
16296
/* Software AES - CFB Decrypt */
16297
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16298
0
{
16299
0
#ifdef WOLF_CRYPTO_CB
16300
0
    if (aes == NULL)
16301
0
        return BAD_FUNC_ARG;
16302
0
    #ifndef WOLF_CRYPTO_CB_FIND
16303
0
    if (aes->devId != INVALID_DEVID)
16304
0
    #endif
16305
0
    {
16306
0
        int crypto_cb_ret = wc_CryptoCb_AesCfbDecrypt(aes, out, in, sz);
16307
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16308
0
            return crypto_cb_ret;
16309
        /* fall-through when unavailable */
16310
0
    }
16311
0
#endif
16312
0
    return AesCfbDecrypt_C(aes, out, in, sz, AES_CFB_MODE);
16313
0
}
16314
#endif /* HAVE_AES_DECRYPT */
16315
#endif /* WOLFSSL_PSOC6_CRYPTO */
16316
16317
#ifndef WOLFSSL_NO_AES_CFB_1_8
16318
/* shift the whole WC_AES_BLOCK_SIZE array left by 8 or 1 bits */
16319
static void shiftLeftArray(byte* ary, byte shift)
16320
22.7k
{
16321
22.7k
    int i;
16322
16323
22.7k
    if (shift == WOLFSSL_BIT_SIZE) {
16324
        /* shifting over by 8 bits */
16325
178k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
16326
167k
            ary[i] = ary[i+1];
16327
167k
        }
16328
11.1k
        ary[i] = 0;
16329
11.1k
    }
16330
11.6k
    else {
16331
        /* shifting over by 7 or less bits */
16332
185k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
16333
174k
            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
16334
174k
            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
16335
174k
            ary[i] = (byte)((ary[i] << shift) + carry);
16336
174k
        }
16337
11.6k
        ary[i] = (byte)(ary[i] << shift);
16338
11.6k
    }
16339
22.7k
}
16340
16341
16342
/* returns 0 on success and negative values on failure */
16343
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
16344
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
16345
96
{
16346
96
    byte *pt;
16347
96
    int ret = 0;
16348
96
#ifdef WC_AES_HAVE_PREFETCH_ARG
16349
96
    int did_prefetches = 0;
16350
96
#endif
16351
16352
96
    if (aes == NULL || out == NULL || in == NULL) {
16353
0
        return BAD_FUNC_ARG;
16354
0
    }
16355
16356
96
    if (sz == 0) {
16357
0
        return 0;
16358
0
    }
16359
16360
96
    VECTOR_REGISTERS_PUSH;
16361
16362
11.2k
    while (sz > 0) {
16363
11.1k
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16364
11.1k
                                        &did_prefetches);
16365
11.1k
        if (ret != 0)
16366
0
            break;
16367
11.1k
        if (dir == AES_DECRYPTION) {
16368
5.27k
            pt = (byte*)aes->reg;
16369
16370
            /* LSB + CAT */
16371
5.27k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
16372
5.27k
            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
16373
5.27k
        }
16374
16375
        /* MSB + XOR */
16376
    #ifdef BIG_ENDIAN_ORDER
16377
        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
16378
    #endif
16379
11.1k
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
16380
11.1k
        if (dir == AES_ENCRYPTION) {
16381
5.89k
            pt = (byte*)aes->reg;
16382
16383
            /* LSB + CAT */
16384
5.89k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
16385
5.89k
            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
16386
5.89k
        }
16387
16388
11.1k
        out += 1;
16389
11.1k
        in  += 1;
16390
11.1k
        sz  -= 1;
16391
11.1k
    }
16392
16393
96
    VECTOR_REGISTERS_POP;
16394
16395
96
    return ret;
16396
96
}
16397
16398
16399
/* returns 0 on success and negative values on failure */
16400
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
16401
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
16402
142
{
16403
142
    byte tmp;
16404
142
    byte cur = 0; /* hold current work in order to handle inline in=out */
16405
142
    byte* pt;
16406
142
    int bit = 7;
16407
142
    int ret = 0;
16408
142
#ifdef WC_AES_HAVE_PREFETCH_ARG
16409
142
    int did_prefetches = 0;
16410
142
#endif
16411
16412
142
    if (aes == NULL || out == NULL || in == NULL) {
16413
0
        return BAD_FUNC_ARG;
16414
0
    }
16415
16416
142
    if (sz == 0) {
16417
0
        return 0;
16418
0
    }
16419
16420
142
    VECTOR_REGISTERS_PUSH;
16421
16422
11.7k
    while (sz > 0) {
16423
11.6k
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16424
11.6k
                                        &did_prefetches);
16425
11.6k
        if (ret != 0)
16426
0
            break;
16427
11.6k
        if (dir == AES_DECRYPTION) {
16428
9.40k
            pt = (byte*)aes->reg;
16429
16430
            /* LSB + CAT */
16431
9.40k
            tmp = (byte)((0X01U << bit) & in[0]);
16432
9.40k
            tmp = (byte)(tmp >> bit);
16433
9.40k
            tmp &= 0x01;
16434
9.40k
            shiftLeftArray((byte*)aes->reg, 1);
16435
9.40k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
16436
9.40k
        }
16437
16438
        /* MSB  + XOR */
16439
11.6k
        tmp = (byte)((0X01U << bit) & in[0]);
16440
11.6k
        pt = (byte*)aes->tmp;
16441
11.6k
        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
16442
11.6k
        tmp &= 0x01;
16443
11.6k
        cur = (byte)(cur | (tmp << bit));
16444
16445
16446
11.6k
        if (dir == AES_ENCRYPTION) {
16447
2.19k
            pt = (byte*)aes->reg;
16448
16449
            /* LSB + CAT */
16450
2.19k
            shiftLeftArray((byte*)aes->reg, 1);
16451
2.19k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
16452
2.19k
        }
16453
16454
11.6k
        bit--;
16455
11.6k
        if (bit < 0) {
16456
1.45k
            out[0] = cur;
16457
1.45k
            out += 1;
16458
1.45k
            in  += 1;
16459
1.45k
            sz  -= 1;
16460
1.45k
            bit = 7U;
16461
1.45k
            cur = 0;
16462
1.45k
        }
16463
10.1k
        else {
16464
10.1k
            sz -= 1;
16465
10.1k
        }
16466
11.6k
    }
16467
16468
142
    if (ret == 0) {
16469
142
        if (bit >= 0 && bit < 7) {
16470
0
            out[0] = cur;
16471
0
        }
16472
142
    }
16473
16474
142
    VECTOR_REGISTERS_POP;
16475
16476
142
    return ret;
16477
142
}
16478
16479
16480
/* CFB 1
16481
 *
16482
 * aes structure holding key to use for encryption
16483
 * out buffer to hold result of encryption (must be at least as large as input
16484
 *     buffer)
16485
 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
16486
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
16487
 *
16488
 * returns 0 on success and negative values on failure
16489
 */
16490
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16491
104
{
16492
104
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
16493
104
}
16494
16495
16496
/* CFB 8
16497
 *
16498
 * aes structure holding key to use for encryption
16499
 * out buffer to hold result of encryption (must be at least as large as input
16500
 *     buffer)
16501
 * in  buffer to encrypt
16502
 * sz  size of input buffer
16503
 *
16504
 * returns 0 on success and negative values on failure
16505
 */
16506
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16507
82
{
16508
82
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
16509
82
}
16510
#ifdef HAVE_AES_DECRYPT
16511
16512
/* CFB 1
16513
 *
16514
 * aes structure holding key to use for encryption
16515
 * out buffer to hold result of encryption (must be at least as large as input
16516
 *     buffer)
16517
 * in  buffer to encrypt
16518
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
16519
 *
16520
 * returns 0 on success and negative values on failure
16521
 */
16522
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16523
38
{
16524
38
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
16525
38
}
16526
16527
16528
/* CFB 8
16529
 *
16530
 * aes structure holding key to use for encryption
16531
 * out buffer to hold result of encryption (must be at least as large as input
16532
 *     buffer)
16533
 * in  buffer to encrypt
16534
 * sz  size of input buffer
16535
 *
16536
 * returns 0 on success and negative values on failure
16537
 */
16538
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16539
14
{
16540
14
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
16541
14
}
16542
#endif /* HAVE_AES_DECRYPT */
16543
#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
16544
#endif /* WOLFSSL_AES_CFB */
16545
16546
#ifdef WOLFSSL_AES_OFB
16547
#ifdef WOLFSSL_NXP_HASHCRYPT_AES
16548
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
16549
16550
#else /* software */
16551
/* OFB AES mode
16552
 *
16553
 * aes structure holding key to use for encryption
16554
 * out buffer to hold result of encryption (must be at least as large as input
16555
 *     buffer)
16556
 * in  buffer to encrypt
16557
 * sz  size of input buffer
16558
 *
16559
 * returns 0 on success and negative error values on failure
16560
 */
16561
/* Software AES - OFB Encrypt/Decrypt */
16562
static WARN_UNUSED_RESULT int AesOfbCrypt_C(Aes* aes, byte* out, const byte* in,
16563
    word32 sz)
16564
472
{
16565
472
    int ret = 0;
16566
472
    word32 processed;
16567
472
#ifdef WC_AES_HAVE_PREFETCH_ARG
16568
472
    int did_prefetches = 0;
16569
472
#endif
16570
16571
472
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16572
0
        return BAD_FUNC_ARG;
16573
0
    }
16574
472
    if (sz == 0) {
16575
0
        return 0;
16576
0
    }
16577
16578
472
    if (aes->left > 0) {
16579
        /* consume any unused bytes left in aes->tmp */
16580
283
        processed = min(aes->left, sz);
16581
283
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16582
283
            processed);
16583
283
        aes->left -= processed;
16584
283
        out += processed;
16585
283
        in += processed;
16586
283
        sz -= processed;
16587
283
    }
16588
16589
472
    VECTOR_REGISTERS_PUSH;
16590
16591
2.17k
    while (sz >= WC_AES_BLOCK_SIZE) {
16592
1.70k
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
16593
1.70k
                                        &did_prefetches);
16594
1.70k
        if (ret != 0) {
16595
0
            break;
16596
0
        }
16597
1.70k
        xorbufout(out, in, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
16598
1.70k
        out += WC_AES_BLOCK_SIZE;
16599
1.70k
        in  += WC_AES_BLOCK_SIZE;
16600
1.70k
        sz  -= WC_AES_BLOCK_SIZE;
16601
1.70k
    }
16602
16603
    /* encrypt left over data */
16604
472
    if ((ret == 0) && sz) {
16605
164
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16606
164
                                        &did_prefetches);
16607
164
        if (ret == 0) {
16608
164
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
16609
164
            xorbufout(out, in, aes->tmp, sz);
16610
164
            aes->left = WC_AES_BLOCK_SIZE - sz;
16611
164
        }
16612
164
    }
16613
16614
472
    VECTOR_REGISTERS_POP;
16615
16616
472
    return ret;
16617
472
}
16618
16619
/* OFB
16620
 *
16621
 * aes structure holding key to use for encryption
16622
 * out buffer to hold result of encryption (must be at least as large as input
16623
 *     buffer)
16624
 * in  buffer to encrypt
16625
 * sz  size of input buffer
16626
 *
16627
 * returns 0 on success and negative error values on failure
16628
 */
16629
/* Software AES - OFB Encrypt */
16630
int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16631
380
{
16632
380
#ifdef WOLF_CRYPTO_CB
16633
380
    if (aes == NULL)
16634
0
        return BAD_FUNC_ARG;
16635
380
    #ifndef WOLF_CRYPTO_CB_FIND
16636
380
    if (aes->devId != INVALID_DEVID)
16637
0
    #endif
16638
0
    {
16639
0
        int crypto_cb_ret = wc_CryptoCb_AesOfbEncrypt(aes, out, in, sz);
16640
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16641
0
            return crypto_cb_ret;
16642
        /* fall-through when unavailable */
16643
0
    }
16644
380
#endif
16645
380
    return AesOfbCrypt_C(aes, out, in, sz);
16646
380
}
16647
16648
16649
#ifdef HAVE_AES_DECRYPT
16650
/* OFB
16651
 *
16652
 * aes structure holding key to use for decryption
16653
 * out buffer to hold result of decryption (must be at least as large as input
16654
 *     buffer)
16655
 * in  buffer to decrypt
16656
 * sz  size of input buffer
16657
 *
16658
 * returns 0 on success and negative error values on failure
16659
 */
16660
/* Software AES - OFB Decrypt */
16661
int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16662
92
{
16663
92
#ifdef WOLF_CRYPTO_CB
16664
92
    if (aes == NULL)
16665
0
        return BAD_FUNC_ARG;
16666
92
    #ifndef WOLF_CRYPTO_CB_FIND
16667
92
    if (aes->devId != INVALID_DEVID)
16668
0
    #endif
16669
0
    {
16670
0
        int crypto_cb_ret = wc_CryptoCb_AesOfbDecrypt(aes, out, in, sz);
16671
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16672
0
            return crypto_cb_ret;
16673
        /* fall-through when unavailable */
16674
0
    }
16675
92
#endif
16676
92
    return AesOfbCrypt_C(aes, out, in, sz);
16677
92
}
16678
#endif /* HAVE_AES_DECRYPT */
16679
#endif /* software */
16680
#endif /* WOLFSSL_AES_OFB */
16681
16682
16683
#ifdef HAVE_AES_KEYWRAP
16684
16685
/* Initialize key wrap counter with value */
16686
static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
16687
0
{
16688
0
    word32 i;
16689
0
    word32 bytes;
16690
16691
0
    bytes = sizeof(word32);
16692
0
    for (i = 0; i < sizeof(word32); i++) {
16693
0
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
16694
0
        bytes--;
16695
0
    }
16696
0
}
16697
16698
/* Increment key wrap counter */
16699
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
16700
0
{
16701
0
    int i;
16702
16703
    /* in network byte order so start at end and work back */
16704
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
16705
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
16706
0
            return;
16707
0
    }
16708
0
}
16709
16710
/* Decrement key wrap counter */
16711
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
16712
0
{
16713
0
    int i;
16714
16715
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
16716
0
        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
16717
0
            return;
16718
0
    }
16719
0
}
16720
16721
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
16722
        word32 outSz, const byte* iv)
16723
0
{
16724
0
    word32 i;
16725
0
    byte* r;
16726
0
    int j;
16727
0
    int ret = 0;
16728
16729
0
    byte t[KEYWRAP_BLOCK_SIZE];
16730
0
    byte tmp[WC_AES_BLOCK_SIZE];
16731
16732
    /* n must be at least 2 64-bit blocks, output size is (n + 1) 8 bytes (64-bit) */
16733
0
    if (aes == NULL || in  == NULL || inSz < 2*KEYWRAP_BLOCK_SIZE ||
16734
0
        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
16735
0
        return BAD_FUNC_ARG;
16736
16737
    /* input must be multiple of 64-bits */
16738
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
16739
0
        return BAD_FUNC_ARG;
16740
16741
0
    r = out + 8;
16742
0
    XMEMCPY(r, in, inSz);
16743
0
    XMEMSET(t, 0, sizeof(t));
16744
16745
    /* user IV is optional */
16746
0
    if (iv == NULL) {
16747
0
        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
16748
0
    } else {
16749
0
        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
16750
0
    }
16751
16752
0
    VECTOR_REGISTERS_PUSH;
16753
16754
0
    for (j = 0; j <= 5; j++) {
16755
0
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
16756
            /* load R[i] */
16757
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
16758
16759
0
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
16760
0
            if (ret != 0)
16761
0
                break;
16762
16763
            /* calculate new A */
16764
0
            IncrementKeyWrapCounter(t);
16765
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
16766
16767
            /* save R[i] */
16768
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
16769
0
            r += KEYWRAP_BLOCK_SIZE;
16770
0
        }
16771
0
        if (ret != 0)
16772
0
            break;
16773
0
        r = out + KEYWRAP_BLOCK_SIZE;
16774
0
    }
16775
16776
0
    VECTOR_REGISTERS_POP;
16777
16778
0
    if (ret != 0)
16779
0
        return ret;
16780
16781
    /* C[0] = A */
16782
0
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
16783
16784
0
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
16785
0
}
16786
16787
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
16788
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
16789
                  byte* out, word32 outSz, const byte* iv)
16790
0
{
16791
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16792
0
    int ret;
16793
16794
0
    if (key == NULL)
16795
0
        return BAD_FUNC_ARG;
16796
16797
0
#ifdef WOLFSSL_SMALL_STACK
16798
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
16799
0
                              DYNAMIC_TYPE_AES)) == NULL)
16800
0
        return MEMORY_E;
16801
0
#endif
16802
16803
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16804
0
    if (ret != 0)
16805
0
        goto out;
16806
16807
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
16808
0
    if (ret != 0) {
16809
0
        wc_AesFree(aes);
16810
0
        goto out;
16811
0
    }
16812
16813
0
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
16814
16815
0
    wc_AesFree(aes);
16816
16817
0
  out:
16818
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
16819
16820
0
    return ret;
16821
0
}
16822
16823
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
16824
        word32 outSz, const byte* iv)
16825
0
{
16826
0
    byte* r;
16827
0
    word32 i, n;
16828
0
    int j;
16829
0
    int ret = 0;
16830
16831
0
    byte t[KEYWRAP_BLOCK_SIZE];
16832
0
    byte tmp[WC_AES_BLOCK_SIZE];
16833
16834
0
    const byte* expIv;
16835
0
    const byte defaultIV[] = {
16836
0
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
16837
0
    };
16838
16839
0
    if (aes == NULL || in == NULL || inSz < 3 * KEYWRAP_BLOCK_SIZE ||
16840
0
        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
16841
0
        return BAD_FUNC_ARG;
16842
16843
    /* input must be multiple of 64-bits */
16844
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
16845
0
        return BAD_FUNC_ARG;
16846
16847
    /* user IV optional */
16848
0
    if (iv != NULL)
16849
0
        expIv = iv;
16850
0
    else
16851
0
        expIv = defaultIV;
16852
16853
    /* A = C[0], R[i] = C[i] */
16854
0
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
16855
0
    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
16856
0
    XMEMSET(t, 0, sizeof(t));
16857
16858
0
    VECTOR_REGISTERS_PUSH;
16859
16860
    /* initialize counter to 6n */
16861
0
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
16862
0
    InitKeyWrapCounter(t, 6 * n);
16863
16864
0
    for (j = 5; j >= 0; j--) {
16865
0
        for (i = n; i >= 1; i--) {
16866
16867
            /* calculate A */
16868
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
16869
0
            DecrementKeyWrapCounter(t);
16870
16871
            /* load R[i], starting at end of R */
16872
0
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
16873
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
16874
0
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
16875
0
            if (ret != 0)
16876
0
                break;
16877
16878
            /* save R[i] */
16879
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
16880
0
        }
16881
0
        if (ret != 0)
16882
0
            break;
16883
0
    }
16884
16885
0
    VECTOR_REGISTERS_POP;
16886
16887
0
    if (ret != 0)
16888
0
        return ret;
16889
16890
    /* verify IV */
16891
0
    if (ConstantCompare(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
16892
0
        return BAD_KEYWRAP_IV_E;
16893
16894
0
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
16895
0
}
16896
16897
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
16898
                    byte* out, word32 outSz, const byte* iv)
16899
0
{
16900
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
16901
0
    int ret;
16902
16903
0
    (void)iv;
16904
16905
0
    if (key == NULL)
16906
0
        return BAD_FUNC_ARG;
16907
16908
0
#ifdef WOLFSSL_SMALL_STACK
16909
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
16910
0
                              DYNAMIC_TYPE_AES)) == NULL)
16911
0
        return MEMORY_E;
16912
0
#endif
16913
16914
16915
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16916
0
    if (ret != 0)
16917
0
        goto out;
16918
16919
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
16920
0
    if (ret != 0) {
16921
0
        wc_AesFree(aes);
16922
0
        goto out;
16923
0
    }
16924
16925
0
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
16926
16927
0
    wc_AesFree(aes);
16928
16929
0
  out:
16930
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
16931
16932
0
    return ret;
16933
0
}
16934
16935
#endif /* HAVE_AES_KEYWRAP */
16936
16937
#ifdef WOLFSSL_AES_XTS
16938
16939
/* Galois Field to use */
16940
822
#define GF_XTS 0x87
16941
16942
/* Set up keys for encryption and/or decryption.
16943
 *
16944
 * aes   buffer holding aes subkeys
16945
 * heap  heap hint to use for memory. Can be NULL
16946
 * devId id to use with async crypto. Can be 0
16947
 *
16948
 * return 0 on success
16949
 */
16950
int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
16951
546
{
16952
546
    int    ret = 0;
16953
16954
546
    if (aes == NULL) {
16955
0
        return BAD_FUNC_ARG;
16956
0
    }
16957
16958
546
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
16959
0
        return ret;
16960
0
    }
16961
546
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
16962
0
        (void)wc_AesFree(&aes->tweak);
16963
0
        return ret;
16964
0
    }
16965
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16966
    if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) {
16967
        (void)wc_AesFree(&aes->tweak);
16968
        (void)wc_AesFree(&aes->aes);
16969
        return ret;
16970
    }
16971
#endif
16972
16973
546
    return 0;
16974
546
}
16975
16976
/* Set up keys for encryption and/or decryption.
16977
 *
16978
 * aes   buffer holding aes subkeys
16979
 * key   AES key for encrypt/decrypt and tweak process (concatenated)
16980
 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
16981
 *       32 for a 16 byte key.
16982
 * dir   direction: AES_ENCRYPTION, AES_DECRYPTION, or
16983
 *       AES_ENCRYPTION_AND_DECRYPTION
16984
 *
16985
 * return 0 on success
16986
 */
16987
int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
16988
541
{
16989
541
    word32 keySz;
16990
541
    int    ret = 0;
16991
16992
541
    if (aes == NULL || key == NULL) {
16993
0
        return BAD_FUNC_ARG;
16994
0
    }
16995
16996
541
    if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION)
16997
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16998
        && (dir != AES_ENCRYPTION_AND_DECRYPTION)
16999
#endif
17000
541
        )
17001
0
    {
17002
0
        return BAD_FUNC_ARG;
17003
0
    }
17004
17005
541
    if ((len != (AES_128_KEY_SIZE*2)) &&
17006
85
#ifndef HAVE_FIPS
17007
        /* XTS-384 not allowed by FIPS and can not be treated like
17008
         * RSA-4096 bit keys back in the day, can not vendor affirm
17009
         * the use of 2 concatenated 192-bit keys (XTS-384) */
17010
85
        (len != (AES_192_KEY_SIZE*2)) &&
17011
85
#endif
17012
85
        (len != (AES_256_KEY_SIZE*2)))
17013
0
    {
17014
0
        WOLFSSL_MSG("Unsupported key size");
17015
0
        return WC_KEY_SIZE_E;
17016
0
    }
17017
17018
541
    keySz = len/2;
17019
17020
541
#if defined(HAVE_FIPS) || !defined(WC_AES_XTS_ALLOW_DUPLICATE_KEYS)
17021
541
    if (XMEMCMP(key, key + keySz, keySz) == 0) {
17022
46
        WOLFSSL_MSG("AES-XTS main and tweak keys must differ");
17023
46
        return BAD_FUNC_ARG;
17024
46
    }
17025
495
#endif
17026
17027
495
    if (dir == AES_ENCRYPTION
17028
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
17029
        || dir == AES_ENCRYPTION_AND_DECRYPTION
17030
#endif
17031
495
        )
17032
212
    {
17033
212
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
17034
212
    }
17035
17036
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
17037
    if ((ret == 0) && ((dir == AES_DECRYPTION)
17038
                       || (dir == AES_ENCRYPTION_AND_DECRYPTION)))
17039
        ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION);
17040
#else
17041
495
    if (dir == AES_DECRYPTION)
17042
283
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
17043
495
#endif
17044
17045
495
    if (ret == 0)
17046
495
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
17047
495
                AES_ENCRYPTION);
17048
17049
#ifdef WOLFSSL_AESNI
17050
    if (ret == 0) {
17051
        /* With WC_C_DYNAMIC_FALLBACK, the main and tweak keys could have
17052
         * conflicting _aesni status, but the AES-XTS asm implementations need
17053
         * them to all be AESNI.  If any aren't, disable AESNI on all.
17054
         */
17055
    #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
17056
        if ((((dir == AES_ENCRYPTION) ||
17057
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
17058
             && (aes->aes.use_aesni != aes->tweak.use_aesni))
17059
            ||
17060
            (((dir == AES_DECRYPTION) ||
17061
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
17062
             && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)))
17063
        {
17064
        #ifdef WC_C_DYNAMIC_FALLBACK
17065
            aes->aes.use_aesni = 0;
17066
            aes->aes_decrypt.use_aesni = 0;
17067
            aes->tweak.use_aesni = 0;
17068
        #else
17069
            ret = SYSLIB_FAILED_E;
17070
        #endif
17071
        }
17072
    #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
17073
        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
17074
        #ifdef WC_C_DYNAMIC_FALLBACK
17075
            aes->aes.use_aesni = 0;
17076
            aes->tweak.use_aesni = 0;
17077
        #else
17078
            ret = SYSLIB_FAILED_E;
17079
        #endif
17080
        }
17081
    #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
17082
    }
17083
#endif /* WOLFSSL_AESNI */
17084
17085
495
    return ret;
17086
541
}
17087
17088
/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
17089
 *
17090
 * Note: is up to user to call wc_AesXtsFree when done.
17091
 *
17092
 * return 0 on success
17093
 */
17094
int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
17095
        void* heap, int devId)
17096
0
{
17097
0
    int    ret = 0;
17098
17099
0
    if (aes == NULL || key == NULL) {
17100
0
        return BAD_FUNC_ARG;
17101
0
    }
17102
17103
0
    ret = wc_AesXtsInit(aes, heap, devId);
17104
0
    if (ret != 0)
17105
0
        return ret;
17106
17107
0
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
17108
17109
0
    if (ret != 0)
17110
0
        wc_AesXtsFree(aes);
17111
17112
0
    return ret;
17113
0
}
17114
17115
17116
/* This is used to free up resources used by Aes structs
17117
 *
17118
 * aes AES keys to free
17119
 *
17120
 * return 0 on success
17121
 */
17122
int wc_AesXtsFree(XtsAes* aes)
17123
546
{
17124
546
    if (aes != NULL) {
17125
546
        wc_AesFree(&aes->aes);
17126
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
17127
        wc_AesFree(&aes->aes_decrypt);
17128
#endif
17129
546
        wc_AesFree(&aes->tweak);
17130
546
    }
17131
17132
546
    return 0;
17133
546
}
17134
17135
17136
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
17137
 * instead of a byte array. This just converts the word64 to a byte array and
17138
 * calls wc_AesXtsEncrypt.
17139
 *
17140
 * aes    AES keys to use for block encrypt/decrypt
17141
 * out    output buffer to hold cipher text
17142
 * in     input plain text buffer to encrypt
17143
 * sz     size of both out and in buffers
17144
 * sector value to use for tweak
17145
 *
17146
 * returns 0 on success
17147
 */
17148
int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
17149
        word32 sz, word64 sector)
17150
0
{
17151
0
    byte* pt;
17152
0
    byte  i[WC_AES_BLOCK_SIZE];
17153
17154
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
17155
#ifdef BIG_ENDIAN_ORDER
17156
    sector = ByteReverseWord64(sector);
17157
#endif
17158
0
    pt = (byte*)&sector;
17159
0
    XMEMCPY(i, pt, sizeof(word64));
17160
17161
0
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
17162
0
}
17163
17164
#ifdef HAVE_AES_DECRYPT
17165
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
17166
 * instead of a byte array. This just converts the word64 to a byte array.
17167
 *
17168
 * aes    AES keys to use for block encrypt/decrypt
17169
 * out    output buffer to hold plain text
17170
 * in     input cipher text buffer to encrypt
17171
 * sz     size of both out and in buffers
17172
 * sector value to use for tweak
17173
 *
17174
 * returns 0 on success
17175
 */
17176
int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
17177
        word64 sector)
17178
0
{
17179
0
    byte* pt;
17180
0
    byte  i[WC_AES_BLOCK_SIZE];
17181
17182
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
17183
#ifdef BIG_ENDIAN_ORDER
17184
    sector = ByteReverseWord64(sector);
17185
#endif
17186
0
    pt = (byte*)&sector;
17187
0
    XMEMCPY(i, pt, sizeof(word64));
17188
17189
0
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
17190
0
}
17191
#endif
17192
17193
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17194
17195
#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
17196
    #define USE_INTEL_SPEEDUP
17197
#endif
17198
17199
#if defined(USE_INTEL_SPEEDUP)
17200
    #define HAVE_INTEL_AVX1
17201
    #define HAVE_INTEL_AVX2
17202
#endif /* USE_INTEL_SPEEDUP */
17203
17204
void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
17205
                     const unsigned char* i, const unsigned char* key,
17206
                     const unsigned char* key2, int nr)
17207
                     XASM_LINK("AES_XTS_encrypt_aesni");
17208
#ifdef WOLFSSL_AESXTS_STREAM
17209
void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
17210
                     int tweak_nr)
17211
                     XASM_LINK("AES_XTS_init_aesni");
17212
void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
17213
                     const unsigned char* key, unsigned char *i, int nr)
17214
                     XASM_LINK("AES_XTS_encrypt_update_aesni");
17215
#endif
17216
#ifdef HAVE_INTEL_AVX1
17217
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
17218
                     word32 sz, const unsigned char* i,
17219
                     const unsigned char* key, const unsigned char* key2,
17220
                     int nr)
17221
                     XASM_LINK("AES_XTS_encrypt_avx1");
17222
#ifdef WOLFSSL_AESXTS_STREAM
17223
void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
17224
                     int tweak_nr)
17225
                     XASM_LINK("AES_XTS_init_avx1");
17226
void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
17227
                     const unsigned char* key, unsigned char *i, int nr)
17228
                     XASM_LINK("AES_XTS_encrypt_update_avx1");
17229
#endif
17230
#endif /* HAVE_INTEL_AVX1 */
17231
#ifdef HAVE_INTEL_VAES
17232
void AES_XTS_encrypt_vaes(const unsigned char *in, unsigned char *out,
17233
                     word32 sz, const unsigned char* i,
17234
                     const unsigned char* key, const unsigned char* key2,
17235
                     int nr)
17236
                     XASM_LINK("AES_XTS_encrypt_vaes");
17237
#ifdef WOLFSSL_AESXTS_STREAM
17238
void AES_XTS_init_vaes(unsigned char* i, const unsigned char* tweak_key,
17239
                     int tweak_nr)
17240
                     XASM_LINK("AES_XTS_init_vaes");
17241
void AES_XTS_encrypt_update_vaes(const unsigned char *in, unsigned char *out, word32 sz,
17242
                     const unsigned char* key, unsigned char *i, int nr)
17243
                     XASM_LINK("AES_XTS_encrypt_update_vaes");
17244
#endif
17245
#endif /* HAVE_INTEL_VAES */
17246
#ifdef HAVE_INTEL_AVX512
17247
void AES_XTS_encrypt_avx512(const unsigned char *in, unsigned char *out,
17248
                     word32 sz, const unsigned char* i,
17249
                     const unsigned char* key, const unsigned char* key2,
17250
                     int nr)
17251
                     XASM_LINK("AES_XTS_encrypt_avx512");
17252
#ifdef WOLFSSL_AESXTS_STREAM
17253
void AES_XTS_init_avx512(unsigned char* i, const unsigned char* tweak_key,
17254
                     int tweak_nr)
17255
                     XASM_LINK("AES_XTS_init_avx512");
17256
void AES_XTS_encrypt_update_avx512(const unsigned char *in, unsigned char *out, word32 sz,
17257
                     const unsigned char* key, unsigned char *i, int nr)
17258
                     XASM_LINK("AES_XTS_encrypt_update_avx512");
17259
#endif
17260
#endif /* HAVE_INTEL_AVX512 */
17261
17262
17263
#ifdef HAVE_AES_DECRYPT
17264
void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
17265
                     const unsigned char* i, const unsigned char* key,
17266
                     const unsigned char* key2, int nr)
17267
                     XASM_LINK("AES_XTS_decrypt_aesni");
17268
#ifdef WOLFSSL_AESXTS_STREAM
17269
void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
17270
                     const unsigned char* key, unsigned char *i, int nr)
17271
                     XASM_LINK("AES_XTS_decrypt_update_aesni");
17272
#endif
17273
#ifdef HAVE_INTEL_AVX1
17274
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
17275
                     word32 sz, const unsigned char* i,
17276
                     const unsigned char* key, const unsigned char* key2,
17277
                     int nr)
17278
                     XASM_LINK("AES_XTS_decrypt_avx1");
17279
#ifdef WOLFSSL_AESXTS_STREAM
17280
void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
17281
                     const unsigned char* key, unsigned char *i, int nr)
17282
                     XASM_LINK("AES_XTS_decrypt_update_avx1");
17283
#endif
17284
#endif /* HAVE_INTEL_AVX1 */
17285
#ifdef HAVE_INTEL_VAES
17286
void AES_XTS_decrypt_vaes(const unsigned char *in, unsigned char *out,
17287
                     word32 sz, const unsigned char* i,
17288
                     const unsigned char* key, const unsigned char* key2,
17289
                     int nr)
17290
                     XASM_LINK("AES_XTS_decrypt_vaes");
17291
#ifdef WOLFSSL_AESXTS_STREAM
17292
void AES_XTS_decrypt_update_vaes(const unsigned char *in, unsigned char *out, word32 sz,
17293
                     const unsigned char* key, unsigned char *i, int nr)
17294
                     XASM_LINK("AES_XTS_decrypt_update_vaes");
17295
#endif
17296
#endif /* HAVE_INTEL_VAES */
17297
#ifdef HAVE_INTEL_AVX512
17298
void AES_XTS_decrypt_avx512(const unsigned char *in, unsigned char *out,
17299
                     word32 sz, const unsigned char* i,
17300
                     const unsigned char* key, const unsigned char* key2,
17301
                     int nr)
17302
                     XASM_LINK("AES_XTS_decrypt_avx512");
17303
#ifdef WOLFSSL_AESXTS_STREAM
17304
void AES_XTS_decrypt_update_avx512(const unsigned char *in, unsigned char *out, word32 sz,
17305
                     const unsigned char* key, unsigned char *i, int nr)
17306
                     XASM_LINK("AES_XTS_decrypt_update_avx512");
17307
#endif
17308
#endif /* HAVE_INTEL_AVX512 */
17309
#endif /* HAVE_AES_DECRYPT */
17310
17311
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
17312
17313
#ifdef HAVE_AES_ECB
17314
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
17315
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
17316
/* helper function for encrypting / decrypting full buffer at once */
17317
static WARN_UNUSED_RESULT int _AesXtsHelper(
17318
    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
17319
423
{
17320
423
    word32 outSz   = sz;
17321
423
    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
17322
423
    byte*  pt      = out;
17323
17324
423
    outSz -= WC_AES_BLOCK_SIZE;
17325
17326
1.03k
    while (outSz > 0) {
17327
612
        word32 j;
17328
612
        byte carry = 0;
17329
17330
        /* multiply by shift left and propagate carry */
17331
9.95k
        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
17332
9.34k
            byte tmpC;
17333
17334
9.34k
            tmpC   = (pt[j] >> 7) & 0x01;
17335
9.34k
            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
17336
9.34k
            carry  = tmpC;
17337
9.34k
        }
17338
612
        if (carry) {
17339
302
            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
17340
302
        }
17341
17342
612
        pt += WC_AES_BLOCK_SIZE;
17343
612
    }
17344
17345
423
    xorbuf(out, in, totalSz);
17346
423
#ifndef WOLFSSL_RISCV_ASM
17347
423
    if (dir == AES_ENCRYPTION) {
17348
142
        return _AesEcbEncrypt(aes, out, out, totalSz);
17349
142
    }
17350
281
    else {
17351
281
        return _AesEcbDecrypt(aes, out, out, totalSz);
17352
281
    }
17353
#else
17354
    if (dir == AES_ENCRYPTION) {
17355
        return wc_AesEcbEncrypt(aes, out, out, totalSz);
17356
    }
17357
    else {
17358
        return wc_AesEcbDecrypt(aes, out, out, totalSz);
17359
    }
17360
#endif
17361
423
}
17362
#endif
17363
#endif /* HAVE_AES_ECB */
17364
17365
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
17366
 *
17367
 * xaes  AES keys to use for block encrypt/decrypt
17368
 * out   output buffer to hold cipher text
17369
 * in    input plain text buffer to encrypt
17370
 * sz    size of both out and in buffers
17371
 * i     value to use for tweak
17372
 *
17373
 * returns 0 on success
17374
 */
17375
/* Software AES - XTS Encrypt  */
17376
17377
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
17378
     defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) && !defined(WOLFSSL_PPC64_ASM)
17379
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
17380
                                  word32 sz,
17381
                                  byte *i);
17382
#if !defined(WOLFSSL_RISCV_ASM)
17383
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17384
        const byte* i)
17385
187
{
17386
187
    int ret;
17387
187
    byte tweak_block[WC_AES_BLOCK_SIZE];
17388
17389
187
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
17390
187
    if (ret != 0)
17391
0
        return ret;
17392
17393
187
    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
17394
187
}
17395
#endif /* !WOLFSSL_RISCV_ASM */
17396
#endif
17397
17398
#ifdef WOLFSSL_AESXTS_STREAM
17399
17400
/* Block-streaming AES-XTS tweak setup.
17401
 *
17402
 * xaes  AES keys to use for block encrypt/decrypt
17403
 * i     readwrite value to use for tweak
17404
 *
17405
 * returns 0 on success
17406
 */
17407
static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
17408
    return wc_AesEncryptDirect(&xaes->tweak, i, i);
17409
}
17410
17411
#endif /* WOLFSSL_AESXTS_STREAM */
17412
17413
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
17414
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || defined(WOLFSSL_AESXTS_STREAM)
17415
/* Block-streaming AES-XTS.
17416
 *
17417
 * Supply block-aligned input data with successive calls.  Final call need not
17418
 * be block aligned.
17419
 *
17420
 * xaes  AES keys to use for block encrypt/decrypt
17421
 * out   output buffer to hold cipher text
17422
 * in    input plain text buffer to encrypt
17423
 * sz    size of both out and in buffers
17424
 *
17425
 * returns 0 on success
17426
 */
17427
/* Software AES - XTS Encrypt  */
17428
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
17429
                                  word32 sz,
17430
                                  byte *i)
17431
187
{
17432
187
    int ret = 0;
17433
187
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
17434
187
    Aes *aes = &xaes->aes;
17435
17436
187
#ifdef HAVE_AES_ECB
17437
    /* encrypt all of buffer at once when possible */
17438
187
    if (in != out) { /* can not handle inline */
17439
142
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
17440
142
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
17441
0
            return ret;
17442
142
    }
17443
187
#endif
17444
17445
687
    while (blocks > 0) {
17446
500
        word32 j;
17447
500
        byte carry = 0;
17448
17449
500
#ifdef HAVE_AES_ECB
17450
500
        if (in == out)
17451
181
#endif
17452
181
        { /* check for if inline */
17453
181
            byte buf[WC_AES_BLOCK_SIZE];
17454
17455
181
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
17456
181
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
17457
181
            ret = wc_AesEncryptDirect(aes, out, buf);
17458
181
            if (ret != 0)
17459
0
                return ret;
17460
181
        }
17461
500
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
17462
17463
        /* multiply by shift left and propagate carry */
17464
8.50k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
17465
8.00k
            byte tmpC;
17466
17467
8.00k
            tmpC   = (i[j] >> 7) & 0x01;
17468
8.00k
            i[j] = (byte)((i[j] << 1) + carry);
17469
8.00k
            carry  = tmpC;
17470
8.00k
        }
17471
500
        if (carry) {
17472
244
            i[0] ^= GF_XTS;
17473
244
        }
17474
17475
500
        in  += WC_AES_BLOCK_SIZE;
17476
500
        out += WC_AES_BLOCK_SIZE;
17477
500
        sz  -= WC_AES_BLOCK_SIZE;
17478
500
        blocks--;
17479
500
    }
17480
17481
    /* stealing operation of XTS to handle left overs */
17482
187
    if (sz > 0) {
17483
18
        byte buf[WC_AES_BLOCK_SIZE];
17484
17485
18
        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
17486
18
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
17487
0
            return BUFFER_E;
17488
0
        }
17489
18
        if (in != out) {
17490
11
            XMEMCPY(out, buf, sz);
17491
11
            XMEMCPY(buf, in, sz);
17492
11
        }
17493
7
        else {
17494
7
            byte buf2[WC_AES_BLOCK_SIZE];
17495
17496
7
            XMEMCPY(buf2, buf, sz);
17497
7
            XMEMCPY(buf, in, sz);
17498
7
            XMEMCPY(out, buf2, sz);
17499
7
        }
17500
17501
18
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
17502
18
        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
17503
18
        if (ret == 0)
17504
18
            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
17505
18
    }
17506
17507
187
    return ret;
17508
187
}
17509
#endif
17510
17511
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
17512
 *
17513
 * xaes  AES keys to use for block encrypt/decrypt
17514
 * out   output buffer to hold cipher text
17515
 * in    input plain text buffer to encrypt
17516
 * sz    size of both out and in buffers
17517
 * i     value to use for tweak
17518
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
17519
 *       adds a sanity check on how the user calls the function.
17520
 *
17521
 * returns 0 on success
17522
 */
17523
int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17524
        const byte* i, word32 iSz)
17525
194
{
17526
194
    int ret;
17527
17528
194
    Aes *aes;
17529
17530
194
    if (xaes == NULL || out == NULL || in == NULL) {
17531
0
        return BAD_FUNC_ARG;
17532
0
    }
17533
17534
#if FIPS_VERSION3_GE(6,0,0)
17535
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
17536
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
17537
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
17538
     */
17539
    if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
17540
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
17541
        return BAD_FUNC_ARG;
17542
    }
17543
#endif
17544
17545
194
    aes = &xaes->aes;
17546
17547
194
    if (aes->keylen == 0) {
17548
0
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
17549
0
        return BAD_FUNC_ARG;
17550
0
    }
17551
17552
194
    if (iSz < WC_AES_BLOCK_SIZE) {
17553
0
        return BAD_FUNC_ARG;
17554
0
    }
17555
17556
194
    if (sz < WC_AES_BLOCK_SIZE) {
17557
7
        WOLFSSL_MSG("Plain text input too small for encryption");
17558
7
        return BAD_FUNC_ARG;
17559
7
    }
17560
17561
#if defined(WOLFSSL_RISCV_ASM)
17562
    AES_XTS_encrypt_RISCV64(in, out, sz, i, (byte*)xaes->aes.key,
17563
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, (int)xaes->aes.rounds);
17564
    ret = 0;
17565
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
17566
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
17567
    AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
17568
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17569
    ret = 0;
17570
#elif defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17571
    if (aes->use_aesni) {
17572
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
17573
#if defined(HAVE_INTEL_AVX512)
17574
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17575
            AES_XTS_encrypt_avx512(in, out, sz, i,
17576
                                   (const byte*)aes->key,
17577
                                   (const byte*)xaes->tweak.key,
17578
                                   (int)aes->rounds);
17579
            ret = 0;
17580
        }
17581
        else
17582
#endif
17583
#if defined(HAVE_INTEL_VAES)
17584
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17585
            AES_XTS_encrypt_vaes(in, out, sz, i,
17586
                                 (const byte*)aes->key,
17587
                                 (const byte*)xaes->tweak.key,
17588
                                 (int)aes->rounds);
17589
            ret = 0;
17590
        }
17591
        else
17592
#endif
17593
#if defined(HAVE_INTEL_AVX1)
17594
        if (IS_INTEL_AVX1(intel_flags)) {
17595
            AES_XTS_encrypt_avx1(in, out, sz, i,
17596
                                 (const byte*)aes->key,
17597
                                 (const byte*)xaes->tweak.key,
17598
                                 (int)aes->rounds);
17599
            ret = 0;
17600
        }
17601
        else
17602
#endif
17603
        {
17604
            AES_XTS_encrypt_aesni(in, out, sz, i,
17605
                                  (const byte*)aes->key,
17606
                                  (const byte*)xaes->tweak.key,
17607
                                  (int)aes->rounds);
17608
            ret = 0;
17609
        }
17610
        RESTORE_VECTOR_REGISTERS();
17611
    }
17612
    else {
17613
        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
17614
    }
17615
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
17616
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
17617
    if (aes->use_aes_hw_crypto) {
17618
        AES_XTS_encrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
17619
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17620
        ret = 0;
17621
    }
17622
    else
17623
#endif
17624
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
17625
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
17626
    if (sz >= 32)
17627
#endif
17628
    {
17629
        AES_XTS_encrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
17630
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17631
        ret = 0;
17632
    }
17633
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
17634
    else
17635
#endif
17636
#endif
17637
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
17638
    {
17639
        AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
17640
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17641
        ret = 0;
17642
    }
17643
#endif
17644
#elif defined(WOLFSSL_PPC64_ASM)
17645
    AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
17646
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
17647
    ret = 0;
17648
#else
17649
187
    ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
17650
187
#endif
17651
17652
187
    return ret;
17653
194
}
17654
17655
#ifdef WOLFSSL_AESXTS_STREAM
17656
17657
/* Block-streaming AES-XTS.
17658
 *
17659
 * xaes  AES keys to use for block encrypt/decrypt
17660
 * i     readwrite value to use for tweak
17661
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
17662
 *       adds a sanity check on how the user calls the function.
17663
 *
17664
 * returns 0 on success
17665
 */
17666
int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
17667
                         struct XtsAesStreamData *stream)
17668
{
17669
    int ret;
17670
17671
    Aes *aes;
17672
17673
    if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
17674
        return BAD_FUNC_ARG;
17675
    }
17676
17677
    if (iSz < WC_AES_BLOCK_SIZE) {
17678
        return BAD_FUNC_ARG;
17679
    }
17680
17681
    aes = &xaes->aes;
17682
17683
    if (aes->keylen == 0) {
17684
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
17685
        return BAD_FUNC_ARG;
17686
    }
17687
17688
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
17689
    stream->bytes_crypted_with_this_tweak = 0;
17690
17691
    {
17692
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17693
        if (aes->use_aesni) {
17694
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
17695
#if defined(HAVE_INTEL_AVX512)
17696
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17697
                AES_XTS_init_avx512(stream->tweak_block,
17698
                                    (const byte*)xaes->tweak.key,
17699
                                    (int)xaes->tweak.rounds);
17700
                ret = 0;
17701
            }
17702
            else
17703
#endif
17704
#if defined(HAVE_INTEL_VAES)
17705
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17706
                AES_XTS_init_vaes(stream->tweak_block,
17707
                                  (const byte*)xaes->tweak.key,
17708
                                  (int)xaes->tweak.rounds);
17709
                ret = 0;
17710
            }
17711
            else
17712
#endif
17713
#if defined(HAVE_INTEL_AVX1)
17714
            if (IS_INTEL_AVX1(intel_flags)) {
17715
                AES_XTS_init_avx1(stream->tweak_block,
17716
                                  (const byte*)xaes->tweak.key,
17717
                                  (int)xaes->tweak.rounds);
17718
                ret = 0;
17719
            }
17720
            else
17721
#endif
17722
            {
17723
                AES_XTS_init_aesni(stream->tweak_block,
17724
                                   (const byte*)xaes->tweak.key,
17725
                                   (int)xaes->tweak.rounds);
17726
                ret = 0;
17727
            }
17728
            RESTORE_VECTOR_REGISTERS();
17729
        }
17730
        else
17731
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
17732
        {
17733
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
17734
        }
17735
    }
17736
17737
    return ret;
17738
}
17739
17740
/* Block-streaming AES-XTS
17741
 *
17742
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
17743
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsEncryptUpdate().
17744
 * wc_AesXtsEncryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
17745
 *
17746
 * xaes  AES keys to use for block encrypt/decrypt
17747
 * out   output buffer to hold cipher text
17748
 * in    input plain text buffer to encrypt
17749
 * sz    size of both out and in buffers -- must be >= WC_AES_BLOCK_SIZE.
17750
 * i     value to use for tweak
17751
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
17752
 *       adds a sanity check on how the user calls the function.
17753
 *
17754
 * returns 0 on success
17755
 */
17756
static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17757
                           struct XtsAesStreamData *stream)
17758
{
17759
    int ret;
17760
17761
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17762
    Aes *aes;
17763
#endif
17764
17765
    if (xaes == NULL || out == NULL || in == NULL) {
17766
        return BAD_FUNC_ARG;
17767
    }
17768
17769
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17770
    aes = &xaes->aes;
17771
#endif
17772
17773
    if (sz < WC_AES_BLOCK_SIZE) {
17774
        WOLFSSL_MSG("Plain text input too small for encryption");
17775
        return BAD_FUNC_ARG;
17776
    }
17777
17778
    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
17779
    {
17780
        WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
17781
        return BAD_FUNC_ARG;
17782
    }
17783
17784
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
17785
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
17786
                             stream->bytes_crypted_with_this_tweak))
17787
    {
17788
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
17789
                    "in AesXtsEncryptUpdate().");
17790
    }
17791
#endif
17792
#if FIPS_VERSION3_GE(6,0,0)
17793
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
17794
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
17795
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
17796
     */
17797
    if (stream->bytes_crypted_with_this_tweak >
17798
        FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
17799
    {
17800
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
17801
        return BAD_FUNC_ARG;
17802
    }
17803
#endif
17804
    {
17805
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
17806
        if (aes->use_aesni) {
17807
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
17808
#if defined(HAVE_INTEL_AVX512)
17809
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17810
                AES_XTS_encrypt_update_avx512(in, out, sz,
17811
                                              (const byte*)aes->key,
17812
                                              stream->tweak_block,
17813
                                              (int)aes->rounds);
17814
                ret = 0;
17815
            }
17816
            else
17817
#endif
17818
#if defined(HAVE_INTEL_VAES)
17819
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
17820
                AES_XTS_encrypt_update_vaes(in, out, sz,
17821
                                            (const byte*)aes->key,
17822
                                            stream->tweak_block,
17823
                                            (int)aes->rounds);
17824
                ret = 0;
17825
            }
17826
            else
17827
#endif
17828
#if defined(HAVE_INTEL_AVX1)
17829
            if (IS_INTEL_AVX1(intel_flags)) {
17830
                AES_XTS_encrypt_update_avx1(in, out, sz,
17831
                                            (const byte*)aes->key,
17832
                                            stream->tweak_block,
17833
                                            (int)aes->rounds);
17834
                ret = 0;
17835
            }
17836
            else
17837
#endif
17838
            {
17839
                AES_XTS_encrypt_update_aesni(in, out, sz,
17840
                                            (const byte*)aes->key,
17841
                                            stream->tweak_block,
17842
                                            (int)aes->rounds);
17843
                ret = 0;
17844
            }
17845
            RESTORE_VECTOR_REGISTERS();
17846
        }
17847
        else
17848
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
17849
        {
17850
            ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
17851
        }
17852
    }
17853
17854
    return ret;
17855
}
17856
17857
int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17858
                           struct XtsAesStreamData *stream)
17859
{
17860
    if (stream == NULL)
17861
        return BAD_FUNC_ARG;
17862
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
17863
        return BAD_FUNC_ARG;
17864
    return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
17865
}
17866
17867
int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17868
                           struct XtsAesStreamData *stream)
17869
{
17870
    int ret;
17871
    if (stream == NULL)
17872
        return BAD_FUNC_ARG;
17873
    if (sz > 0)
17874
        ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
17875
    else
17876
        ret = 0;
17877
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
17878
     * after finalization.
17879
     */
17880
    stream->bytes_crypted_with_this_tweak |= 1U;
17881
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
17882
#ifdef WOLFSSL_CHECK_MEM_ZERO
17883
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
17884
#endif
17885
    return ret;
17886
}
17887
17888
#endif /* WOLFSSL_AESXTS_STREAM */
17889
17890
#ifdef HAVE_AES_DECRYPT
17891
17892
/* Same process as encryption but use aes_decrypt key.
17893
 *
17894
 * xaes  AES keys to use for block encrypt/decrypt
17895
 * out   output buffer to hold plain text
17896
 * in    input cipher text buffer to decrypt
17897
 * sz    size of both out and in buffers
17898
 * i     value to use for tweak
17899
 *
17900
 * returns 0 on success
17901
 */
17902
/* Software AES - XTS Decrypt */
17903
17904
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
17905
     defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) && !defined(WOLFSSL_PPC64_ASM)
17906
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
17907
                                  word32 sz, byte *i);
17908
17909
#if !defined(WOLFSSL_RISCV_ASM)
17910
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
17911
        const byte* i)
17912
281
{
17913
281
    int ret;
17914
281
    byte tweak_block[WC_AES_BLOCK_SIZE];
17915
17916
281
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
17917
281
    if (ret != 0)
17918
0
        return ret;
17919
17920
281
    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
17921
281
}
17922
#endif /* !WOLFSSL_RISCV_ASM */
17923
#endif
17924
17925
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
17926
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
17927
/* Block-streaming AES-XTS.
17928
 *
17929
 * Same process as encryption but use decrypt key.
17930
 *
17931
 * Supply block-aligned input data with successive calls.  Final call need not
17932
 * be block aligned.
17933
 *
17934
 * xaes  AES keys to use for block encrypt/decrypt
17935
 * out   output buffer to hold plain text
17936
 * in    input cipher text buffer to decrypt
17937
 * sz    size of both out and in buffers
17938
 * i     value to use for tweak
17939
 *
17940
 * returns 0 on success
17941
 */
17942
/* Software AES - XTS Decrypt */
17943
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
17944
                                  word32 sz, byte *i)
17945
281
{
17946
281
    int ret = 0;
17947
281
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
17948
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
17949
    Aes *aes = &xaes->aes_decrypt;
17950
#else
17951
281
    Aes *aes = &xaes->aes;
17952
281
#endif
17953
281
    word32 j;
17954
281
    byte carry = 0;
17955
281
    byte stl = (sz % WC_AES_BLOCK_SIZE);
17956
17957
    /* if Stealing then break out of loop one block early to handle special
17958
     * case */
17959
281
    if (stl > 0) {
17960
111
        blocks--;
17961
111
    }
17962
17963
281
#ifdef HAVE_AES_ECB
17964
    /* decrypt all of buffer at once when possible */
17965
281
    if (in != out) { /* can not handle inline */
17966
281
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
17967
281
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
17968
0
            return ret;
17969
281
    }
17970
281
#endif
17971
17972
764
    while (blocks > 0) {
17973
483
#ifdef HAVE_AES_ECB
17974
483
        if (in == out)
17975
0
#endif
17976
0
        { /* check for if inline */
17977
0
            byte buf[WC_AES_BLOCK_SIZE];
17978
17979
0
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
17980
0
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
17981
0
            ret = wc_AesDecryptDirect(aes, out, buf);
17982
0
            if (ret != 0)
17983
0
                return ret;
17984
0
        }
17985
483
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
17986
17987
        /* multiply by shift left and propagate carry */
17988
8.21k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
17989
7.72k
            byte tmpC;
17990
17991
7.72k
            tmpC   = (i[j] >> 7) & 0x01;
17992
7.72k
            i[j] = (byte)((i[j] << 1) + carry);
17993
7.72k
            carry  = tmpC;
17994
7.72k
        }
17995
483
        if (carry) {
17996
230
            i[0] ^= GF_XTS;
17997
230
        }
17998
483
        carry = 0;
17999
18000
483
        in  += WC_AES_BLOCK_SIZE;
18001
483
        out += WC_AES_BLOCK_SIZE;
18002
483
        sz  -= WC_AES_BLOCK_SIZE;
18003
483
        blocks--;
18004
483
    }
18005
18006
    /* stealing operation of XTS to handle left overs */
18007
281
    if (sz >= WC_AES_BLOCK_SIZE) {
18008
111
        byte buf[WC_AES_BLOCK_SIZE];
18009
111
        byte tmp2[WC_AES_BLOCK_SIZE];
18010
18011
        /* multiply by shift left and propagate carry */
18012
1.88k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
18013
1.77k
            byte tmpC;
18014
18015
1.77k
            tmpC   = (i[j] >> 7) & 0x01;
18016
1.77k
            tmp2[j] = (byte)((i[j] << 1) + carry);
18017
1.77k
            carry  = tmpC;
18018
1.77k
        }
18019
111
        if (carry) {
18020
46
            tmp2[0] ^= GF_XTS;
18021
46
        }
18022
18023
111
        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
18024
111
        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
18025
111
        ret = wc_AesDecryptDirect(aes, out, buf);
18026
111
        if (ret != 0)
18027
0
            return ret;
18028
111
        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
18029
18030
        /* tmp2 holds partial | last */
18031
111
        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
18032
111
        in  += WC_AES_BLOCK_SIZE;
18033
111
        out += WC_AES_BLOCK_SIZE;
18034
111
        sz  -= WC_AES_BLOCK_SIZE;
18035
18036
        /* Make buffer with end of cipher text | last */
18037
111
        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
18038
111
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
18039
0
            return BUFFER_E;
18040
0
        }
18041
111
        XMEMCPY(buf, in,   sz);
18042
111
        XMEMCPY(out, tmp2, sz);
18043
18044
111
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
18045
111
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
18046
111
        if (ret != 0)
18047
0
            return ret;
18048
111
        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
18049
111
        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
18050
111
    }
18051
18052
281
    return ret;
18053
281
}
18054
#endif
18055
18056
/* Same process as encryption but Aes key is AES_DECRYPTION type.
18057
 *
18058
 * xaes  AES keys to use for block encrypt/decrypt
18059
 * out   output buffer to hold plain text
18060
 * in    input cipher text buffer to decrypt
18061
 * sz    size of both out and in buffers
18062
 * i     value to use for tweak
18063
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
18064
 *       adds a sanity check on how the user calls the function.
18065
 *
18066
 * returns 0 on success
18067
 */
18068
int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
18069
        const byte* i, word32 iSz)
18070
283
{
18071
283
    int ret;
18072
283
    Aes *aes;
18073
18074
283
    if (xaes == NULL || out == NULL || in == NULL) {
18075
0
        return BAD_FUNC_ARG;
18076
0
    }
18077
18078
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18079
    aes = &xaes->aes_decrypt;
18080
#else
18081
283
    aes = &xaes->aes;
18082
283
#endif
18083
18084
/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
18085
 * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
18086
 * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes or
18087
 * 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
18088
 * return whenever sz / WC_AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
18089
 * not a sequence of complete blocks.
18090
 */
18091
18092
283
    if (aes->keylen == 0) {
18093
0
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
18094
0
        return BAD_FUNC_ARG;
18095
0
    }
18096
18097
283
    if (iSz < WC_AES_BLOCK_SIZE) {
18098
0
        return BAD_FUNC_ARG;
18099
0
    }
18100
18101
283
    if (sz < WC_AES_BLOCK_SIZE) {
18102
2
        WOLFSSL_MSG("Cipher text input too small for decryption");
18103
2
        return BAD_FUNC_ARG;
18104
2
    }
18105
18106
#if defined(WOLFSSL_RISCV_ASM)
18107
    /* Use the selected decrypt schedule (aes), not xaes->aes - under
18108
     * WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS xaes->aes holds the
18109
     * ENCRYPT schedule; matches the AESNI branch below. */
18110
    AES_XTS_decrypt_RISCV64(in, out, sz, i, (byte*)aes->key,
18111
        (byte*)xaes->tweak.key, (byte*)aes->tmp, (int)aes->rounds);
18112
    ret = 0;
18113
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
18114
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
18115
    AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
18116
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18117
    ret = 0;
18118
#elif defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18119
    if (aes->use_aesni) {
18120
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
18121
#if defined(HAVE_INTEL_AVX512)
18122
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18123
            AES_XTS_decrypt_avx512(in, out, sz, i,
18124
                                   (const byte*)aes->key,
18125
                                   (const byte*)xaes->tweak.key,
18126
                                   (int)aes->rounds);
18127
            ret = 0;
18128
        }
18129
        else
18130
#endif
18131
#if defined(HAVE_INTEL_VAES)
18132
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18133
            AES_XTS_decrypt_vaes(in, out, sz, i,
18134
                                 (const byte*)aes->key,
18135
                                 (const byte*)xaes->tweak.key,
18136
                                 (int)aes->rounds);
18137
            ret = 0;
18138
        }
18139
        else
18140
#endif
18141
#if defined(HAVE_INTEL_AVX1)
18142
        if (IS_INTEL_AVX1(intel_flags)) {
18143
            AES_XTS_decrypt_avx1(in, out, sz, i,
18144
                                 (const byte*)aes->key,
18145
                                 (const byte*)xaes->tweak.key,
18146
                                 (int)aes->rounds);
18147
            ret = 0;
18148
        }
18149
        else
18150
#endif
18151
        {
18152
            AES_XTS_decrypt_aesni(in, out, sz, i,
18153
                                  (const byte*)aes->key,
18154
                                  (const byte*)xaes->tweak.key,
18155
                                  (int)aes->rounds);
18156
            ret = 0;
18157
        }
18158
        RESTORE_VECTOR_REGISTERS();
18159
    }
18160
    else {
18161
        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
18162
    }
18163
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
18164
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
18165
    if (aes->use_aes_hw_crypto) {
18166
        AES_XTS_decrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
18167
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18168
        ret = 0;
18169
    }
18170
    else
18171
#endif
18172
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
18173
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18174
    if (sz >= 64)
18175
#endif
18176
    {
18177
        AES_XTS_decrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
18178
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18179
        ret = 0;
18180
    }
18181
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18182
    else
18183
#endif
18184
#endif
18185
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18186
    {
18187
        AES_XTS_decrypt(in, out, sz, i, (byte*)xaes->aes.key,
18188
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18189
        ret = 0;
18190
    }
18191
#endif
18192
#elif defined(WOLFSSL_PPC64_ASM)
18193
    AES_XTS_decrypt(in, out, sz, i, (byte*)xaes->aes.key,
18194
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18195
    ret = 0;
18196
#else
18197
281
    ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
18198
281
#endif
18199
18200
281
    return ret;
18201
283
}
18202
18203
#ifdef WOLFSSL_AESXTS_STREAM
18204
18205
/* Same process as encryption but Aes key is AES_DECRYPTION type.
18206
 *
18207
 * xaes  AES keys to use for block encrypt/decrypt
18208
 * i     readwrite value to use for tweak
18209
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
18210
 *       adds a sanity check on how the user calls the function.
18211
 *
18212
 * returns 0 on success
18213
 */
18214
int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
18215
                         struct XtsAesStreamData *stream)
18216
{
18217
    int ret;
18218
    Aes *aes;
18219
18220
    if (xaes == NULL) {
18221
        return BAD_FUNC_ARG;
18222
    }
18223
18224
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18225
    aes = &xaes->aes_decrypt;
18226
#else
18227
    aes = &xaes->aes;
18228
#endif
18229
18230
    if (aes->keylen == 0) {
18231
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
18232
        return BAD_FUNC_ARG;
18233
    }
18234
18235
    if (iSz < WC_AES_BLOCK_SIZE) {
18236
        return BAD_FUNC_ARG;
18237
    }
18238
18239
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
18240
    stream->bytes_crypted_with_this_tweak = 0;
18241
18242
    {
18243
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18244
        if (aes->use_aesni) {
18245
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
18246
#if defined(HAVE_INTEL_AVX512)
18247
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18248
                AES_XTS_init_avx512(stream->tweak_block,
18249
                                    (const byte*)xaes->tweak.key,
18250
                                    (int)xaes->tweak.rounds);
18251
                ret = 0;
18252
            }
18253
            else
18254
#endif
18255
#if defined(HAVE_INTEL_VAES)
18256
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18257
                AES_XTS_init_vaes(stream->tweak_block,
18258
                                  (const byte*)xaes->tweak.key,
18259
                                  (int)xaes->tweak.rounds);
18260
                ret = 0;
18261
            }
18262
            else
18263
#endif
18264
#if defined(HAVE_INTEL_AVX1)
18265
            if (IS_INTEL_AVX1(intel_flags)) {
18266
                AES_XTS_init_avx1(stream->tweak_block,
18267
                                  (const byte*)xaes->tweak.key,
18268
                                  (int)xaes->tweak.rounds);
18269
                ret = 0;
18270
            }
18271
            else
18272
#endif
18273
            {
18274
                AES_XTS_init_aesni(stream->tweak_block,
18275
                                   (const byte*)xaes->tweak.key,
18276
                                   (int)xaes->tweak.rounds);
18277
                ret = 0;
18278
            }
18279
            RESTORE_VECTOR_REGISTERS();
18280
        }
18281
        else
18282
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
18283
        {
18284
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
18285
        }
18286
18287
    }
18288
18289
    return ret;
18290
}
18291
18292
/* Block-streaming AES-XTS
18293
 *
18294
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
18295
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsDecryptUpdate().
18296
 * wc_AesXtsDecryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
18297
 *
18298
 * xaes  AES keys to use for block encrypt/decrypt
18299
 * out   output buffer to hold plain text
18300
 * in    input cipher text buffer to decrypt
18301
 * sz    size of both out and in buffers
18302
 * i     tweak buffer of size WC_AES_BLOCK_SIZE.
18303
 *
18304
 * returns 0 on success
18305
 */
18306
static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
18307
                           struct XtsAesStreamData *stream)
18308
{
18309
    int ret;
18310
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18311
    Aes *aes;
18312
#endif
18313
18314
    if (xaes == NULL || out == NULL || in == NULL) {
18315
        return BAD_FUNC_ARG;
18316
    }
18317
18318
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18319
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18320
    aes = &xaes->aes_decrypt;
18321
#else
18322
    aes = &xaes->aes;
18323
#endif
18324
#endif
18325
18326
    if (sz < WC_AES_BLOCK_SIZE) {
18327
        WOLFSSL_MSG("Cipher text input too small for decryption");
18328
        return BAD_FUNC_ARG;
18329
    }
18330
18331
    if (stream->bytes_crypted_with_this_tweak &
18332
        ((word32)WC_AES_BLOCK_SIZE - 1U))
18333
    {
18334
        WOLFSSL_MSG("AesXtsDecryptUpdate after previous finalizing call");
18335
        return BAD_FUNC_ARG;
18336
    }
18337
18338
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
18339
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
18340
                             stream->bytes_crypted_with_this_tweak))
18341
    {
18342
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
18343
                    "in AesXtsDecryptUpdate().");
18344
    }
18345
#endif
18346
18347
    {
18348
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18349
        if (aes->use_aesni) {
18350
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
18351
#if defined(HAVE_INTEL_AVX512)
18352
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18353
                AES_XTS_decrypt_update_avx512(in, out, sz,
18354
                                              (const byte*)aes->key,
18355
                                              stream->tweak_block,
18356
                                              (int)aes->rounds);
18357
                ret = 0;
18358
            }
18359
            else
18360
#endif
18361
#if defined(HAVE_INTEL_VAES)
18362
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18363
                AES_XTS_decrypt_update_vaes(in, out, sz,
18364
                                            (const byte*)aes->key,
18365
                                            stream->tweak_block,
18366
                                            (int)aes->rounds);
18367
                ret = 0;
18368
            }
18369
            else
18370
#endif
18371
#if defined(HAVE_INTEL_AVX1)
18372
            if (IS_INTEL_AVX1(intel_flags)) {
18373
                AES_XTS_decrypt_update_avx1(in, out, sz,
18374
                                            (const byte*)aes->key,
18375
                                            stream->tweak_block,
18376
                                            (int)aes->rounds);
18377
                ret = 0;
18378
            }
18379
            else
18380
#endif
18381
            {
18382
                AES_XTS_decrypt_update_aesni(in, out, sz,
18383
                                             (const byte*)aes->key,
18384
                                             stream->tweak_block,
18385
                                             (int)aes->rounds);
18386
                ret = 0;
18387
            }
18388
            RESTORE_VECTOR_REGISTERS();
18389
        }
18390
        else
18391
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
18392
        {
18393
            ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
18394
                                         stream->tweak_block);
18395
        }
18396
    }
18397
18398
    return ret;
18399
}
18400
18401
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
18402
                           struct XtsAesStreamData *stream)
18403
{
18404
    if (stream == NULL)
18405
        return BAD_FUNC_ARG;
18406
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
18407
        return BAD_FUNC_ARG;
18408
    return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
18409
}
18410
18411
int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
18412
                           struct XtsAesStreamData *stream)
18413
{
18414
    int ret;
18415
    if (stream == NULL)
18416
        return BAD_FUNC_ARG;
18417
    if (sz > 0)
18418
        ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
18419
    else
18420
        ret = 0;
18421
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
18422
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
18423
     * after finalization.
18424
     */
18425
    stream->bytes_crypted_with_this_tweak |= 1U;
18426
#ifdef WOLFSSL_CHECK_MEM_ZERO
18427
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
18428
#endif
18429
    return ret;
18430
}
18431
18432
#endif /* WOLFSSL_AESXTS_STREAM */
18433
#endif /* HAVE_AES_DECRYPT */
18434
18435
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
18436
 * sectorSz bytes
18437
 *
18438
 * xaes     AES keys to use for block encrypt
18439
 * out      output buffer to hold cipher text
18440
 * in       input plain text buffer to encrypt
18441
 * sz       size of both out and in buffers
18442
 * sector   value to use for tweak
18443
 * sectorSz size of the sector
18444
 *
18445
 * returns 0 on success
18446
 */
18447
int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
18448
        word32 sz, word64 sector, word32 sectorSz)
18449
0
{
18450
0
    int ret  = 0;
18451
0
    word32 iter = 0;
18452
0
    word32 sectorCount;
18453
0
    word32 remainder;
18454
18455
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
18456
0
        return BAD_FUNC_ARG;
18457
0
    }
18458
18459
0
    if (sz < WC_AES_BLOCK_SIZE) {
18460
0
        WOLFSSL_MSG("Cipher text input too small for encryption");
18461
0
        return BAD_FUNC_ARG;
18462
0
    }
18463
18464
0
    sectorCount  = sz / sectorSz;
18465
0
    remainder = sz % sectorSz;
18466
18467
0
    while (sectorCount) {
18468
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
18469
0
                in + (iter * sectorSz), sectorSz, sector);
18470
0
        if (ret != 0)
18471
0
            break;
18472
18473
0
        sectorCount--;
18474
0
        iter++;
18475
0
        sector++;
18476
0
    }
18477
18478
0
    if (remainder && ret == 0)
18479
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
18480
0
                in + (iter * sectorSz), remainder, sector);
18481
18482
0
    return ret;
18483
0
}
18484
18485
#ifdef HAVE_AES_DECRYPT
18486
18487
/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
18488
 *
18489
 * xaes     AES keys to use for block decrypt
18490
 * out      output buffer to hold cipher text
18491
 * in       input plain text buffer to encrypt
18492
 * sz       size of both out and in buffers
18493
 * sector   value to use for tweak
18494
 * sectorSz size of the sector
18495
 *
18496
 * returns 0 on success
18497
 */
18498
int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
18499
        word32 sz, word64 sector, word32 sectorSz)
18500
0
{
18501
0
    int ret  = 0;
18502
0
    word32 iter = 0;
18503
0
    word32 sectorCount;
18504
0
    word32 remainder;
18505
18506
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
18507
0
        return BAD_FUNC_ARG;
18508
0
    }
18509
18510
0
    if (sz < WC_AES_BLOCK_SIZE) {
18511
0
        WOLFSSL_MSG("Cipher text input too small for decryption");
18512
0
        return BAD_FUNC_ARG;
18513
0
    }
18514
18515
0
    sectorCount  = sz / sectorSz;
18516
0
    remainder = sz % sectorSz;
18517
18518
0
    while (sectorCount) {
18519
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
18520
0
                in + (iter * sectorSz), sectorSz, sector);
18521
0
        if (ret != 0)
18522
0
            break;
18523
18524
0
        sectorCount--;
18525
0
        iter++;
18526
0
        sector++;
18527
0
    }
18528
18529
0
    if (remainder && ret == 0)
18530
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
18531
0
                in + (iter * sectorSz), remainder, sector);
18532
18533
0
    return ret;
18534
0
}
18535
#endif /* HAVE_AES_DECRYPT */
18536
#endif /* WOLFSSL_AES_XTS */
18537
18538
#ifdef WOLFSSL_CMAC
18539
18540
1.54k
int wc_local_CmacUpdateAes(struct Cmac *cmac, const byte* in, word32 inSz) {
18541
1.54k
    int ret = 0;
18542
1.54k
    Aes *aes = &cmac->aes;
18543
1.54k
#ifdef WC_AES_HAVE_PREFETCH_ARG
18544
1.54k
    int did_prefetches = 0;
18545
1.54k
#endif
18546
18547
1.54k
    VECTOR_REGISTERS_PUSH;
18548
18549
6.88k
    while ((ret == 0) && (inSz != 0)) {
18550
5.33k
        word32 add = min(inSz, WC_AES_BLOCK_SIZE - cmac->bufferSz);
18551
5.33k
        XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
18552
18553
5.33k
        cmac->bufferSz += add;
18554
5.33k
        inSz -= add;
18555
5.33k
        in += add;
18556
18557
5.33k
        if (cmac->bufferSz == WC_AES_BLOCK_SIZE && inSz != 0) {
18558
5.10k
            xorbuf(cmac->buffer, cmac->digest, WC_AES_BLOCK_SIZE);
18559
5.10k
            ret = AesEncrypt_preFetchOpt(aes, cmac->buffer,
18560
5.10k
                                            cmac->digest, &did_prefetches);
18561
5.10k
            if (ret == 0) {
18562
5.10k
                cmac->totalSz += WC_AES_BLOCK_SIZE;
18563
5.10k
                cmac->bufferSz = 0;
18564
5.10k
            }
18565
5.10k
        }
18566
5.33k
    }
18567
18568
1.54k
    VECTOR_REGISTERS_POP;
18569
18570
1.54k
    return ret;
18571
1.54k
}
18572
18573
#endif /* WOLFSSL_CMAC */
18574
18575
#ifdef WOLFSSL_AES_SIV
18576
18577
/*
18578
 * See RFC 5297 Section 2.4.
18579
 */
18580
static WARN_UNUSED_RESULT int S2V(
18581
    const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc,
18582
    const byte* nonce, word32 nonceSz, const byte* data,
18583
    word32 dataSz, byte* out)
18584
0
{
18585
0
#ifdef WOLFSSL_SMALL_STACK
18586
0
    byte* tmp[3] = {NULL, NULL, NULL};
18587
0
    int i;
18588
0
    Cmac* cmac;
18589
#else
18590
    byte tmp[3][WC_AES_BLOCK_SIZE];
18591
    Cmac cmac[1];
18592
#endif
18593
0
    word32 macSz = WC_AES_BLOCK_SIZE;
18594
0
    int ret = 0;
18595
0
    byte tmpi = 0;
18596
0
    word32 ai;
18597
0
    word32 zeroBytes;
18598
18599
0
#ifdef WOLFSSL_SMALL_STACK
18600
0
    for (i = 0; i < 3; ++i) {
18601
0
        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18602
0
        if (tmp[i] == NULL) {
18603
0
            ret = MEMORY_E;
18604
0
            break;
18605
0
        }
18606
0
    }
18607
0
    if (ret == 0)
18608
0
#endif
18609
18610
0
    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
18611
        /* See RFC 5297 Section 7. */
18612
0
        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
18613
0
                    " 126.");
18614
0
        ret = BAD_FUNC_ARG;
18615
0
    }
18616
18617
0
    if (ret == 0) {
18618
0
        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
18619
0
        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
18620
18621
0
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
18622
0
                                 key, keySz);
18623
0
    }
18624
18625
0
    if (ret == 0) {
18626
        /* Loop over authenticated associated data AD1..ADn */
18627
0
        for (ai = 0; ai < numAssoc; ++ai) {
18628
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
18629
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
18630
0
                                     assoc[ai].assocSz, key, keySz);
18631
0
            if (ret != 0)
18632
0
                break;
18633
0
            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
18634
0
            tmpi = (byte)(1 - tmpi);
18635
0
        }
18636
18637
        /* Add nonce as final AD. See RFC 5297 Section 3. */
18638
0
        if ((ret == 0) && (nonceSz > 0)) {
18639
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
18640
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
18641
0
                                     nonceSz, key, keySz);
18642
0
            if (ret == 0) {
18643
0
                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
18644
0
            }
18645
0
            tmpi = (byte)(1U - tmpi);
18646
0
        }
18647
18648
        /* For simplicity of the remaining code, make sure the "final" result
18649
           is always in tmp[0]. */
18650
0
        if (tmpi == 1) {
18651
0
            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
18652
0
        }
18653
0
    }
18654
18655
0
    if (ret == 0) {
18656
0
        if (dataSz >= WC_AES_BLOCK_SIZE) {
18657
18658
0
            WC_ALLOC_VAR_EX(cmac, Cmac, 1, NULL, DYNAMIC_TYPE_CMAC,
18659
0
                ret=MEMORY_E);
18660
0
            if (WC_VAR_OK(cmac))
18661
0
            {
18662
            #ifdef WOLFSSL_CHECK_MEM_ZERO
18663
                /* Aes part is checked by wc_AesFree. */
18664
                wc_MemZero_Add("wc_AesCmacGenerate cmac",
18665
                    ((unsigned char *)cmac) + sizeof(Aes),
18666
                    sizeof(Cmac) - sizeof(Aes));
18667
            #endif
18668
0
                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
18669
0
                       WC_AES_BLOCK_SIZE);
18670
0
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
18671
0
                if (ret == 0) {
18672
0
                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
18673
0
                }
18674
0
                if (ret == 0) {
18675
0
                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
18676
0
                }
18677
0
                if (ret == 0) {
18678
0
                    ret = wc_CmacFinal(cmac, out, &macSz);
18679
0
                }
18680
0
            }
18681
0
        #ifdef WOLFSSL_SMALL_STACK
18682
0
            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
18683
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
18684
            wc_MemZero_Check(cmac, sizeof(Cmac));
18685
        #endif
18686
0
        }
18687
0
        else {
18688
0
            XMEMCPY(tmp[2], data, dataSz);
18689
0
            tmp[2][dataSz] |= 0x80;
18690
0
            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
18691
0
            if (zeroBytes != 0) {
18692
0
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
18693
0
            }
18694
0
            ShiftAndXorRb(tmp[1], tmp[0]);
18695
0
            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
18696
0
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
18697
0
                                     keySz);
18698
0
        }
18699
0
    }
18700
18701
0
#ifdef WOLFSSL_SMALL_STACK
18702
0
    for (i = 0; i < 3; ++i) {
18703
0
        if (tmp[i] != NULL) {
18704
0
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
18705
0
        }
18706
0
    }
18707
0
#endif
18708
18709
0
    return ret;
18710
0
}
18711
18712
static WARN_UNUSED_RESULT int AesSivCipher(
18713
    const byte* key, word32 keySz, const AesSivAssoc* assoc,
18714
    word32 numAssoc, const byte* nonce, word32 nonceSz,
18715
    const byte* data, word32 dataSz, byte* siv, byte* out,
18716
    int enc)
18717
0
{
18718
0
    int ret = 0;
18719
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
18720
0
    byte sivTmp[WC_AES_BLOCK_SIZE];
18721
18722
0
    if (key == NULL || siv == NULL || out == NULL) {
18723
0
        WOLFSSL_MSG("Bad parameter");
18724
0
        ret = BAD_FUNC_ARG;
18725
0
    }
18726
18727
0
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
18728
0
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
18729
0
        ret = BAD_FUNC_ARG;
18730
0
    }
18731
18732
0
    if (ret == 0) {
18733
0
        if (enc == 1) {
18734
0
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
18735
0
                      dataSz, sivTmp);
18736
0
            if (ret != 0) {
18737
0
                WOLFSSL_MSG("S2V failed.");
18738
0
            }
18739
0
            else {
18740
0
                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
18741
0
            }
18742
0
        }
18743
0
        else {
18744
0
            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
18745
0
        }
18746
0
    }
18747
18748
0
    if (ret == 0) {
18749
0
#ifdef WOLFSSL_SMALL_STACK
18750
0
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
18751
#else
18752
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
18753
#endif
18754
0
        if (ret != 0) {
18755
0
            WOLFSSL_MSG("Failed to initialized AES object.");
18756
0
        }
18757
0
    }
18758
18759
0
    if (ret == 0) {
18760
0
        if (dataSz > 0) {
18761
0
            sivTmp[12] &= 0x7f;
18762
0
            sivTmp[8] &= 0x7f;
18763
0
            ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
18764
0
                               AES_ENCRYPTION);
18765
0
            if (ret != 0) {
18766
0
                WOLFSSL_MSG("Failed to set key for AES-CTR.");
18767
0
            }
18768
0
            else {
18769
0
                ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
18770
0
                if (ret != 0) {
18771
0
                    WOLFSSL_MSG("AES-CTR encryption failed.");
18772
0
                }
18773
0
            }
18774
0
        }
18775
18776
0
        if (ret == 0 && enc == 0) {
18777
0
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out,
18778
0
                      dataSz, sivTmp);
18779
0
            if (ret != 0) {
18780
0
                WOLFSSL_MSG("S2V failed.");
18781
0
            }
18782
18783
0
            if (ret == 0 && ConstantCompare(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
18784
0
                WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
18785
0
                ret = AES_SIV_AUTH_E;
18786
0
            }
18787
0
        }
18788
18789
0
        if (ret != 0) {
18790
0
            ForceZero(out, dataSz);
18791
0
        }
18792
18793
0
    #ifdef WOLFSSL_SMALL_STACK
18794
0
        wc_AesDelete(aes, NULL);
18795
    #else
18796
        wc_AesFree(aes);
18797
    #endif
18798
0
    }
18799
18800
0
    ForceZero(sivTmp, sizeof(sivTmp));
18801
18802
0
    return ret;
18803
0
}
18804
18805
/*
18806
 * See RFC 5297 Section 2.6.
18807
 */
18808
int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
18809
                     word32 assocSz, const byte* nonce, word32 nonceSz,
18810
                     const byte* in, word32 inSz, byte* siv, byte* out)
18811
0
{
18812
0
    AesSivAssoc ad;
18813
0
    ad.assoc = assoc;
18814
0
    ad.assocSz = assocSz;
18815
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
18816
0
                        siv, out, 1);
18817
0
}
18818
18819
/*
18820
 * See RFC 5297 Section 2.7.
18821
 */
18822
int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
18823
                     word32 assocSz, const byte* nonce, word32 nonceSz,
18824
                     const byte* in, word32 inSz, byte* siv, byte* out)
18825
0
{
18826
0
    AesSivAssoc ad;
18827
0
    ad.assoc = assoc;
18828
0
    ad.assocSz = assocSz;
18829
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
18830
0
                        siv, out, 0);
18831
0
}
18832
18833
/*
18834
 * See RFC 5297 Section 2.6.
18835
 */
18836
int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
18837
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
18838
                        const byte* in, word32 inSz, byte* siv, byte* out)
18839
0
{
18840
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
18841
0
                        siv, out, 1);
18842
0
}
18843
18844
/*
18845
 * See RFC 5297 Section 2.7.
18846
 */
18847
int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
18848
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
18849
                        const byte* in, word32 inSz, byte* siv, byte* out)
18850
0
{
18851
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
18852
0
                        siv, out, 0);
18853
0
}
18854
18855
#endif /* WOLFSSL_AES_SIV */
18856
18857
#ifdef WOLFSSL_AESGCM_SIV
18858
18859
/* AES-GCM-SIV - a nonce misuse-resistant AEAD. See RFC 8452.
18860
 *
18861
 * The implementation here is portable C.  AES block operations reuse the
18862
 * internal wc_AesEncrypt(), so HAVE_AESGCM is required for that to be built.
18863
 */
18864
#ifndef HAVE_AESGCM
18865
    #error "WOLFSSL_AESGCM_SIV requires HAVE_AESGCM"
18866
#endif
18867
18868
#define AES_GCM_SIV_NONCE_SZ  12
18869
#define AES_GCM_SIV_TAG_SZ    WC_AES_BLOCK_SIZE
18870
18871
#ifndef GCM_SMALL
18872
/* GF(2^128) reduction table used by the table-based software multiplies; not
18873
 * needed by the table-free GCM_SMALL variant. R[a] is the contribution, to the
18874
 * top two bytes, of reducing a nibble 'a' shifted out past x^127 (the GHASH
18875
 * polynomial x^128+x^7+x^2+x+1). Same table wolfSSL uses for table GHASH. */
18876
static const byte AES_GCM_SIV_R[16][2] = {
18877
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
18878
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
18879
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
18880
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
18881
};
18882
#endif
18883
18884
/* Reverse the order of the 16 bytes of a block. in and out must not alias. */
18885
static WC_INLINE void AesGcmSivByteReverse(byte* out, const byte* in)
18886
{
18887
#if !defined(WOLFSSL_USE_ALIGN) && defined(WORD64_AVAILABLE)
18888
    /* Unaligned word access is permitted: reverse eight bytes at a time with a
18889
     * hardware byte-swap rather than one byte at a time. Endian independent -
18890
     * load native, reverse the value's bytes, store native: that reverses the
18891
     * bytes in memory on both little- and big-endian. */
18892
    word64 lo, hi;
18893
    XMEMCPY(&lo, in,     sizeof(lo));
18894
    XMEMCPY(&hi, in + 8, sizeof(hi));
18895
    lo = ByteReverseWord64(lo);
18896
    hi = ByteReverseWord64(hi);
18897
    XMEMCPY(out,     &hi, sizeof(hi));
18898
    XMEMCPY(out + 8, &lo, sizeof(lo));
18899
#else
18900
    int i;
18901
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
18902
        out[i] = in[WC_AES_BLOCK_SIZE - 1 - i];
18903
    }
18904
#endif
18905
}
18906
18907
/* POLYVAL state (RFC 8452 Section 3). POLYVAL is GHASH on byte-reversed inputs,
18908
 * so the field is the GHASH field with the most-significant bit of byte 0 the
18909
 * x^0 coefficient (see RFC 8452 Appendix A). The key is one of:
18910
 *  - GCM_SMALL: the 16-byte key (table-free, smallest footprint).
18911
 *  - word64:    a Shoup 4-bit table (256 bytes), word64 multiply - used when a
18912
 *               64-bit type is available and GCM_WORD32 is not requested.
18913
 *  - word32:    the same 4-bit table, word32 multiply - used for GCM_WORD32 or
18914
 *               when no 64-bit type is available.
18915
 *
18916
 * Every variant reads the message, key and running sum a byte at a time and
18917
 * (the word64/word32 variants) load/store their words with explicit shifts or
18918
 * a byte-swap rather than casting buffers, so all are independent of platform
18919
 * endianness; the word loads also respect WOLFSSL_USE_ALIGN, so input, key and
18920
 * output buffers may be little- or big-endian and aligned or unaligned.
18921
 */
18922
/* When the generated x86_64 AES-NI/PCLMUL POLYVAL multiply is available
18923
 * (aes_gcm_asm.S), the per-block multiply can be offloaded to it at runtime.
18924
 * This is the generated external assembly - no assembly lives in this file. */
18925
#if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
18926
    #define WC_POLYVAL_ASM
18927
#ifdef __cplusplus
18928
    extern "C" {
18929
#endif
18930
    /* s += POLYVAL of 'blocks' 16-byte blocks of data, hash key h prepared as
18931
     * the byte-reversed mulX_GHASH(ByteReverse(authKey)); s is POLYVAL byte
18932
     * order. */
18933
    void AES_GCMSIV_polyval_aesni(unsigned char* s, const unsigned char* h,
18934
        const unsigned char* data, word32 blocks)
18935
        XASM_LINK("AES_GCMSIV_polyval_aesni");
18936
#ifdef HAVE_INTEL_AVX1
18937
    void AES_GCMSIV_polyval_avx1(unsigned char* s, const unsigned char* h,
18938
        const unsigned char* data, word32 blocks)
18939
        XASM_LINK("AES_GCMSIV_polyval_avx1");
18940
#endif
18941
#ifdef HAVE_INTEL_VAES
18942
    /* Aggregated 2-blocks-per-ymm POLYVAL (VPCLMULQDQ). */
18943
    void AES_GCMSIV_polyval_vaes(unsigned char* s, const unsigned char* h,
18944
        const unsigned char* data, word32 blocks)
18945
        XASM_LINK("AES_GCMSIV_polyval_vaes");
18946
#endif
18947
#ifdef HAVE_INTEL_AVX512
18948
    /* Aggregated 4-blocks-per-zmm POLYVAL (VPCLMULQDQ). */
18949
    void AES_GCMSIV_polyval_avx512(unsigned char* s, const unsigned char* h,
18950
        const unsigned char* data, word32 blocks)
18951
        XASM_LINK("AES_GCMSIV_polyval_avx512");
18952
#endif
18953
    /* AES-GCM-SIV CTR keystream (RFC 8452): a 32-bit little-endian counter in
18954
     * the first 4 bytes of the block (mod 2^32, no carry), block used directly
18955
     * as the AES input. Encrypts the full-16-byte-block portion of 'length'
18956
     * bytes (pipelined), advancing and writing 'ctr' back. */
18957
    #define WC_GCMSIV_CTR_ASM
18958
    void AES_GCMSIV_ctr_aesni(const unsigned char* in, unsigned char* out,
18959
        unsigned long length, const unsigned char* KS, int nr,
18960
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_aesni");
18961
#ifdef HAVE_INTEL_AVX1
18962
    void AES_GCMSIV_ctr_avx1(const unsigned char* in, unsigned char* out,
18963
        unsigned long length, const unsigned char* KS, int nr,
18964
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_avx1");
18965
#endif
18966
#ifdef HAVE_INTEL_VAES
18967
    void AES_GCMSIV_ctr_vaes(const unsigned char* in, unsigned char* out,
18968
        unsigned long length, const unsigned char* KS, int nr,
18969
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_vaes");
18970
#endif
18971
#ifdef HAVE_INTEL_AVX512
18972
    void AES_GCMSIV_ctr_avx512(const unsigned char* in, unsigned char* out,
18973
        unsigned long length, const unsigned char* KS, int nr,
18974
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_avx512");
18975
#endif
18976
#ifdef __cplusplus
18977
    }
18978
#endif
18979
#elif defined(WOLFSSL_ARMASM) && defined(__aarch64__)
18980
    /* The generated AArch64 POLYVAL multiplies (armv8-aes-asm.S) offload the
18981
     * per-block multiply: PMULL when the CPU has the crypto extension, else the
18982
     * 8-bit-pmul NEON variant, else the scalar (base) variant. This is the
18983
     * generated external assembly - no assembly lives here. */
18984
    #define WC_POLYVAL_ASM
18985
    #define WC_POLYVAL_ASM_AARCH64
18986
    /* The base (scalar) variant multiplies through the word64 software table
18987
     * poly->m, so it is only available when that table is built. */
18988
    #if defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) && \
18989
        !defined(GCM_SMALL) && !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
18990
        #define WC_POLYVAL_ASM_AARCH64_BASE
18991
    #endif
18992
#ifdef __cplusplus
18993
    extern "C" {
18994
#endif
18995
    /* s += POLYVAL of 'blocks' 16-byte blocks of data. For the PMULL and NEON
18996
     * variants h is the prepared key (byte-reversed mulX_GHASH(ByteReverse(
18997
     * authKey))); for the base variant h is the word64 table poly->m. s is in
18998
     * POLYVAL byte order in every case. */
18999
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
19000
    void AES_GCMSIV_polyval_pmull(unsigned char* s, const unsigned char* h,
19001
        const unsigned char* data, word32 blocks)
19002
        XASM_LINK("AES_GCMSIV_polyval_pmull");
19003
#endif
19004
#ifndef WOLFSSL_ARMASM_NO_NEON
19005
    void AES_GCMSIV_polyval_neon(unsigned char* s, const unsigned char* h,
19006
        const unsigned char* data, word32 blocks)
19007
        XASM_LINK("AES_GCMSIV_polyval_neon");
19008
#endif
19009
#ifdef WC_POLYVAL_ASM_AARCH64_BASE
19010
    void AES_GCMSIV_polyval_base(unsigned char* s, const unsigned char* h,
19011
        const unsigned char* data, word32 blocks)
19012
        XASM_LINK("AES_GCMSIV_polyval_base");
19013
#endif
19014
    /* AES-GCM-SIV CTR keystream (RFC 8452): 32-bit little-endian counter in the
19015
     * first 4 bytes of the block, mod 2^32, block used directly. Full-block
19016
     * portion only (the C tail finishes any partial block). The crypto variant
19017
     * pipelines aese; the NEON/base variants pipeline software table AES. KS is
19018
     * the AES key schedule in every case. */
19019
    #define WC_GCMSIV_CTR_ASM
19020
    #define WC_GCMSIV_CTR_ASM_AARCH64
19021
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
19022
    void AES_GCMSIV_ctr_aarch64(const unsigned char* in, unsigned char* out,
19023
        unsigned long length, const unsigned char* KS, int nr,
19024
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_aarch64");
19025
#endif
19026
#ifndef WOLFSSL_ARMASM_NO_NEON
19027
    void AES_GCMSIV_ctr_neon(const unsigned char* in, unsigned char* out,
19028
        unsigned long length, const unsigned char* KS, int nr,
19029
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_neon");
19030
#endif
19031
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
19032
    void AES_GCMSIV_ctr_base(const unsigned char* in, unsigned char* out,
19033
        unsigned long length, const unsigned char* KS, int nr,
19034
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_base");
19035
#endif
19036
#ifdef __cplusplus
19037
    }
19038
#endif
19039
#elif defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
19040
      !defined(WOLFSSL_ARMASM_THUMB2)
19041
    /* AArch32 (32-bit ARM). The generated armv8-32-aes-asm.S provides POLYVAL
19042
     * and CTR for the crypto (vmull.p64 / aese) and base (table) variants.
19043
     * crypto-vs-base is compile-time (WOLFSSL_ARMASM_NO_HW_CRYPTO) with no
19044
     * runtime fallback - the same as the rest of the AArch32 AES. */
19045
    #define WC_POLYVAL_ASM
19046
    #define WC_POLYVAL_ASM_AARCH32
19047
    #define WC_GCMSIV_CTR_ASM
19048
    #define WC_GCMSIV_CTR_ASM_AARCH32
19049
    /* The base POLYVAL multiplies through the word64 software table poly->m. It
19050
     * is only compiled in the base (no-crypto) build and only when that table
19051
     * is built. */
19052
    #if defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) && defined(WORD64_AVAILABLE) && \
19053
        !defined(GCM_WORD32) && !defined(GCM_SMALL)
19054
        #define WC_POLYVAL_ASM_AARCH32_BASE
19055
    #endif
19056
#ifdef __cplusplus
19057
    extern "C" {
19058
#endif
19059
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
19060
    void AES_GCMSIV_polyval_crypto(unsigned char* s, const unsigned char* h,
19061
        const unsigned char* data, word32 blocks)
19062
        XASM_LINK("AES_GCMSIV_polyval_crypto");
19063
    void AES_GCMSIV_ctr_crypto(const unsigned char* in, unsigned char* out,
19064
        unsigned long length, const unsigned char* KS, int nr,
19065
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_crypto");
19066
#else
19067
#ifdef WC_POLYVAL_ASM_AARCH32_BASE
19068
    void AES_GCMSIV_polyval_base(unsigned char* s, const unsigned char* h,
19069
        const unsigned char* data, word32 blocks)
19070
        XASM_LINK("AES_GCMSIV_polyval_base");
19071
#endif
19072
    void AES_GCMSIV_ctr_base(const unsigned char* in, unsigned char* out,
19073
        unsigned long length, const unsigned char* KS, int nr,
19074
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_base");
19075
#endif
19076
#ifdef __cplusplus
19077
    }
19078
#endif
19079
#elif defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_THUMB2)
19080
    /* Thumb-2 (32-bit ARM, Thumb-2 encoding). A single table-based variant
19081
     * (ported from the AArch32 base): POLYVAL multiplies through the word64
19082
     * software table poly->m; CTR is the table AES with the SIV counter. */
19083
    #define WC_GCMSIV_CTR_ASM
19084
    #define WC_GCMSIV_CTR_ASM_THUMB2
19085
    #if defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) && !defined(GCM_SMALL)
19086
        #define WC_POLYVAL_ASM
19087
        #define WC_POLYVAL_ASM_THUMB2
19088
    #endif
19089
#ifdef __cplusplus
19090
    extern "C" {
19091
#endif
19092
#ifdef WC_POLYVAL_ASM_THUMB2
19093
    void AES_GCMSIV_polyval_thumb2(unsigned char* s, const unsigned char* h,
19094
        const unsigned char* data, word32 blocks)
19095
        XASM_LINK("AES_GCMSIV_polyval_thumb2");
19096
#endif
19097
    void AES_GCMSIV_ctr_thumb2(const unsigned char* in, unsigned char* out,
19098
        unsigned long length, const unsigned char* KS, int nr,
19099
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_thumb2");
19100
#ifdef __cplusplus
19101
    }
19102
#endif
19103
#endif
19104
19105
#ifdef WC_POLYVAL_ASM
19106
    typedef void (*AesGcmSivPolyvalFn)(unsigned char* s, const unsigned char* h,
19107
        const unsigned char* data, word32 blocks);
19108
#endif
19109
#ifdef WC_GCMSIV_CTR_ASM
19110
    typedef void (*AesGcmSivCtrFn)(const unsigned char* in, unsigned char* out,
19111
        unsigned long length, const unsigned char* KS, int nr,
19112
        unsigned char* ctr);
19113
#endif
19114
19115
typedef struct AesGcmSivPolyval {
19116
#ifdef WC_POLYVAL_ASM
19117
    byte hHw[WC_AES_BLOCK_SIZE]; /* prepared key for the asm multiply */
19118
    const byte* asmKey;          /* key passed to fn: hHw, or the table below */
19119
    AesGcmSivPolyvalFn fn;       /* asm multiply, or NULL for software */
19120
#endif
19121
#if defined(GCM_SMALL)
19122
    byte   h[WC_AES_BLOCK_SIZE]; /* hash key = mulX_GHASH(ByteReverse(H)) */
19123
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
19124
    word64 m[16][2];             /* m[i] = i * mulX_GHASH(ByteReverse(H)) */
19125
#else
19126
    word32 m[16][4];             /* m[i] = i * mulX_GHASH(ByteReverse(H)) */
19127
#endif
19128
    byte s[WC_AES_BLOCK_SIZE];   /* running sum, GHASH representation */
19129
} AesGcmSivPolyval;
19130
19131
/* Multiply a GF(2^128) element (GHASH bit order: the most-significant bit of
19132
 * byte 0 is the x^0 coefficient) by x: shift the 128-bit value right by one
19133
 * and reduce with the GHASH polynomial. Branch free, so constant time. Used by
19134
 * the GCM_SMALL multiply and to derive the carry-less-multiply asm hash key
19135
 * (mulX_GHASH); the word64/word32 table variants use AesGcmSivMulX64/32, so this
19136
 * is only compiled when one of those two callers is. Placed after the
19137
 * WC_POLYVAL_ASM #defines above so that guard is resolved here. */
19138
#if defined(GCM_SMALL) || defined(WC_POLYVAL_ASM)
19139
static WC_INLINE void AesGcmSivMulX(byte* x)
19140
{
19141
    int i;
19142
    byte carryIn = 0;
19143
    byte borrow = (byte)((0x00U - (x[WC_AES_BLOCK_SIZE - 1] & 0x01U)) & 0xE1U);
19144
19145
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
19146
        byte carryOut = (byte)((x[i] & 0x01) << 7);
19147
        x[i] = (byte)((x[i] >> 1) | carryIn);
19148
        carryIn = carryOut;
19149
    }
19150
    x[0] ^= borrow;
19151
}
19152
#endif /* GCM_SMALL || WC_POLYVAL_ASM */
19153
19154
#if defined(GCM_SMALL)
19155
19156
/* s = s * h with no precomputed table: decompose h bit-by-bit and accumulate
19157
 * shifted copies of s. Mirrors wolfSSL's GCM_SMALL GMULT. */
19158
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
19159
{
19160
    byte Z[WC_AES_BLOCK_SIZE];
19161
    byte V[WC_AES_BLOCK_SIZE];
19162
    int i, j;
19163
19164
    XMEMSET(Z, 0, sizeof(Z));
19165
    XMEMCPY(V, poly->s, WC_AES_BLOCK_SIZE);
19166
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
19167
        byte y = poly->h[i];
19168
        for (j = 0; j < 8; j++) {
19169
            if (y & 0x80) {
19170
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
19171
            }
19172
            AesGcmSivMulX(V);
19173
            y = (byte)(y << 1);
19174
        }
19175
    }
19176
    XMEMCPY(poly->s, Z, WC_AES_BLOCK_SIZE);
19177
}
19178
19179
/* Store the hash key mulX_GHASH(ByteReverse(h)); no table to build. */
19180
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
19181
{
19182
    AesGcmSivByteReverse(poly->h, h);
19183
    AesGcmSivMulX(poly->h);
19184
    XMEMSET(poly->s, 0, sizeof(poly->s));
19185
}
19186
19187
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
19188
19189
/* Load/store a big-endian word64 - the high word is bytes 0..7 of the block,
19190
 * so byte 0 (the x^0..x^7 coefficients) is the most-significant byte.
19191
 *
19192
 * Where unaligned word access is permitted (!WOLFSSL_USE_ALIGN) this is a
19193
 * single word64 load/store plus a hardware byte-swap on little-endian; where
19194
 * alignment is required it is assembled a byte at a time. Both forms are
19195
 * endian independent. */
19196
#ifndef WOLFSSL_USE_ALIGN
19197
static WC_INLINE word64 AesGcmSivLoad64(const byte* b)
19198
{
19199
    word64 v;
19200
    XMEMCPY(&v, b, sizeof(v));
19201
#ifdef LITTLE_ENDIAN_ORDER
19202
    v = ByteReverseWord64(v);
19203
#endif
19204
    return v;
19205
}
19206
static WC_INLINE void AesGcmSivStore64(byte* b, word64 v)
19207
{
19208
#ifdef LITTLE_ENDIAN_ORDER
19209
    v = ByteReverseWord64(v);
19210
#endif
19211
    XMEMCPY(b, &v, sizeof(v));
19212
}
19213
#else
19214
static WC_INLINE word64 AesGcmSivLoad64(const byte* b)
19215
{
19216
    return ((word64)b[0] << 56) | ((word64)b[1] << 48) |
19217
           ((word64)b[2] << 40) | ((word64)b[3] << 32) |
19218
           ((word64)b[4] << 24) | ((word64)b[5] << 16) |
19219
           ((word64)b[6] <<  8) | ((word64)b[7]);
19220
}
19221
static WC_INLINE void AesGcmSivStore64(byte* b, word64 v)
19222
{
19223
    b[0] = (byte)(v >> 56); b[1] = (byte)(v >> 48);
19224
    b[2] = (byte)(v >> 40); b[3] = (byte)(v >> 32);
19225
    b[4] = (byte)(v >> 24); b[5] = (byte)(v >> 16);
19226
    b[6] = (byte)(v >>  8); b[7] = (byte)(v);
19227
}
19228
#endif
19229
19230
/* Multiply the 128-bit value (hi,lo) by x and reduce: a right shift by one of
19231
 * the whole value, XOR-ing the reduction polynomial (0xe1 into byte 0) when a
19232
 * one is shifted out past x^127 (the low bit of lo). */
19233
static WC_INLINE void AesGcmSivMulX64(word64* hi, word64* lo)
19234
{
19235
    word64 carry = *lo & 1;
19236
    *lo = (*lo >> 1) | (*hi << 63);
19237
    *hi = (*hi >> 1) ^ (W64LIT(0xe100000000000000) & (word64)(0 - carry));
19238
}
19239
19240
/* s = s * H. The accumulator is shifted right a nibble at a time; the nibble
19241
 * that falls off is reduced through AES_GCM_SIV_R into the top two bytes. */
19242
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
19243
{
19244
    byte* x = poly->s;
19245
    word64 (*m)[2] = poly->m;
19246
    word64 zHi = 0, zLo = 0;
19247
    int i;
19248
19249
    for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
19250
        byte xi = x[i];
19251
        byte a;
19252
19253
        /* low nibble */
19254
        zHi ^= m[xi & 0xf][0];
19255
        zLo ^= m[xi & 0xf][1];
19256
        a = (byte)(zLo & 0xf);
19257
        zLo = (zLo >> 4) | (zHi << 60);
19258
        zHi = zHi >> 4;
19259
        zHi ^= ((word64)AES_GCM_SIV_R[a][0] << 56) |
19260
               ((word64)AES_GCM_SIV_R[a][1] << 48);
19261
19262
        /* high nibble */
19263
        zHi ^= m[xi >> 4][0];
19264
        zLo ^= m[xi >> 4][1];
19265
        if (i == 0) {
19266
            break;
19267
        }
19268
        a = (byte)(zLo & 0xf);
19269
        zLo = (zLo >> 4) | (zHi << 60);
19270
        zHi = zHi >> 4;
19271
        zHi ^= ((word64)AES_GCM_SIV_R[a][0] << 56) |
19272
               ((word64)AES_GCM_SIV_R[a][1] << 48);
19273
    }
19274
19275
    AesGcmSivStore64(x,     zHi);
19276
    AesGcmSivStore64(x + 8, zLo);
19277
}
19278
19279
/* Build the 4-bit table for mulX_GHASH(ByteReverse(h)). */
19280
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
19281
{
19282
    byte hrev[WC_AES_BLOCK_SIZE];
19283
    word64 (*m)[2] = poly->m;
19284
    int i;
19285
19286
    /* m[8] = 1 * H = mulX_GHASH(ByteReverse(h)); successive halvings give the
19287
     * power-of-two nibble entries. */
19288
    AesGcmSivByteReverse(hrev, h);
19289
    m[0x8][0] = AesGcmSivLoad64(hrev);
19290
    m[0x8][1] = AesGcmSivLoad64(hrev + 8);
19291
    AesGcmSivMulX64(&m[0x8][0], &m[0x8][1]);
19292
    m[0x4][0] = m[0x8][0]; m[0x4][1] = m[0x8][1]; AesGcmSivMulX64(&m[0x4][0], &m[0x4][1]);
19293
    m[0x2][0] = m[0x4][0]; m[0x2][1] = m[0x4][1]; AesGcmSivMulX64(&m[0x2][0], &m[0x2][1]);
19294
    m[0x1][0] = m[0x2][0]; m[0x1][1] = m[0x2][1]; AesGcmSivMulX64(&m[0x1][0], &m[0x1][1]);
19295
19296
    /* The rest are sums of those basis entries (i = high bit + remainder). */
19297
    m[0x0][0] = 0; m[0x0][1] = 0;
19298
    for (i = 0; i < 16; i++) {
19299
        static const byte hibit[16] =
19300
            { 0, 0, 0, 2, 0, 4, 4, 4, 0, 8, 8, 8, 8, 8, 8, 8 };
19301
        int top = hibit[i];
19302
        if (top != 0) {
19303
            m[i][0] = m[top][0] ^ m[i - top][0];
19304
            m[i][1] = m[top][1] ^ m[i - top][1];
19305
        }
19306
    }
19307
19308
    XMEMSET(poly->s, 0, sizeof(poly->s));
19309
    /* hrev held ByteReverse(H), the per-message hash key; wipe it. */
19310
    ForceZero(hrev, sizeof(hrev));
19311
}
19312
19313
#else /* word32: GCM_WORD32 or no 64-bit type */
19314
19315
/* Load/store a big-endian word32 - byte 0 is the most-significant byte. Same
19316
 * aligned/unaligned split as AesGcmSivLoad64/Store64; both forms are endian
19317
 * independent. */
19318
#ifndef WOLFSSL_USE_ALIGN
19319
static WC_INLINE word32 AesGcmSivLoad32(const byte* b)
19320
{
19321
    word32 v;
19322
    XMEMCPY(&v, b, sizeof(v));
19323
#ifdef LITTLE_ENDIAN_ORDER
19324
    v = ByteReverseWord32(v);
19325
#endif
19326
    return v;
19327
}
19328
static WC_INLINE void AesGcmSivStore32(byte* b, word32 v)
19329
{
19330
#ifdef LITTLE_ENDIAN_ORDER
19331
    v = ByteReverseWord32(v);
19332
#endif
19333
    XMEMCPY(b, &v, sizeof(v));
19334
}
19335
#else
19336
static WC_INLINE word32 AesGcmSivLoad32(const byte* b)
19337
{
19338
    return ((word32)b[0] << 24) | ((word32)b[1] << 16) |
19339
           ((word32)b[2] <<  8) | ((word32)b[3]);
19340
}
19341
static WC_INLINE void AesGcmSivStore32(byte* b, word32 v)
19342
{
19343
    b[0] = (byte)(v >> 24); b[1] = (byte)(v >> 16);
19344
    b[2] = (byte)(v >>  8); b[3] = (byte)(v);
19345
}
19346
#endif
19347
19348
/* Multiply the 128-bit value (z[0] most significant) by x and reduce: shift
19349
 * the whole value right by one, XOR-ing 0xe1 into byte 0 when a one is shifted
19350
 * out past x^127 (the low bit of z[3]). */
19351
static WC_INLINE void AesGcmSivMulX32(word32* z)
19352
{
19353
    word32 carry = z[3] & 1;
19354
    z[3] = (z[3] >> 1) | (z[2] << 31);
19355
    z[2] = (z[2] >> 1) | (z[1] << 31);
19356
    z[1] = (z[1] >> 1) | (z[0] << 31);
19357
    z[0] = (z[0] >> 1) ^ (0xe1000000U & (word32)(0 - carry));
19358
}
19359
19360
/* s = s * H. The accumulator is shifted right a nibble at a time; the nibble
19361
 * that falls off is reduced through AES_GCM_SIV_R into the top two bytes. */
19362
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
19363
{
19364
    byte* x = poly->s;
19365
    word32 (*m)[4] = poly->m;
19366
    word32 z0 = 0, z1 = 0, z2 = 0, z3 = 0;
19367
    int i;
19368
19369
    for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
19370
        word32* mr;
19371
        byte xi = x[i];
19372
        byte a;
19373
19374
        /* low nibble */
19375
        mr = m[xi & 0xf];
19376
        z0 ^= mr[0]; z1 ^= mr[1]; z2 ^= mr[2]; z3 ^= mr[3];
19377
        a = (byte)(z3 & 0xf);
19378
        z3 = (z3 >> 4) | (z2 << 28);
19379
        z2 = (z2 >> 4) | (z1 << 28);
19380
        z1 = (z1 >> 4) | (z0 << 28);
19381
        z0 = z0 >> 4;
19382
        z0 ^= ((word32)AES_GCM_SIV_R[a][0] << 24) |
19383
              ((word32)AES_GCM_SIV_R[a][1] << 16);
19384
19385
        /* high nibble */
19386
        mr = m[xi >> 4];
19387
        z0 ^= mr[0]; z1 ^= mr[1]; z2 ^= mr[2]; z3 ^= mr[3];
19388
        if (i == 0) {
19389
            break;
19390
        }
19391
        a = (byte)(z3 & 0xf);
19392
        z3 = (z3 >> 4) | (z2 << 28);
19393
        z2 = (z2 >> 4) | (z1 << 28);
19394
        z1 = (z1 >> 4) | (z0 << 28);
19395
        z0 = z0 >> 4;
19396
        z0 ^= ((word32)AES_GCM_SIV_R[a][0] << 24) |
19397
              ((word32)AES_GCM_SIV_R[a][1] << 16);
19398
    }
19399
19400
    AesGcmSivStore32(x,      z0);
19401
    AesGcmSivStore32(x + 4,  z1);
19402
    AesGcmSivStore32(x + 8,  z2);
19403
    AesGcmSivStore32(x + 12, z3);
19404
}
19405
19406
/* Build the 4-bit table for mulX_GHASH(ByteReverse(h)). */
19407
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
19408
{
19409
    byte hrev[WC_AES_BLOCK_SIZE];
19410
    word32 (*m)[4] = poly->m;
19411
    int i;
19412
19413
    /* m[8] = 1 * H = mulX_GHASH(ByteReverse(h)); successive halvings give the
19414
     * power-of-two nibble entries. */
19415
    AesGcmSivByteReverse(hrev, h);
19416
    m[0x8][0] = AesGcmSivLoad32(hrev);
19417
    m[0x8][1] = AesGcmSivLoad32(hrev + 4);
19418
    m[0x8][2] = AesGcmSivLoad32(hrev + 8);
19419
    m[0x8][3] = AesGcmSivLoad32(hrev + 12);
19420
    AesGcmSivMulX32(m[0x8]);
19421
    XMEMCPY(m[0x4], m[0x8], sizeof(m[0x4])); AesGcmSivMulX32(m[0x4]);
19422
    XMEMCPY(m[0x2], m[0x4], sizeof(m[0x2])); AesGcmSivMulX32(m[0x2]);
19423
    XMEMCPY(m[0x1], m[0x2], sizeof(m[0x1])); AesGcmSivMulX32(m[0x1]);
19424
19425
    /* The rest are sums of those basis entries (i = high bit + remainder). */
19426
    m[0x0][0] = 0; m[0x0][1] = 0; m[0x0][2] = 0; m[0x0][3] = 0;
19427
    for (i = 0; i < 16; i++) {
19428
        static const byte hibit[16] =
19429
            { 0, 0, 0, 2, 0, 4, 4, 4, 0, 8, 8, 8, 8, 8, 8, 8 };
19430
        int top = hibit[i];
19431
        if (top != 0) {
19432
            m[i][0] = m[top][0] ^ m[i - top][0];
19433
            m[i][1] = m[top][1] ^ m[i - top][1];
19434
            m[i][2] = m[top][2] ^ m[i - top][2];
19435
            m[i][3] = m[top][3] ^ m[i - top][3];
19436
        }
19437
    }
19438
19439
    XMEMSET(poly->s, 0, sizeof(poly->s));
19440
    /* hrev held ByteReverse(H), the per-message hash key; wipe it. */
19441
    ForceZero(hrev, sizeof(hrev));
19442
}
19443
19444
#endif /* POLYVAL multiply variant */
19445
19446
#ifdef WC_POLYVAL_ASM_THUMB2
19447
/* Thumb-2: the single table POLYVAL variant. */
19448
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
19449
{
19450
    return &AES_GCMSIV_polyval_thumb2;
19451
}
19452
#elif defined(WC_POLYVAL_ASM_AARCH32)
19453
/* AArch32: crypto (vmull.p64) or base (table) POLYVAL, chosen at compile time. */
19454
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
19455
{
19456
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
19457
    return &AES_GCMSIV_polyval_crypto;
19458
#elif defined(WC_POLYVAL_ASM_AARCH32_BASE)
19459
    return &AES_GCMSIV_polyval_base;
19460
#else
19461
    return NULL;
19462
#endif
19463
}
19464
#elif defined(WC_POLYVAL_ASM_AARCH64)
19465
/* Select the best available generated POLYVAL multiply: PMULL when the CPU has
19466
 * the crypto extension, else the 8-bit-pmul NEON variant, else the scalar base
19467
 * variant, else NULL to fall back to software. */
19468
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
19469
{
19470
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
19471
    cpuid_get_flags_ex(&cpuid_flags);
19472
    if (IS_AARCH64_PMULL(cpuid_flags)) {
19473
        return &AES_GCMSIV_polyval_pmull;
19474
    }
19475
#endif
19476
#ifndef WOLFSSL_ARMASM_NO_NEON
19477
    return &AES_GCMSIV_polyval_neon;
19478
#elif defined(WC_POLYVAL_ASM_AARCH64_BASE)
19479
    return &AES_GCMSIV_polyval_base;
19480
#else
19481
    return NULL;
19482
#endif
19483
}
19484
#elif defined(WC_POLYVAL_ASM)
19485
/* Select the best available generated POLYVAL multiply for this CPU, or NULL
19486
 * to fall back to software. PCLMUL is present on every AES-NI capable CPU, so
19487
 * AES-NI gates the base path (matching wolfSSL's AES-GCM). */
19488
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
19489
{
19490
    cpuid_get_flags_ex(&intel_flags);
19491
    if (!IS_INTEL_AESNI(intel_flags)) {
19492
        return NULL;
19493
    }
19494
#ifdef HAVE_INTEL_AVX512
19495
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19496
        return &AES_GCMSIV_polyval_avx512;
19497
    }
19498
#endif
19499
#ifdef HAVE_INTEL_VAES
19500
    if (IS_INTEL_VAES(intel_flags) && IS_INTEL_AVX2(intel_flags)) {
19501
        return &AES_GCMSIV_polyval_vaes;
19502
    }
19503
#endif
19504
#ifdef HAVE_INTEL_AVX1
19505
    if (IS_INTEL_AVX1(intel_flags)) {
19506
        return &AES_GCMSIV_polyval_avx1;
19507
    }
19508
#endif
19509
    return &AES_GCMSIV_polyval_aesni;
19510
}
19511
#endif
19512
19513
#ifdef WC_GCMSIV_CTR_ASM_THUMB2
19514
/* Thumb-2: the single table CTR variant. */
19515
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
19516
{
19517
    return &AES_GCMSIV_ctr_thumb2;
19518
}
19519
#elif defined(WC_GCMSIV_CTR_ASM_AARCH32)
19520
/* AArch32: crypto (aese) or base (table) CTR, chosen at compile time. */
19521
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
19522
{
19523
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
19524
    return &AES_GCMSIV_ctr_crypto;
19525
#else
19526
    return &AES_GCMSIV_ctr_base;
19527
#endif
19528
}
19529
#elif defined(WC_GCMSIV_CTR_ASM_AARCH64)
19530
/* Select the best generated CTR keystream: pipelined aese when the CPU has the
19531
 * AES extension, else the NEON or base software-table variant, else NULL. */
19532
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
19533
{
19534
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
19535
    cpuid_get_flags_ex(&cpuid_flags);
19536
    if (IS_AARCH64_AES(cpuid_flags)) {
19537
        return &AES_GCMSIV_ctr_aarch64;
19538
    }
19539
#endif
19540
#ifndef WOLFSSL_ARMASM_NO_NEON
19541
    return &AES_GCMSIV_ctr_neon;
19542
#elif !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
19543
    return &AES_GCMSIV_ctr_base;
19544
#else
19545
    return NULL;
19546
#endif
19547
}
19548
#elif defined(WC_GCMSIV_CTR_ASM)
19549
/* Select the best generated AES-GCM-SIV CTR keystream for this CPU. AES-NI is
19550
 * the base; AVX1/VAES/AVX512 are progressively wider pipelines. */
19551
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
19552
{
19553
    cpuid_get_flags_ex(&intel_flags);
19554
    if (!IS_INTEL_AESNI(intel_flags)) {
19555
        return NULL;
19556
    }
19557
#ifdef HAVE_INTEL_AVX512
19558
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19559
        return &AES_GCMSIV_ctr_avx512;
19560
    }
19561
#endif
19562
#ifdef HAVE_INTEL_VAES
19563
    if (IS_INTEL_VAES(intel_flags) && IS_INTEL_AVX2(intel_flags)) {
19564
        return &AES_GCMSIV_ctr_vaes;
19565
    }
19566
#endif
19567
#ifdef HAVE_INTEL_AVX1
19568
    if (IS_INTEL_AVX1(intel_flags)) {
19569
        return &AES_GCMSIV_ctr_avx1;
19570
    }
19571
#endif
19572
    return &AES_GCMSIV_ctr_aesni;
19573
}
19574
#endif
19575
19576
/* Initialize POLYVAL with the 16-byte hash key h, using the generated assembly
19577
 * multiply when the CPU supports it and a software variant otherwise. */
19578
static void AesGcmSivPolyvalInit(AesGcmSivPolyval* poly, const byte* h)
19579
{
19580
#ifdef WC_POLYVAL_ASM
19581
    AesGcmSivPolyvalFn fn = AesGcmSivPolyvalAsm();
19582
    if (fn != NULL) {
19583
#if defined(WC_POLYVAL_ASM_AARCH64_BASE) || defined(WC_POLYVAL_ASM_AARCH32_BASE)
19584
        if (fn == &AES_GCMSIV_polyval_base) {
19585
            /* The scalar variant multiplies through the word64 software table,
19586
             * so build it and point the asm at it. */
19587
            AesGcmSivPolyvalInitSw(poly, h);
19588
            poly->asmKey = (const byte*)poly->m;
19589
            poly->fn = fn;
19590
            return;
19591
        }
19592
#endif
19593
#ifdef WC_POLYVAL_ASM_THUMB2
19594
        if (fn == &AES_GCMSIV_polyval_thumb2) {
19595
            /* Table variant: build the word64 software table and point at it. */
19596
            AesGcmSivPolyvalInitSw(poly, h);
19597
            poly->asmKey = (const byte*)poly->m;
19598
            poly->fn = fn;
19599
            return;
19600
        }
19601
#endif
19602
        {
19603
            byte t[WC_AES_BLOCK_SIZE];
19604
            /* Prepare the hash key for the asm: byte-reversed
19605
             * mulX_GHASH(ByteReverse(h)). */
19606
            AesGcmSivByteReverse(t, h);
19607
            AesGcmSivMulX(t);
19608
            AesGcmSivByteReverse(poly->hHw, t);
19609
            XMEMSET(poly->s, 0, sizeof(poly->s));
19610
            poly->asmKey = poly->hHw;
19611
            poly->fn = fn;
19612
            /* t held the prepared hash key; wipe the stack copy. */
19613
            ForceZero(t, sizeof(t));
19614
        }
19615
        return;
19616
    }
19617
    poly->fn = NULL;
19618
#endif
19619
    AesGcmSivPolyvalInitSw(poly, h);
19620
}
19621
19622
/* Add data to the POLYVAL sum. A trailing partial block is zero-padded to a
19623
 * full block, which is exactly the padding RFC 8452 applies to the AAD and
19624
 * the plaintext independently. */
19625
static void AesGcmSivPolyvalUpdate(AesGcmSivPolyval* poly, const byte* data,
19626
    word32 sz)
19627
{
19628
    byte block[WC_AES_BLOCK_SIZE];
19629
    byte rev[WC_AES_BLOCK_SIZE];
19630
    int k;
19631
19632
#ifdef WC_POLYVAL_ASM
19633
    if (poly->fn != NULL) {
19634
        word32 blocks = sz / WC_AES_BLOCK_SIZE;
19635
        word32 partial = sz % WC_AES_BLOCK_SIZE;
19636
        if (blocks > 0) {
19637
            poly->fn(poly->s, poly->asmKey, data, blocks);
19638
            data += blocks * WC_AES_BLOCK_SIZE;
19639
        }
19640
        if (partial > 0) {
19641
            XMEMSET(block, 0, sizeof(block));
19642
            XMEMCPY(block, data, partial);
19643
            poly->fn(poly->s, poly->asmKey, block, 1);
19644
        }
19645
        /* block may have held a padded AAD/plaintext tail; wipe it. */
19646
        ForceZero(block, sizeof(block));
19647
        return;
19648
    }
19649
#endif
19650
    while (sz >= WC_AES_BLOCK_SIZE) {
19651
        AesGcmSivByteReverse(rev, data);
19652
        for (k = 0; k < WC_AES_BLOCK_SIZE; k++) {
19653
            poly->s[k] ^= rev[k];
19654
        }
19655
        AesGcmSivGMult(poly);
19656
        data += WC_AES_BLOCK_SIZE;
19657
        sz   -= WC_AES_BLOCK_SIZE;
19658
    }
19659
    if (sz > 0) {
19660
        XMEMSET(block, 0, sizeof(block));
19661
        XMEMCPY(block, data, sz);
19662
        AesGcmSivByteReverse(rev, block);
19663
        for (k = 0; k < WC_AES_BLOCK_SIZE; k++) {
19664
            poly->s[k] ^= rev[k];
19665
        }
19666
        AesGcmSivGMult(poly);
19667
    }
19668
    /* block/rev held byte-reversed AAD/plaintext blocks; wipe them. */
19669
    ForceZero(block, sizeof(block));
19670
    ForceZero(rev, sizeof(rev));
19671
}
19672
19673
/* Output the 16-byte POLYVAL result and wipe the key material and state. */
19674
static void AesGcmSivPolyvalFinal(AesGcmSivPolyval* poly, byte* out)
19675
{
19676
    AesGcmSivByteReverse(out, poly->s);
19677
    ForceZero(poly, sizeof(*poly));
19678
}
19679
19680
/* Derive the message-authentication-key and message-encryption-key from the
19681
 * key-generating-key (loaded into kgk) and the nonce. See RFC 8452 Section 4.
19682
 *
19683
 * authKey is 16 bytes; encKey is keySz bytes (16 or 32). */
19684
static WARN_UNUSED_RESULT int AesGcmSivDeriveKeys(Aes* kgk, const byte* nonce,
19685
    word32 keySz, byte* authKey, byte* encKey)
19686
{
19687
    byte block[WC_AES_BLOCK_SIZE];
19688
    byte out[WC_AES_BLOCK_SIZE];
19689
    word32 ctr;
19690
    word32 encBlocks = keySz / 8; /* 2 for AES-128, 4 for AES-256 */
19691
    int ret = 0;
19692
19693
    /* Each derivation block is: LE32(counter) || nonce(12 bytes). The low 8
19694
     * bytes of each AES output are concatenated to form the derived keys. */
19695
    XMEMCPY(block + 4, nonce, AES_GCM_SIV_NONCE_SZ);
19696
19697
    for (ctr = 0; ctr < 2; ctr++) {
19698
        block[0] = (byte)ctr;
19699
        block[1] = 0; block[2] = 0; block[3] = 0;
19700
        ret = wc_AesEncrypt(kgk, block, out);
19701
        if (ret != 0)
19702
            break;
19703
        XMEMCPY(authKey + ctr * 8, out, 8);
19704
    }
19705
19706
    for (ctr = 0; (ret == 0) && (ctr < encBlocks); ctr++) {
19707
        block[0] = (byte)(ctr + 2);
19708
        block[1] = 0; block[2] = 0; block[3] = 0;
19709
        ret = wc_AesEncrypt(kgk, block, out);
19710
        if (ret != 0)
19711
            break;
19712
        XMEMCPY(encKey + ctr * 8, out, 8);
19713
    }
19714
19715
    ForceZero(block, sizeof(block));
19716
    ForceZero(out, sizeof(out));
19717
19718
    return ret;
19719
}
19720
19721
/* Compute the AES-GCM-SIV tag over the AAD and plaintext. enc holds the
19722
 * message-encryption-key. See RFC 8452 Section 4. */
19723
static WARN_UNUSED_RESULT int AesGcmSivCalcTag(Aes* enc, const byte* authKey,
19724
    const byte* nonce, const byte* aad, word32 aadSz, const byte* plain,
19725
    word32 plainSz, byte* tag)
19726
{
19727
    AesGcmSivPolyval poly;
19728
    byte lenBlock[WC_AES_BLOCK_SIZE];
19729
    byte s[WC_AES_BLOCK_SIZE];
19730
    /* Bit lengths (sz * 8) as 64-bit values, computed without needing a
19731
     * 64-bit type: low 32 bits and the 3 bits that carry into the next word. */
19732
    word32 aadLo = aadSz << 3, aadHi = aadSz >> 29;
19733
    word32 ptLo  = plainSz << 3, ptHi = plainSz >> 29;
19734
    int i;
19735
    int ret;
19736
19737
    AesGcmSivPolyvalInit(&poly, authKey);
19738
    AesGcmSivPolyvalUpdate(&poly, aad, aadSz);
19739
    AesGcmSivPolyvalUpdate(&poly, plain, plainSz);
19740
19741
    /* Length block: LE64(aad_bits) || LE64(plaintext_bits). */
19742
    lenBlock[0]  = (byte)aadLo; lenBlock[1] = (byte)(aadLo >> 8);
19743
    lenBlock[2]  = (byte)(aadLo >> 16); lenBlock[3] = (byte)(aadLo >> 24);
19744
    lenBlock[4]  = (byte)aadHi; lenBlock[5] = (byte)(aadHi >> 8);
19745
    lenBlock[6]  = (byte)(aadHi >> 16); lenBlock[7] = (byte)(aadHi >> 24);
19746
    lenBlock[8]  = (byte)ptLo; lenBlock[9] = (byte)(ptLo >> 8);
19747
    lenBlock[10] = (byte)(ptLo >> 16); lenBlock[11] = (byte)(ptLo >> 24);
19748
    lenBlock[12] = (byte)ptHi; lenBlock[13] = (byte)(ptHi >> 8);
19749
    lenBlock[14] = (byte)(ptHi >> 16); lenBlock[15] = (byte)(ptHi >> 24);
19750
    AesGcmSivPolyvalUpdate(&poly, lenBlock, WC_AES_BLOCK_SIZE);
19751
19752
    AesGcmSivPolyvalFinal(&poly, s);
19753
19754
    /* XOR the nonce into the first 12 bytes and clear the top bit of the
19755
     * last byte, then encrypt to produce the tag. */
19756
    for (i = 0; i < AES_GCM_SIV_NONCE_SZ; i++) {
19757
        s[i] ^= nonce[i];
19758
    }
19759
    s[WC_AES_BLOCK_SIZE - 1] &= 0x7f;
19760
19761
    ret = wc_AesEncrypt(enc, s, tag);
19762
19763
    ForceZero(s, sizeof(s));
19764
    return ret;
19765
}
19766
19767
/* Apply AES-GCM-SIV's counter mode to in, producing out. enc holds the
19768
 * message-encryption-key, tag is the 16-byte authentication tag. The counter
19769
 * is the tag with the top bit of the last byte set; only the first 4 bytes
19770
 * are incremented, as a little-endian 32-bit value, wrapping modulo 2^32.
19771
 * See RFC 8452 Section 4. */
19772
static WARN_UNUSED_RESULT int AesGcmSivCtr(Aes* enc, const byte* tag,
19773
    const byte* in, word32 sz, byte* out)
19774
{
19775
    byte ctrBlock[WC_AES_BLOCK_SIZE];
19776
    byte ks[WC_AES_BLOCK_SIZE];
19777
    word32 c;
19778
    int ret = 0;
19779
19780
    XMEMCPY(ctrBlock, tag, WC_AES_BLOCK_SIZE);
19781
    ctrBlock[WC_AES_BLOCK_SIZE - 1] |= 0x80;
19782
19783
#ifdef WC_GCMSIV_CTR_ASM
19784
    /* Offload the full-block keystream to the pipelined assembly; it advances
19785
     * and writes ctrBlock back. The final partial block (if any) is finished by
19786
     * the scalar loop below. */
19787
    {
19788
        AesGcmSivCtrFn fn = AesGcmSivCtrAsm();
19789
        if (fn != NULL) {
19790
            word32 full = sz & ~(word32)(WC_AES_BLOCK_SIZE - 1);
19791
            if (full > 0) {
19792
                fn(in, out, (unsigned long)full, (const byte*)enc->key,
19793
                    (int)enc->rounds, ctrBlock);
19794
                in  += full;
19795
                out += full;
19796
                sz  -= full;
19797
            }
19798
        }
19799
    }
19800
#endif
19801
19802
    c = (word32)ctrBlock[0]        | ((word32)ctrBlock[1] << 8) |
19803
        ((word32)ctrBlock[2] << 16) | ((word32)ctrBlock[3] << 24);
19804
19805
    while (sz > 0) {
19806
        word32 n = (sz < WC_AES_BLOCK_SIZE) ? sz : (word32)WC_AES_BLOCK_SIZE;
19807
        word32 i;
19808
19809
        ret = wc_AesEncrypt(enc, ctrBlock, ks);
19810
        if (ret != 0)
19811
            break;
19812
        for (i = 0; i < n; i++) {
19813
            out[i] = (byte)(in[i] ^ ks[i]);
19814
        }
19815
19816
        in  += n;
19817
        out += n;
19818
        sz  -= n;
19819
19820
        c++;
19821
        ctrBlock[0] = (byte)c;         ctrBlock[1] = (byte)(c >> 8);
19822
        ctrBlock[2] = (byte)(c >> 16); ctrBlock[3] = (byte)(c >> 24);
19823
    }
19824
19825
    ForceZero(ks, sizeof(ks));
19826
    ForceZero(ctrBlock, sizeof(ctrBlock));
19827
    return ret;
19828
}
19829
19830
/* Common validation for the encrypt/decrypt entry points. */
19831
static WARN_UNUSED_RESULT int AesGcmSivCheckArgs(const byte* key, word32 keySz,
19832
    const byte* nonce, word32 nonceSz, const byte* aad, word32 aadSz,
19833
    const byte* in, word32 inSz, const byte* out, const byte* tag,
19834
    word32 tagSz)
19835
{
19836
    if (key == NULL || nonce == NULL || tag == NULL) {
19837
        return BAD_FUNC_ARG;
19838
    }
19839
    if ((inSz != 0) && ((in == NULL) || (out == NULL))) {
19840
        return BAD_FUNC_ARG;
19841
    }
19842
    if ((aadSz != 0) && (aad == NULL)) {
19843
        return BAD_FUNC_ARG;
19844
    }
19845
    if ((keySz != 16) && (keySz != 32)) {
19846
        return BAD_FUNC_ARG;
19847
    }
19848
    if (nonceSz != AES_GCM_SIV_NONCE_SZ) {
19849
        return BAD_FUNC_ARG;
19850
    }
19851
    if (tagSz != AES_GCM_SIV_TAG_SZ) {
19852
        return BAD_FUNC_ARG;
19853
    }
19854
    return 0;
19855
}
19856
19857
/*
19858
 * Encrypt with AES-GCM-SIV. See RFC 8452 Section 4.
19859
 *
19860
 * out receives inSz bytes of ciphertext; tag receives the 16-byte tag.
19861
 */
19862
int wc_AesGcmSivEncrypt(const byte* key, word32 keySz, const byte* nonce,
19863
    word32 nonceSz, const byte* aad, word32 aadSz, const byte* in,
19864
    word32 inSz, byte* out, byte* tag, word32 tagSz)
19865
{
19866
    WC_DECLARE_VAR(aes, Aes, 1, 0);
19867
    byte authKey[WC_AES_BLOCK_SIZE];
19868
    byte encKey[32];
19869
    byte tagTmp[AES_GCM_SIV_TAG_SZ];
19870
    int ret;
19871
19872
    ret = AesGcmSivCheckArgs(key, keySz, nonce, nonceSz, aad, aadSz, in, inSz,
19873
                             out, tag, tagSz);
19874
19875
    if (ret == 0) {
19876
    #ifdef WOLFSSL_SMALL_STACK
19877
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
19878
    #else
19879
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
19880
    #endif
19881
    }
19882
19883
    if (ret == 0) {
19884
        /* Load the key-generating-key and derive the per-message keys. */
19885
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
19886
        if (ret == 0) {
19887
            ret = AesGcmSivDeriveKeys(aes, nonce, keySz, authKey, encKey);
19888
        }
19889
        /* Switch the AES object to the message-encryption-key. */
19890
        if (ret == 0) {
19891
            ret = wc_AesSetKey(aes, encKey, keySz, NULL, AES_ENCRYPTION);
19892
        }
19893
        /* Tag is computed over the plaintext, then the plaintext is
19894
         * encrypted with the tag-derived counter. */
19895
        if (ret == 0) {
19896
            ret = AesGcmSivCalcTag(aes, authKey, nonce, aad, aadSz, in, inSz,
19897
                                   tagTmp);
19898
        }
19899
        if (ret == 0) {
19900
            ret = AesGcmSivCtr(aes, tagTmp, in, inSz, out);
19901
        }
19902
        if (ret == 0) {
19903
            XMEMCPY(tag, tagTmp, AES_GCM_SIV_TAG_SZ);
19904
        }
19905
19906
    #ifdef WOLFSSL_SMALL_STACK
19907
        wc_AesDelete(aes, NULL);
19908
    #else
19909
        wc_AesFree(aes);
19910
    #endif
19911
    }
19912
19913
    ForceZero(authKey, sizeof(authKey));
19914
    ForceZero(encKey, sizeof(encKey));
19915
    ForceZero(tagTmp, sizeof(tagTmp));
19916
19917
    return ret;
19918
}
19919
19920
/*
19921
 * Decrypt with AES-GCM-SIV. See RFC 8452 Section 4.
19922
 *
19923
 * in is inSz bytes of ciphertext, tag is the received 16-byte tag. On a
19924
 * successful authentication out receives inSz bytes of plaintext; on failure
19925
 * out is zeroed and AES_GCM_AUTH_E is returned.
19926
 */
19927
int wc_AesGcmSivDecrypt(const byte* key, word32 keySz, const byte* nonce,
19928
    word32 nonceSz, const byte* aad, word32 aadSz, const byte* in,
19929
    word32 inSz, byte* out, const byte* tag, word32 tagSz)
19930
{
19931
    WC_DECLARE_VAR(aes, Aes, 1, 0);
19932
    byte authKey[WC_AES_BLOCK_SIZE];
19933
    byte encKey[32];
19934
    byte expTag[AES_GCM_SIV_TAG_SZ];
19935
    int ret;
19936
19937
    ret = AesGcmSivCheckArgs(key, keySz, nonce, nonceSz, aad, aadSz, in, inSz,
19938
                             out, tag, tagSz);
19939
19940
    if (ret == 0) {
19941
    #ifdef WOLFSSL_SMALL_STACK
19942
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
19943
    #else
19944
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
19945
    #endif
19946
    }
19947
19948
    if (ret == 0) {
19949
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
19950
        if (ret == 0) {
19951
            ret = AesGcmSivDeriveKeys(aes, nonce, keySz, authKey, encKey);
19952
        }
19953
        if (ret == 0) {
19954
            ret = wc_AesSetKey(aes, encKey, keySz, NULL, AES_ENCRYPTION);
19955
        }
19956
        /* Recover the plaintext, then recompute and verify the tag over it. */
19957
        if (ret == 0) {
19958
            ret = AesGcmSivCtr(aes, tag, in, inSz, out);
19959
        }
19960
        if (ret == 0) {
19961
            ret = AesGcmSivCalcTag(aes, authKey, nonce, aad, aadSz, out, inSz,
19962
                                   expTag);
19963
        }
19964
        if (ret == 0) {
19965
            if (ConstantCompare(expTag, tag, AES_GCM_SIV_TAG_SZ) != 0) {
19966
                ret = AES_GCM_AUTH_E;
19967
            }
19968
        }
19969
        if (ret != 0) {
19970
            ForceZero(out, inSz);
19971
        }
19972
19973
    #ifdef WOLFSSL_SMALL_STACK
19974
        wc_AesDelete(aes, NULL);
19975
    #else
19976
        wc_AesFree(aes);
19977
    #endif
19978
    }
19979
19980
    ForceZero(authKey, sizeof(authKey));
19981
    ForceZero(encKey, sizeof(encKey));
19982
    ForceZero(expTag, sizeof(expTag));
19983
19984
    return ret;
19985
}
19986
19987
#endif /* WOLFSSL_AESGCM_SIV */
19988
19989
#if defined(WOLFSSL_AES_EAX)
19990
19991
/*
19992
 * AES EAX one-shot API
19993
 * Encrypts input data and computes an auth tag over the input
19994
 * auth data and ciphertext
19995
 *
19996
 * Returns 0 on success
19997
 * Returns error code on failure
19998
 */
19999
int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
20000
                          const byte* in, word32 inSz,
20001
                          const byte* nonce, word32 nonceSz,
20002
                          /* output computed auth tag */
20003
                          byte* authTag, word32 authTagSz,
20004
                          /* input data to authenticate */
20005
                          const byte* authIn, word32 authInSz)
20006
{
20007
#if defined(WOLFSSL_SMALL_STACK)
20008
    AesEax *eax;
20009
#else
20010
    AesEax eax_mem;
20011
    AesEax *eax = &eax_mem;
20012
#endif
20013
    int ret;
20014
    int eaxInited = 0;
20015
20016
    if (key == NULL || nonce == NULL || authTag == NULL
20017
            || (inSz > 0 && (out == NULL || in == NULL))
20018
            || (authInSz > 0 && authIn == NULL)) {
20019
        return BAD_FUNC_ARG;
20020
    }
20021
20022
#if defined(WOLFSSL_SMALL_STACK)
20023
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
20024
                                 NULL,
20025
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
20026
        return MEMORY_E;
20027
    }
20028
#endif
20029
20030
    if ((ret = wc_AesEaxInit(eax,
20031
                             key, keySz,
20032
                             nonce, nonceSz,
20033
                             authIn, authInSz)) != 0) {
20034
        goto cleanup;
20035
    }
20036
    eaxInited = 1;
20037
20038
    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
20039
        goto cleanup;
20040
    }
20041
20042
    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
20043
        goto cleanup;
20044
    }
20045
20046
cleanup:
20047
    if (eaxInited)
20048
        wc_AesEaxFree(eax);
20049
#if defined(WOLFSSL_SMALL_STACK)
20050
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
20051
#endif
20052
    return ret;
20053
}
20054
20055
20056
/*
20057
 * AES EAX one-shot API
20058
 * Decrypts and authenticates data against a supplied auth tag
20059
 *
20060
 * Returns 0 on success
20061
 * Returns error code on failure
20062
 */
20063
int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
20064
                          const byte* in, word32 inSz,
20065
                          const byte* nonce, word32 nonceSz,
20066
                          /* auth tag to verify against */
20067
                          const byte* authTag, word32 authTagSz,
20068
                          /* input data to authenticate */
20069
                          const byte* authIn, word32 authInSz)
20070
{
20071
#if defined(WOLFSSL_SMALL_STACK)
20072
    AesEax *eax;
20073
#else
20074
    AesEax eax_mem;
20075
    AesEax *eax = &eax_mem;
20076
#endif
20077
    int ret;
20078
    int eaxInited = 0;
20079
20080
    if (key == NULL || nonce == NULL || authTag == NULL
20081
            || (inSz > 0 && (out == NULL || in == NULL))
20082
            || (authInSz > 0 && authIn == NULL)) {
20083
        return BAD_FUNC_ARG;
20084
    }
20085
20086
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ
20087
            || authTagSz > WC_AES_BLOCK_SIZE) {
20088
        return BAD_FUNC_ARG;
20089
    }
20090
20091
#if defined(WOLFSSL_SMALL_STACK)
20092
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
20093
                                 NULL,
20094
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
20095
        return MEMORY_E;
20096
    }
20097
#endif
20098
20099
    if ((ret = wc_AesEaxInit(eax,
20100
                             key, keySz,
20101
                             nonce, nonceSz,
20102
                             authIn, authInSz)) != 0) {
20103
20104
        goto cleanup;
20105
    }
20106
    eaxInited = 1;
20107
20108
    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
20109
        goto cleanup;
20110
    }
20111
20112
    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
20113
        goto cleanup;
20114
    }
20115
20116
cleanup:
20117
    if (eaxInited)
20118
        wc_AesEaxFree(eax);
20119
#if defined(WOLFSSL_SMALL_STACK)
20120
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
20121
#endif
20122
    return ret;
20123
}
20124
20125
20126
/*
20127
 * AES EAX Incremental API:
20128
 * Initializes an AES EAX encryption or decryption operation. This must be
20129
 * called before any other EAX APIs are used on the AesEax struct
20130
 *
20131
 * Returns 0 on success
20132
 * Returns error code on failure
20133
 */
20134
int  wc_AesEaxInit(AesEax* eax,
20135
                   const byte* key, word32 keySz,
20136
                   const byte* nonce, word32 nonceSz,
20137
                   const byte* authIn, word32 authInSz)
20138
{
20139
    int ret = 0;
20140
    word32 cmacSize;
20141
    int aesInited = 0;
20142
    int nonceCmacInited = 0;
20143
    int aadCmacInited = 0;
20144
20145
    if (eax == NULL || key == NULL ||  nonce == NULL) {
20146
        return BAD_FUNC_ARG;
20147
    }
20148
20149
    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
20150
20151
    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
20152
        goto out;
20153
    }
20154
    aesInited = 1;
20155
20156
    if ((ret = wc_AesSetKey(&eax->aes,
20157
                            key,
20158
                            keySz,
20159
                            NULL,
20160
                            AES_ENCRYPTION)) != 0) {
20161
        goto out;
20162
    }
20163
20164
    /*
20165
    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
20166
    *   N' = OMAC^0_K(N)
20167
    */
20168
    if ((ret = wc_InitCmac(&eax->nonceCmac,
20169
                           key,
20170
                           keySz,
20171
                           WC_CMAC_AES,
20172
                           NULL)) != 0) {
20173
        return ret;
20174
    }
20175
    nonceCmacInited = 1;
20176
20177
    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
20178
                             eax->prefixBuf,
20179
                             sizeof(eax->prefixBuf))) != 0) {
20180
        goto out;
20181
    }
20182
20183
    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
20184
        goto out;
20185
    }
20186
20187
    cmacSize = WC_AES_BLOCK_SIZE;
20188
    if ((ret = wc_CmacFinal(&eax->nonceCmac,
20189
                            eax->nonceCmacFinal,
20190
                            &cmacSize)) != 0) {
20191
        goto out;
20192
    }
20193
20194
    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
20195
        goto out;
20196
    }
20197
20198
    /*
20199
     * start the OMAC used to build the auth tag chunk for the AD .
20200
     * This CMAC is continued in subsequent update calls when more auth data is
20201
     * provided
20202
     *   H' = OMAC^1_K(H)
20203
     */
20204
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 1;
20205
    if ((ret = wc_InitCmac(&eax->aadCmac,
20206
                           key,
20207
                           keySz,
20208
                           WC_CMAC_AES,
20209
                           NULL)) != 0) {
20210
        goto out;
20211
    }
20212
    aadCmacInited = 1;
20213
20214
    if ((ret = wc_CmacUpdate(&eax->aadCmac,
20215
                             eax->prefixBuf,
20216
                             sizeof(eax->prefixBuf))) != 0) {
20217
        goto out;
20218
    }
20219
20220
    if (authIn != NULL) {
20221
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
20222
            goto out;
20223
        }
20224
    }
20225
20226
    /*
20227
     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
20228
     * updated in subsequent calls to encrypt/decrypt
20229
     *  C' = OMAC^2_K(C)
20230
     */
20231
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 2;
20232
    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
20233
                           key,
20234
                           keySz,
20235
                           WC_CMAC_AES,
20236
                           NULL)) != 0) {
20237
        goto out;
20238
    }
20239
20240
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
20241
                             eax->prefixBuf,
20242
                             sizeof(eax->prefixBuf))) != 0) {
20243
        goto out;
20244
    }
20245
20246
out:
20247
20248
    if (ret != 0) {
20249
        if (aesInited)
20250
            wc_AesFree(&eax->aes);
20251
        if (nonceCmacInited)
20252
            wc_CmacFree(&eax->nonceCmac);
20253
        if (aadCmacInited)
20254
            wc_CmacFree(&eax->aadCmac);
20255
    }
20256
20257
    return ret;
20258
}
20259
20260
20261
/*
20262
 * AES EAX Incremental API:
20263
 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
20264
 * the authentication stream
20265
 *
20266
 * Returns 0 on success
20267
 * Returns error code on failure
20268
 */
20269
int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
20270
                            const byte* in, word32 inSz,
20271
                            const byte* authIn, word32 authInSz)
20272
{
20273
    int ret;
20274
20275
    if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))
20276
            || (authInSz > 0 && authIn == NULL)) {
20277
        return BAD_FUNC_ARG;
20278
    }
20279
20280
    if (inSz > 0) {
20281
        /*
20282
         * Encrypt the plaintext using AES CTR
20283
         *  C = CTR(M)
20284
         */
20285
        if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
20286
            return ret;
20287
        }
20288
20289
        /*
20290
         * update OMAC with new ciphertext
20291
         *  C' = OMAC^2_K(C)
20292
         */
20293
        if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
20294
            return ret;
20295
        }
20296
    }
20297
20298
    /* If there exists new auth data, update the OMAC for that as well */
20299
    if (authIn != NULL) {
20300
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
20301
            return ret;
20302
        }
20303
    }
20304
20305
    return 0;
20306
}
20307
20308
20309
/*
20310
 * AES EAX Incremental API:
20311
 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
20312
 * the authentication stream
20313
 *
20314
 * Returns 0 on success
20315
 * Returns error code on failure
20316
 */
20317
int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
20318
                            const byte* in, word32 inSz,
20319
                            const byte* authIn, word32 authInSz)
20320
{
20321
    int ret;
20322
20323
    if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))
20324
            || (authInSz > 0 && authIn == NULL)) {
20325
        return BAD_FUNC_ARG;
20326
    }
20327
20328
    if (inSz > 0) {
20329
        /*
20330
         * Decrypt the plaintext using AES CTR
20331
         *  C = CTR(M)
20332
         */
20333
        if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
20334
            return ret;
20335
        }
20336
20337
        /*
20338
         * update OMAC with new ciphertext
20339
         *  C' = OMAC^2_K(C)
20340
         */
20341
        if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
20342
            return ret;
20343
        }
20344
    }
20345
20346
    /* If there exists new auth data, update the OMAC for that as well */
20347
    if (authIn != NULL) {
20348
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
20349
            return ret;
20350
        }
20351
    }
20352
20353
    return 0;
20354
}
20355
20356
20357
/*
20358
 * AES EAX Incremental API:
20359
 * Provides additional auth data information to the authentication
20360
 * stream for an authenticated encryption or decryption operation
20361
 *
20362
 * Returns 0 on success
20363
 * Returns error code on failure
20364
 */
20365
int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
20366
{
20367
    if (eax == NULL) {
20368
        return BAD_FUNC_ARG;
20369
    }
20370
    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
20371
}
20372
20373
20374
/*
20375
 * AES EAX Incremental API:
20376
 * Finalizes the authenticated encryption operation, computing the auth tag
20377
 * over previously supplied auth data and computed ciphertext
20378
 *
20379
 * Returns 0 on success
20380
 * Returns error code on failure
20381
 */
20382
int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
20383
{
20384
    word32 cmacSize;
20385
    int ret;
20386
    word32 i;
20387
20388
    if (eax == NULL || authTag == NULL || authTagSz == 0 ||
20389
            authTagSz > WC_AES_BLOCK_SIZE || authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
20390
        return BAD_FUNC_ARG;
20391
    }
20392
20393
    /* Complete the OMAC for the ciphertext */
20394
    cmacSize = WC_AES_BLOCK_SIZE;
20395
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
20396
                                  eax->ciphertextCmacFinal,
20397
                                  &cmacSize)) != 0) {
20398
        return ret;
20399
    }
20400
20401
    /* Complete the OMAC for auth data */
20402
    cmacSize = WC_AES_BLOCK_SIZE;
20403
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
20404
                                  eax->aadCmacFinal,
20405
                                  &cmacSize)) != 0) {
20406
        return ret;
20407
    }
20408
20409
    /*
20410
     * Concatenate all three auth tag chunks into the final tag, truncating
20411
     * at the specified tag length
20412
     *   T = Tag [first authTagSz bytes]
20413
     */
20414
    for (i = 0; i < authTagSz; i++) {
20415
        authTag[i] = eax->nonceCmacFinal[i]
20416
                    ^ eax->aadCmacFinal[i]
20417
                    ^ eax->ciphertextCmacFinal[i];
20418
    }
20419
20420
    return 0;
20421
}
20422
20423
20424
/*
20425
 * AES EAX Incremental API:
20426
 * Finalizes the authenticated decryption operation, computing the auth tag
20427
 * for the previously supplied auth data and cipher text and validating it
20428
 * against a provided auth tag
20429
 *
20430
 * Returns 0 on success
20431
 * Return error code for failure
20432
 */
20433
int wc_AesEaxDecryptFinal(AesEax* eax,
20434
                          const byte* authIn, word32 authInSz)
20435
{
20436
    int ret;
20437
    word32 i;
20438
    word32 cmacSize;
20439
20440
#if defined(WOLFSSL_SMALL_STACK)
20441
    byte *authTag;
20442
#else
20443
    byte authTag[WC_AES_BLOCK_SIZE];
20444
#endif
20445
20446
    if (eax == NULL || authIn == NULL || authInSz > WC_AES_BLOCK_SIZE
20447
            || authInSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
20448
        return BAD_FUNC_ARG;
20449
    }
20450
20451
    /* Complete the OMAC for the ciphertext */
20452
    cmacSize = WC_AES_BLOCK_SIZE;
20453
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
20454
                                  eax->ciphertextCmacFinal,
20455
                                  &cmacSize)) != 0) {
20456
        return ret;
20457
    }
20458
20459
    /* Complete the OMAC for auth data */
20460
    cmacSize = WC_AES_BLOCK_SIZE;
20461
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
20462
                                  eax->aadCmacFinal,
20463
                                  &cmacSize)) != 0) {
20464
        return ret;
20465
    }
20466
20467
#if defined(WOLFSSL_SMALL_STACK)
20468
    authTag = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20469
    if (authTag == NULL) {
20470
        return MEMORY_E;
20471
    }
20472
#endif
20473
20474
    /*
20475
     * Concatenate all three auth tag chunks into the final tag, truncating
20476
     * at the specified tag length
20477
     *   T = Tag [first authInSz bytes]
20478
     */
20479
    for (i = 0; i < authInSz; i++) {
20480
        authTag[i] = eax->nonceCmacFinal[i]
20481
                    ^ eax->aadCmacFinal[i]
20482
                    ^ eax->ciphertextCmacFinal[i];
20483
    }
20484
20485
    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
20486
        ret = AES_EAX_AUTH_E;
20487
    }
20488
    else {
20489
        ret = 0;
20490
    }
20491
20492
#if defined(WOLFSSL_SMALL_STACK)
20493
    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20494
#endif
20495
20496
    return ret;
20497
}
20498
20499
/*
20500
 * Frees the underlying CMAC and AES contexts. Must be called when done using
20501
 * the AES EAX context structure.
20502
 *
20503
 * Returns 0 on success
20504
 * Returns error code on failure
20505
 */
20506
int wc_AesEaxFree(AesEax* eax)
20507
{
20508
    if (eax == NULL) {
20509
        return BAD_FUNC_ARG;
20510
    }
20511
20512
    (void)wc_CmacFree(&eax->ciphertextCmac);
20513
    (void)wc_CmacFree(&eax->aadCmac);
20514
    wc_AesFree(&eax->aes);
20515
20516
    return 0;
20517
}
20518
20519
#endif /* WOLFSSL_AES_EAX */
20520
20521
#ifdef WOLFSSL_AES_CTS
20522
20523
20524
/* One-shot API */
20525
int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out,
20526
                     const byte* in, word32 inSz,
20527
                     const byte* iv)
20528
{
20529
    WC_DECLARE_VAR(aes, Aes, 1, 0);
20530
    int ret = 0;
20531
    word32 outSz = inSz;
20532
20533
    if (key == NULL || out == NULL || in == NULL || iv == NULL)
20534
        return BAD_FUNC_ARG;
20535
20536
#ifdef WOLFSSL_SMALL_STACK
20537
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
20538
#else
20539
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
20540
#endif
20541
    if (ret == 0)
20542
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
20543
    if (ret == 0)
20544
        ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz);
20545
    if (ret == 0) {
20546
        out += outSz;
20547
        outSz = inSz - outSz;
20548
        ret = wc_AesCtsEncryptFinal(aes, out, &outSz);
20549
    }
20550
20551
#ifdef WOLFSSL_SMALL_STACK
20552
    wc_AesDelete(aes, NULL);
20553
#else
20554
    wc_AesFree(aes);
20555
#endif
20556
    return ret;
20557
}
20558
20559
int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out,
20560
                     const byte* in, word32 inSz,
20561
                     const byte* iv)
20562
{
20563
    WC_DECLARE_VAR(aes, Aes, 1, 0);
20564
    int ret = 0;
20565
    word32 outSz = inSz;
20566
20567
    if (key == NULL || out == NULL || in == NULL || iv == NULL) {
20568
        return BAD_FUNC_ARG;
20569
    }
20570
20571
#ifdef WOLFSSL_SMALL_STACK
20572
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
20573
#else
20574
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
20575
#endif
20576
    if (ret == 0)
20577
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
20578
    if (ret == 0)
20579
        ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz);
20580
    if (ret == 0) {
20581
        out += outSz;
20582
        outSz = inSz - outSz;
20583
        ret = wc_AesCtsDecryptFinal(aes, out, &outSz);
20584
    }
20585
20586
#ifdef WOLFSSL_SMALL_STACK
20587
    wc_AesDelete(aes, NULL);
20588
#else
20589
    wc_AesFree(aes);
20590
#endif
20591
    return ret;
20592
}
20593
20594
static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz,
20595
                        const byte* in, word32 inSz, int enc)
20596
{
20597
    word32 blocks = 0;
20598
    int ret = 0;
20599
    word32 writtenSz = 0;
20600
    word32 tmpOutSz;
20601
20602
    if (aes == NULL || out == NULL || in == NULL || outSz == NULL)
20603
        return BAD_FUNC_ARG;
20604
20605
    /* Error out early for easy sanity check */
20606
    if (*outSz < inSz)
20607
        return BUFFER_E;
20608
    tmpOutSz = *outSz;
20609
20610
    /* We need to store last two blocks of plaintext */
20611
    if (aes->left > 0) {
20612
        word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left);
20613
        XMEMCPY(aes->ctsBlock + aes->left, in, copySz);
20614
        aes->left += copySz;
20615
        in += copySz;
20616
        inSz -= copySz;
20617
20618
        if (aes->left == WC_AES_BLOCK_SIZE * 2) {
20619
            if (inSz > WC_AES_BLOCK_SIZE) {
20620
                if (tmpOutSz < WC_AES_BLOCK_SIZE * 2)
20621
                    return BUFFER_E;
20622
                if (enc) {
20623
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
20624
                                           WC_AES_BLOCK_SIZE * 2);
20625
                }
20626
                else {
20627
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
20628
                                           WC_AES_BLOCK_SIZE * 2);
20629
                }
20630
                if (ret != 0)
20631
                    return ret;
20632
                out += WC_AES_BLOCK_SIZE * 2;
20633
                writtenSz += WC_AES_BLOCK_SIZE * 2;
20634
                tmpOutSz -= WC_AES_BLOCK_SIZE * 2;
20635
                aes->left = 0;
20636
            }
20637
            else if (inSz > 0) {
20638
                if (tmpOutSz < WC_AES_BLOCK_SIZE)
20639
                    return BUFFER_E;
20640
                if (enc) {
20641
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
20642
                                           WC_AES_BLOCK_SIZE);
20643
                }
20644
                else {
20645
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
20646
                                           WC_AES_BLOCK_SIZE);
20647
                }
20648
                if (ret != 0)
20649
                    return ret;
20650
                out += WC_AES_BLOCK_SIZE;
20651
                writtenSz += WC_AES_BLOCK_SIZE;
20652
                tmpOutSz -= WC_AES_BLOCK_SIZE;
20653
                /* Move the last block in ctsBlock to the beginning for
20654
                 * next operation */
20655
                XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE,
20656
                        WC_AES_BLOCK_SIZE);
20657
                XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz);
20658
                aes->left = WC_AES_BLOCK_SIZE + inSz;
20659
                *outSz = writtenSz;
20660
                return ret; /* Return the result of encryption */
20661
            }
20662
            else {
20663
                /* Can't output data as we need > 1 block for Final call */
20664
                *outSz = writtenSz;
20665
                return 0;
20666
            }
20667
        }
20668
        else {
20669
            /* All input has been absorbed into aes->ctsBlock */
20670
            *outSz = 0;
20671
            return 0;
20672
        }
20673
    }
20674
    if (inSz > WC_AES_BLOCK_SIZE) {
20675
        /* We need to store the last two full or partial blocks */
20676
        blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE;
20677
        blocks -= 2;
20678
    }
20679
    if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE)
20680
        return BUFFER_E;
20681
    if (enc)
20682
        ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
20683
    else
20684
        ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
20685
    in += blocks * WC_AES_BLOCK_SIZE;
20686
    inSz -= blocks * WC_AES_BLOCK_SIZE;
20687
    XMEMCPY(aes->ctsBlock, in, inSz);
20688
    aes->left = inSz;
20689
    writtenSz += blocks * WC_AES_BLOCK_SIZE;
20690
    *outSz = writtenSz;
20691
    return ret;
20692
}
20693
20694
/* Incremental API */
20695
int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz,
20696
                           const byte* in, word32 inSz)
20697
{
20698
    return AesCtsUpdate(aes, out, outSz, in, inSz, 1);
20699
}
20700
20701
int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz)
20702
{
20703
    int ret = 0;
20704
20705
    if (aes == NULL || out == NULL || outSz == NULL)
20706
        return BAD_FUNC_ARG;
20707
    if (*outSz < aes->left)
20708
        return BUFFER_E;
20709
20710
    /* Input must be at least two complete or partial blocks */
20711
    if (aes->left <= WC_AES_BLOCK_SIZE)
20712
        return BAD_FUNC_ARG;
20713
20714
    /* Zero padding */
20715
    XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left);
20716
20717
    ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock,
20718
                           WC_AES_BLOCK_SIZE * 2);
20719
    if (ret != 0)
20720
        return ret;
20721
20722
    XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
20723
    XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock,
20724
            aes->left - WC_AES_BLOCK_SIZE);
20725
    *outSz = aes->left;
20726
    return ret;
20727
}
20728
20729
int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz,
20730
                           const byte* in, word32 inSz)
20731
{
20732
    return AesCtsUpdate(aes, out, outSz, in, inSz, 0);
20733
}
20734
20735
int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz)
20736
{
20737
    int ret = 0;
20738
    byte iv[WC_AES_BLOCK_SIZE];
20739
    byte tmp[WC_AES_BLOCK_SIZE];
20740
    word32 partialSz;
20741
    word32 padSz;
20742
20743
    if (aes == NULL || out == NULL || outSz == NULL)
20744
        return BAD_FUNC_ARG;
20745
    if (*outSz < aes->left)
20746
        return BUFFER_E;
20747
20748
    /* Input must be at least two complete or partial blocks */
20749
    if (aes->left <= WC_AES_BLOCK_SIZE)
20750
        return BAD_FUNC_ARG;
20751
20752
    partialSz = aes->left - WC_AES_BLOCK_SIZE;
20753
    padSz = 2 * WC_AES_BLOCK_SIZE - aes->left;
20754
    /* Zero pad */
20755
    XMEMSET(aes->ctsBlock + aes->left, 0, padSz);
20756
20757
    /* Store IV */
20758
    XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE);
20759
    /* Load IV */
20760
    XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
20761
20762
    ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE);
20763
    if (ret != 0)
20764
        return ret;
20765
20766
    /* Write out partial block */
20767
    XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz);
20768
    /* Retrieve the padding */
20769
    XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz);
20770
    /* Restore IV */
20771
    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
20772
20773
    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE,
20774
                           WC_AES_BLOCK_SIZE);
20775
    if (ret != 0)
20776
        return ret;
20777
20778
    *outSz = aes->left;
20779
    return ret;
20780
}
20781
20782
#endif /* WOLFSSL_AES_CTS */
20783
20784
#endif /* !NO_AES */