Coverage Report

Created: 2026-09-20 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-heapmath/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_KEYWRAP_PADDING: AES key wrap padding (RFC 5649) default: off
60
 * WOLFSSL_AES_CBC_LENGTH_CHECKS: Validate CBC input length       default: off
61
 *
62
 * AES-GCM:
63
 * HAVE_AESGCM:             Enable AES-GCM mode                   default: off
64
 * HAVE_AESGCM_DECRYPT:     Enable AES-GCM decryption             default: on
65
 *                           (when HAVE_AESGCM is enabled)
66
 * WOLFSSL_AESGCM_STREAM:   Enable streaming AES-GCM API          default: off
67
 * WC_AES_GCM_DEC_AUTH_EARLY: Authenticate tag before decryption  default: off
68
 * GCM_SMALL:               Small GCM table, saves memory         default: off
69
 * GCM_TABLE:               Full 4-bit GCM lookup table, faster   default: off
70
 * GCM_TABLE_4BIT:          Explicit 4-bit GCM table mode         default: off
71
 * GCM_WORD32:              Use 32-bit word GCM implementation    default: off
72
 * GCM_GMULT_LEN:           GCM GMULT length optimization         default: off
73
 *
74
 * AES-XTS Stream:
75
 * WOLFSSL_AESXTS_STREAM:   Enable streaming AES-XTS API          default: off
76
 * WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING:
77
 *                           Disable XTS stream request accounting default: off
78
 * WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS:
79
 *                           Support both encrypt and decrypt keys default: off
80
 *                           simultaneously in XTS context
81
 *
82
 * Performance / Side-Channel:
83
 * WOLFSSL_AESNI:           Enable Intel AES-NI instructions      default: off
84
 * WOLFSSL_AESNI_BY4:       AES-NI 4-block parallel processing    default: off
85
 * WOLFSSL_AESNI_BY6:       AES-NI 6-block parallel processing    default: off
86
 * USE_INTEL_SPEEDUP:       Intel AVX/AVX2 for AES acceleration   default: off
87
 * USE_INTEL_SPEEDUP_FOR_AES:
88
                            Same as USE_INTEL_SPEEDUP, but scoped
89
                              to AES.                             default: off
90
 * WOLFSSL_AES_SMALL_TABLES: Use smaller AES S-box tables         default: off
91
 * WOLFSSL_AES_NO_UNROLL:   Disable AES round loop unrolling      default: off
92
 * WOLFSSL_AES_TOUCH_LINES: Touch all cache lines for             default: off
93
 *                           side-channel resistance
94
 * WC_AES_BITSLICED:        Use bitsliced AES implementation      default: off
95
 * AES_GCM_GMULT_NCT:       GCM GMULT non-constant-time          default: off
96
 * NO_WOLFSSL_ALLOC_ALIGN:  Disable aligned memory allocation     default: off
97
 * WOLFSSL_AES_REQUIRE_KEY_SET:
98
 *                          Reject mode calls made before a key    default: on,
99
 *                            is installed. Off automatically on      see aes.h
100
 *                            backends that replace the mode
101
 *                            entry points.
102
 * WOLFSSL_NO_AES_KEY_SET_CHECK:
103
 *                          Force the above check off              default: off
104
 *
105
 * Hardware Acceleration (AES-specific):
106
 * WC_ASYNC_ENABLE_AES:     Enable async AES operations           default: off
107
 * WOLFSSL_CRYPTOCELL_AES:  CryptoCell AES acceleration           default: off
108
 * WOLFSSL_DEVCRYPTO_AES:   /dev/crypto AES acceleration          default: off
109
 * WOLFSSL_DEVCRYPTO_CBC:   /dev/crypto AES-CBC acceleration      default: off
110
 * WOLFSSL_KCAPI_AES:       Linux kernel crypto API for AES       default: off
111
 * WOLFSSL_NO_KCAPI_AES_CBC: Disable KCAPI AES-CBC                default: off
112
 * WOLFSSL_NRF51_AES:       nRF51 hardware AES                    default: off
113
 * WOLFSSL_PSA_NO_AES:      Disable PSA AES                       default: off
114
 * WOLFSSL_SCE_NO_AES:      Disable Renesas SCE AES               default: off
115
 * NO_IMX6_CAAM_AES:        Disable i.MX6 CAAM AES               default: off
116
 * WOLFSSL_AFALG_XILINX_AES: AF_ALG Xilinx AES acceleration      default: off
117
 * NO_WOLFSSL_ESP32_CRYPT_AES: Disable ESP32 AES acceleration     default: off
118
 * STM32_CRYPTO_AES_ONLY:   STM32 AES-only crypto mode            default: off
119
 *
120
 * Debug:
121
 * WC_DEBUG_CIPHER_LIFECYCLE: Debug cipher init/free lifecycle     default: off
122
 * WOLFSSL_HW_METRICS:      Track hardware acceleration usage     default: off
123
 */
124
125
#define WC_FIPS_LL_CRYPTO
126
#define _WC_BUILDING_AES_C
127
128
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
129
130
#if !defined(NO_AES)
131
132
/* Tip: Locate the software cipher modes by searching for "Software AES" */
133
134
#if FIPS_VERSION3_GE(2,0,0)
135
    #ifdef USE_WINDOWS_API
136
        #pragma code_seg(".fipsA$b")
137
        #pragma const_seg(".fipsB$b")
138
    #endif
139
#endif
140
141
#include <wolfssl/wolfcrypt/aes.h>
142
143
#ifdef WOLFSSL_AESNI
144
#include <wmmintrin.h>
145
#include <emmintrin.h>
146
#include <smmintrin.h>
147
#endif /* WOLFSSL_AESNI */
148
149
#include <wolfssl/wolfcrypt/cpuid.h>
150
151
#ifdef WOLF_CRYPTO_CB
152
    #include <wolfssl/wolfcrypt/cryptocb.h>
153
#endif
154
155
#ifdef WOLFSSL_NXP_HASHCRYPT_AES
156
    #include <wolfssl/wolfcrypt/port/nxp/hashcrypt_port.h>
157
#endif
158
159
#ifdef WOLFSSL_SECO_CAAM
160
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
161
#endif
162
163
#ifdef WOLFSSL_IMXRT_DCP
164
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
165
#endif
166
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
167
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
168
#endif
169
#ifdef WOLFSSL_MICROCHIP_TA100
170
    #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
171
#endif
172
#ifdef WOLFSSL_CMAC
173
    #include <wolfssl/wolfcrypt/cmac.h>
174
#endif
175
176
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
177
    #include <wolfssl/wolfcrypt/port/psa/psa.h>
178
#endif
179
180
#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
181
    #include <wolfssl/wolfcrypt/port/maxim/max3266x.h>
182
#ifdef MAX3266X_CB
183
    /* Revert back to SW so HW CB works */
184
    /* HW only works for AES: ECB, CBC, and partial via ECB for other modes */
185
    #include <wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h>
186
    /* Turn off MAX3266X_AES in the context of this file when using CB */
187
    #undef MAX3266X_AES
188
#endif
189
#endif
190
191
#if defined(WOLFSSL_TI_CRYPT)
192
    #include <wolfcrypt/src/port/ti/ti-aes.c>
193
194
    #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
195
        wc_AesEncryptDirect(aes, outBlock, inBlock)
196
    #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
197
        wc_AesDecryptDirect(aes, outBlock, inBlock)
198
#else
199
200
201
#if defined(WOLFSSL_PSOC6_CRYPTO)
202
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
203
#endif /* WOLFSSL_PSOC6_CRYPTO */
204
205
#ifdef NO_INLINE
206
    #include <wolfssl/wolfcrypt/misc.h>
207
#else
208
    #define WOLFSSL_MISC_INCLUDED
209
    #include <wolfcrypt/src/misc.c>
210
#endif
211
212
#ifdef WOLFSSL_IMX6_CAAM_BLOB
213
    /* case of possibly not using hardware acceleration for AES but using key
214
       blobs */
215
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
216
#endif
217
218
#ifdef DEBUG_AESNI
219
    #include <stdio.h>
220
#endif
221
222
#ifdef _MSC_VER
223
    /* 4127 warning constant while(1)  */
224
    #pragma warning(disable: 4127)
225
#endif
226
227
#if (!defined(WOLFSSL_ARMASM) && FIPS_VERSION3_GE(6,0,0)) || \
228
    FIPS_VERSION3_GE(7,0,0)
229
    const unsigned int wolfCrypt_FIPS_aes_ro_sanity[2] =
230
                                                     { 0x1a2b3c4d, 0x00000002 };
231
    int wolfCrypt_FIPS_AES_sanity(void)
232
    {
233
        return 0;
234
    }
235
#endif
236
237
/* Select the base or the crypto-extension AES at run time on 32-bit Arm.  Same
238
 * test as WOLFSSL_ARM32_AES_HW_FLAGS in aes.h - which documents it - plus the
239
 * run-time detection needed to make the choice. */
240
#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
241
    !defined(WOLFSSL_ARMASM_THUMB2) && \
242
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) && \
243
    !defined(WOLFSSL_ARMASM_NO_BASE_IMPL) && defined(HAVE_CPUID_ARM32)
244
    #define WOLFSSL_ARM32_AES_DISPATCH
245
#endif
246
247
#if defined(STM32_CRYPTO) && !defined(WOLFSSL_STM32_BARE) && \
248
    !defined(WOLFSSL_STM32_CUBEMX)
249
/* Push one AES block through CRYP. CRYP_DataIn/Out work in 32-bit words,
250
 * so stage the caller's byte buffers through an aligned local. */
251
static WC_INLINE void wc_Stm32_CrypAesBlock(const byte* in, byte* out)
252
{
253
    uint32_t tmp[WC_AES_BLOCK_SIZE / sizeof(uint32_t)];
254
255
    XMEMCPY(tmp, in, WC_AES_BLOCK_SIZE);
256
257
    CRYP_DataIn(tmp[0]);
258
    CRYP_DataIn(tmp[1]);
259
    CRYP_DataIn(tmp[2]);
260
    CRYP_DataIn(tmp[3]);
261
262
    /* wait until the complete message has been processed */
263
    while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
264
265
    tmp[0] = CRYP_DataOut();
266
    tmp[1] = CRYP_DataOut();
267
    tmp[2] = CRYP_DataOut();
268
    tmp[3] = CRYP_DataOut();
269
270
    XMEMCPY(out, tmp, WC_AES_BLOCK_SIZE);
271
}
272
#endif
273
274
/* Define AES implementation includes and functions */
275
#if defined(STM32_CRYPTO) && !defined(WOLF_CRYPTO_CB_ONLY_AES)
276
     /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
277
278
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
279
280
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
281
        Aes* aes, const byte* inBlock, byte* outBlock)
282
    {
283
    #ifdef WOLFSSL_STM32_BARE
284
        /* Bare-metal driver handles mutex, clock and key/IV internally.
285
         * DHUK is routed via the crypto-callback framework, not here. */
286
        return wc_Stm32_Aes_Ecb(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE, 1);
287
    #else
288
        int ret = 0;
289
    #ifdef WOLFSSL_STM32_CUBEMX
290
        CRYP_HandleTypeDef hcryp;
291
    #else
292
        CRYP_InitTypeDef cryptInit;
293
        CRYP_KeyInitTypeDef keyInit;
294
    #endif
295
296
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
297
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
298
        if (ret < 0)
299
            return ret;
300
#endif
301
302
    #if defined(WOLFSSL_STM32_CUBEMX)
303
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
304
        if (ret != 0)
305
            return ret;
306
307
        ret = wolfSSL_CryptHwMutexLock();
308
        if (ret != 0)
309
            return ret;
310
311
    #if defined(STM32_HAL_V2)
312
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
313
    #elif defined(STM32_CRYPTO_AES_ONLY)
314
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
315
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
316
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
317
    #endif
318
        if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
319
            ret = BAD_FUNC_ARG;
320
        }
321
322
        if (ret == 0) {
323
        #if defined(STM32_HAL_V2)
324
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
325
                (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
326
        #elif defined(STM32_CRYPTO_AES_ONLY)
327
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
328
                outBlock, STM32_HAL_TIMEOUT);
329
        #else
330
            ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
331
                outBlock, STM32_HAL_TIMEOUT);
332
        #endif
333
            if (ret != HAL_OK) {
334
                ret = WC_TIMEOUT_E;
335
            }
336
            HAL_CRYP_DeInit(&hcryp);
337
        }
338
339
    #else /* Standard Peripheral Library */
340
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
341
        if (ret != 0)
342
            return ret;
343
344
        ret = wolfSSL_CryptHwMutexLock();
345
        if (ret != 0)
346
            return ret;
347
348
        /* reset registers to their default values */
349
        CRYP_DeInit();
350
351
        /* setup key */
352
        CRYP_KeyInit(&keyInit);
353
354
        /* set direction and mode */
355
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
356
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
357
        CRYP_Init(&cryptInit);
358
359
        /* enable crypto processor */
360
        CRYP_Cmd(ENABLE);
361
362
        /* flush IN/OUT FIFOs */
363
        CRYP_FIFOFlush();
364
365
        wc_Stm32_CrypAesBlock(inBlock, outBlock);
366
367
        /* disable crypto processor */
368
        CRYP_Cmd(DISABLE);
369
    #endif /* WOLFSSL_STM32_CUBEMX */
370
        wolfSSL_CryptHwMutexUnLock();
371
        wc_Stm32_Aes_Cleanup();
372
373
        return ret;
374
    #endif /* !WOLFSSL_STM32_BARE */
375
    }
376
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
377
378
#ifdef HAVE_AES_DECRYPT
379
    #if defined(WOLFSSL_AES_DIRECT)
380
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
381
        Aes* aes, const byte* inBlock, byte* outBlock)
382
    {
383
    #ifdef WOLFSSL_STM32_BARE
384
        /* DHUK is routed via the crypto-callback framework, not here. */
385
        return wc_Stm32_Aes_Ecb(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE, 0);
386
    #else
387
        int ret = 0;
388
    #ifdef WOLFSSL_STM32_CUBEMX
389
        CRYP_HandleTypeDef hcryp;
390
    #else
391
        CRYP_InitTypeDef cryptInit;
392
        CRYP_KeyInitTypeDef keyInit;
393
    #endif
394
395
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
396
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
397
        if (ret < 0)
398
            return ret;
399
#endif
400
401
    #if defined(WOLFSSL_STM32_CUBEMX)
402
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
403
        if (ret != 0)
404
            return ret;
405
406
        ret = wolfSSL_CryptHwMutexLock();
407
        if (ret != 0)
408
            return ret;
409
410
    #if defined(STM32_HAL_V2)
411
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
412
    #elif defined(STM32_CRYPTO_AES_ONLY)
413
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
414
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
415
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
416
    #endif
417
        HAL_CRYP_Init(&hcryp);
418
419
    #if defined(STM32_HAL_V2)
420
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
421
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
422
    #elif defined(STM32_CRYPTO_AES_ONLY)
423
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
424
            outBlock, STM32_HAL_TIMEOUT);
425
    #else
426
        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
427
            outBlock, STM32_HAL_TIMEOUT);
428
    #endif
429
        if (ret != HAL_OK) {
430
            ret = WC_TIMEOUT_E;
431
        }
432
        HAL_CRYP_DeInit(&hcryp);
433
434
    #else /* Standard Peripheral Library */
435
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
436
        if (ret != 0)
437
            return ret;
438
439
        ret = wolfSSL_CryptHwMutexLock();
440
        if (ret != 0)
441
            return ret;
442
443
        /* reset registers to their default values */
444
        CRYP_DeInit();
445
446
        /* set direction and key */
447
        CRYP_KeyInit(&keyInit);
448
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
449
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
450
        CRYP_Init(&cryptInit);
451
452
        /* enable crypto processor */
453
        CRYP_Cmd(ENABLE);
454
455
        /* wait until decrypt key has been initialized */
456
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
457
458
        /* set direction and mode */
459
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
460
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
461
        CRYP_Init(&cryptInit);
462
463
        /* enable crypto processor */
464
        CRYP_Cmd(ENABLE);
465
466
        /* flush IN/OUT FIFOs */
467
        CRYP_FIFOFlush();
468
469
        wc_Stm32_CrypAesBlock(inBlock, outBlock);
470
471
        /* disable crypto processor */
472
        CRYP_Cmd(DISABLE);
473
    #endif /* WOLFSSL_STM32_CUBEMX */
474
        wolfSSL_CryptHwMutexUnLock();
475
        wc_Stm32_Aes_Cleanup();
476
477
        return ret;
478
    #endif /* !WOLFSSL_STM32_BARE */
479
    }
480
    #endif /* WOLFSSL_AES_DIRECT */
481
#endif /* HAVE_AES_DECRYPT */
482
483
#elif defined(HAVE_COLDFIRE_SEC)
484
    /* Freescale Coldfire SEC support for CBC mode.
485
     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
486
    #include "sec.h"
487
    #include "mcf5475_sec.h"
488
    #include "mcf5475_siu.h"
489
#elif defined(FREESCALE_LTC)
490
    #include "fsl_ltc.h"
491
    #if defined(FREESCALE_LTC_AES_GCM)
492
        #undef NEED_AES_TABLES
493
        #undef GCM_TABLE
494
    #endif
495
496
        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
497
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
498
            Aes* aes, const byte* inBlock, byte* outBlock)
499
        {
500
            word32 keySize = 0;
501
            byte* key = (byte*)aes->key;
502
            int ret = wc_AesGetKeySize(aes, &keySize);
503
            if (ret != 0)
504
                return ret;
505
506
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
507
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
508
            if (ret < 0)
509
                return ret;
510
#endif
511
512
            if (wolfSSL_CryptHwMutexLock() == 0) {
513
                LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
514
                    key, keySize);
515
                wolfSSL_CryptHwMutexUnLock();
516
            }
517
            return 0;
518
        }
519
        #ifdef HAVE_AES_DECRYPT
520
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
521
            Aes* aes, const byte* inBlock, byte* outBlock)
522
        {
523
            word32 keySize = 0;
524
            byte* key = (byte*)aes->key;
525
            int ret = wc_AesGetKeySize(aes, &keySize);
526
            if (ret != 0)
527
                return ret;
528
529
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
530
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
531
            if (ret < 0)
532
                return ret;
533
#endif
534
535
            if (wolfSSL_CryptHwMutexLock() == 0) {
536
                LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
537
                    key, keySize, kLTC_EncryptKey);
538
                wolfSSL_CryptHwMutexUnLock();
539
            }
540
            return 0;
541
        }
542
        #endif
543
544
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
545
546
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
547
548
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
549
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
550
        Aes* aes, const byte* inBlock, byte* outBlock)
551
    {
552
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
553
        {
554
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
555
            if (ret < 0)
556
                return ret;
557
        }
558
#endif
559
        /* Thread mutex protection handled in Pic32Crypto */
560
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
561
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
562
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
563
    }
564
    #endif
565
566
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
567
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
568
        Aes* aes, const byte* inBlock, byte* outBlock)
569
    {
570
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
571
        {
572
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
573
            if (ret < 0)
574
                return ret;
575
        }
576
#endif
577
        /* Thread mutex protection handled in Pic32Crypto */
578
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
579
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
580
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
581
    }
582
    #endif
583
584
#elif defined(WOLFSSL_NRF51_AES)
585
    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
586
    #include "wolfssl/wolfcrypt/port/nrf51.h"
587
588
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
589
        Aes* aes, const byte* inBlock, byte* outBlock)
590
    {
591
        int ret;
592
593
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
594
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
595
        if (ret < 0)
596
            return ret;
597
#endif
598
599
        ret = wolfSSL_CryptHwMutexLock();
600
        if (ret == 0) {
601
            ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds,
602
                                    outBlock);
603
            wolfSSL_CryptHwMutexUnLock();
604
        }
605
        return ret;
606
    }
607
608
    #ifdef HAVE_AES_DECRYPT
609
        #error nRF51 AES Hardware does not support decrypt
610
    #endif /* HAVE_AES_DECRYPT */
611
612
#elif defined(WOLFSSL_ESP32_CRYPT) && \
613
     !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
614
    #include <esp_log.h>
615
    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
616
    #define TAG "aes"
617
618
    /* We'll use SW for fallback:
619
     *   unsupported key lengths. (e.g. ESP32-S3)
620
     *   chipsets not implemented.
621
     *   hardware busy. */
622
    #define NEED_AES_TABLES
623
    #define NEED_AES_HW_FALLBACK
624
    #define NEED_SOFTWARE_AES_SETKEY
625
    #undef  WOLFSSL_AES_DIRECT
626
    #define WOLFSSL_AES_DIRECT
627
628
    /* Encrypt: If we choose to never have a fallback to SW: */
629
    #if !defined(NEED_AES_HW_FALLBACK) && \
630
        (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
631
    /* calling this one when NO_AES_192 is defined */
632
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
633
        Aes* aes, const byte* inBlock, byte* outBlock)
634
    {
635
        int ret;
636
637
    #ifdef WC_DEBUG_CIPHER_LIFECYCLE
638
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
639
        if (ret < 0)
640
            return ret;
641
    #endif
642
643
        /* Thread mutex protection handled in esp_aes_hw_InUse */
644
    #ifdef NEED_AES_HW_FALLBACK
645
        if (wc_esp32AesSupportedKeyLen(aes)) {
646
            ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
647
        }
648
    #else
649
        ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
650
    #endif
651
        return ret;
652
    }
653
    #endif
654
655
    /* Decrypt: If we choose to never have a fallback to SW: */
656
    #if !defined(NEED_AES_HW_FALLBACK) && \
657
        (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
658
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
659
        Aes* aes, const byte* inBlock, byte* outBlock)
660
    {
661
        int ret = 0;
662
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
663
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
664
        if (ret < 0)
665
            return ret;
666
#endif
667
        /* Thread mutex protection handled in esp_aes_hw_InUse */
668
    #ifdef NEED_AES_HW_FALLBACK
669
        if (wc_esp32AesSupportedKeyLen(aes)) {
670
            ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
671
        }
672
        else {
673
            ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
674
        }
675
    #else
676
        /* if we don't need fallback, always use HW */
677
        ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
678
    #endif
679
        return ret;
680
    }
681
    #endif
682
683
#elif defined(WOLFSSL_AESNI)
684
685
    #define NEED_AES_TABLES
686
687
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
688
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
689
     */
690
691
    #ifndef AESNI_ALIGN
692
        #define AESNI_ALIGN 16
693
    #endif
694
695
    /* Note that all write access to these static variables must be idempotent,
696
     * as arranged by Check_CPU_support_AES(), else they will be susceptible to
697
     * data races.  Don't use wolfSSL_Atomic_Uint here, to avoid atomic access
698
     * overhead on subsequent calls.
699
     */
700
    static int checkedAESNI = 0;
701
    static int haveAESNI = 0;
702
    static cpuid_flags_t intel_flags = WC_CPUID_INITIALIZER;
703
704
    static WARN_UNUSED_RESULT int Check_CPU_support_AES(void)
705
    {
706
        cpuid_get_flags_ex(&intel_flags);
707
708
        return IS_INTEL_AESNI(intel_flags) != 0;
709
    }
710
711
712
    /* tell C compiler these are asm functions in case any mix up of ABI underscore
713
       prefix between clang/gcc/llvm etc */
714
    #ifdef HAVE_AES_CBC
715
        void AES_CBC_encrypt_AESNI(const unsigned char* in, unsigned char* out,
716
                             unsigned char* ivec, unsigned long length,
717
                             const unsigned char* KS, int nr)
718
                             XASM_LINK("AES_CBC_encrypt_AESNI");
719
720
        #ifdef HAVE_AES_DECRYPT
721
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
722
                void AES_CBC_decrypt_AESNI_by4(const unsigned char* in, unsigned char* out,
723
                                         unsigned char* ivec, unsigned long length,
724
                                         const unsigned char* KS, int nr)
725
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by4");
726
            #elif defined(WOLFSSL_AESNI_BY6)
727
                void AES_CBC_decrypt_AESNI_by6(const unsigned char* in, unsigned char* out,
728
                                         unsigned char* ivec, unsigned long length,
729
                                         const unsigned char* KS, int nr)
730
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by6");
731
            #else /* WOLFSSL_AESNI_BYx */
732
                void AES_CBC_decrypt_AESNI_by8(const unsigned char* in, unsigned char* out,
733
                                         unsigned char* ivec, unsigned long length,
734
                                         const unsigned char* KS, int nr)
735
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by8");
736
            #endif /* WOLFSSL_AESNI_BYx */
737
        #endif /* HAVE_AES_DECRYPT */
738
    #endif /* HAVE_AES_CBC */
739
740
    void AES_ECB_encrypt_AESNI(const unsigned char* in, unsigned char* out,
741
                         unsigned long length, const unsigned char* KS, int nr)
742
                         XASM_LINK("AES_ECB_encrypt_AESNI");
743
744
    #ifdef HAVE_AES_DECRYPT
745
        void AES_ECB_decrypt_AESNI(const unsigned char* in, unsigned char* out,
746
                             unsigned long length, const unsigned char* KS, int nr)
747
                             XASM_LINK("AES_ECB_decrypt_AESNI");
748
    #endif
749
750
    void AES_128_Key_Expansion_AESNI(const unsigned char* userkey,
751
                               unsigned char* key_schedule)
752
                               XASM_LINK("AES_128_Key_Expansion_AESNI");
753
754
    void AES_192_Key_Expansion_AESNI(const unsigned char* userkey,
755
                               unsigned char* key_schedule)
756
                               XASM_LINK("AES_192_Key_Expansion_AESNI");
757
758
    void AES_256_Key_Expansion_AESNI(const unsigned char* userkey,
759
                               unsigned char* key_schedule)
760
                               XASM_LINK("AES_256_Key_Expansion_AESNI");
761
762
#ifdef WOLFSSL_X86_64_BUILD
763
    #if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
764
        #define USE_INTEL_SPEEDUP
765
    #endif
766
767
    /* Wide ECB / CBC / CTR variants for x86_64.  They share the AES-NI key
768
     * schedule declared above and are selected at runtime from intel_flags.
769
     * AES_CBC_decrypt_AESNI is the single max-width path (the by4/by6/by8
770
     * variants are only used by the 32-bit x86 build). */
771
    #if defined(USE_INTEL_SPEEDUP)
772
        #ifndef HAVE_INTEL_AVX1
773
            #define HAVE_INTEL_AVX1
774
        #endif
775
        #if !defined(NO_AVX2_SUPPORT) && !defined(HAVE_INTEL_AVX2)
776
            #define HAVE_INTEL_AVX2
777
        #endif
778
        #if !defined(NO_VAES_SUPPORT) && !defined(HAVE_INTEL_VAES)
779
            #define HAVE_INTEL_VAES
780
        #endif
781
        #if !defined(NO_AVX512_SUPPORT) && !defined(HAVE_INTEL_AVX512)
782
            #define HAVE_INTEL_AVX512
783
        #endif
784
785
        /* Below this threshold the narrower path (AVX1 / AES-NI) is faster on
786
         * Zen 4 than the wide VAES/AVX512 path.  Verify and tune
787
         * per-microarchecture.
788
         */
789
        #ifndef WC_VAES_MIN_BLOCKS
790
            #define WC_VAES_MIN_BLOCKS 8
791
        #elif WC_VAES_MIN_BLOCKS < 1
792
            #error Invalid WC_VAES_MIN_BLOCKS
793
        #endif
794
        /* ECB/CBC/CTR/XTS: the wide ladder handles 2+ blocks in parallel and
795
         * only caches round keys once it pays off (>= 32B), so the wide path
796
         * beats the single-block AES-NI fallback from 2 blocks up; a lone block
797
         * stays on AES-NI. (Measured +8..+58% at 2-6 blocks on Zen5.) */
798
        #ifndef WC_VAES_ECB_MIN_BLOCKS
799
            #define WC_VAES_ECB_MIN_BLOCKS 2
800
        #elif WC_VAES_ECB_MIN_BLOCKS < 1
801
            #error Invalid WC_VAES_ECB_MIN_BLOCKS
802
        #endif
803
        /* GCM one-shot: AVX2 faster than wide below this (layout/setup, not
804
         * amortization); pure GMAC (sz==0) routes to AVX2 by construction.
805
         */
806
        #ifndef WC_VAES_GCM_MIN_BLOCKS
807
            #define WC_VAES_GCM_MIN_BLOCKS WC_VAES_MIN_BLOCKS
808
        #elif WC_VAES_GCM_MIN_BLOCKS < 1
809
            #error Invalid WC_VAES_GCM_MIN_BLOCKS
810
        #endif
811
    #endif
812
813
    void AES_CTR_encrypt_AESNI(const unsigned char* in, unsigned char* out,
814
        unsigned long length, const unsigned char* KS, int nr,
815
        unsigned char* ctr) XASM_LINK("AES_CTR_encrypt_AESNI");
816
    #ifdef HAVE_AES_DECRYPT
817
    void AES_CBC_decrypt_AESNI(const unsigned char* in, unsigned char* out,
818
        unsigned char* ivec, unsigned long length, const unsigned char* KS,
819
        int nr) XASM_LINK("AES_CBC_decrypt_AESNI");
820
    #endif
821
822
    #define AES_DECL_VARIANT(suff)                                            \
823
        void AES_ECB_encrypt_##suff(const unsigned char* in,                  \
824
            unsigned char* out, unsigned long length,                         \
825
            const unsigned char* KS, int nr)                                  \
826
            XASM_LINK("AES_ECB_encrypt_" #suff);                              \
827
        void AES_CBC_encrypt_##suff(const unsigned char* in,                  \
828
            unsigned char* out, unsigned char* ivec, unsigned long length,    \
829
            const unsigned char* KS, int nr)                                  \
830
            XASM_LINK("AES_CBC_encrypt_" #suff);                              \
831
        void AES_CTR_encrypt_##suff(const unsigned char* in,                  \
832
            unsigned char* out, unsigned long length,                         \
833
            const unsigned char* KS, int nr, unsigned char* ctr)              \
834
            XASM_LINK("AES_CTR_encrypt_" #suff)
835
    #ifdef HAVE_AES_DECRYPT
836
        #define AES_DECL_VARIANT_DEC(suff)                                    \
837
            void AES_ECB_decrypt_##suff(const unsigned char* in,              \
838
                unsigned char* out, unsigned long length,                     \
839
                const unsigned char* KS, int nr)                              \
840
                XASM_LINK("AES_ECB_decrypt_" #suff);                          \
841
            void AES_CBC_decrypt_##suff(const unsigned char* in,              \
842
                unsigned char* out, unsigned char* ivec,                      \
843
                unsigned long length, const unsigned char* KS, int nr)        \
844
                XASM_LINK("AES_CBC_decrypt_" #suff)
845
    #else
846
        #define AES_DECL_VARIANT_DEC(suff) /* no decrypt */
847
    #endif
848
849
    #ifdef HAVE_INTEL_AVX1
850
        AES_DECL_VARIANT(avx1);
851
        AES_DECL_VARIANT_DEC(avx1);
852
    #endif
853
    #ifdef HAVE_INTEL_VAES
854
        AES_DECL_VARIANT(vaes);
855
        AES_DECL_VARIANT_DEC(vaes);
856
    #endif
857
    #ifdef HAVE_INTEL_AVX512
858
        AES_DECL_VARIANT(avx512);
859
        AES_DECL_VARIANT_DEC(avx512);
860
    #endif
861
862
    /* Pick the widest available implementation at runtime.  Callers must
863
     * already be inside a VECTOR_REGISTERS_PUSH / SAVE_VECTOR_REGISTERS
864
     * region (all bulk AES-NI call sites are). */
865
    #ifdef HAVE_AES_ECB
866
    static WC_INLINE void AesEcbEncryptBlocks(const unsigned char* in,
867
        unsigned char* out, word32 sz, const unsigned char* key, int nr)
868
    {
869
    #ifdef HAVE_INTEL_AVX512
870
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
871
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
872
            AES_ECB_encrypt_avx512(in, out, sz, key, nr);
873
        }
874
        else
875
    #endif
876
    #ifdef HAVE_INTEL_VAES
877
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
878
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
879
            AES_ECB_encrypt_vaes(in, out, sz, key, nr);
880
        }
881
        else
882
    #endif
883
    #ifdef HAVE_INTEL_AVX1
884
        if (IS_INTEL_AVX1(intel_flags)) {
885
            AES_ECB_encrypt_avx1(in, out, sz, key, nr);
886
        }
887
        else
888
    #endif
889
        {
890
            AES_ECB_encrypt_AESNI(in, out, sz, key, nr);
891
        }
892
    }
893
    #endif /* HAVE_AES_ECB */
894
895
    #if defined(HAVE_AES_ECB) && defined(HAVE_AES_DECRYPT)
896
    static WC_INLINE void AesEcbDecryptBlocks(const unsigned char* in,
897
        unsigned char* out, word32 sz, const unsigned char* key, int nr)
898
    {
899
    #ifdef HAVE_INTEL_AVX512
900
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
901
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
902
            AES_ECB_decrypt_avx512(in, out, sz, key, nr);
903
        }
904
        else
905
    #endif
906
    #ifdef HAVE_INTEL_VAES
907
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
908
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
909
            AES_ECB_decrypt_vaes(in, out, sz, key, nr);
910
        }
911
        else
912
    #endif
913
    #ifdef HAVE_INTEL_AVX1
914
        if (IS_INTEL_AVX1(intel_flags)) {
915
            AES_ECB_decrypt_avx1(in, out, sz, key, nr);
916
        }
917
        else
918
    #endif
919
        {
920
            AES_ECB_decrypt_AESNI(in, out, sz, key, nr);
921
        }
922
    }
923
    #endif /* HAVE_AES_ECB && HAVE_AES_DECRYPT */
924
925
    #ifdef HAVE_AES_CBC
926
    static WC_MAYBE_UNUSED WC_INLINE void AesCbcEncryptBlocks(const unsigned char* in,
927
        unsigned char* out, unsigned char* iv, word32 sz,
928
        const unsigned char* key, int nr)
929
    {
930
    #ifdef HAVE_INTEL_AVX512
931
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
932
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
933
            AES_CBC_encrypt_avx512(in, out, iv, sz, key, nr);
934
        }
935
        else
936
    #endif
937
    #ifdef HAVE_INTEL_VAES
938
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
939
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
940
            AES_CBC_encrypt_vaes(in, out, iv, sz, key, nr);
941
        }
942
        else
943
    #endif
944
    #ifdef HAVE_INTEL_AVX1
945
        if (IS_INTEL_AVX1(intel_flags)) {
946
            AES_CBC_encrypt_avx1(in, out, iv, sz, key, nr);
947
        }
948
        else
949
    #endif
950
        {
951
            AES_CBC_encrypt_AESNI(in, out, iv, sz, key, nr);
952
        }
953
    }
954
    #endif /* HAVE_AES_CBC */
955
956
    #ifdef HAVE_AES_DECRYPT
957
    static WC_MAYBE_UNUSED WC_INLINE void AesCbcDecryptBlocks(const unsigned char* in,
958
        unsigned char* out, unsigned char* iv, word32 sz,
959
        const unsigned char* key, int nr)
960
    {
961
    #ifdef HAVE_INTEL_AVX512
962
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
963
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
964
            AES_CBC_decrypt_avx512(in, out, iv, sz, key, nr);
965
        }
966
        else
967
    #endif
968
    #ifdef HAVE_INTEL_VAES
969
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
970
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
971
            AES_CBC_decrypt_vaes(in, out, iv, sz, key, nr);
972
        }
973
        else
974
    #endif
975
    #ifdef HAVE_INTEL_AVX1
976
        if (IS_INTEL_AVX1(intel_flags)) {
977
            AES_CBC_decrypt_avx1(in, out, iv, sz, key, nr);
978
        }
979
        else
980
    #endif
981
        {
982
            AES_CBC_decrypt_AESNI(in, out, iv, sz, key, nr);
983
        }
984
    }
985
    #endif /* HAVE_AES_DECRYPT */
986
987
    #ifdef WOLFSSL_AES_COUNTER
988
    static WC_INLINE void AesCtrEncryptBlocks(const unsigned char* in,
989
        unsigned char* out, word32 sz, const unsigned char* key, int nr,
990
        unsigned char* ctr)
991
    {
992
    #ifdef HAVE_INTEL_AVX512
993
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
994
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
995
            AES_CTR_encrypt_avx512(in, out, sz, key, nr, ctr);
996
        }
997
        else
998
    #endif
999
    #ifdef HAVE_INTEL_VAES
1000
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_ECB_MIN_BLOCKS) &&
1001
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
1002
            AES_CTR_encrypt_vaes(in, out, sz, key, nr, ctr);
1003
        }
1004
        else
1005
    #endif
1006
    #ifdef HAVE_INTEL_AVX1
1007
        if (IS_INTEL_AVX1(intel_flags)) {
1008
            AES_CTR_encrypt_avx1(in, out, sz, key, nr, ctr);
1009
        }
1010
        else
1011
    #endif
1012
        {
1013
            AES_CTR_encrypt_AESNI(in, out, sz, key, nr, ctr);
1014
        }
1015
    }
1016
    #endif /* WOLFSSL_AES_COUNTER */
1017
#endif /* WOLFSSL_X86_64_BUILD */
1018
1019
1020
    static WARN_UNUSED_RESULT int AES_set_encrypt_key_AESNI(
1021
        const unsigned char *userKey, const int bits, Aes* aes)
1022
    {
1023
        int ret;
1024
1025
        ASSERT_SAVED_VECTOR_REGISTERS();
1026
1027
        if (!userKey || !aes)
1028
            return BAD_FUNC_ARG;
1029
1030
        switch (bits) {
1031
            case 128:
1032
               AES_128_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 10;
1033
               return 0;
1034
            case 192:
1035
               AES_192_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 12;
1036
               return 0;
1037
            case 256:
1038
               AES_256_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 14;
1039
               return 0;
1040
            default:
1041
                ret = BAD_FUNC_ARG;
1042
        }
1043
1044
        return ret;
1045
    }
1046
1047
    #ifdef HAVE_AES_DECRYPT
1048
        static WARN_UNUSED_RESULT int AES_set_decrypt_key_AESNI(
1049
            const unsigned char* userKey, const int bits, Aes* aes)
1050
        {
1051
            word32 nr;
1052
            WC_DECLARE_VAR(temp_key, Aes, 1, 0);
1053
            __m128i *Key_Schedule;
1054
            __m128i *Temp_Key_Schedule;
1055
1056
            ASSERT_SAVED_VECTOR_REGISTERS();
1057
1058
            if (!userKey || !aes)
1059
                return BAD_FUNC_ARG;
1060
1061
#ifdef WOLFSSL_SMALL_STACK
1062
            if ((temp_key = (Aes *)XMALLOC(sizeof *aes, aes->heap,
1063
                                           DYNAMIC_TYPE_AES)) == NULL)
1064
                return MEMORY_E;
1065
#endif
1066
1067
            if (AES_set_encrypt_key_AESNI(userKey,bits,temp_key)
1068
                == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
1069
                WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
1070
                return BAD_FUNC_ARG;
1071
            }
1072
1073
            Key_Schedule = (__m128i*)aes->key;
1074
            Temp_Key_Schedule = (__m128i*)temp_key->key;
1075
1076
            nr = temp_key->rounds;
1077
            aes->rounds = nr;
1078
1079
            Key_Schedule[nr] = Temp_Key_Schedule[0];
1080
            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
1081
            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
1082
            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
1083
            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
1084
            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
1085
            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
1086
            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
1087
            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
1088
            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
1089
1090
            if (nr>10) {
1091
                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
1092
                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
1093
            }
1094
1095
            if (nr>12) {
1096
                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
1097
                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
1098
            }
1099
1100
            Key_Schedule[0] = Temp_Key_Schedule[nr];
1101
1102
            WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
1103
1104
            return 0;
1105
        }
1106
    #endif /* HAVE_AES_DECRYPT */
1107
1108
#elif defined(WOLFSSL_ARMASM)
1109
/* WOLFSSL_ARM32_AES_DISPATCH - run-time selection between the base and the
1110
 * crypto-extension AES on 32-bit Arm - is defined at the top of this file.  See
1111
 * WOLFSSL_ARM32_AES_HW_FLAGS in aes.h for how the two relate. */
1112
1113
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1114
static cpuid_flags_t cpuid_flags = WC_CPUID_INITIALIZER;
1115
1116
static void Check_CPU_support_HwCrypto(Aes* aes)
1117
{
1118
    if (cpuid_flags == WC_CPUID_INITIALIZER)
1119
        cpuid_get_flags_ex(&cpuid_flags);
1120
    aes->use_aes_hw_crypto = IS_AARCH64_AES(cpuid_flags);
1121
#ifdef HAVE_AESGCM
1122
    aes->use_pmull_hw_crypto = IS_AARCH64_PMULL(cpuid_flags);
1123
    aes->use_sha3_hw_crypto = IS_AARCH64_SHA3(cpuid_flags);
1124
#endif
1125
}
1126
#elif defined(WOLFSSL_ARM32_AES_DISPATCH)
1127
static cpuid_flags_t cpuid_flags = WC_CPUID_INITIALIZER;
1128
1129
/* Record on the Aes object whether this CPU implements the Armv8 AES and PMULL
1130
 * crypto-extension instructions, so the per-operation code can select the
1131
 * crypto or the base assembly at run time.  Called from key setup.
1132
 *
1133
 * @param [in, out] aes  AES object whose use_aes_hw_crypto /
1134
 *                       use_pmull_hw_crypto flags are set. */
1135
static void Check_CPU_support_HwCrypto(Aes* aes)
1136
{
1137
    if (cpuid_flags == WC_CPUID_INITIALIZER)
1138
        cpuid_get_flags_ex(&cpuid_flags);
1139
#ifdef HAVE_AESGCM
1140
    aes->use_pmull_hw_crypto = IS_ARM32_PMULL(cpuid_flags);
1141
    /* The crypto and base AES key schedules are incompatible.  When PMULL is
1142
     * absent, AES-GCM (and AES-GCM-SIV) fall back to the base (software) path,
1143
     * which drives its AES through the base AES_ECB_encrypt and so needs the
1144
     * base key schedule.  Only take the crypto AES path when PMULL is present
1145
     * too, so the whole cipher stays consistent.  (A CPU implementing AES but
1146
     * not PMULL is rare - the crypto extension provides them together.) */
1147
    aes->use_aes_hw_crypto = IS_ARM32_AES(cpuid_flags) &&
1148
                             aes->use_pmull_hw_crypto;
1149
#else
1150
    aes->use_aes_hw_crypto = IS_ARM32_AES(cpuid_flags);
1151
#endif
1152
}
1153
#endif /* (__aarch64__ && !WOLFSSL_ARMASM_NO_HW_CRYPTO) ||
1154
        * WOLFSSL_ARM32_AES_DISPATCH */
1155
1156
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
1157
    defined(WOLFSSL_AESGCM_STREAM) || defined(WOLFSSL_AESGCM_SIV)
1158
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
1159
    byte* outBlock)
1160
{
1161
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
1162
#if !defined(__aarch64__)
1163
#ifdef WOLFSSL_ARM32_AES_DISPATCH
1164
    if (aes->use_aes_hw_crypto) {
1165
        AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key,
1166
            (int)aes->rounds);
1167
    }
1168
    else
1169
#else
1170
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1171
#endif /* WOLFSSL_ARM32_AES_DISPATCH */
1172
#else
1173
    if (aes->use_aes_hw_crypto) {
1174
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
1175
           (int)aes->rounds);
1176
    }
1177
    else
1178
#endif /* !__aarch64__ */
1179
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
1180
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
1181
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
1182
    {
1183
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
1184
            (const unsigned char*)aes->key, aes->rounds);
1185
    }
1186
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
1187
      defined(WOLFSSL_ARM32_AES_DISPATCH)
1188
    {
1189
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1190
            (int)aes->rounds);
1191
    }
1192
#endif
1193
1194
    return 0;
1195
}
1196
#endif
1197
1198
#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1199
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
1200
    byte* outBlock)
1201
{
1202
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
1203
#if !defined(__aarch64__)
1204
#ifdef WOLFSSL_ARM32_AES_DISPATCH
1205
    if (aes->use_aes_hw_crypto) {
1206
        AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key,
1207
            (int)aes->rounds);
1208
    }
1209
    else
1210
#else
1211
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1212
#endif /* WOLFSSL_ARM32_AES_DISPATCH */
1213
#else
1214
    if (aes->use_aes_hw_crypto) {
1215
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
1216
            (int)aes->rounds);
1217
    }
1218
    else
1219
#endif /* !__aarch64__ */
1220
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
1221
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
1222
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
1223
    {
1224
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
1225
            (byte*)aes->key, (int)aes->rounds);
1226
    }
1227
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
1228
      defined(WOLFSSL_ARM32_AES_DISPATCH)
1229
    {
1230
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1231
            (int)aes->rounds);
1232
    }
1233
#endif
1234
    return 0;
1235
}
1236
#endif /* HAVE_AES_DECRYPT && WOLFSSL_AES_DIRECT */
1237
1238
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
1239
1240
#if defined(WOLFSSL_PPC64_ASM) && defined(WOLFSSL_PPC64_ASM_CRYPTO)
1241
/* POWER8+ has vector AES (vcipher/vncipher...) instructions.  When built in,
1242
 * select the "_crypto" implementations at run time if the CPU supports them.
1243
 *
1244
 * A run-time flag with direct calls is used rather than a function pointer: an
1245
 * indirect call would require an ELFv1 function descriptor, whereas direct
1246
 * calls work under both the ELFv1 and ELFv2 ABIs.  The dispatch is expressed as
1247
 * self-referential macros - the base name inside each macro is not re-expanded
1248
 * (C99 6.10.3.4), so it names the real base function.  In a PPC build the ARM
1249
 * branches that also call these names are #if'd out, so only the live PPC call
1250
 * sites are redirected. */
1251
1252
/* Resolved dispatch decision (0 = base, 1 = vector-crypto).  The write here is
1253
 * idempotent so a benign concurrent double-write is harmless.  Avoid atomic for
1254
 * this, as for intel_flags above, to avoid unnecessary expensive reads. */
1255
static int aes_ppc64_use_crypto = 0;
1256
1257
/* True when the CPU supports the vector-crypto instructions. */
1258
#define AES_PPC64_USE_CRYPTO()   (aes_ppc64_use_crypto != 0)
1259
1260
/* Check and set the decision together (as Check_CPU_support_AES/HwCrypto do);
1261
 * called from the key-setup path before any AES_*_crypto use. */
1262
static void Aes_SetCrypto(void)
1263
{
1264
    static cpuid_flags_t cpu_flags = WC_CPUID_INITIALIZER;
1265
    if (cpu_flags == WC_CPUID_INITIALIZER)
1266
        cpuid_get_flags_ex(&cpu_flags);
1267
    aes_ppc64_use_crypto = (IS_PPC64_VEC_CRYPTO(cpu_flags) != 0);
1268
}
1269
1270
#define AES_set_encrypt_key(key, len, ks)                                     \
1271
    (AES_PPC64_USE_CRYPTO() ?                                               \
1272
        AES_set_encrypt_key_crypto((key), (len), (ks)) :                      \
1273
        AES_set_encrypt_key((key), (len), (ks)))
1274
#define AES_invert_key(ks, rounds)                                            \
1275
    (AES_PPC64_USE_CRYPTO() ?                                               \
1276
        AES_invert_key_crypto((ks), (rounds)) :                              \
1277
        AES_invert_key((ks), (rounds)))
1278
#define AES_ECB_encrypt(in, out, len, ks, nr)                                 \
1279
    (AES_PPC64_USE_CRYPTO() ?                                               \
1280
        AES_ECB_encrypt_crypto((in), (out), (len), (ks), (nr)) :              \
1281
        AES_ECB_encrypt((in), (out), (len), (ks), (nr)))
1282
#define AES_ECB_decrypt(in, out, len, ks, nr)                                 \
1283
    (AES_PPC64_USE_CRYPTO() ?                                               \
1284
        AES_ECB_decrypt_crypto((in), (out), (len), (ks), (nr)) :              \
1285
        AES_ECB_decrypt((in), (out), (len), (ks), (nr)))
1286
#define AES_CBC_encrypt(in, out, len, ks, nr, iv)                             \
1287
    (AES_PPC64_USE_CRYPTO() ?                                               \
1288
        AES_CBC_encrypt_crypto((in), (out), (len), (ks), (nr), (iv)) :        \
1289
        AES_CBC_encrypt((in), (out), (len), (ks), (nr), (iv)))
1290
#define AES_CBC_decrypt(in, out, len, ks, nr, iv)                             \
1291
    (AES_PPC64_USE_CRYPTO() ?                                               \
1292
        AES_CBC_decrypt_crypto((in), (out), (len), (ks), (nr), (iv)) :        \
1293
        AES_CBC_decrypt((in), (out), (len), (ks), (nr), (iv)))
1294
#define AES_CTR_encrypt(in, out, len, ks, nr, ctr)                            \
1295
    (AES_PPC64_USE_CRYPTO() ?                                               \
1296
        AES_CTR_encrypt_crypto((in), (out), (len), (ks), (nr), (ctr)) :       \
1297
        AES_CTR_encrypt((in), (out), (len), (ks), (nr), (ctr)))
1298
#define AES_GCM_encrypt(in, out, len, ks, nr, ctr)                            \
1299
    (AES_PPC64_USE_CRYPTO() ?                                               \
1300
        AES_GCM_encrypt_crypto((in), (out), (len), (ks), (nr), (ctr)) :       \
1301
        AES_GCM_encrypt((in), (out), (len), (ks), (nr), (ctr)))
1302
#if defined(WOLFSSL_AES_XTS)
1303
#define AES_XTS_encrypt(in, out, sz, i, key, key2, tmp, nr)                   \
1304
    (AES_PPC64_USE_CRYPTO() ?                                               \
1305
        AES_XTS_encrypt_crypto((in), (out), (sz), (i), (key), (key2), (tmp),  \
1306
            (nr)) :                                                           \
1307
        AES_XTS_encrypt((in), (out), (sz), (i), (key), (key2), (tmp), (nr)))
1308
#define AES_XTS_decrypt(in, out, sz, i, key, key2, tmp, nr)                   \
1309
    (AES_PPC64_USE_CRYPTO() ?                                               \
1310
        AES_XTS_decrypt_crypto((in), (out), (sz), (i), (key), (key2), (tmp),  \
1311
            (nr)) :                                                           \
1312
        AES_XTS_decrypt((in), (out), (sz), (i), (key), (key2), (tmp), (nr)))
1313
#endif /* WOLFSSL_AES_XTS */
1314
#else
1315
#define Aes_SetCrypto()                 WC_DO_NOTHING
1316
#endif /* WOLFSSL_PPC64_ASM && WOLFSSL_PPC64_ASM_CRYPTO */
1317
1318
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
1319
    defined(WOLFSSL_AESGCM_STREAM) || defined(HAVE_AESGCM)
1320
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
1321
    byte* outBlock)
1322
{
1323
    AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1324
        (int)aes->rounds);
1325
1326
    return 0;
1327
}
1328
#endif
1329
1330
#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1331
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
1332
    byte* outBlock)
1333
{
1334
    AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
1335
        (int)aes->rounds);
1336
    return 0;
1337
}
1338
#endif /* HAVE_AES_DECRYPT && WOLFSSL_AES_DIRECT */
1339
1340
#elif defined(FREESCALE_MMCAU)
1341
    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
1342
     * through the CAU/mmCAU library. Documentation located in
1343
     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
1344
     * Guide (See note in README). */
1345
    #ifdef FREESCALE_MMCAU_CLASSIC
1346
        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
1347
        #include "cau_api.h"
1348
    #else
1349
        #include "fsl_mmcau.h"
1350
    #endif
1351
1352
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1353
        Aes* aes, const byte* inBlock, byte* outBlock)
1354
    {
1355
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1356
        {
1357
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1358
            if (ret < 0)
1359
                return ret;
1360
        }
1361
#endif
1362
1363
    #ifdef FREESCALE_MMCAU_CLASSIC
1364
        if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1365
            WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
1366
            return BAD_ALIGN_E;
1367
        }
1368
    #endif
1369
1370
        if (wolfSSL_CryptHwMutexLock() == 0) {
1371
        #ifdef FREESCALE_MMCAU_CLASSIC
1372
            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1373
        #else
1374
            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1375
                                 outBlock);
1376
        #endif
1377
            wolfSSL_CryptHwMutexUnLock();
1378
        }
1379
        return 0;
1380
    }
1381
    #ifdef HAVE_AES_DECRYPT
1382
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1383
        Aes* aes, const byte* inBlock, byte* outBlock)
1384
    {
1385
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1386
        {
1387
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1388
            if (ret < 0)
1389
                return ret;
1390
        }
1391
#endif
1392
    #ifdef FREESCALE_MMCAU_CLASSIC
1393
        if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1394
            WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
1395
            return BAD_ALIGN_E;
1396
        }
1397
    #endif
1398
1399
        if (wolfSSL_CryptHwMutexLock() == 0) {
1400
        #ifdef FREESCALE_MMCAU_CLASSIC
1401
            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1402
        #else
1403
            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1404
                                 outBlock);
1405
        #endif
1406
            wolfSSL_CryptHwMutexUnLock();
1407
        }
1408
        return 0;
1409
    }
1410
    #endif /* HAVE_AES_DECRYPT */
1411
1412
#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
1413
        && !defined(WOLFSSL_QNX_CAAM)) || \
1414
      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
1415
        defined(HAVE_AESCCM))
1416
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1417
            Aes* aes, const byte* inBlock, byte* outBlock)
1418
        {
1419
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1420
            {
1421
                int ret =
1422
                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1423
                if (ret < 0)
1424
                    return ret;
1425
            }
1426
#endif
1427
            return wc_AesEncryptDirect(aes, outBlock, inBlock);
1428
        }
1429
1430
#elif defined(WOLFSSL_AFALG)
1431
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
1432
1433
#elif defined(WOLFSSL_DEVCRYPTO_AES)
1434
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
1435
1436
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
1437
    #include "hal_data.h"
1438
1439
    #ifndef WOLFSSL_SCE_AES256_HANDLE
1440
        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
1441
    #endif
1442
1443
    #ifndef WOLFSSL_SCE_AES192_HANDLE
1444
        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
1445
    #endif
1446
1447
    #ifndef WOLFSSL_SCE_AES128_HANDLE
1448
        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
1449
    #endif
1450
1451
    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
1452
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1453
    {
1454
        word32 ret = SSP_SUCCESS;
1455
        /* The SCE driver needs 32-bit words: stage the caller's byte
1456
         * buffers through aligned locals, leaving the input untouched. */
1457
        word32 in32[WC_AES_BLOCK_SIZE / sizeof(word32)];
1458
        word32 out32[WC_AES_BLOCK_SIZE / sizeof(word32)];
1459
        int bigEndian = (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1460
                CRYPTO_WORD_ENDIAN_BIG);
1461
        int i;
1462
1463
        if ((sz % WC_AES_BLOCK_SIZE) != 0) {
1464
            return BAD_FUNC_ARG;
1465
        }
1466
1467
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
1468
            XMEMCPY(in32, inBlock + i, WC_AES_BLOCK_SIZE);
1469
            if (bigEndian) {
1470
                ByteReverseWords(in32, in32, WC_AES_BLOCK_SIZE);
1471
            }
1472
1473
            switch (aes->keylen) {
1474
        #ifdef WOLFSSL_AES_128
1475
                case AES_128_KEY_SIZE:
1476
                    ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
1477
                            WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, NULL,
1478
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1479
                    break;
1480
        #endif
1481
        #ifdef WOLFSSL_AES_192
1482
                case AES_192_KEY_SIZE:
1483
                    ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
1484
                            WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, NULL,
1485
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1486
                    break;
1487
        #endif
1488
        #ifdef WOLFSSL_AES_256
1489
                case AES_256_KEY_SIZE:
1490
                    ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
1491
                            WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, NULL,
1492
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1493
                    break;
1494
        #endif
1495
                default:
1496
                    WOLFSSL_MSG("Unknown key size");
1497
                    return BAD_FUNC_ARG;
1498
            }
1499
1500
            if (ret != SSP_SUCCESS) {
1501
                return WC_HW_E;
1502
            }
1503
1504
            if (bigEndian) {
1505
                ByteReverseWords(out32, out32, WC_AES_BLOCK_SIZE);
1506
            }
1507
            XMEMCPY(outBlock + i, out32, WC_AES_BLOCK_SIZE);
1508
        }
1509
1510
        return 0;
1511
    }
1512
1513
    #if defined(HAVE_AES_DECRYPT)
1514
    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
1515
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1516
    {
1517
        word32 ret = SSP_SUCCESS;
1518
        /* The SCE driver needs 32-bit words: stage the caller's byte
1519
         * buffers through aligned locals, leaving the input untouched. */
1520
        word32 in32[WC_AES_BLOCK_SIZE / sizeof(word32)];
1521
        word32 out32[WC_AES_BLOCK_SIZE / sizeof(word32)];
1522
        int bigEndian = (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1523
                CRYPTO_WORD_ENDIAN_BIG);
1524
        int i;
1525
1526
        if ((sz % WC_AES_BLOCK_SIZE) != 0) {
1527
            return BAD_FUNC_ARG;
1528
        }
1529
1530
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
1531
            XMEMCPY(in32, inBlock + i, WC_AES_BLOCK_SIZE);
1532
            if (bigEndian) {
1533
                ByteReverseWords(in32, in32, WC_AES_BLOCK_SIZE);
1534
            }
1535
1536
            switch (aes->keylen) {
1537
        #ifdef WOLFSSL_AES_128
1538
                case AES_128_KEY_SIZE:
1539
                    ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
1540
                            WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
1541
                            aes->reg,
1542
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1543
                    break;
1544
        #endif
1545
        #ifdef WOLFSSL_AES_192
1546
                case AES_192_KEY_SIZE:
1547
                    ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
1548
                            WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
1549
                            aes->reg,
1550
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1551
                    break;
1552
        #endif
1553
        #ifdef WOLFSSL_AES_256
1554
                case AES_256_KEY_SIZE:
1555
                    ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
1556
                            WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
1557
                            aes->reg,
1558
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1559
                    break;
1560
        #endif
1561
                default:
1562
                    WOLFSSL_MSG("Unknown key size");
1563
                    return BAD_FUNC_ARG;
1564
            }
1565
1566
            if (ret != SSP_SUCCESS) {
1567
                return WC_HW_E;
1568
            }
1569
1570
            if (bigEndian) {
1571
                ByteReverseWords(out32, out32, WC_AES_BLOCK_SIZE);
1572
            }
1573
            XMEMCPY(outBlock + i, out32, WC_AES_BLOCK_SIZE);
1574
        }
1575
1576
        return 0;
1577
    }
1578
    #endif /* HAVE_AES_DECRYPT */
1579
1580
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
1581
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1582
        Aes* aes, const byte* inBlock, byte* outBlock)
1583
    {
1584
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1585
        {
1586
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1587
            if (ret < 0)
1588
                return ret;
1589
        }
1590
#endif
1591
        return AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1592
    }
1593
    #endif
1594
1595
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1596
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1597
        Aes* aes, const byte* inBlock, byte* outBlock)
1598
    {
1599
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1600
        {
1601
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1602
            if (ret < 0)
1603
                return ret;
1604
        }
1605
#endif
1606
        return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1607
    }
1608
    #endif
1609
1610
#elif defined(WOLFSSL_KCAPI_AES)
1611
    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
1612
    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
1613
        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1614
        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
1615
        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
1616
        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
1617
1618
        #define NEED_AES_TABLES
1619
    #endif
1620
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
1621
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
1622
1623
#elif defined(WOLFSSL_RISCV_ASM)
1624
/* Block cipher implemented by the generated RISC-V assembly
1625
 * (riscv-64-aes-asm.S / _c.c). The key schedule is wired in wc_AesSetKeyLocal.
1626
 * Vector-crypto overrides the bulk modes (ECB/CBC/CTR/GCM/XTS) with asm; scalar
1627
 * and base run the common-C modes over these single-block primitives, so the
1628
 * block routine is needed whenever a common-C mode (or Direct/CCM/GCM-stream)
1629
 * is built. */
1630
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
1631
    defined(WOLFSSL_AESGCM_STREAM) || defined(HAVE_AESGCM) || \
1632
    defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) || \
1633
    defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_XTS) || \
1634
    defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1635
    defined(WOLFSSL_AES_CFB)
1636
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
1637
    byte* outBlock)
1638
{
1639
    AES_encrypt_RISCV64(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1640
    return 0;
1641
}
1642
#endif
1643
1644
#if defined(HAVE_AES_DECRYPT) && (defined(WOLFSSL_AES_DIRECT) || \
1645
    defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
1646
    defined(WOLFSSL_AES_XTS) || defined(HAVE_AESCCM))
1647
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
1648
    byte* outBlock)
1649
{
1650
    AES_decrypt_RISCV64(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1651
    return 0;
1652
}
1653
#endif
1654
1655
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1656
/* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
1657
1658
#elif defined(WOLFSSL_PSOC6_CRYPTO)
1659
1660
    #if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
1661
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1662
            Aes* aes, const byte* inBlock, byte* outBlock)
1663
        {
1664
            return wc_Psoc6_Aes_Encrypt(aes, inBlock, outBlock);
1665
        }
1666
    #endif
1667
1668
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1669
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
1670
            Aes* aes, const byte* inBlock, byte* outBlock)
1671
        {
1672
            return wc_Psoc6_Aes_Decrypt(aes, inBlock, outBlock);
1673
        }
1674
1675
    #endif
1676
#elif defined(WOLF_CRYPTO_CB_ONLY_AES)
1677
    /* No software implementation AES T-tables, S-box, Rcon and the C key
1678
     * schedule are stripped. */
1679
#else
1680
1681
    /* using wolfCrypt software implementation */
1682
    #define NEED_AES_TABLES
1683
#endif
1684
1685
1686
1687
#if defined(WC_AES_BITSLICED) && !defined(HAVE_AES_ECB)
1688
    #error "When WC_AES_BITSLICED is defined, HAVE_AES_ECB is needed."
1689
#endif
1690
1691
#ifdef NEED_AES_TABLES
1692
1693
#ifndef WC_AES_BITSLICED
1694
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1695
#if !defined(WOLFSSL_ESP32_CRYPT) || \
1696
    (defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
1697
     defined(NEED_AES_HW_FALLBACK))
1698
#ifndef WOLFSSL_PPC64_ASM
1699
static const FLASH_QUALIFIER word32 rcon[] = {
1700
    0x01000000, 0x02000000, 0x04000000, 0x08000000,
1701
    0x10000000, 0x20000000, 0x40000000, 0x80000000,
1702
    0x1B000000, 0x36000000,
1703
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1704
};
1705
#endif
1706
#endif /* ESP32 */
1707
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1708
1709
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
1710
      defined(HAVE_AESCCM)
1711
#ifndef WOLFSSL_AES_SMALL_TABLES
1712
static const FLASH_QUALIFIER word32 Te[4][256] = {
1713
{
1714
    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1715
    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1716
    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1717
    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1718
    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1719
    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1720
    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1721
    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1722
    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1723
    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1724
    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1725
    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1726
    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1727
    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1728
    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1729
    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1730
    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1731
    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1732
    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1733
    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1734
    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1735
    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1736
    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1737
    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1738
    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1739
    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1740
    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1741
    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1742
    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1743
    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1744
    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1745
    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1746
    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1747
    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1748
    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1749
    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1750
    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1751
    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1752
    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1753
    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1754
    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1755
    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1756
    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1757
    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1758
    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1759
    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1760
    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1761
    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1762
    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1763
    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1764
    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1765
    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1766
    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1767
    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1768
    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1769
    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1770
    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1771
    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1772
    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1773
    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1774
    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1775
    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1776
    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1777
    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1778
},
1779
{
1780
    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1781
    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1782
    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1783
    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1784
    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1785
    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1786
    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1787
    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1788
    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1789
    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1790
    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1791
    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1792
    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1793
    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1794
    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1795
    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1796
    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1797
    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1798
    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1799
    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1800
    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1801
    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1802
    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1803
    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1804
    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1805
    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1806
    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1807
    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1808
    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1809
    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1810
    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1811
    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1812
    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1813
    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1814
    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1815
    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1816
    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1817
    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1818
    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1819
    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1820
    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1821
    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1822
    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1823
    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1824
    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1825
    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1826
    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1827
    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1828
    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1829
    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1830
    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1831
    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1832
    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1833
    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1834
    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1835
    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1836
    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1837
    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1838
    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1839
    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1840
    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1841
    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1842
    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1843
    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1844
},
1845
{
1846
    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1847
    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1848
    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1849
    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1850
    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1851
    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1852
    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1853
    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1854
    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1855
    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1856
    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1857
    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1858
    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1859
    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1860
    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1861
    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1862
    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1863
    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1864
    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1865
    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1866
    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1867
    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1868
    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1869
    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1870
    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1871
    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1872
    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1873
    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1874
    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1875
    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1876
    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1877
    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1878
    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1879
    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1880
    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1881
    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1882
    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1883
    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1884
    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1885
    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1886
    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1887
    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1888
    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1889
    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1890
    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1891
    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1892
    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1893
    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1894
    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1895
    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1896
    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1897
    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1898
    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1899
    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1900
    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1901
    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1902
    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1903
    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1904
    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1905
    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1906
    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1907
    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1908
    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1909
    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1910
},
1911
{
1912
    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1913
    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1914
    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1915
    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1916
    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1917
    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1918
    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1919
    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1920
    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1921
    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1922
    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1923
    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1924
    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1925
    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1926
    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1927
    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1928
    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1929
    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1930
    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1931
    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1932
    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1933
    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1934
    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1935
    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1936
    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1937
    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1938
    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1939
    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1940
    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1941
    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1942
    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1943
    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1944
    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1945
    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1946
    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1947
    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1948
    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1949
    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1950
    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1951
    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1952
    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1953
    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1954
    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1955
    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1956
    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1957
    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1958
    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1959
    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1960
    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1961
    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1962
    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1963
    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1964
    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1965
    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1966
    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1967
    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1968
    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1969
    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1970
    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1971
    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1972
    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1973
    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1974
    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1975
    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1976
}
1977
};
1978
1979
#ifdef HAVE_AES_DECRYPT
1980
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1981
static const FLASH_QUALIFIER word32 Td[4][256] = {
1982
{
1983
    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1984
    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1985
    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1986
    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1987
    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1988
    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1989
    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1990
    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1991
    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1992
    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1993
    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1994
    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1995
    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1996
    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1997
    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1998
    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1999
    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
2000
    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
2001
    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
2002
    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
2003
    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
2004
    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
2005
    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
2006
    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
2007
    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
2008
    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
2009
    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
2010
    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
2011
    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
2012
    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
2013
    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
2014
    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
2015
    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
2016
    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
2017
    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
2018
    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
2019
    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
2020
    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
2021
    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
2022
    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
2023
    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
2024
    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
2025
    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
2026
    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
2027
    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
2028
    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
2029
    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
2030
    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
2031
    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
2032
    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
2033
    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
2034
    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
2035
    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
2036
    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
2037
    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
2038
    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
2039
    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
2040
    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
2041
    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
2042
    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
2043
    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
2044
    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
2045
    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
2046
    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
2047
},
2048
{
2049
    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
2050
    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
2051
    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
2052
    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
2053
    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
2054
    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
2055
    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
2056
    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
2057
    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
2058
    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
2059
    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
2060
    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
2061
    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
2062
    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
2063
    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
2064
    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
2065
    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
2066
    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
2067
    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
2068
    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
2069
    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
2070
    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
2071
    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
2072
    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
2073
    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
2074
    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
2075
    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
2076
    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
2077
    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
2078
    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
2079
    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
2080
    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
2081
    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
2082
    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
2083
    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
2084
    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
2085
    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
2086
    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
2087
    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
2088
    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
2089
    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
2090
    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
2091
    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
2092
    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
2093
    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
2094
    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
2095
    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
2096
    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
2097
    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
2098
    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
2099
    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
2100
    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
2101
    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
2102
    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
2103
    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
2104
    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
2105
    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
2106
    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
2107
    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
2108
    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
2109
    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
2110
    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
2111
    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
2112
    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
2113
},
2114
{
2115
    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
2116
    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
2117
    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
2118
    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
2119
    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
2120
    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
2121
    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
2122
    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
2123
    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
2124
    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
2125
    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
2126
    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
2127
    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
2128
    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
2129
    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
2130
    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
2131
    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
2132
    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
2133
    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
2134
    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
2135
2136
    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
2137
    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
2138
    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
2139
    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
2140
    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
2141
    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
2142
    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
2143
    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
2144
    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
2145
    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
2146
    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
2147
    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
2148
    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
2149
    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
2150
    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
2151
    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
2152
    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
2153
    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
2154
    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
2155
    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
2156
    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
2157
    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
2158
    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
2159
    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
2160
    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
2161
    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
2162
    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
2163
    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
2164
    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
2165
    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
2166
    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
2167
    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
2168
    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
2169
    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
2170
    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
2171
    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
2172
    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
2173
    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
2174
    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
2175
    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
2176
    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
2177
    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
2178
    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
2179
    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
2180
},
2181
{
2182
    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
2183
    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
2184
    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
2185
    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
2186
    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
2187
    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
2188
    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
2189
    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
2190
    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
2191
    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
2192
    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
2193
    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
2194
    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
2195
    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
2196
    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
2197
    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
2198
    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
2199
    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
2200
    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
2201
    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
2202
    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
2203
    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
2204
    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
2205
    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
2206
    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
2207
    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
2208
    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
2209
    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
2210
    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
2211
    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
2212
    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
2213
    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
2214
    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
2215
    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
2216
    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
2217
    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
2218
    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
2219
    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
2220
    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
2221
    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
2222
    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
2223
    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
2224
    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
2225
    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
2226
    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
2227
    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
2228
    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
2229
    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
2230
    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
2231
    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
2232
    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
2233
    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
2234
    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
2235
    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
2236
    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
2237
    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
2238
    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
2239
    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
2240
    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
2241
    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
2242
    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
2243
    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
2244
    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
2245
    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
2246
}
2247
};
2248
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
2249
#endif /* HAVE_AES_DECRYPT */
2250
#endif /* WOLFSSL_AES_SMALL_TABLES */
2251
2252
#ifdef HAVE_AES_DECRYPT
2253
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
2254
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)
2255
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
2256
static const FLASH_QUALIFIER byte Td4[256] =
2257
{
2258
    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
2259
    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
2260
    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
2261
    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
2262
    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
2263
    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
2264
    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
2265
    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
2266
    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
2267
    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
2268
    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
2269
    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
2270
    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
2271
    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
2272
    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
2273
    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
2274
    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
2275
    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
2276
    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
2277
    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
2278
    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
2279
    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
2280
    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
2281
    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
2282
    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
2283
    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
2284
    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
2285
    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
2286
    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
2287
    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
2288
    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
2289
    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
2290
};
2291
#endif
2292
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
2293
#endif /* HAVE_AES_DECRYPT */
2294
2295
/* Extract octet y of word x.  Mask with 0xFF explicitly: a (byte) cast only
2296
 * truncates to 8 bits where a byte is 8 bits; on a wider-byte target (C28x,
2297
 * CHAR_BIT==16) it would leave a >8-bit Te/Td table index. */
2298
#define GETBYTE(x, y) (word32)(((x) >> (8 * (y))) & 0xFFU)
2299
2300
#ifdef WOLFSSL_AES_SMALL_TABLES
2301
static const byte Tsbox[256] = {
2302
    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
2303
    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
2304
    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
2305
    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
2306
    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
2307
    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
2308
    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
2309
    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
2310
    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
2311
    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
2312
    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
2313
    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
2314
    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
2315
    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
2316
    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
2317
    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
2318
    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
2319
    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
2320
    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
2321
    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
2322
    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
2323
    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
2324
    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
2325
    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
2326
    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
2327
    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
2328
    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
2329
    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
2330
    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
2331
    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
2332
    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
2333
    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
2334
};
2335
2336
#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
2337
2338
static WARN_UNUSED_RESULT word32 col_mul(
2339
    word32 t, int i2, int i3, int ia, int ib)
2340
{
2341
    byte t3 = GETBYTE(t, i3);
2342
    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
2343
2344
    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
2345
}
2346
2347
#if defined(HAVE_AES_DECRYPT) && \
2348
    (defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
2349
     defined(WOLFSSL_AES_DIRECT))
2350
static WARN_UNUSED_RESULT word32 inv_col_mul(
2351
    word32 t, int i9, int ib, int id, int ie)
2352
{
2353
    byte t9 = GETBYTE(t, i9);
2354
    byte tb = GETBYTE(t, ib);
2355
    byte td = GETBYTE(t, id);
2356
    byte te = GETBYTE(t, ie);
2357
    byte t0 = t9 ^ tb ^ td;
2358
    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
2359
}
2360
#endif /* HAVE_AES_DECRYPT && (HAVE_AES_CBC || HAVE_AES_ECB || WOLFSSL_AES_DIRECT) */
2361
#endif /* WOLFSSL_AES_SMALL_TABLES */
2362
#endif
2363
#endif
2364
2365
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
2366
                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
2367
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
2368
      defined(HAVE_AESCCM)
2369
2370
2371
#ifndef WC_AES_BITSLICED
2372
2373
#ifndef WC_CACHE_LINE_SZ
2374
    #if defined(__x86_64__) || defined(_M_X64) || \
2375
       (defined(__ILP32__) && (__ILP32__ >= 1))
2376
1.67M
        #define WC_CACHE_LINE_SZ 64
2377
    #else
2378
        /* default cache line size */
2379
        #define WC_CACHE_LINE_SZ 32
2380
    #endif
2381
#endif
2382
2383
#ifndef WC_NO_CACHE_RESISTANT
2384
2385
#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
2386
    #define WOLFSSL_AES_TOUCH_LINES
2387
#endif
2388
2389
#ifndef WOLFSSL_AES_SMALL_TABLES
2390
/* load 4 Te Tables into cache by cache line stride */
2391
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
2392
25.3k
{
2393
25.3k
#ifndef WOLFSSL_AES_TOUCH_LINES
2394
25.3k
    volatile word32 x = 0;
2395
25.3k
    int i;
2396
25.3k
    int j;
2397
2398
126k
    for (i = 0; i < 4; i++) {
2399
        /* 256 elements, each one is 4 bytes */
2400
1.72M
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
2401
1.62M
            x &= Te[i][j];
2402
1.62M
        }
2403
101k
    }
2404
2405
25.3k
    return x;
2406
#else
2407
    return 0;
2408
#endif
2409
25.3k
}
2410
#else
2411
/* load sbox into cache by cache line stride */
2412
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
2413
{
2414
#ifndef WOLFSSL_AES_TOUCH_LINES
2415
    volatile word32 x = 0;
2416
    int i;
2417
2418
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
2419
        x &= Tsbox[i];
2420
    }
2421
2422
    return x;
2423
#else
2424
    return 0;
2425
#endif
2426
}
2427
#endif
2428
#endif
2429
2430
#ifdef WOLFSSL_AES_TOUCH_LINES
2431
#if WC_CACHE_LINE_SZ == 128
2432
    #define WC_CACHE_LINE_BITS      5
2433
    #define WC_CACHE_LINE_MASK_HI   0xe0
2434
    #define WC_CACHE_LINE_MASK_LO   0x1f
2435
    #define WC_CACHE_LINE_ADD       0x20
2436
#elif WC_CACHE_LINE_SZ == 64
2437
    #define WC_CACHE_LINE_BITS      4
2438
    #define WC_CACHE_LINE_MASK_HI   0xf0
2439
    #define WC_CACHE_LINE_MASK_LO   0x0f
2440
    #define WC_CACHE_LINE_ADD       0x10
2441
#elif WC_CACHE_LINE_SZ == 32
2442
    #define WC_CACHE_LINE_BITS      3
2443
    #define WC_CACHE_LINE_MASK_HI   0xf8
2444
    #define WC_CACHE_LINE_MASK_LO   0x07
2445
    #define WC_CACHE_LINE_ADD       0x08
2446
#elif WC_CACHE_LINE_SZ == 16
2447
    #define WC_CACHE_LINE_BITS      2
2448
    #define WC_CACHE_LINE_MASK_HI   0xfc
2449
    #define WC_CACHE_LINE_MASK_LO   0x03
2450
    #define WC_CACHE_LINE_ADD       0x04
2451
#else
2452
    #error Cache line size not supported
2453
#endif
2454
2455
#ifndef WOLFSSL_AES_SMALL_TABLES
2456
static word32 GetTable(const word32* t, byte o)
2457
{
2458
#if WC_CACHE_LINE_SZ == 64
2459
    word32 e;
2460
    byte hi = o & 0xf0;
2461
    byte lo = o & 0x0f;
2462
2463
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2464
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2465
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2466
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2467
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2468
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2469
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2470
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2471
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2472
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2473
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2474
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2475
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2476
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2477
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2478
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2479
2480
    return e;
2481
#else
2482
    word32 e = 0;
2483
    int i;
2484
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2485
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2486
2487
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2488
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2489
        hi -= WC_CACHE_LINE_ADD;
2490
    }
2491
2492
    return e;
2493
#endif
2494
}
2495
#endif
2496
2497
#ifdef WOLFSSL_AES_SMALL_TABLES
2498
static byte GetTable8(const byte* t, byte o)
2499
{
2500
#if WC_CACHE_LINE_SZ == 64
2501
    byte e;
2502
    byte hi = o & 0xf0;
2503
    byte lo = o & 0x0f;
2504
2505
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2506
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2507
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2508
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2509
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2510
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2511
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2512
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2513
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2514
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2515
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2516
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2517
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2518
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2519
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2520
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2521
2522
    return e;
2523
#else
2524
    byte e = 0;
2525
    int i;
2526
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2527
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2528
2529
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2530
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2531
        hi -= WC_CACHE_LINE_ADD;
2532
    }
2533
2534
    return e;
2535
#endif
2536
}
2537
#endif
2538
2539
#ifndef WOLFSSL_AES_SMALL_TABLES
2540
static void GetTable_Multi(const word32* t, word32* t0, byte o0,
2541
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2542
{
2543
    word32 e0 = 0;
2544
    word32 e1 = 0;
2545
    word32 e2 = 0;
2546
    word32 e3 = 0;
2547
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2548
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2549
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2550
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2551
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2552
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2553
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2554
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2555
    int i;
2556
2557
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2558
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2559
        hi0 -= WC_CACHE_LINE_ADD;
2560
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2561
        hi1 -= WC_CACHE_LINE_ADD;
2562
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2563
        hi2 -= WC_CACHE_LINE_ADD;
2564
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2565
        hi3 -= WC_CACHE_LINE_ADD;
2566
    }
2567
    *t0 = e0;
2568
    *t1 = e1;
2569
    *t2 = e2;
2570
    *t3 = e3;
2571
}
2572
static void XorTable_Multi(const word32* t, word32* t0, byte o0,
2573
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2574
{
2575
    word32 e0 = 0;
2576
    word32 e1 = 0;
2577
    word32 e2 = 0;
2578
    word32 e3 = 0;
2579
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2580
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2581
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2582
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2583
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2584
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2585
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2586
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2587
    int i;
2588
2589
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2590
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2591
        hi0 -= WC_CACHE_LINE_ADD;
2592
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2593
        hi1 -= WC_CACHE_LINE_ADD;
2594
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2595
        hi2 -= WC_CACHE_LINE_ADD;
2596
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2597
        hi3 -= WC_CACHE_LINE_ADD;
2598
    }
2599
    *t0 ^= e0;
2600
    *t1 ^= e1;
2601
    *t2 ^= e2;
2602
    *t3 ^= e3;
2603
}
2604
static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
2605
{
2606
    word32 e = 0;
2607
    int i;
2608
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2609
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2610
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2611
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2612
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2613
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2614
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2615
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2616
2617
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2618
        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
2619
             << 24;
2620
        hi0 -= WC_CACHE_LINE_ADD;
2621
        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
2622
             << 16;
2623
        hi1 -= WC_CACHE_LINE_ADD;
2624
        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
2625
             <<  8;
2626
        hi2 -= WC_CACHE_LINE_ADD;
2627
        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
2628
             <<  0;
2629
        hi3 -= WC_CACHE_LINE_ADD;
2630
    }
2631
2632
    return e;
2633
}
2634
#endif
2635
#else
2636
2637
33.6M
#define GetTable(t, o)  t[o]
2638
#define GetTable8(t, o) t[o]
2639
#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2640
    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
2641
#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2642
    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
2643
#define GetTable8_4(t, o0, o1, o2, o3) \
2644
32.4k
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
2645
32.4k
     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
2646
#endif
2647
2648
#ifndef HAVE_CUDA
2649
/* Encrypt a block using AES.
2650
 *
2651
 * @param [in]  aes       AES object.
2652
 * @param [in]  inBlock   Block to encrypt.
2653
 * @param [out] outBlock  Encrypted block.
2654
 * @param [in]  r         Rounds divided by 2.
2655
 */
2656
#define WC_AES_HAVE_PREFETCH_ARG
2657
static int always_prefetch = 0;
2658
WC_MAYBE_UNUSED static int never_prefetch = 1;
2659
WC_ARGS_NOT_NULL((1, 2, 3, 5))
2660
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2661
        word32 r, int *prefetch_ptr)
2662
176k
{
2663
176k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
2664
176k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
2665
176k
    const word32* rk;
2666
#ifdef WOLFSSL_WIDE_BYTE
2667
    word32 stw[4]; /* octet-wise block I/O scratch (CHAR_BIT != 8) */
2668
#endif
2669
2670
#ifdef WC_C_DYNAMIC_FALLBACK
2671
    rk = aes->key_C_fallback;
2672
#else
2673
176k
    rk = aes->key;
2674
176k
#endif
2675
2676
    /*
2677
     * map byte array block to cipher state
2678
     * and add initial round key:
2679
     */
2680
#ifdef WOLFSSL_WIDE_BYTE
2681
    /* A C byte is wider than an octet here: the block is one octet per cell, so
2682
     * assemble the 4 big-endian state words octet-wise (no aliasing/reverse). */
2683
    WordsFromBytesBE32(stw, inBlock, 4);
2684
    s0 = stw[0]; s1 = stw[1]; s2 = stw[2]; s3 = stw[3];
2685
#else
2686
176k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
2687
176k
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
2688
176k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
2689
176k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
2690
2691
176k
#ifdef LITTLE_ENDIAN_ORDER
2692
176k
    s0 = ByteReverseWord32(s0);
2693
176k
    s1 = ByteReverseWord32(s1);
2694
176k
    s2 = ByteReverseWord32(s2);
2695
176k
    s3 = ByteReverseWord32(s3);
2696
176k
#endif
2697
176k
#endif /* WOLFSSL_WIDE_BYTE */
2698
2699
    /* AddRoundKey */
2700
176k
    s0 ^= rk[0];
2701
176k
    s1 ^= rk[1];
2702
176k
    s2 ^= rk[2];
2703
176k
    s3 ^= rk[3];
2704
2705
176k
#ifndef WOLFSSL_AES_SMALL_TABLES
2706
2707
176k
#ifndef WC_NO_CACHE_RESISTANT
2708
176k
    if (*prefetch_ptr == 0) {
2709
25.3k
        s0 |= PreFetchTe();
2710
25.3k
        if (prefetch_ptr != &always_prefetch)
2711
3.13k
            *prefetch_ptr = 1;
2712
25.3k
    }
2713
#else
2714
    (void)prefetch_ptr;
2715
#endif
2716
2717
176k
#ifndef WOLFSSL_AES_TOUCH_LINES
2718
176k
#define ENC_ROUND_T_S(o)                                                       \
2719
996k
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
2720
996k
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
2721
996k
         rk[(o)+4];                                                            \
2722
996k
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
2723
996k
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
2724
996k
         rk[(o)+5];                                                            \
2725
996k
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
2726
996k
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
2727
996k
         rk[(o)+6];                                                            \
2728
996k
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
2729
996k
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
2730
996k
         rk[(o)+7]
2731
176k
#define ENC_ROUND_S_T(o)                                                       \
2732
819k
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
2733
819k
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
2734
819k
         rk[(o)+0];                                                            \
2735
819k
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
2736
819k
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
2737
819k
         rk[(o)+1];                                                            \
2738
819k
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
2739
819k
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
2740
819k
         rk[(o)+2];                                                            \
2741
819k
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
2742
819k
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
2743
819k
         rk[(o)+3]
2744
#else
2745
#define ENC_ROUND_T_S(o)                                                       \
2746
    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
2747
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
2748
    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
2749
                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
2750
    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
2751
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
2752
    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
2753
                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
2754
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
2755
2756
#define ENC_ROUND_S_T(o)                                                       \
2757
    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
2758
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
2759
    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
2760
                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
2761
    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
2762
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2763
    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
2764
                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
2765
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2766
#endif
2767
2768
176k
#ifndef WOLFSSL_AES_NO_UNROLL
2769
/* Unroll the loop. */
2770
176k
                       ENC_ROUND_T_S( 0);
2771
176k
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2772
176k
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2773
176k
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2774
176k
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2775
176k
    if (r > 5) {
2776
65.9k
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2777
65.9k
        if (r > 6) {
2778
49.4k
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2779
49.4k
        }
2780
65.9k
    }
2781
176k
    rk += r * 8;
2782
#else
2783
    /*
2784
     * Nr - 1 full rounds:
2785
     */
2786
2787
    for (;;) {
2788
        ENC_ROUND_T_S(0);
2789
2790
        rk += 8;
2791
        if (--r == 0) {
2792
            break;
2793
        }
2794
2795
        ENC_ROUND_S_T(0);
2796
    }
2797
#endif
2798
2799
    /*
2800
     * apply last round and
2801
     * map cipher state to byte array block:
2802
     */
2803
2804
176k
#ifndef WOLFSSL_AES_TOUCH_LINES
2805
176k
    s0 =
2806
176k
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2807
176k
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2808
176k
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2809
176k
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2810
176k
        rk[0];
2811
176k
    s1 =
2812
176k
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2813
176k
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2814
176k
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2815
176k
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2816
176k
        rk[1];
2817
176k
    s2 =
2818
176k
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2819
176k
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2820
176k
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2821
176k
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2822
176k
        rk[2];
2823
176k
    s3 =
2824
176k
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2825
176k
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2826
176k
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2827
176k
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2828
176k
        rk[3];
2829
#else
2830
{
2831
    word32 u0;
2832
    word32 u1;
2833
    word32 u2;
2834
    word32 u3;
2835
2836
    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
2837
    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
2838
                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
2839
    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
2840
    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
2841
    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
2842
                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
2843
    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
2844
    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
2845
    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
2846
                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
2847
    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
2848
    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
2849
    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
2850
                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
2851
    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
2852
    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
2853
}
2854
#endif
2855
2856
#else /* WOLFSSL_AES_SMALL_TABLES */
2857
2858
#ifndef WC_NO_CACHE_RESISTANT
2859
    if (*prefetch_ptr == 0) {
2860
        s0 |= PreFetchSBox();
2861
        if (prefetch_ptr != &always_prefetch)
2862
            *prefetch_ptr = 1;
2863
    }
2864
#else
2865
    (void)prefetch_ptr;
2866
#endif
2867
2868
    r *= 2;
2869
    /* Two rounds at a time */
2870
    for (rk += 4; r > 1; r--, rk += 4) {
2871
        t0 =
2872
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2873
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2874
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2875
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2876
        t1 =
2877
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2878
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2879
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2880
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2881
        t2 =
2882
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2883
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2884
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2885
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2886
        t3 =
2887
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2888
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2889
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2890
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2891
2892
        s0 =
2893
            (col_mul(t0, 3, 2, 0, 1) << 24) ^
2894
            (col_mul(t0, 2, 1, 0, 3) << 16) ^
2895
            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
2896
            (col_mul(t0, 0, 3, 2, 1)      ) ^
2897
            rk[0];
2898
        s1 =
2899
            (col_mul(t1, 3, 2, 0, 1) << 24) ^
2900
            (col_mul(t1, 2, 1, 0, 3) << 16) ^
2901
            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
2902
            (col_mul(t1, 0, 3, 2, 1)      ) ^
2903
            rk[1];
2904
        s2 =
2905
            (col_mul(t2, 3, 2, 0, 1) << 24) ^
2906
            (col_mul(t2, 2, 1, 0, 3) << 16) ^
2907
            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
2908
            (col_mul(t2, 0, 3, 2, 1)      ) ^
2909
            rk[2];
2910
        s3 =
2911
            (col_mul(t3, 3, 2, 0, 1) << 24) ^
2912
            (col_mul(t3, 2, 1, 0, 3) << 16) ^
2913
            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
2914
            (col_mul(t3, 0, 3, 2, 1)      ) ^
2915
            rk[3];
2916
    }
2917
2918
    t0 =
2919
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2920
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2921
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2922
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2923
    t1 =
2924
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2925
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2926
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2927
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2928
    t2 =
2929
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2930
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2931
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2932
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2933
    t3 =
2934
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2935
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2936
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2937
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2938
    s0 = t0 ^ rk[0];
2939
    s1 = t1 ^ rk[1];
2940
    s2 = t2 ^ rk[2];
2941
    s3 = t3 ^ rk[3];
2942
2943
#endif /* WOLFSSL_AES_SMALL_TABLES */
2944
2945
    /* write out */
2946
#ifdef WOLFSSL_WIDE_BYTE
2947
    stw[0] = s0; stw[1] = s1; stw[2] = s2; stw[3] = s3;
2948
    BytesFromWordsBE32(outBlock, stw, WC_AES_BLOCK_SIZE);
2949
#else
2950
176k
#ifdef LITTLE_ENDIAN_ORDER
2951
176k
    s0 = ByteReverseWord32(s0);
2952
176k
    s1 = ByteReverseWord32(s1);
2953
176k
    s2 = ByteReverseWord32(s2);
2954
176k
    s3 = ByteReverseWord32(s3);
2955
176k
#endif
2956
2957
176k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2958
176k
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2959
176k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2960
176k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2961
176k
#endif /* WOLFSSL_WIDE_BYTE */
2962
176k
}
2963
2964
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2965
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
2966
    !defined(MAX3266X_AES)
2967
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
2968
/* Encrypt a number of blocks using AES.
2969
 *
2970
 * @param [in]  aes  AES object.
2971
 * @param [in]  in   Block to encrypt.
2972
 * @param [out] out  Encrypted block.
2973
 * @param [in]  sz   Number of blocks to encrypt.
2974
 */
2975
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2976
779
{
2977
779
    word32 i;
2978
779
    int did_prefetches = 0;
2979
2980
18.9k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
2981
18.1k
        AesEncrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
2982
18.1k
        in += WC_AES_BLOCK_SIZE;
2983
18.1k
        out += WC_AES_BLOCK_SIZE;
2984
18.1k
    }
2985
779
}
2986
#endif
2987
#endif
2988
#else
2989
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2990
        word32 r);
2991
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2992
#endif /* HAVE_CUDA */
2993
2994
#else
2995
2996
/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
2997
 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
2998
 */
2999
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
3000
static void bs_sub_bytes(bs_word u[8])
3001
{
3002
    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
3003
    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
3004
    bs_word y20, y21;
3005
    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
3006
    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
3007
    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
3008
    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
3009
    bs_word t40, t41, t42, t43, t44, t45;
3010
    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
3011
    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
3012
    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
3013
    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
3014
    bs_word tc20, tc21, tc26;
3015
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
3016
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
3017
3018
    U0 = u[7];
3019
    U1 = u[6];
3020
    U2 = u[5];
3021
    U3 = u[4];
3022
    U4 = u[3];
3023
    U5 = u[2];
3024
    U6 = u[1];
3025
    U7 = u[0];
3026
3027
    y14 = U3 ^ U5;
3028
    y13 = U0 ^ U6;
3029
    y9 = U0 ^ U3;
3030
    y8 = U0 ^ U5;
3031
    t0 = U1 ^ U2;
3032
    y1 = t0 ^ U7;
3033
    y4 = y1 ^ U3;
3034
    y12 = y13 ^ y14;
3035
    y2 = y1 ^ U0;
3036
    y5 = y1 ^ U6;
3037
    y3 = y5 ^ y8;
3038
    t1 = U4 ^ y12;
3039
    y15 = t1 ^ U5;
3040
    y20 = t1 ^ U1;
3041
    y6 = y15 ^ U7;
3042
    y10 = y15 ^ t0;
3043
    y11 = y20 ^ y9;
3044
    y7 = U7 ^ y11;
3045
    y17 = y10 ^ y11;
3046
    y19 = y10 ^ y8;
3047
    y16 = t0 ^ y11;
3048
    y21 = y13 ^ y16;
3049
    y18 = U0 ^ y16;
3050
    t2 = y12 & y15;
3051
    t3 = y3 & y6;
3052
    t4 = t3 ^ t2;
3053
    t5 = y4 & U7;
3054
    t6 = t5 ^ t2;
3055
    t7 = y13 & y16;
3056
    t8 = y5 & y1;
3057
    t9 = t8 ^ t7;
3058
    t10 = y2 & y7;
3059
    t11 = t10 ^ t7;
3060
    t12 = y9 & y11;
3061
    t13 = y14 & y17;
3062
    t14 = t13 ^ t12;
3063
    t15 = y8 & y10;
3064
    t16 = t15 ^ t12;
3065
    t17 = t4 ^ y20;
3066
    t18 = t6 ^ t16;
3067
    t19 = t9 ^ t14;
3068
    t20 = t11 ^ t16;
3069
    t21 = t17 ^ t14;
3070
    t22 = t18 ^ y19;
3071
    t23 = t19 ^ y21;
3072
    t24 = t20 ^ y18;
3073
    t25 = t21 ^ t22;
3074
    t26 = t21 & t23;
3075
    t27 = t24 ^ t26;
3076
    t28 = t25 & t27;
3077
    t29 = t28 ^ t22;
3078
    t30 = t23 ^ t24;
3079
    t31 = t22 ^ t26;
3080
    t32 = t31 & t30;
3081
    t33 = t32 ^ t24;
3082
    t34 = t23 ^ t33;
3083
    t35 = t27 ^ t33;
3084
    t36 = t24 & t35;
3085
    t37 = t36 ^ t34;
3086
    t38 = t27 ^ t36;
3087
    t39 = t29 & t38;
3088
    t40 = t25 ^ t39;
3089
    t41 = t40 ^ t37;
3090
    t42 = t29 ^ t33;
3091
    t43 = t29 ^ t40;
3092
    t44 = t33 ^ t37;
3093
    t45 = t42 ^ t41;
3094
    z0 = t44 & y15;
3095
    z1 = t37 & y6;
3096
    z2 = t33 & U7;
3097
    z3 = t43 & y16;
3098
    z4 = t40 & y1;
3099
    z5 = t29 & y7;
3100
    z6 = t42 & y11;
3101
    z7 = t45 & y17;
3102
    z8 = t41 & y10;
3103
    z9 = t44 & y12;
3104
    z10 = t37 & y3;
3105
    z11 = t33 & y4;
3106
    z12 = t43 & y13;
3107
    z13 = t40 & y5;
3108
    z14 = t29 & y2;
3109
    z15 = t42 & y9;
3110
    z16 = t45 & y14;
3111
    z17 = t41 & y8;
3112
    tc1 = z15 ^ z16;
3113
    tc2 = z10 ^ tc1;
3114
    tc3 = z9 ^ tc2;
3115
    tc4 = z0 ^ z2;
3116
    tc5 = z1 ^ z0;
3117
    tc6 = z3 ^ z4;
3118
    tc7 = z12 ^ tc4;
3119
    tc8 = z7 ^ tc6;
3120
    tc9 = z8 ^ tc7;
3121
    tc10 = tc8 ^ tc9;
3122
    tc11 = tc6 ^ tc5;
3123
    tc12 = z3 ^ z5;
3124
    tc13 = z13 ^ tc1;
3125
    tc14 = tc4 ^ tc12;
3126
    S3 = tc3 ^ tc11;
3127
    tc16 = z6 ^ tc8;
3128
    tc17 = z14 ^ tc10;
3129
    tc18 = tc13 ^ tc14;
3130
    S7 = ~(z12 ^ tc18);
3131
    tc20 = z15 ^ tc16;
3132
    tc21 = tc2 ^ z11;
3133
    S0 = tc3 ^ tc16;
3134
    S6 = ~(tc10 ^ tc18);
3135
    S4 = tc14 ^ S3;
3136
    S1 = ~(S3 ^ tc16);
3137
    tc26 = tc17 ^ tc20;
3138
    S2 = ~(tc26 ^ z17);
3139
    S5 = tc21 ^ tc17;
3140
3141
    u[0] = S7;
3142
    u[1] = S6;
3143
    u[2] = S5;
3144
    u[3] = S4;
3145
    u[4] = S3;
3146
    u[5] = S2;
3147
    u[6] = S1;
3148
    u[7] = S0;
3149
}
3150
3151
#define BS_MASK_BIT_SET(w, j, bmask) \
3152
    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
3153
3154
#define BS_TRANS_8(t, o, w, bmask, s)                   \
3155
    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
3156
    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
3157
    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
3158
    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
3159
    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
3160
    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
3161
    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
3162
    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
3163
3164
static void bs_transpose(bs_word* t, bs_word* blocks)
3165
{
3166
    bs_word bmask = 1;
3167
    int i;
3168
3169
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
3170
3171
    for (i = 0; i < BS_WORD_SIZE; i++) {
3172
        int j;
3173
        int o = 0;
3174
        for (j = 0; j < BS_BLOCK_WORDS; j++) {
3175
        #ifdef LITTLE_ENDIAN_ORDER
3176
            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
3177
        #else
3178
            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
3179
        #endif
3180
    #ifdef WOLFSSL_AES_NO_UNROLL
3181
            int k;
3182
            for (k = 0; k < BS_WORD_SIZE; k++) {
3183
                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
3184
            }
3185
    #else
3186
            BS_TRANS_8(t, o, w, bmask,  0);
3187
        #if BS_WORD_SIZE >= 16
3188
            BS_TRANS_8(t, o, w, bmask,  8);
3189
        #endif
3190
        #if BS_WORD_SIZE >= 32
3191
            BS_TRANS_8(t, o, w, bmask, 16);
3192
            BS_TRANS_8(t, o, w, bmask, 24);
3193
        #endif
3194
        #if BS_WORD_SIZE >= 64
3195
            BS_TRANS_8(t, o, w, bmask, 32);
3196
            BS_TRANS_8(t, o, w, bmask, 40);
3197
            BS_TRANS_8(t, o, w, bmask, 48);
3198
            BS_TRANS_8(t, o, w, bmask, 56);
3199
        #endif
3200
    #endif
3201
            o += BS_WORD_SIZE;
3202
        }
3203
        bmask <<= 1;
3204
    }
3205
}
3206
3207
#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
3208
    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
3209
    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
3210
    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
3211
    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
3212
    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
3213
    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
3214
    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
3215
    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
3216
3217
static void bs_inv_transpose(bs_word* t, bs_word* blocks)
3218
{
3219
    int o;
3220
3221
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
3222
3223
    for (o = 0; o < BS_BLOCK_WORDS; o++) {
3224
        int i;
3225
        for (i = 0; i < BS_WORD_SIZE; i++) {
3226
        #ifdef LITTLE_ENDIAN_ORDER
3227
            bs_word bmask = (bs_word)1 << i;
3228
        #else
3229
            bs_word bmask = bs_bswap((bs_word)1 << i);
3230
        #endif
3231
            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
3232
    #ifdef WOLFSSL_AES_NO_UNROLL
3233
            int j;
3234
            for (j = 0; j < BS_WORD_SIZE; j++) {
3235
                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
3236
            }
3237
    #else
3238
            BS_INV_TRANS_8(t, o, w, bmask, 0);
3239
        #if BS_WORD_SIZE >= 16
3240
            BS_INV_TRANS_8(t, o, w, bmask, 8);
3241
        #endif
3242
        #if BS_WORD_SIZE >= 32
3243
            BS_INV_TRANS_8(t, o, w, bmask, 16);
3244
            BS_INV_TRANS_8(t, o, w, bmask, 24);
3245
        #endif
3246
        #if BS_WORD_SIZE >= 64
3247
            BS_INV_TRANS_8(t, o, w, bmask, 32);
3248
            BS_INV_TRANS_8(t, o, w, bmask, 40);
3249
            BS_INV_TRANS_8(t, o, w, bmask, 48);
3250
            BS_INV_TRANS_8(t, o, w, bmask, 56);
3251
        #endif
3252
    #endif
3253
        }
3254
    }
3255
}
3256
3257
#define BS_ROW_OFF_0    0
3258
#define BS_ROW_OFF_1    32
3259
#define BS_ROW_OFF_2    64
3260
#define BS_ROW_OFF_3    96
3261
3262
#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
3263
#define BS_IDX_MASK     0x7f
3264
3265
#define BS_ASSIGN_8(d, od, s, os)   \
3266
    d[(od) + 0] = s[(os) + 0];      \
3267
    d[(od) + 1] = s[(os) + 1];      \
3268
    d[(od) + 2] = s[(os) + 2];      \
3269
    d[(od) + 3] = s[(os) + 3];      \
3270
    d[(od) + 4] = s[(os) + 4];      \
3271
    d[(od) + 5] = s[(os) + 5];      \
3272
    d[(od) + 6] = s[(os) + 6];      \
3273
    d[(od) + 7] = s[(os) + 7]
3274
3275
static void bs_shift_rows(bs_word* t, bs_word* b)
3276
{
3277
    int i;
3278
3279
    for (i = 0; i < 128; i += 32) {
3280
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
3281
        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
3282
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
3283
        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
3284
    }
3285
}
3286
3287
#define BS_SHIFT_OFF_0  0
3288
#define BS_SHIFT_OFF_1  8
3289
#define BS_SHIFT_OFF_2  16
3290
#define BS_SHIFT_OFF_3  24
3291
3292
/* Shift rows and mix columns.
3293
 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
3294
 */
3295
3296
#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
3297
        of      = br0[7] ^ br1[7];                                  \
3298
        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
3299
        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
3300
        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
3301
        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
3302
        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
3303
        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
3304
        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
3305
        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
3306
3307
static void bs_shift_mix(bs_word* t, bs_word* b)
3308
{
3309
    int i;
3310
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
3311
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
3312
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
3313
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
3314
3315
    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
3316
        bs_word* br0 = b + or0;
3317
        bs_word* br1 = b + or1;
3318
        bs_word* br2 = b + or2;
3319
        bs_word* br3 = b + or3;
3320
        bs_word of;
3321
3322
        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
3323
        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
3324
        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
3325
        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
3326
3327
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3328
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3329
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3330
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3331
    }
3332
}
3333
3334
static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
3335
{
3336
    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
3337
}
3338
3339
static void bs_sub_bytes_blocks(bs_word* b)
3340
{
3341
    int i;
3342
3343
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
3344
        bs_sub_bytes(b + i);
3345
    }
3346
}
3347
3348
static const FLASH_QUALIFIER byte bs_rcon[] = {
3349
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
3350
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
3351
};
3352
3353
static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
3354
    bs_word block[AES_BLOCK_BITS];
3355
    bs_word trans[AES_BLOCK_BITS];
3356
3357
    XMEMSET(block, 0, sizeof(block));
3358
    XMEMCPY(block, in, 4);
3359
3360
    bs_transpose(trans, block);
3361
    bs_sub_bytes_blocks(trans);
3362
    bs_inv_transpose(block, trans);
3363
3364
    XMEMCPY(out, block, 4);
3365
}
3366
3367
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
3368
    /* Rotate left 8 bits. The key schedule is a byte array, so use the
3369
     * unaligned accessors. */
3370
#ifdef LITTLE_ENDIAN_ORDER
3371
    (void)writeUnalignedWord32(out, rotrFixed(readUnalignedWord32(in), 8));
3372
#else
3373
    (void)writeUnalignedWord32(out, rotlFixed(readUnalignedWord32(in), 8));
3374
#endif
3375
    bs_ke_sub_bytes(out, out);
3376
    /* On just the first byte, add 2^i to the byte */
3377
    out[0] ^= bs_rcon[i];
3378
}
3379
3380
/* r = a ^ b, on schedule words in byte arrays of unknown alignment. */
3381
static void bs_ke_xor(unsigned char* r, const unsigned char* a,
3382
    const unsigned char* b)
3383
{
3384
    (void)writeUnalignedWord32(r,
3385
        readUnalignedWord32(a) ^ readUnalignedWord32(b));
3386
}
3387
3388
static void bs_expand_key(unsigned char *in, word32 sz) {
3389
    unsigned char t[4];
3390
    word32 o;
3391
    word8 i = 0;
3392
3393
    if (sz == 176) {
3394
        /* Total of 11 rounds - AES-128. */
3395
        for (o = 16; o < sz; o += 16) {
3396
            bs_ke_transform(t, in + o - 4, i);
3397
            i++;
3398
            bs_ke_xor(in + o +  0, in + o - 16, t);
3399
            bs_ke_xor(in + o +  4, in + o - 12, in + o +  0);
3400
            bs_ke_xor(in + o +  8, in + o -  8, in + o +  4);
3401
            bs_ke_xor(in + o + 12, in + o -  4, in + o +  8);
3402
        }
3403
    }
3404
    else if (sz == 208) {
3405
        /* Total of 13 rounds - AES-192. */
3406
        for (o = 24; o < sz; o += 24) {
3407
            bs_ke_transform(t, in + o - 4, i);
3408
            i++;
3409
            bs_ke_xor(in + o +  0, in + o - 24, t);
3410
            bs_ke_xor(in + o +  4, in + o - 20, in + o +  0);
3411
            bs_ke_xor(in + o +  8, in + o - 16, in + o +  4);
3412
            bs_ke_xor(in + o + 12, in + o - 12, in + o +  8);
3413
            bs_ke_xor(in + o + 16, in + o -  8, in + o + 12);
3414
            bs_ke_xor(in + o + 20, in + o -  4, in + o + 16);
3415
        }
3416
    }
3417
    else if (sz == 240) {
3418
        /* Total of 15 rounds - AES-256. */
3419
        for (o = 32; o < sz; o += 16) {
3420
            if ((o & 0x1f) == 0) {
3421
                bs_ke_transform(t, in + o - 4, i);
3422
                i++;
3423
            }
3424
            else {
3425
                bs_ke_sub_bytes(t, in + o - 4);
3426
            }
3427
            bs_ke_xor(in + o +  0, in + o - 32, t);
3428
            bs_ke_xor(in + o +  4, in + o - 28, in + o +  0);
3429
            bs_ke_xor(in + o +  8, in + o - 24, in + o +  4);
3430
            bs_ke_xor(in + o + 12, in + o - 20, in + o +  8);
3431
        }
3432
    }
3433
}
3434
3435
static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
3436
    word32 rounds)
3437
{
3438
    int i;
3439
    byte bs_key[15 * WC_AES_BLOCK_SIZE];
3440
    int ksSz = (rounds + 1) * WC_AES_BLOCK_SIZE;
3441
    bs_word block[AES_BLOCK_BITS];
3442
3443
    /* Fist round. */
3444
    XMEMCPY(bs_key, key, keyLen);
3445
    bs_expand_key(bs_key, ksSz);
3446
3447
    for (i = 0; i < ksSz; i += WC_AES_BLOCK_SIZE) {
3448
        int k;
3449
3450
        XMEMCPY(block, bs_key + i, WC_AES_BLOCK_SIZE);
3451
        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
3452
            int l;
3453
            for (l = 0; l < BS_BLOCK_WORDS; l++) {
3454
                block[k + l] = block[l];
3455
            }
3456
        }
3457
        bs_transpose(rk, block);
3458
        rk += AES_BLOCK_BITS;
3459
    }
3460
}
3461
3462
static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
3463
{
3464
    word32 i;
3465
    bs_word trans[AES_BLOCK_BITS];
3466
3467
    bs_transpose(trans, state);
3468
3469
    bs_add_round_key(trans, trans, rk);
3470
    for (i = 1; i < r; i++) {
3471
        bs_sub_bytes_blocks(trans);
3472
        bs_shift_mix(state, trans);
3473
        rk += AES_BLOCK_BITS;
3474
        bs_add_round_key(trans, state, rk);
3475
    }
3476
    bs_sub_bytes_blocks(trans);
3477
    bs_shift_rows(state, trans);
3478
    rk += AES_BLOCK_BITS;
3479
    bs_add_round_key(trans, state, rk);
3480
    bs_inv_transpose(state, trans);
3481
}
3482
3483
#ifndef HAVE_CUDA
3484
/* Encrypt a block using AES.
3485
 *
3486
 * @param [in]  aes       AES object.
3487
 * @param [in]  inBlock   Block to encrypt.
3488
 * @param [out] outBlock  Encrypted block.
3489
 * @param [in]  r         Rounds divided by 2.
3490
 */
3491
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3492
        word32 r)
3493
{
3494
    bs_word state[AES_BLOCK_BITS];
3495
3496
    (void)r;
3497
3498
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
3499
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
3500
3501
    bs_encrypt(state, aes->bs_key, aes->rounds);
3502
3503
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
3504
}
3505
3506
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3507
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3508
/* Encrypt a number of blocks using AES.
3509
 *
3510
 * @param [in]  aes  AES object.
3511
 * @param [in]  in   Block to encrypt.
3512
 * @param [out] out  Encrypted block.
3513
 * @param [in]  sz   Number of blocks to encrypt.
3514
 */
3515
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3516
{
3517
    bs_word state[AES_BLOCK_BITS];
3518
3519
    while (sz >= BS_BLOCK_SIZE) {
3520
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3521
        bs_encrypt(state, aes->bs_key, aes->rounds);
3522
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3523
        sz  -= BS_BLOCK_SIZE;
3524
        in  += BS_BLOCK_SIZE;
3525
        out += BS_BLOCK_SIZE;
3526
    }
3527
    if (sz > 0) {
3528
        XMEMCPY(state, in, sz);
3529
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3530
        bs_encrypt(state, aes->bs_key, aes->rounds);
3531
        XMEMCPY(out, state, sz);
3532
    }
3533
}
3534
#endif
3535
#else
3536
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3537
        word32 r);
3538
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
3539
#endif /* HAVE_CUDA */
3540
3541
#endif /* !WC_AES_BITSLICED */
3542
3543
#ifdef WC_AES_HAVE_PREFETCH_ARG
3544
#define wc_AesEncrypt(aes, inBlock, outBlock) \
3545
7.76k
    AesEncrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
3546
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesEncrypt_preFetchOpt(
3547
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
3548
#else
3549
#define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
3550
    wc_AesEncrypt(aes, inBlock, outBlock)
3551
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesEncrypt(
3552
    Aes* aes, const byte* inBlock, byte* outBlock)
3553
#endif
3554
157k
{
3555
#if defined(MAX3266X_AES)
3556
    word32 keySize;
3557
#endif
3558
#if defined(MAX3266X_CB)
3559
    int ret_cb;
3560
#endif
3561
157k
    word32 r;
3562
3563
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3564
    {
3565
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3566
        if (ret < 0)
3567
            return ret;
3568
    }
3569
#endif
3570
3571
157k
    r = aes->rounds >> 1;
3572
3573
157k
    if (r > 7 || r == 0) {
3574
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3575
0
        return KEYUSAGE_E;
3576
0
    }
3577
3578
#ifdef WOLFSSL_AESNI
3579
    if (aes->use_aesni) {
3580
        ASSERT_SAVED_VECTOR_REGISTERS();
3581
3582
        #ifdef DEBUG_AESNI
3583
            printf("about to aes encrypt\n");
3584
            printf("in  = %p\n", inBlock);
3585
            printf("out = %p\n", outBlock);
3586
            printf("aes->key = %p\n", aes->key);
3587
            printf("aes->rounds = %d\n", aes->rounds);
3588
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
3589
        #endif
3590
3591
        /* check alignment, decrypt doesn't need alignment */
3592
        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
3593
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
3594
            byte* tmp = (byte*)XMALLOC(WC_AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
3595
                                                      DYNAMIC_TYPE_TMP_BUFFER);
3596
            byte* tmp_align;
3597
            if (tmp == NULL)
3598
                return MEMORY_E;
3599
3600
            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
3601
3602
            XMEMCPY(tmp_align, inBlock, WC_AES_BLOCK_SIZE);
3603
            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, WC_AES_BLOCK_SIZE,
3604
                    (byte*)aes->key, (int)aes->rounds);
3605
            XMEMCPY(outBlock, tmp_align, WC_AES_BLOCK_SIZE);
3606
            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3607
            return 0;
3608
        #else
3609
            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
3610
            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
3611
            return BAD_ALIGN_E;
3612
        #endif
3613
        }
3614
3615
        AES_ECB_encrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3616
                        (int)aes->rounds);
3617
3618
        return 0;
3619
    }
3620
    else {
3621
        #ifdef DEBUG_AESNI
3622
            printf("Skipping AES-NI\n");
3623
        #endif
3624
    }
3625
#elif defined(WOLFSSL_ARMASM)
3626
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
3627
#if !defined(__aarch64__)
3628
#ifdef WOLFSSL_ARM32_AES_DISPATCH
3629
    if (aes->use_aes_hw_crypto) {
3630
        AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key,
3631
            (int)aes->rounds);
3632
    }
3633
    else
3634
#else
3635
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
3636
#endif /* WOLFSSL_ARM32_AES_DISPATCH */
3637
#else
3638
    if (aes->use_aes_hw_crypto) {
3639
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3640
            (int)aes->rounds);
3641
    }
3642
    else
3643
#endif /* !__aarch64__ */
3644
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
3645
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
3646
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
3647
    {
3648
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3649
            (const unsigned char*)aes->key, aes->rounds);
3650
    }
3651
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
3652
      defined(WOLFSSL_ARM32_AES_DISPATCH)
3653
    {
3654
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3655
            (const unsigned char*)aes->key, aes->rounds);
3656
    }
3657
#endif
3658
    return 0;
3659
#endif /* WOLFSSL_AESNI */
3660
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3661
    AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3662
    return 0;
3663
#endif
3664
3665
#if defined(WOLFSSL_IMXRT_DCP)
3666
    if (aes->keylen == 16) {
3667
        DCPAesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3668
        return 0;
3669
    }
3670
#endif
3671
3672
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3673
    if (aes->useSWCrypt == 0) {
3674
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3675
                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
3676
    }
3677
#endif
3678
3679
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3680
    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
3681
    if (wc_esp32AesSupportedKeyLen(aes)) {
3682
        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
3683
    }
3684
    else {
3685
        /* For example, the ESP32-S3 does not support HW for len = 24,
3686
         * so fall back to SW */
3687
    #ifdef DEBUG_WOLFSSL
3688
        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
3689
                      aes->keylen);
3690
    #endif
3691
    }
3692
#endif
3693
3694
#if defined(MAX3266X_AES)
3695
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3696
        return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3697
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3698
                                    outBlock, (unsigned int)keySize);
3699
    }
3700
#endif
3701
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3702
    #ifndef WOLF_CRYPTO_CB_FIND
3703
    if (aes->devId != INVALID_DEVID)
3704
    #endif
3705
    {
3706
        ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock,
3707
                                            WC_AES_BLOCK_SIZE);
3708
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3709
            return ret_cb;
3710
        /* fall-through when unavailable */
3711
    }
3712
#endif
3713
3714
157k
#ifdef WC_AES_HAVE_PREFETCH_ARG
3715
157k
    AesEncrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
3716
#else
3717
    AesEncrypt_C(aes, inBlock, outBlock, r);
3718
#endif
3719
3720
157k
    return 0;
3721
157k
} /* wc_AesEncrypt */
3722
#endif
3723
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
3724
3725
#if defined(HAVE_AES_DECRYPT)
3726
#if ((defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3727
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)) && \
3728
    (defined(__aarch64__) || !defined(WOLFSSL_ARMASM))
3729
3730
#ifndef WC_AES_BITSLICED
3731
#ifndef WC_NO_CACHE_RESISTANT
3732
#ifndef WOLFSSL_AES_SMALL_TABLES
3733
/* load 4 Td Tables into cache by cache line stride */
3734
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
3735
718
{
3736
718
    volatile word32 x = 0;
3737
718
    int i;
3738
718
    int j;
3739
3740
3.59k
    for (i = 0; i < 4; i++) {
3741
        /* 256 elements, each one is 4 bytes */
3742
48.8k
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
3743
45.9k
            x &= Td[i][j];
3744
45.9k
        }
3745
2.87k
    }
3746
3747
718
    return x;
3748
718
}
3749
#endif /* !WOLFSSL_AES_SMALL_TABLES */
3750
3751
/* load Td Table4 into cache by cache line stride */
3752
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
3753
718
{
3754
718
#ifndef WOLFSSL_AES_TOUCH_LINES
3755
718
    volatile word32 x = 0;
3756
718
    int i;
3757
3758
3.59k
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
3759
2.87k
        x &= (word32)Td4[i];
3760
2.87k
    }
3761
3762
718
    return x;
3763
#else
3764
    return 0;
3765
#endif
3766
718
}
3767
#endif /* !WC_NO_CACHE_RESISTANT */
3768
3769
/* Decrypt a block using AES.
3770
 *
3771
 * @param [in]  aes       AES object.
3772
 * @param [in]  inBlock   Block to encrypt.
3773
 * @param [out] outBlock  Encrypted block.
3774
 * @param [in]  r         Rounds divided by 2.
3775
 */
3776
#ifndef WC_AES_HAVE_PREFETCH_ARG
3777
    #define WC_AES_HAVE_PREFETCH_ARG
3778
    static int always_prefetch = 0;
3779
    WC_MAYBE_UNUSED static int never_prefetch = 1;
3780
#endif
3781
WC_ARGS_NOT_NULL((1, 2, 3, 5))
3782
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3783
    word32 r, int *prefetch_ptr)
3784
8.10k
{
3785
8.10k
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
3786
8.10k
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
3787
8.10k
    const word32* rk;
3788
#ifdef WOLFSSL_WIDE_BYTE
3789
    word32 stw[4]; /* octet-wise block I/O scratch (CHAR_BIT != 8) */
3790
#endif
3791
3792
#ifdef WC_C_DYNAMIC_FALLBACK
3793
    rk = aes->key_C_fallback;
3794
#else
3795
8.10k
    rk = aes->key;
3796
8.10k
#endif
3797
3798
    /*
3799
     * map byte array block to cipher state
3800
     * and add initial round key:
3801
     */
3802
#ifdef WOLFSSL_WIDE_BYTE
3803
    /* A C byte is wider than an octet here: the block is one octet per cell, so
3804
     * assemble the 4 big-endian state words octet-wise (no aliasing/reverse). */
3805
    WordsFromBytesBE32(stw, inBlock, 4);
3806
    s0 = stw[0]; s1 = stw[1]; s2 = stw[2]; s3 = stw[3];
3807
#else
3808
8.10k
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
3809
8.10k
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
3810
8.10k
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
3811
8.10k
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
3812
3813
8.10k
#ifdef LITTLE_ENDIAN_ORDER
3814
8.10k
    s0 = ByteReverseWord32(s0);
3815
8.10k
    s1 = ByteReverseWord32(s1);
3816
8.10k
    s2 = ByteReverseWord32(s2);
3817
8.10k
    s3 = ByteReverseWord32(s3);
3818
8.10k
#endif
3819
8.10k
#endif /* WOLFSSL_WIDE_BYTE */
3820
3821
8.10k
    s0 ^= rk[0];
3822
8.10k
    s1 ^= rk[1];
3823
8.10k
    s2 ^= rk[2];
3824
8.10k
    s3 ^= rk[3];
3825
3826
8.10k
#ifndef WOLFSSL_AES_SMALL_TABLES
3827
3828
8.10k
#ifndef WC_NO_CACHE_RESISTANT
3829
8.10k
    if (*prefetch_ptr == 0) {
3830
718
        s0 |= PreFetchTd();
3831
        /* don't set the prefetched flag here -- PreFetchTd4() is called
3832
         * below.
3833
         */
3834
718
    }
3835
#else
3836
    (void)prefetch_ptr;
3837
#endif
3838
3839
8.10k
#ifndef WOLFSSL_AES_TOUCH_LINES
3840
/* Unroll the loop. */
3841
8.10k
#define DEC_ROUND_T_S(o)                                            \
3842
50.5k
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
3843
50.5k
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
3844
50.5k
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
3845
50.5k
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
3846
50.5k
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
3847
50.5k
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
3848
50.5k
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
3849
50.5k
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
3850
8.10k
#define DEC_ROUND_S_T(o)                                            \
3851
42.4k
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
3852
42.4k
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
3853
42.4k
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
3854
42.4k
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
3855
42.4k
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
3856
42.4k
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
3857
42.4k
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
3858
42.4k
         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
3859
#else
3860
#define DEC_ROUND_T_S(o)                                                       \
3861
    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
3862
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
3863
    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
3864
                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
3865
    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
3866
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
3867
    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
3868
                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
3869
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
3870
3871
#define DEC_ROUND_S_T(o)                                                       \
3872
    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
3873
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
3874
    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
3875
                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
3876
    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
3877
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
3878
    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
3879
                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
3880
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
3881
#endif
3882
3883
8.10k
#ifndef WOLFSSL_AES_NO_UNROLL
3884
8.10k
                       DEC_ROUND_T_S( 0);
3885
8.10k
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3886
8.10k
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3887
8.10k
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3888
8.10k
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3889
8.10k
    if (r > 5) {
3890
6.18k
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3891
6.18k
        if (r > 6) {
3892
3.81k
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3893
3.81k
        }
3894
6.18k
    }
3895
8.10k
    rk += r * 8;
3896
#else
3897
3898
    /*
3899
     * Nr - 1 full rounds:
3900
     */
3901
3902
    for (;;) {
3903
        DEC_ROUND_T_S(0);
3904
3905
        rk += 8;
3906
        if (--r == 0) {
3907
            break;
3908
        }
3909
3910
        DEC_ROUND_S_T(0);
3911
    }
3912
#endif
3913
    /*
3914
     * apply last round and
3915
     * map cipher state to byte array block:
3916
     */
3917
3918
8.10k
#ifndef WC_NO_CACHE_RESISTANT
3919
8.10k
    if (*prefetch_ptr == 0) {
3920
718
        t0 |= PreFetchTd4();
3921
718
        if (prefetch_ptr != &always_prefetch)
3922
518
            *prefetch_ptr = 1;
3923
718
    }
3924
#else
3925
    (void)prefetch_ptr;
3926
#endif
3927
3928
8.10k
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3929
8.10k
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3930
8.10k
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3931
8.10k
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3932
8.10k
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3933
8.10k
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3934
8.10k
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3935
8.10k
                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
3936
3937
#else /* WOLFSSL_AES_SMALL_TABLES */
3938
3939
#ifndef WC_NO_CACHE_RESISTANT
3940
    if (*prefetch_ptr == 0) {
3941
        s0 |= PreFetchTd4();
3942
        if (prefetch_ptr != &always_prefetch)
3943
            *prefetch_ptr = 1;
3944
    }
3945
#else
3946
    (void)prefetch_ptr;
3947
#endif
3948
3949
    r *= 2;
3950
    for (rk += 4; r > 1; r--, rk += 4) {
3951
        t0 =
3952
            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3953
            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3954
            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3955
            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
3956
            rk[0];
3957
        t1 =
3958
            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3959
            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3960
            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3961
            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
3962
            rk[1];
3963
        t2 =
3964
            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3965
            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3966
            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3967
            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
3968
            rk[2];
3969
        t3 =
3970
            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3971
            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3972
            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3973
            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
3974
            rk[3];
3975
3976
        s0 =
3977
            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
3978
            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
3979
            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
3980
            (inv_col_mul(t0, 1, 3, 2, 0)      );
3981
        s1 =
3982
            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
3983
            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
3984
            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
3985
            (inv_col_mul(t1, 1, 3, 2, 0)      );
3986
        s2 =
3987
            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
3988
            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
3989
            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
3990
            (inv_col_mul(t2, 1, 3, 2, 0)      );
3991
        s3 =
3992
            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
3993
            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
3994
            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
3995
            (inv_col_mul(t3, 1, 3, 2, 0)      );
3996
    }
3997
3998
    t0 =
3999
        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
4000
        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
4001
        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
4002
        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
4003
    t1 =
4004
        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
4005
        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
4006
        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
4007
        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
4008
    t2 =
4009
        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
4010
        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
4011
        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
4012
        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
4013
    t3 =
4014
        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
4015
        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
4016
        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
4017
        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
4018
    s0 = t0 ^ rk[0];
4019
    s1 = t1 ^ rk[1];
4020
    s2 = t2 ^ rk[2];
4021
    s3 = t3 ^ rk[3];
4022
4023
#endif /* WOLFSSL_AES_SMALL_TABLES */
4024
4025
    /* write out */
4026
#ifdef WOLFSSL_WIDE_BYTE
4027
    stw[0] = s0; stw[1] = s1; stw[2] = s2; stw[3] = s3;
4028
    BytesFromWordsBE32(outBlock, stw, WC_AES_BLOCK_SIZE);
4029
#else
4030
8.10k
#ifdef LITTLE_ENDIAN_ORDER
4031
8.10k
    s0 = ByteReverseWord32(s0);
4032
8.10k
    s1 = ByteReverseWord32(s1);
4033
8.10k
    s2 = ByteReverseWord32(s2);
4034
8.10k
    s3 = ByteReverseWord32(s3);
4035
8.10k
#endif
4036
4037
8.10k
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
4038
8.10k
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
4039
8.10k
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
4040
8.10k
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
4041
8.10k
#endif /* WOLFSSL_WIDE_BYTE */
4042
4043
8.10k
}
4044
4045
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
4046
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
4047
    !defined(MAX3266X_AES)
4048
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
4049
/* Decrypt a number of blocks using AES.
4050
 *
4051
 * @param [in]  aes  AES object.
4052
 * @param [in]  in   Block to encrypt.
4053
 * @param [out] out  Encrypted block.
4054
 * @param [in]  sz   Number of blocks to encrypt.
4055
 */
4056
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
4057
337
{
4058
337
    word32 i;
4059
337
    int did_prefetches = 0;
4060
4061
1.03k
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
4062
696
        AesDecrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
4063
696
        in += WC_AES_BLOCK_SIZE;
4064
696
        out += WC_AES_BLOCK_SIZE;
4065
696
    }
4066
337
}
4067
#endif
4068
#endif
4069
4070
#else /* WC_AES_BITSLICED */
4071
4072
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
4073
static void bs_inv_sub_bytes(bs_word u[8])
4074
{
4075
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
4076
    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
4077
    bs_word RTL0, RTL1, RTL2;
4078
    bs_word sa0, sa1;
4079
    bs_word sb0, sb1;
4080
    bs_word ab0, ab1, ab2, ab3;
4081
    bs_word ab20, ab21, ab22, ab23;
4082
    bs_word al, ah, aa, bl, bh, bb;
4083
    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
4084
    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
4085
    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
4086
    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
4087
    bs_word rr1, rr2;
4088
    bs_word r10, r11;
4089
    bs_word cp1, cp2, cp3, cp4;
4090
    bs_word vr1, vr2, vr3;
4091
    bs_word pr1, pr2, pr3;
4092
    bs_word wr1, wr2, wr3;
4093
    bs_word qr1, qr2, qr3;
4094
    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
4095
    bs_word tinv10, tinv11, tinv12, tinv13;
4096
    bs_word t01, t02;
4097
    bs_word d0, d1, d2, d3;
4098
    bs_word dl, dd, dh;
4099
    bs_word sd0, sd1;
4100
    bs_word p0, p1, p2, p3, p4, p6, p7;
4101
    bs_word X11, X13, X14, X16, X18, X19;
4102
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
4103
4104
    U0 = u[7];
4105
    U1 = u[6];
4106
    U2 = u[5];
4107
    U3 = u[4];
4108
    U4 = u[3];
4109
    U5 = u[2];
4110
    U6 = u[1];
4111
    U7 = u[0];
4112
4113
    Y0 = U0 ^ U3;
4114
    Y2 = ~(U1 ^ U3);
4115
    Y4 = U0 ^ Y2;
4116
    RTL0 = U6 ^ U7;
4117
    Y1 = Y2 ^ RTL0;
4118
    Y7 = ~(U2 ^ Y1);
4119
    RTL1 = U3 ^ U4;
4120
    Y6 = ~(U7 ^ RTL1);
4121
    Y3 = Y1 ^ RTL1;
4122
    RTL2 = ~(U0 ^ U2);
4123
    Y5 = U5 ^ RTL2;
4124
    sa1 = Y0 ^ Y2;
4125
    sa0 = Y1 ^ Y3;
4126
    sb1 = Y4 ^ Y6;
4127
    sb0 = Y5 ^ Y7;
4128
    ah = Y0 ^ Y1;
4129
    al = Y2 ^ Y3;
4130
    aa = sa0 ^ sa1;
4131
    bh = Y4 ^ Y5;
4132
    bl = Y6 ^ Y7;
4133
    bb = sb0 ^ sb1;
4134
    ab20 = sa0 ^ sb0;
4135
    ab22 = al ^ bl;
4136
    ab23 = Y3 ^ Y7;
4137
    ab21 = sa1 ^ sb1;
4138
    abcd1 = ah & bh;
4139
    rr1 = Y0 & Y4;
4140
    ph11 = ab20 ^ abcd1;
4141
    t01 = Y1 & Y5;
4142
    ph01 = t01 ^ abcd1;
4143
    abcd2 = al & bl;
4144
    r1 = Y2 & Y6;
4145
    pl11 = ab22 ^ abcd2;
4146
    r2 = Y3 & Y7;
4147
    pl01 = r2 ^ abcd2;
4148
    r3 = sa0 & sb0;
4149
    vr1 = aa & bb;
4150
    pr1 = vr1 ^ r3;
4151
    wr1 = sa1 & sb1;
4152
    qr1 = wr1 ^ r3;
4153
    ab0 = ph11 ^ rr1;
4154
    ab1 = ph01 ^ ab21;
4155
    ab2 = pl11 ^ r1;
4156
    ab3 = pl01 ^ qr1;
4157
    cp1 = ab0 ^ pr1;
4158
    cp2 = ab1 ^ qr1;
4159
    cp3 = ab2 ^ pr1;
4160
    cp4 = ab3 ^ ab23;
4161
    tinv1 = cp3 ^ cp4;
4162
    tinv2 = cp3 & cp1;
4163
    tinv3 = cp2 ^ tinv2;
4164
    tinv4 = cp1 ^ cp2;
4165
    tinv5 = cp4 ^ tinv2;
4166
    tinv6 = tinv5 & tinv4;
4167
    tinv7 = tinv3 & tinv1;
4168
    d2 = cp4 ^ tinv7;
4169
    d0 = cp2 ^ tinv6;
4170
    tinv8 = cp1 & cp4;
4171
    tinv9 = tinv4 & tinv8;
4172
    tinv10 = tinv4 ^ tinv2;
4173
    d1 = tinv9 ^ tinv10;
4174
    tinv11 = cp2 & cp3;
4175
    tinv12 = tinv1 & tinv11;
4176
    tinv13 = tinv1 ^ tinv2;
4177
    d3 = tinv12 ^ tinv13;
4178
    sd1 = d1 ^ d3;
4179
    sd0 = d0 ^ d2;
4180
    dl = d0 ^ d1;
4181
    dh = d2 ^ d3;
4182
    dd = sd0 ^ sd1;
4183
    abcd3 = dh & bh;
4184
    rr2 = d3 & Y4;
4185
    t02 = d2 & Y5;
4186
    abcd4 = dl & bl;
4187
    r4 = d1 & Y6;
4188
    r5 = d0 & Y7;
4189
    r6 = sd0 & sb0;
4190
    vr2 = dd & bb;
4191
    wr2 = sd1 & sb1;
4192
    abcd5 = dh & ah;
4193
    r7 = d3 & Y0;
4194
    r8 = d2 & Y1;
4195
    abcd6 = dl & al;
4196
    r9 = d1 & Y2;
4197
    r10 = d0 & Y3;
4198
    r11 = sd0 & sa0;
4199
    vr3 = dd & aa;
4200
    wr3 = sd1 & sa1;
4201
    ph12 = rr2 ^ abcd3;
4202
    ph02 = t02 ^ abcd3;
4203
    pl12 = r4 ^ abcd4;
4204
    pl02 = r5 ^ abcd4;
4205
    pr2 = vr2 ^ r6;
4206
    qr2 = wr2 ^ r6;
4207
    p0 = ph12 ^ pr2;
4208
    p1 = ph02 ^ qr2;
4209
    p2 = pl12 ^ pr2;
4210
    p3 = pl02 ^ qr2;
4211
    ph13 = r7 ^ abcd5;
4212
    ph03 = r8 ^ abcd5;
4213
    pl13 = r9 ^ abcd6;
4214
    pl03 = r10 ^ abcd6;
4215
    pr3 = vr3 ^ r11;
4216
    qr3 = wr3 ^ r11;
4217
    p4 = ph13 ^ pr3;
4218
    S7 = ph03 ^ qr3;
4219
    p6 = pl13 ^ pr3;
4220
    p7 = pl03 ^ qr3;
4221
    S3 = p1 ^ p6;
4222
    S6 = p2 ^ p6;
4223
    S0 = p3 ^ p6;
4224
    X11 = p0 ^ p2;
4225
    S5 = S0 ^ X11;
4226
    X13 = p4 ^ p7;
4227
    X14 = X11 ^ X13;
4228
    S1 = S3 ^ X14;
4229
    X16 = p1 ^ S7;
4230
    S2 = X14 ^ X16;
4231
    X18 = p0 ^ p4;
4232
    X19 = S5 ^ X16;
4233
    S4 = X18 ^ X19;
4234
4235
    u[0] = S7;
4236
    u[1] = S6;
4237
    u[2] = S5;
4238
    u[3] = S4;
4239
    u[4] = S3;
4240
    u[5] = S2;
4241
    u[6] = S1;
4242
    u[7] = S0;
4243
}
4244
4245
static void bs_inv_shift_rows(bs_word* b)
4246
{
4247
    bs_word t[AES_BLOCK_BITS];
4248
    int i;
4249
4250
    for (i = 0; i < 128; i += 32) {
4251
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
4252
        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
4253
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
4254
        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
4255
    }
4256
4257
    XMEMCPY(b, t, sizeof(t));
4258
}
4259
4260
#define O0  0
4261
#define O1  8
4262
#define O2  16
4263
#define O3  24
4264
4265
#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
4266
    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
4267
          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
4268
    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
4269
          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
4270
    of2 =                     b[O0+7] ^             b[O1+7] ^               \
4271
                    b[O2+7] ^ b[O3+7];                                      \
4272
                                                                            \
4273
    br[0] =                                                   b[O1+0] ^     \
4274
            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
4275
    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
4276
            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
4277
    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
4278
            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
4279
    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
4280
            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
4281
    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
4282
            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
4283
    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
4284
            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
4285
    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
4286
            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
4287
    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
4288
            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
4289
4290
/* Inverse mix columns and shift rows. */
4291
static void bs_inv_mix_shift(bs_word* t, bs_word* b)
4292
{
4293
    bs_word* bp = b;
4294
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
4295
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
4296
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
4297
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
4298
    int i;
4299
4300
    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
4301
        bs_word* br;
4302
        bs_word of0;
4303
        bs_word of1;
4304
        bs_word of2;
4305
4306
        br = t + or0;
4307
        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
4308
        br = t + or1;
4309
        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
4310
        br = t + or2;
4311
        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
4312
        br = t + or3;
4313
        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
4314
4315
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4316
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4317
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4318
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4319
4320
        bp += AES_BLOCK_BITS / 4;
4321
    }
4322
}
4323
4324
static void bs_inv_sub_bytes_blocks(bs_word* b)
4325
{
4326
    int i;
4327
4328
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
4329
        bs_inv_sub_bytes(b + i);
4330
    }
4331
}
4332
4333
static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
4334
{
4335
    int i;
4336
    bs_word trans[AES_BLOCK_BITS];
4337
4338
    bs_transpose(trans, state);
4339
4340
    rk += r * AES_BLOCK_BITS;
4341
    bs_add_round_key(trans, trans, rk);
4342
    bs_inv_shift_rows(trans);
4343
    bs_inv_sub_bytes_blocks(trans);
4344
    rk -= AES_BLOCK_BITS;
4345
    bs_add_round_key(trans, trans, rk);
4346
    for (i = (int)r - 2; i >= 0; i--) {
4347
        bs_inv_mix_shift(state, trans);
4348
        bs_inv_sub_bytes_blocks(state);
4349
        rk -= AES_BLOCK_BITS;
4350
        bs_add_round_key(trans, state, rk);
4351
    }
4352
4353
    bs_inv_transpose(state, trans);
4354
}
4355
4356
#ifdef WOLFSSL_AES_DIRECT
4357
/* Decrypt a block using AES.
4358
 *
4359
 * @param [in]  aes       AES object.
4360
 * @param [in]  inBlock   Block to encrypt.
4361
 * @param [out] outBlock  Encrypted block.
4362
 * @param [in]  r         Rounds divided by 2.
4363
 */
4364
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
4365
    word32 r)
4366
{
4367
    bs_word state[AES_BLOCK_BITS];
4368
4369
    (void)r;
4370
4371
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
4372
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
4373
4374
    bs_decrypt(state, aes->bs_key, aes->rounds);
4375
4376
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
4377
}
4378
#endif
4379
4380
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
4381
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
4382
/* Decrypt a number of blocks using AES.
4383
 *
4384
 * @param [in]  aes  AES object.
4385
 * @param [in]  in   Block to encrypt.
4386
 * @param [out] out  Encrypted block.
4387
 * @param [in]  sz   Number of blocks to encrypt.
4388
 */
4389
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
4390
{
4391
    bs_word state[AES_BLOCK_BITS];
4392
4393
    while (sz >= BS_BLOCK_SIZE) {
4394
        XMEMCPY(state, in, BS_BLOCK_SIZE);
4395
        bs_decrypt(state, aes->bs_key, aes->rounds);
4396
        XMEMCPY(out, state, BS_BLOCK_SIZE);
4397
        sz  -= BS_BLOCK_SIZE;
4398
        in  += BS_BLOCK_SIZE;
4399
        out += BS_BLOCK_SIZE;
4400
    }
4401
    if (sz > 0) {
4402
        XMEMCPY(state, in, sz);
4403
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
4404
        bs_decrypt(state, aes->bs_key, aes->rounds);
4405
        XMEMCPY(out, state, sz);
4406
    }
4407
}
4408
#endif
4409
4410
#endif /* !WC_AES_BITSLICED */
4411
#endif
4412
4413
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
4414
    defined(WOLFSSL_AES_DIRECT)
4415
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
4416
#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
4417
/* Software AES - ECB Decrypt */
4418
4419
#ifdef WC_AES_HAVE_PREFETCH_ARG
4420
#define wc_AesDecrypt(aes, inBlock, outBlock) \
4421
200
    AesDecrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
4422
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesDecrypt_preFetchOpt(
4423
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
4424
#else
4425
#define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
4426
    wc_AesDecrypt(aes, inBlock, outBlock)
4427
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
4428
    Aes* aes, const byte* inBlock, byte* outBlock)
4429
#endif
4430
7.41k
{
4431
#if defined(MAX3266X_AES)
4432
    word32 keySize;
4433
#endif
4434
#if defined(MAX3266X_CB)
4435
    int ret_cb;
4436
#endif
4437
7.41k
    word32 r;
4438
4439
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4440
    {
4441
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4442
        if (ret < 0)
4443
            return ret;
4444
    }
4445
#endif
4446
4447
7.41k
    r = aes->rounds >> 1;
4448
4449
7.41k
    if (r > 7 || r == 0) {
4450
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
4451
0
        return KEYUSAGE_E;
4452
0
    }
4453
4454
#ifdef WOLFSSL_AESNI
4455
    if (aes->use_aesni) {
4456
        ASSERT_SAVED_VECTOR_REGISTERS();
4457
4458
        #ifdef DEBUG_AESNI
4459
            printf("about to aes decrypt\n");
4460
            printf("in  = %p\n", inBlock);
4461
            printf("out = %p\n", outBlock);
4462
            printf("aes->key = %p\n", aes->key);
4463
            printf("aes->rounds = %d\n", aes->rounds);
4464
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
4465
        #endif
4466
4467
        /* if input and output same will overwrite input iv */
4468
        if ((const byte*)aes->tmp != inBlock)
4469
            XMEMCPY(aes->tmp, inBlock, WC_AES_BLOCK_SIZE);
4470
        AES_ECB_decrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
4471
                        (int)aes->rounds);
4472
        return 0;
4473
    }
4474
    else {
4475
        #ifdef DEBUG_AESNI
4476
            printf("Skipping AES-NI\n");
4477
        #endif
4478
    }
4479
#elif defined(WOLFSSL_ARMASM)
4480
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4481
#if !defined(__aarch64__)
4482
#ifdef WOLFSSL_ARM32_AES_DISPATCH
4483
    if (aes->use_aes_hw_crypto) {
4484
        AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key,
4485
            (int)aes->rounds);
4486
    }
4487
    else
4488
#else
4489
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
4490
#endif /* WOLFSSL_ARM32_AES_DISPATCH */
4491
#else
4492
    if (aes->use_aes_hw_crypto) {
4493
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
4494
            (int)aes->rounds);
4495
    }
4496
    else
4497
#endif /* !__aarch64__ */
4498
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
4499
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
4500
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
4501
    {
4502
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4503
            (const unsigned char*)aes->key, aes->rounds);
4504
    }
4505
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
4506
      defined(WOLFSSL_ARM32_AES_DISPATCH)
4507
    {
4508
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4509
            (const unsigned char*)aes->key, aes->rounds);
4510
    }
4511
#endif
4512
    return 0;
4513
#endif /* WOLFSSL_AESNI */
4514
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
4515
    return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
4516
#endif
4517
#if defined(WOLFSSL_IMXRT_DCP)
4518
    if (aes->keylen == 16) {
4519
        DCPAesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4520
        return 0;
4521
    }
4522
#endif
4523
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
4524
    if (aes->useSWCrypt == 0) {
4525
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
4526
                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
4527
    }
4528
#endif
4529
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
4530
    if (wc_esp32AesSupportedKeyLen(aes)) {
4531
        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
4532
    }
4533
    else {
4534
        /* For example, the ESP32-S3 does not support HW for len = 24,
4535
         * so fall back to SW */
4536
    #ifdef DEBUG_WOLFSSL
4537
        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
4538
                        "unsupported keylen = %d", aes->keylen);
4539
    #endif
4540
    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
4541
#endif
4542
4543
#if defined(MAX3266X_AES)
4544
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
4545
        return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
4546
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
4547
                                    outBlock, (unsigned int)keySize);
4548
    }
4549
#endif
4550
4551
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
4552
    #ifndef WOLF_CRYPTO_CB_FIND
4553
    if (aes->devId != INVALID_DEVID)
4554
    #endif
4555
    {
4556
        ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock,
4557
                                            WC_AES_BLOCK_SIZE);
4558
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4559
            return ret_cb;
4560
        /* fall-through when unavailable */
4561
    }
4562
#endif
4563
4564
7.41k
#ifdef WC_AES_HAVE_PREFETCH_ARG
4565
7.41k
    AesDecrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
4566
#else
4567
    AesDecrypt_C(aes, inBlock, outBlock, r);
4568
#endif
4569
4570
7.41k
    return 0;
4571
7.41k
} /* wc_AesDecrypt[_SW]() */
4572
#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
4573
#endif
4574
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
4575
#endif /* HAVE_AES_DECRYPT */
4576
4577
#endif /* NEED_AES_TABLES */
4578
4579
#ifdef WOLF_CRYPTO_CB_ONLY_AES
4580
/* Under WOLF_CRYPTO_CB_ONLY_AES the per-block primitive is a thin shim over
4581
 * the cryptocb ECB callback. When the callback returns CRYPTOCB_UNAVAILABLE
4582
 * there is no software fallback, so the operation fails with NO_VALID_DEVID. */
4583
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
4584
    byte* outBlock)
4585
{
4586
    int ret;
4587
4588
    if (aes == NULL || inBlock == NULL || outBlock == NULL)
4589
        return BAD_FUNC_ARG;
4590
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4591
    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4592
    if (ret < 0)
4593
        return ret;
4594
#endif
4595
4596
    ret = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4597
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4598
        return ret;
4599
    return NO_VALID_DEVID;
4600
}
4601
4602
#ifdef HAVE_AES_DECRYPT
4603
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
4604
    byte* outBlock)
4605
{
4606
    int ret;
4607
4608
    if (aes == NULL || inBlock == NULL || outBlock == NULL)
4609
        return BAD_FUNC_ARG;
4610
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4611
    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4612
    if (ret < 0)
4613
        return ret;
4614
#endif
4615
4616
    ret = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4617
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4618
        return ret;
4619
    return NO_VALID_DEVID;
4620
}
4621
#endif /* HAVE_AES_DECRYPT */
4622
#endif /* WOLF_CRYPTO_CB_ONLY_AES */
4623
4624
#ifndef WC_AES_HAVE_PREFETCH_ARG
4625
    #ifndef AesEncrypt_preFetchOpt
4626
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4627
            wc_AesEncrypt(aes, inBlock, outBlock)
4628
    #endif
4629
    #ifndef AesDecrypt_preFetchOpt
4630
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4631
            wc_AesDecrypt(aes, inBlock, outBlock)
4632
    #endif
4633
#endif
4634
4635
/* wc_AesSetKey */
4636
#if defined(STM32_CRYPTO)
4637
4638
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4639
            const byte* iv, int dir)
4640
    {
4641
        word32 *rk;
4642
4643
        (void)dir;
4644
4645
        if (aes == NULL || (keylen != 16 &&
4646
        #ifdef WOLFSSL_AES_192
4647
            keylen != 24 &&
4648
        #endif
4649
            keylen != 32)) {
4650
            return BAD_FUNC_ARG;
4651
        }
4652
4653
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4654
        {
4655
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4656
            if (ret < 0)
4657
                return ret;
4658
        }
4659
#endif
4660
4661
        rk = aes->key;
4662
        aes->keylen = keylen;
4663
        aes->keyInstalled = 1;
4664
        aes->rounds = keylen/4 + 6;
4665
        XMEMCPY(rk, userKey, keylen);
4666
    #ifdef WOLF_CRYPTO_CB
4667
        /* Keep a raw (non-reversed) copy for crypto-callback offload, e.g. the
4668
         * DHUK device reads the seed from devKey. Mirrors the generic
4669
         * wc_AesSetKey cryptocb path. */
4670
        if (keylen <= sizeof(aes->devKey)) {
4671
            XMEMCPY(aes->devKey, userKey, keylen);
4672
        }
4673
    #endif
4674
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
4675
        ByteReverseWords(rk, rk, keylen);
4676
    #endif
4677
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4678
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4679
        defined(WOLFSSL_AES_CTS)
4680
        aes->left = 0;
4681
    #endif
4682
        return wc_AesSetIV(aes, iv);
4683
    }
4684
    #if defined(WOLFSSL_AES_DIRECT)
4685
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4686
                            const byte* iv, int dir)
4687
        {
4688
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4689
        }
4690
    #endif
4691
4692
#elif defined(HAVE_COLDFIRE_SEC)
4693
    #if defined (HAVE_THREADX)
4694
        #include "memory_pools.h"
4695
        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
4696
    #endif
4697
4698
    #define AES_BUFFER_SIZE (WC_AES_BLOCK_SIZE * 64)
4699
    static unsigned char *AESBuffIn = NULL;
4700
    static unsigned char *AESBuffOut = NULL;
4701
    static byte *secReg;
4702
    static byte *secKey;
4703
    static volatile SECdescriptorType *secDesc;
4704
4705
    static wolfSSL_Mutex Mutex_AesSEC;
4706
4707
    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
4708
    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
4709
4710
    extern volatile unsigned char __MBAR[];
4711
4712
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4713
        const byte* iv, int dir)
4714
    {
4715
        if (AESBuffIn == NULL) {
4716
        #if defined (HAVE_THREADX)
4717
            int s1, s2, s3, s4, s5;
4718
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
4719
                                  sizeof(SECdescriptorType), TX_NO_WAIT);
4720
            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
4721
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4722
            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
4723
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4724
            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
4725
                                  WC_AES_BLOCK_SIZE*2, TX_NO_WAIT);
4726
            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
4727
                                  WC_AES_BLOCK_SIZE, TX_NO_WAIT);
4728
4729
            if (s1 || s2 || s3 || s4 || s5)
4730
                return BAD_FUNC_ARG;
4731
        #else
4732
            #warning "Allocate non-Cache buffers"
4733
        #endif
4734
4735
            wc_InitMutex(&Mutex_AesSEC);
4736
        }
4737
4738
        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4739
            return BAD_FUNC_ARG;
4740
4741
        if (aes == NULL)
4742
            return BAD_FUNC_ARG;
4743
4744
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4745
        {
4746
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4747
            if (ret < 0)
4748
                return ret;
4749
        }
4750
#endif
4751
4752
        aes->keylen = keylen;
4753
        aes->keyInstalled = 1;
4754
        aes->rounds = keylen/4 + 6;
4755
        XMEMCPY(aes->key, userKey, keylen);
4756
4757
        if (iv)
4758
            XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4759
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
4766
        return 0;
4767
    }
4768
#elif defined(FREESCALE_LTC)
4769
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
4770
        const byte* iv, int dir, int checkKeyLen)
4771
    {
4772
        if (aes == NULL)
4773
            return BAD_FUNC_ARG;
4774
4775
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4776
        {
4777
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4778
            if (ret < 0)
4779
                return ret;
4780
        }
4781
#endif
4782
4783
        if (checkKeyLen) {
4784
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4785
                return BAD_FUNC_ARG;
4786
        }
4787
        (void)dir;
4788
4789
        aes->rounds = keylen/4 + 6;
4790
        XMEMCPY(aes->key, userKey, keylen);
4791
        aes->keyInstalled = 1;
4792
4793
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4794
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4795
        defined(WOLFSSL_AES_CTS)
4796
        aes->left = 0;
4797
    #endif
4798
4799
        return wc_AesSetIV(aes, iv);
4800
    }
4801
4802
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4803
        const byte* iv, int dir)
4804
    {
4805
        if (aes == NULL || userKey == NULL) {
4806
            return BAD_FUNC_ARG;
4807
        }
4808
        if (keylen > sizeof(aes->key)) {
4809
            return BAD_FUNC_ARG;
4810
        }
4811
4812
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4813
    }
4814
4815
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4816
                        const byte* iv, int dir)
4817
    {
4818
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4819
    }
4820
#elif defined(WOLFSSL_NRF51_AES)
4821
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4822
        const byte* iv, int dir)
4823
    {
4824
        int ret;
4825
4826
        (void)dir;
4827
        (void)iv;
4828
4829
        if (aes == NULL || keylen != 16)
4830
            return BAD_FUNC_ARG;
4831
4832
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4833
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4834
        if (ret < 0)
4835
            return ret;
4836
#endif
4837
4838
        aes->keylen = keylen;
4839
        aes->keyInstalled = 1;
4840
        aes->rounds = keylen/4 + 6;
4841
        XMEMCPY(aes->key, userKey, keylen);
4842
        ret = nrf51_aes_set_key(userKey);
4843
4844
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4845
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4846
        defined(WOLFSSL_AES_CTS)
4847
        aes->left = 0;
4848
    #endif
4849
4850
        return ret;
4851
    }
4852
4853
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4854
                        const byte* iv, int dir)
4855
    {
4856
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4857
    }
4858
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4859
    /* This is the only definition for HW only.
4860
     * but needs to be renamed when fallback needed.
4861
     * See call in wc_AesSetKey() */
4862
    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
4863
        const byte* iv, int dir)
4864
    {
4865
        (void)dir;
4866
        (void)iv;
4867
        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
4868
        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
4869
            return BAD_FUNC_ARG;
4870
        }
4871
4872
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4873
        {
4874
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4875
            if (ret < 0)
4876
                return ret;
4877
        }
4878
#endif
4879
4880
    #if !defined(WOLFSSL_AES_128)
4881
        if (keylen == 16) {
4882
            return BAD_FUNC_ARG;
4883
        }
4884
    #endif
4885
4886
    #if !defined(WOLFSSL_AES_192)
4887
        if (keylen == 24) {
4888
            return BAD_FUNC_ARG;
4889
        }
4890
    #endif
4891
4892
    #if !defined(WOLFSSL_AES_256)
4893
        if (keylen == 32) {
4894
            return BAD_FUNC_ARG;
4895
        }
4896
    #endif
4897
4898
        aes->keylen = keylen;
4899
        aes->keyInstalled = 1;
4900
        aes->rounds = keylen/4 + 6;
4901
4902
        XMEMCPY(aes->key, userKey, keylen);
4903
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4904
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4905
            defined(WOLFSSL_AES_CTS)
4906
            aes->left = 0;
4907
        #endif
4908
        return wc_AesSetIV(aes, iv);
4909
    } /* wc_AesSetKey */
4910
4911
    /* end #elif ESP32 */
4912
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
4913
4914
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
4915
                    int dir)
4916
    {
4917
        SaSiError_t ret = SASI_OK;
4918
        SaSiAesIv_t iv_aes;
4919
4920
        if (aes == NULL ||
4921
           (keylen != AES_128_KEY_SIZE &&
4922
            keylen != AES_192_KEY_SIZE &&
4923
            keylen != AES_256_KEY_SIZE)) {
4924
            return BAD_FUNC_ARG;
4925
        }
4926
4927
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4928
        {
4929
            int ret2 =
4930
                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4931
            if (ret2 < 0)
4932
                return ret2;
4933
        }
4934
#endif
4935
4936
    #if defined(AES_MAX_KEY_SIZE)
4937
        if (keylen > (AES_MAX_KEY_SIZE/8)) {
4938
            return BAD_FUNC_ARG;
4939
        }
4940
    #endif
4941
        if (dir != AES_ENCRYPTION &&
4942
            dir != AES_DECRYPTION) {
4943
            return BAD_FUNC_ARG;
4944
        }
4945
4946
        if (dir == AES_ENCRYPTION) {
4947
            aes->ctx.mode = SASI_AES_ENCRYPT;
4948
            SaSi_AesInit(&aes->ctx.user_ctx,
4949
                         SASI_AES_ENCRYPT,
4950
                         SASI_AES_MODE_CBC,
4951
                         SASI_AES_PADDING_NONE);
4952
        }
4953
        else {
4954
            aes->ctx.mode = SASI_AES_DECRYPT;
4955
            SaSi_AesInit(&aes->ctx.user_ctx,
4956
                         SASI_AES_DECRYPT,
4957
                         SASI_AES_MODE_CBC,
4958
                         SASI_AES_PADDING_NONE);
4959
        }
4960
4961
        aes->keylen = keylen;
4962
        aes->keyInstalled = 1;
4963
        aes->rounds = keylen/4 + 6;
4964
        XMEMCPY(aes->key, userKey, keylen);
4965
4966
        aes->ctx.key.pKey = (byte*)aes->key;
4967
        aes->ctx.key.keySize= keylen;
4968
4969
        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
4970
                             SASI_AES_USER_KEY,
4971
                             &aes->ctx.key,
4972
                             sizeof(aes->ctx.key));
4973
        if (ret != SASI_OK) {
4974
            return BAD_FUNC_ARG;
4975
        }
4976
4977
        ret = wc_AesSetIV(aes, iv);
4978
4979
        if (iv)
4980
            XMEMCPY(iv_aes, iv, WC_AES_BLOCK_SIZE);
4981
        else
4982
            XMEMSET(iv_aes,  0, WC_AES_BLOCK_SIZE);
4983
4984
4985
        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
4986
        if (ret != SASI_OK) {
4987
            return ret;
4988
        }
4989
       return ret;
4990
    }
4991
    #if defined(WOLFSSL_AES_DIRECT)
4992
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4993
                            const byte* iv, int dir)
4994
        {
4995
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4996
        }
4997
    #endif
4998
4999
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
5000
    && !defined(WOLFSSL_QNX_CAAM)
5001
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
5002
5003
#elif defined(WOLFSSL_AFALG)
5004
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
5005
5006
#elif defined(WOLFSSL_DEVCRYPTO_AES)
5007
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
5008
5009
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5010
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
5011
5012
#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
5013
     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
5014
    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
5015
5016
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
5017
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5018
            const byte* iv, int dir)
5019
    {
5020
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5021
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5022
        defined(WOLFSSL_AES_CTS)
5023
        aes->left = 0;
5024
    #endif
5025
5026
        aes->keylen = (int)keylen;
5027
        aes->rounds = (keylen/4) + 6;
5028
        aes->keyInstalled = 1;
5029
5030
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
5031
#ifdef WOLFSSL_ARM32_AES_DISPATCH
5032
        Check_CPU_support_HwCrypto(aes);
5033
        if (aes->use_aes_hw_crypto) {
5034
            AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5035
        }
5036
        else
5037
#else
5038
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5039
#endif /* WOLFSSL_ARM32_AES_DISPATCH */
5040
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
5041
#if defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || defined(WOLFSSL_ARM32_AES_DISPATCH)
5042
        {
5043
            AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5044
5045
        #ifdef HAVE_AES_DECRYPT
5046
            if (dir == AES_DECRYPTION) {
5047
                AES_invert_key((byte*)aes->key, aes->rounds);
5048
            }
5049
        #else
5050
            (void)dir;
5051
        #endif
5052
        }
5053
#endif
5054
        return wc_AesSetIV(aes, iv);
5055
    }
5056
5057
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5058
            const byte* iv, int dir)
5059
    {
5060
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
5061
        int cbRet;
5062
#endif
5063
        if ((aes == NULL) || (userKey == NULL)) {
5064
            return BAD_FUNC_ARG;
5065
        }
5066
5067
        switch (keylen) {
5068
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5069
        defined(WOLFSSL_AES_128)
5070
        case 16:
5071
    #endif
5072
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5073
        defined(WOLFSSL_AES_192)
5074
        case 24:
5075
    #endif
5076
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5077
        defined(WOLFSSL_AES_256)
5078
        case 32:
5079
    #endif
5080
            break;
5081
        default:
5082
            return BAD_FUNC_ARG;
5083
        }
5084
5085
    #ifdef WOLF_CRYPTO_CB
5086
        if (aes->devId != INVALID_DEVID) {
5087
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5088
            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5089
            if (ret == 0) {
5090
                /* Callback succeeded - SE owns the key */
5091
                aes->keylen = (int)keylen;
5092
                aes->keyInstalled = 1;
5093
                if (iv != NULL)
5094
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5095
                else
5096
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5097
                return 0;
5098
            }
5099
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5100
                aes->devCtx = NULL;
5101
                return ret;
5102
            }
5103
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5104
        #endif
5105
        #ifdef WOLF_CRYPTO_CB_SETKEY
5106
            cbRet = wc_CryptoCb_SetKey(aes->devId,
5107
                WC_SETKEY_AES, aes, (void*)userKey, keylen,
5108
                (void*)iv,
5109
                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
5110
            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5111
                if (cbRet == 0) {
5112
                    /* Callback succeeded - the device owns the key, so mark it
5113
                     * installed like the AES_SETKEY path above. */
5114
                    aes->keylen = (int)keylen;
5115
                    aes->keyInstalled = 1;
5116
                }
5117
                return cbRet;
5118
            }
5119
            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
5120
        #endif /* WOLF_CRYPTO_CB_SETKEY */
5121
            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
5122
            if (keylen > sizeof(aes->devKey)) {
5123
                return BAD_FUNC_ARG;
5124
            }
5125
            XMEMCPY(aes->devKey, userKey, keylen);
5126
        }
5127
    #endif
5128
5129
        return AesSetKey(aes, userKey, keylen, iv, dir);
5130
    }
5131
5132
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5133
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5134
        /* This function allows key sizes that are not 128/192/256 bits */
5135
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5136
                           const byte* iv, int dir)
5137
    {
5138
        if (aes == NULL) {
5139
            return BAD_FUNC_ARG;
5140
        }
5141
        if (keylen > sizeof(aes->key)) {
5142
            return BAD_FUNC_ARG;
5143
        }
5144
5145
        return AesSetKey(aes, userKey, keylen, iv, dir);
5146
    }
5147
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5148
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
5149
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5150
            const byte* iv, int dir)
5151
    {
5152
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5153
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5154
        defined(WOLFSSL_AES_CTS)
5155
        aes->left = 0;
5156
    #endif
5157
5158
        aes->keylen = (int)keylen;
5159
        aes->rounds = (keylen/4) + 6;
5160
        aes->keyInstalled = 1;
5161
5162
        /* Determine base vs vector-crypto before the (dispatched) key setup so
5163
         * the schedule matches the mode functions that later consume it. */
5164
        Aes_SetCrypto();
5165
        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5166
5167
    #ifdef HAVE_AES_DECRYPT
5168
        if (dir == AES_DECRYPTION) {
5169
            AES_invert_key((byte*)aes->key, aes->rounds);
5170
        }
5171
    #else
5172
        (void)dir;
5173
    #endif
5174
        return wc_AesSetIV(aes, iv);
5175
    }
5176
5177
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5178
            const byte* iv, int dir)
5179
    {
5180
        if ((aes == NULL) || (userKey == NULL)) {
5181
            return BAD_FUNC_ARG;
5182
        }
5183
5184
        switch (keylen) {
5185
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5186
        defined(WOLFSSL_AES_128)
5187
        case 16:
5188
    #endif
5189
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5190
        defined(WOLFSSL_AES_192)
5191
        case 24:
5192
    #endif
5193
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5194
        defined(WOLFSSL_AES_256)
5195
        case 32:
5196
    #endif
5197
            break;
5198
        default:
5199
            return BAD_FUNC_ARG;
5200
        }
5201
5202
    #ifdef WOLF_CRYPTO_CB
5203
        if (aes->devId != INVALID_DEVID) {
5204
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5205
            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5206
            if (ret == 0) {
5207
                /* Callback succeeded - SE owns the key */
5208
                aes->keylen = (int)keylen;
5209
                aes->keyInstalled = 1;
5210
                if (iv != NULL)
5211
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5212
                else
5213
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5214
                return 0;
5215
            }
5216
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5217
                aes->devCtx = NULL;
5218
                return ret;
5219
            }
5220
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5221
        #endif
5222
            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
5223
            if (keylen > sizeof(aes->devKey)) {
5224
                return BAD_FUNC_ARG;
5225
            }
5226
            XMEMCPY(aes->devKey, userKey, keylen);
5227
        }
5228
    #endif
5229
5230
        return AesSetKey(aes, userKey, keylen, iv, dir);
5231
    }
5232
5233
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5234
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5235
        /* This function allows key sizes that are not 128/192/256 bits */
5236
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5237
                           const byte* iv, int dir)
5238
    {
5239
        if (aes == NULL) {
5240
            return BAD_FUNC_ARG;
5241
        }
5242
        if (keylen > sizeof(aes->key)) {
5243
            return BAD_FUNC_ARG;
5244
        }
5245
5246
        return AesSetKey(aes, userKey, keylen, iv, dir);
5247
    }
5248
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5249
#elif defined(FREESCALE_MMCAU)
5250
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
5251
        const byte* iv, int dir, int checkKeyLen)
5252
    {
5253
        int ret;
5254
        byte* rk;
5255
        byte* tmpKey = (byte*)userKey;
5256
        int tmpKeyDynamic = 0;
5257
        word32 alignOffset = 0;
5258
5259
        (void)dir;
5260
5261
        if (aes == NULL)
5262
            return BAD_FUNC_ARG;
5263
5264
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5265
        {
5266
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5267
            if (ret < 0)
5268
                return ret;
5269
        }
5270
#endif
5271
5272
        if (checkKeyLen) {
5273
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
5274
                return BAD_FUNC_ARG;
5275
        }
5276
5277
        rk = (byte*)aes->key;
5278
        if (rk == NULL)
5279
            return BAD_FUNC_ARG;
5280
5281
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5282
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5283
        defined(WOLFSSL_AES_CTS)
5284
        aes->left = 0;
5285
    #endif
5286
5287
        aes->rounds = keylen/4 + 6;
5288
5289
    #ifdef FREESCALE_MMCAU_CLASSIC
5290
        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
5291
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
5292
            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
5293
                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5294
            if (tmp == NULL) {
5295
                return MEMORY_E;
5296
            }
5297
            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
5298
                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
5299
            tmpKey = tmp + alignOffset;
5300
            XMEMCPY(tmpKey, userKey, keylen);
5301
            tmpKeyDynamic = 1;
5302
        #else
5303
            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
5304
            return BAD_ALIGN_E;
5305
        #endif
5306
        }
5307
    #endif
5308
5309
        ret = wolfSSL_CryptHwMutexLock();
5310
        if(ret == 0) {
5311
        #ifdef FREESCALE_MMCAU_CLASSIC
5312
            cau_aes_set_key(tmpKey, keylen*8, rk);
5313
        #else
5314
            MMCAU_AES_SetKey(tmpKey, keylen, rk);
5315
        #endif
5316
            wolfSSL_CryptHwMutexUnLock();
5317
5318
            aes->keyInstalled = 1;
5319
5320
            ret = wc_AesSetIV(aes, iv);
5321
        }
5322
5323
        if (tmpKeyDynamic == 1) {
5324
            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5325
        }
5326
5327
        return ret;
5328
    }
5329
5330
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5331
        const byte* iv, int dir)
5332
    {
5333
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
5334
    }
5335
5336
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5337
                        const byte* iv, int dir)
5338
    {
5339
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
5340
    }
5341
5342
#elif defined(WOLFSSL_PSOC6_CRYPTO)
5343
5344
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5345
        const byte* iv, int dir)
5346
    {
5347
        int ret;
5348
5349
        if (aes == NULL)
5350
            return BAD_FUNC_ARG;
5351
5352
        ret = wc_Psoc6_Aes_SetKey(aes, userKey, keylen, iv, dir);
5353
        if (ret == 0)
5354
            aes->keyInstalled = 1;
5355
        return ret;
5356
    }
5357
5358
    #if defined(WOLFSSL_AES_DIRECT)
5359
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5360
                            const byte* iv, int dir)
5361
        {
5362
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
5363
        }
5364
    #endif /* WOLFSSL_AES_DIRECT */
5365
#else
5366
    #define NEED_SOFTWARE_AES_SETKEY
5367
#endif
5368
5369
/* Either we fell though with no HW support at all,
5370
 * or perhaps there's HW support for *some* keylengths
5371
 * and we need both HW and SW. */
5372
#ifdef NEED_SOFTWARE_AES_SETKEY
5373
5374
#ifdef NEED_AES_TABLES
5375
5376
#ifndef WC_AES_BITSLICED
5377
#if !defined(WOLFSSL_ARMASM)
5378
/* Set the AES key and expand.
5379
 *
5380
 * @param [in]  aes    AES object.
5381
 * @param [in]  key    Block to encrypt.
5382
 * @param [in]  keySz  Number of bytes in key.
5383
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
5384
 */
5385
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
5386
4.26k
{
5387
#ifdef WC_C_DYNAMIC_FALLBACK
5388
    word32* rk = aes->key_C_fallback;
5389
#else
5390
4.26k
    word32* rk = aes->key;
5391
4.26k
#endif
5392
4.26k
    word32 temp;
5393
4.26k
    unsigned int i = 0;
5394
5395
#ifdef WOLFSSL_WIDE_BYTE
5396
    /* A C byte is wider than an octet: assemble the big-endian key schedule
5397
     * words octet-wise rather than aliasing the key byte buffer as word32. */
5398
    WordsFromBytesBE32(rk, key, keySz / 4);
5399
#else
5400
4.26k
    XMEMCPY(rk, key, keySz);
5401
4.26k
#endif
5402
4.26k
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_WIDE_BYTE) && \
5403
4.26k
    !defined(WOLFSSL_PIC32MZ_CRYPT) && \
5404
4.26k
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
5405
4.26k
    !defined(MAX3266X_AES)
5406
    /* Always reverse words when using only SW */
5407
4.26k
    {
5408
4.26k
        ByteReverseWords(rk, rk, keySz);
5409
4.26k
    }
5410
#else
5411
    /* Sometimes reverse words when using supported HW */
5412
    #if defined(WOLFSSL_ESPIDF)
5413
        /* Some platforms may need SW fallback (e.g. AES192) */
5414
        #if defined(NEED_AES_HW_FALLBACK)
5415
        {
5416
            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
5417
            if (wc_esp32AesSupportedKeyLen(aes)) {
5418
                /* don't reverse for HW supported key lengths */
5419
            }
5420
            else {
5421
                ByteReverseWords(rk, rk, keySz);
5422
            }
5423
        }
5424
        #else
5425
            /* If we don't need SW fallback, don't need to reverse words. */
5426
        #endif /* NEED_AES_HW_FALLBACK */
5427
    #endif /* WOLFSSL_ESPIDF */
5428
#endif /* LITTLE_ENDIAN_ORDER, etc */
5429
5430
4.26k
    switch (keySz) {
5431
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
5432
0
        defined(WOLFSSL_AES_128)
5433
2.40k
    case 16:
5434
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5435
        temp = (word32)-1;
5436
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5437
    #endif
5438
24.0k
        while (1)
5439
24.0k
        {
5440
24.0k
            temp  = rk[3];
5441
24.0k
            rk[4] = rk[0] ^
5442
24.0k
        #ifndef WOLFSSL_AES_SMALL_TABLES
5443
24.0k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5444
24.0k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5445
24.0k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5446
24.0k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5447
        #else
5448
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5449
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5450
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5451
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5452
        #endif
5453
24.0k
                rcon[i];
5454
24.0k
            rk[5] = rk[1] ^ rk[4];
5455
24.0k
            rk[6] = rk[2] ^ rk[5];
5456
24.0k
            rk[7] = rk[3] ^ rk[6];
5457
24.0k
            if (++i == 10)
5458
2.40k
                break;
5459
21.6k
            rk += 4;
5460
21.6k
        }
5461
2.40k
        break;
5462
0
#endif /* 128 */
5463
5464
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
5465
0
        defined(WOLFSSL_AES_192)
5466
690
    case 24:
5467
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5468
        temp = (word32)-1;
5469
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5470
    #endif
5471
        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
5472
5.52k
        while (1)
5473
5.52k
        {
5474
5.52k
            temp = rk[ 5];
5475
5.52k
            rk[ 6] = rk[ 0] ^
5476
5.52k
        #ifndef WOLFSSL_AES_SMALL_TABLES
5477
5.52k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5478
5.52k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5479
5.52k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5480
5.52k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5481
        #else
5482
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5483
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5484
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5485
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5486
        #endif
5487
5.52k
                rcon[i];
5488
5.52k
            rk[ 7] = rk[ 1] ^ rk[ 6];
5489
5.52k
            rk[ 8] = rk[ 2] ^ rk[ 7];
5490
5.52k
            rk[ 9] = rk[ 3] ^ rk[ 8];
5491
5.52k
            if (++i == 8)
5492
690
                break;
5493
4.83k
            rk[10] = rk[ 4] ^ rk[ 9];
5494
4.83k
            rk[11] = rk[ 5] ^ rk[10];
5495
4.83k
            rk += 6;
5496
4.83k
        }
5497
690
        break;
5498
0
#endif /* 192 */
5499
5500
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
5501
0
        defined(WOLFSSL_AES_256)
5502
1.16k
    case 32:
5503
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5504
        temp = (word32)-1;
5505
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5506
    #endif
5507
8.16k
        while (1)
5508
8.16k
        {
5509
8.16k
            temp = rk[ 7];
5510
8.16k
            rk[ 8] = rk[ 0] ^
5511
8.16k
        #ifndef WOLFSSL_AES_SMALL_TABLES
5512
8.16k
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5513
8.16k
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5514
8.16k
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5515
8.16k
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5516
        #else
5517
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5518
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5519
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5520
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5521
        #endif
5522
8.16k
                rcon[i];
5523
8.16k
            rk[ 9] = rk[ 1] ^ rk[ 8];
5524
8.16k
            rk[10] = rk[ 2] ^ rk[ 9];
5525
8.16k
            rk[11] = rk[ 3] ^ rk[10];
5526
8.16k
            if (++i == 7)
5527
1.16k
                break;
5528
7.00k
            temp = rk[11];
5529
7.00k
            rk[12] = rk[ 4] ^
5530
7.00k
        #ifndef WOLFSSL_AES_SMALL_TABLES
5531
7.00k
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
5532
7.00k
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
5533
7.00k
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
5534
7.00k
                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
5535
        #else
5536
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
5537
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
5538
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
5539
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
5540
        #endif
5541
7.00k
            rk[13] = rk[ 5] ^ rk[12];
5542
7.00k
            rk[14] = rk[ 6] ^ rk[13];
5543
7.00k
            rk[15] = rk[ 7] ^ rk[14];
5544
5545
7.00k
            rk += 8;
5546
7.00k
        }
5547
1.16k
        break;
5548
4.26k
#endif /* 256 */
5549
4.26k
    } /* switch */
5550
4.26k
    ForceZero(&temp, sizeof(temp));
5551
5552
4.26k
#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
5553
4.26k
    if (dir == AES_DECRYPTION) {
5554
577
        unsigned int j;
5555
5556
#ifdef WC_C_DYNAMIC_FALLBACK
5557
        rk = aes->key_C_fallback;
5558
#else
5559
577
        rk = aes->key;
5560
577
#endif
5561
5562
        /* invert the order of the round keys: */
5563
3.81k
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
5564
3.24k
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
5565
3.24k
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
5566
3.24k
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
5567
3.24k
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
5568
3.24k
        }
5569
577
        ForceZero(&temp, sizeof(temp));
5570
577
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
5571
        /* apply the inverse MixColumn transform to all round keys but the
5572
           first and the last: */
5573
6.48k
        for (i = 1; i < aes->rounds; i++) {
5574
5.90k
            rk += 4;
5575
5.90k
            rk[0] =
5576
5.90k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
5577
5.90k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
5578
5.90k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
5579
5.90k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
5580
5.90k
            rk[1] =
5581
5.90k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
5582
5.90k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
5583
5.90k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
5584
5.90k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
5585
5.90k
            rk[2] =
5586
5.90k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
5587
5.90k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
5588
5.90k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
5589
5.90k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
5590
5.90k
            rk[3] =
5591
5.90k
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
5592
5.90k
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
5593
5.90k
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
5594
5.90k
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
5595
5.90k
        }
5596
577
    #endif
5597
577
    }
5598
#else
5599
    (void)dir;
5600
#endif /* HAVE_AES_DECRYPT */
5601
5602
#ifdef WOLFSSL_CHECK_MEM_ZERO
5603
    wc_MemZero_Check(&temp, sizeof(temp));
5604
#else
5605
4.26k
    (void)temp;
5606
4.26k
#endif
5607
4.26k
}
5608
#endif
5609
#else /* WC_AES_BITSLICED */
5610
/* Set the AES key and expand.
5611
 *
5612
 * @param [in]  aes    AES object.
5613
 * @param [in]  key    Block to encrypt.
5614
 * @param [in]  keySz  Number of bytes in key.
5615
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
5616
 */
5617
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
5618
{
5619
    /* No need to invert when decrypting. */
5620
    (void)dir;
5621
5622
    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
5623
}
5624
#endif /* WC_AES_BITSLICED */
5625
5626
#endif /* NEED_AES_TABLES */
5627
5628
    static WARN_UNUSED_RESULT int AesSetKeyLocal_body(
5629
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
5630
        int checkKeyLen);
5631
5632
    /* AES - SetKey (block schedule via generated asm on RISC-V)
5633
     *
5634
     * keyInstalled is derived from the return value here rather than set
5635
     * inside the body. The body has failure returns after the point where the
5636
     * key material is accepted (AES-NI SAVE_VECTOR_REGISTERS2/BAD_ALIGN_E, the
5637
     * hardware key installs), and marking the context keyed on those paths
5638
     * would let it pass WC_AES_KEY_IS_SET with an all-zero key schedule. */
5639
    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
5640
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
5641
        int checkKeyLen)
5642
4.26k
    {
5643
4.26k
        int ret;
5644
5645
4.26k
        if (aes == NULL)
5646
0
            return BAD_FUNC_ARG;
5647
5648
4.26k
        aes->keyInstalled = 0;
5649
4.26k
        ret = AesSetKeyLocal_body(aes, userKey, keylen, iv, dir, checkKeyLen);
5650
4.26k
        aes->keyInstalled = (ret == 0) ? 1 : 0;
5651
5652
4.26k
        return ret;
5653
4.26k
    }
5654
5655
    static WARN_UNUSED_RESULT int AesSetKeyLocal_body(
5656
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
5657
        int checkKeyLen)
5658
4.26k
    {
5659
4.26k
        int ret;
5660
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
5661
        int cbRet;
5662
#endif
5663
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5664
        byte   local[32];
5665
        word32 localSz = 32;
5666
    #endif
5667
5668
4.26k
        if (aes == NULL)
5669
0
            return BAD_FUNC_ARG;
5670
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5671
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5672
        if (ret < 0)
5673
            return ret;
5674
#endif
5675
5676
4.26k
        switch (keylen) {
5677
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5678
0
        defined(WOLFSSL_AES_128)
5679
2.40k
        case 16:
5680
2.40k
    #endif
5681
2.40k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5682
2.40k
        defined(WOLFSSL_AES_192)
5683
3.09k
        case 24:
5684
3.09k
    #endif
5685
3.09k
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5686
3.09k
        defined(WOLFSSL_AES_256)
5687
4.26k
        case 32:
5688
4.26k
    #endif
5689
4.26k
            break;
5690
0
        default:
5691
0
            return BAD_FUNC_ARG;
5692
4.26k
        }
5693
5694
4.26k
    #ifdef WOLF_CRYPTO_CB
5695
4.26k
        #ifndef WOLF_CRYPTO_CB_FIND
5696
4.26k
        if (aes->devId != INVALID_DEVID)
5697
936
        #endif
5698
936
        {
5699
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5700
            ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5701
            if (ret == 0) {
5702
                /* Callback succeeded - SE owns the key */
5703
                aes->keylen = (int)keylen;
5704
                if (iv != NULL)
5705
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5706
                else
5707
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5708
                return 0;
5709
            }
5710
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5711
                aes->devCtx = NULL;
5712
                return ret;
5713
            }
5714
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5715
        #endif
5716
        #ifdef WOLF_CRYPTO_CB_SETKEY
5717
            cbRet = wc_CryptoCb_SetKey(aes->devId,
5718
                WC_SETKEY_AES, aes, (void*)userKey, keylen,
5719
                (void*)iv,
5720
                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
5721
            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5722
                if (cbRet == 0) {
5723
                    /* Callback succeeded - the device owns the key. rounds is
5724
                     * left at 0: there is no software key schedule, and the
5725
                     * XTS entry points use that to reject the context. */
5726
                    aes->keylen = (int)keylen;
5727
                }
5728
                return cbRet;
5729
            }
5730
            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
5731
        #endif /* WOLF_CRYPTO_CB_SETKEY */
5732
            /* Standard CryptoCB path - copy key to devKey */
5733
936
            if (keylen > sizeof(aes->devKey)) {
5734
0
                return BAD_FUNC_ARG;
5735
0
            }
5736
936
            XMEMCPY(aes->devKey, userKey, keylen);
5737
936
        }
5738
4.26k
    #endif
5739
5740
    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
5741
        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
5742
            return WC_HW_E;
5743
        }
5744
    #endif
5745
5746
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5747
        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
5748
            keylen == (24 + WC_CAAM_BLOB_SZ) ||
5749
            keylen == (32 + WC_CAAM_BLOB_SZ)) {
5750
            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
5751
                return BAD_FUNC_ARG;
5752
            }
5753
5754
            /* set local values */
5755
            userKey = local;
5756
            keylen = localSz;
5757
        }
5758
    #endif
5759
5760
    #ifdef WOLFSSL_SECO_CAAM
5761
        /* if set to use hardware than import the key */
5762
        if (aes->devId == WOLFSSL_SECO_DEVID) {
5763
            int keyGroup = 1; /* group one was chosen arbitrarily */
5764
            unsigned int keyIdOut;
5765
            byte importiv[GCM_NONCE_MID_SZ];
5766
            int importivSz = GCM_NONCE_MID_SZ;
5767
            int keyType = 0;
5768
            WC_RNG rng;
5769
5770
            if (wc_InitRng(&rng) != 0) {
5771
                WOLFSSL_MSG("RNG init for IV failed");
5772
                return WC_HW_E;
5773
            }
5774
5775
            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
5776
                WOLFSSL_MSG("Generate IV failed");
5777
                wc_FreeRng(&rng);
5778
                return WC_HW_E;
5779
            }
5780
            wc_FreeRng(&rng);
5781
5782
            if (iv)
5783
                XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5784
            else
5785
                XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5786
5787
            switch (keylen) {
5788
                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
5789
                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
5790
                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
5791
            }
5792
5793
            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
5794
                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
5795
            if (keyIdOut == 0) {
5796
                return WC_HW_E;
5797
            }
5798
            aes->blackKey = keyIdOut;
5799
            return 0;
5800
        }
5801
    #endif
5802
5803
4.26k
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
5804
4.26k
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
5805
4.26k
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) || \
5806
4.26k
        defined(WOLFSSL_NXP_HASHCRYPT_AES)
5807
4.26k
        #ifdef WOLF_CRYPTO_CB
5808
4.26k
        #ifndef WOLF_CRYPTO_CB_FIND
5809
4.26k
        if (aes->devId != INVALID_DEVID)
5810
936
        #endif
5811
936
        #endif
5812
936
        {
5813
936
            if (keylen > sizeof(aes->devKey)) {
5814
0
                return BAD_FUNC_ARG;
5815
0
            }
5816
936
            XMEMCPY(aes->devKey, userKey, keylen);
5817
936
        }
5818
4.26k
    #endif
5819
5820
    #ifdef WOLF_CRYPTO_CB_ONLY_AES
5821
        /* No software AES schedule under CB_ONLY: aes->key[] (round keys) are
5822
         * unused because the static wc_AesEncrypt/wc_AesDecrypt are cryptocb-
5823
         * ECB shims. aes->rounds is still populated because wc_AesGetKeySize()
5824
         * reads it as the source of truth for the configured key size. */
5825
        aes->keylen = (int)keylen;
5826
        aes->rounds = (keylen / 4) + 6;
5827
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5828
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5829
            defined(WOLFSSL_AES_CTS)
5830
        aes->left = 0;
5831
        #endif
5832
        (void)dir;
5833
        return wc_AesSetIV(aes, iv);
5834
    #endif
5835
5836
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
5837
        if (checkKeyLen) {
5838
            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
5839
             * all key sizes. Otherwise this condition is never true. */
5840
            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
5841
                return BAD_FUNC_ARG;
5842
            }
5843
        }
5844
    #else
5845
4.26k
        (void) checkKeyLen;
5846
4.26k
    #endif
5847
5848
4.26k
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5849
4.26k
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5850
4.26k
        defined(WOLFSSL_AES_CTS)
5851
4.26k
        aes->left = 0;
5852
4.26k
    #endif
5853
5854
4.26k
        aes->keylen = (int)keylen;
5855
4.26k
        aes->rounds = (keylen/4) + 6;
5856
4.26k
        ret = wc_AesSetIV(aes, iv);
5857
4.26k
        if (ret != 0)
5858
0
            return ret;
5859
5860
#ifdef WC_C_DYNAMIC_FALLBACK
5861
#ifdef NEED_AES_TABLES
5862
        AesSetKey_C(aes, userKey, keylen, dir);
5863
#endif /* NEED_AES_TABLES */
5864
#endif /* WC_C_DYNAMIC_FALLBACK */
5865
5866
    #ifdef WOLFSSL_AESNI
5867
5868
       /* The dynamics for determining whether AES-NI will be used are tricky.
5869
        *
5870
        * First, we check for CPU support and cache the result -- if AES-NI is
5871
        * missing, we always shortcut to the AesSetKey_C() path.
5872
        *
5873
        * Second, if the CPU supports AES-NI, we confirm on a per-call basis
5874
        * that it's safe to use in the caller context, using
5875
        * SAVE_VECTOR_REGISTERS2().  This is an always-true no-op in user-space
5876
        * builds, but has substantive logic behind it in kernel module builds.
5877
        *
5878
        * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on
5879
        * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with
5880
        * success but with AES-NI disabled (the earlier AesSetKey_C() allows
5881
        * future encrypt/decrypt calls to succeed), otherwise we fail.
5882
        *
5883
        * Upon successful return, aes->use_aesni will have a zero value if
5884
        * AES-NI is disabled, and a nonzero value if it's enabled.
5885
        *
5886
        * An additional, optional semantic is available via
5887
        * WC_FLAG_DONT_USE_VECTOR_OPS, and is used in some kernel module builds
5888
        * to let the caller inhibit AES-NI.  When this macro is defined,
5889
        * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of
5890
        * uninitialized data in aes->use_aesni.  That's why support for
5891
        * WC_FLAG_DONT_USE_VECTOR_OPS must remain optional -- wc_AesInit() was
5892
        * only added in release 3.11.0, so legacy applications inevitably call
5893
        * wc_AesSetKey() on uninitialized Aes contexts.  This must continue to
5894
        * function correctly with default build settings.
5895
        */
5896
5897
        if (checkedAESNI == 0) {
5898
            haveAESNI = Check_CPU_support_AES();
5899
            checkedAESNI = 1;
5900
        }
5901
        if (haveAESNI
5902
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS) && !defined(WC_C_DYNAMIC_FALLBACK)
5903
            && (aes->use_aesni != WC_FLAG_DONT_USE_VECTOR_OPS)
5904
#endif
5905
            )
5906
        {
5907
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS)
5908
            if (aes->use_aesni == WC_FLAG_DONT_USE_VECTOR_OPS) {
5909
                aes->use_aesni = 0;
5910
                return 0;
5911
            }
5912
#endif
5913
            aes->use_aesni = 0;
5914
            #ifdef WOLFSSL_KERNEL_MODE
5915
            /* runtime alignment check */
5916
            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
5917
                ret = BAD_ALIGN_E;
5918
            }
5919
            else
5920
            #endif /* WOLFSSL_KERNEL_MODE */
5921
            {
5922
                ret = SAVE_VECTOR_REGISTERS2();
5923
            }
5924
            if (ret == 0) {
5925
                if (dir == AES_ENCRYPTION)
5926
                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5927
#ifdef HAVE_AES_DECRYPT
5928
                else
5929
                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5930
#endif
5931
5932
                RESTORE_VECTOR_REGISTERS();
5933
5934
                if (ret == 0)
5935
                    aes->use_aesni = 1;
5936
                else {
5937
#ifdef WC_C_DYNAMIC_FALLBACK
5938
                    ret = 0;
5939
#endif
5940
                }
5941
                return ret;
5942
            } else {
5943
#ifdef WC_C_DYNAMIC_FALLBACK
5944
                return 0;
5945
#else
5946
                return ret;
5947
#endif
5948
            }
5949
        }
5950
        else {
5951
            aes->use_aesni = 0;
5952
#ifdef WC_C_DYNAMIC_FALLBACK
5953
            /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C()
5954
             * above.
5955
             */
5956
            return 0;
5957
#endif
5958
        }
5959
    #endif /* WOLFSSL_AESNI */
5960
5961
4.26k
#ifndef WC_C_DYNAMIC_FALLBACK
5962
5963
#if defined(WOLFSSL_RISCV_ASM)
5964
        /* Generated RISC-V assembly key schedule (all paths). aes->rounds /
5965
         * aes->keylen were set above. */
5966
        AES_set_key_RISCV64(userKey, (int)keylen, (byte*)aes->key, dir);
5967
        return 0;
5968
#elif defined(WOLFSSL_ARMASM)
5969
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5970
    #ifndef __aarch64__
5971
      #ifdef WOLFSSL_ARM32_AES_DISPATCH
5972
        Check_CPU_support_HwCrypto(aes);
5973
        if (aes->use_aes_hw_crypto) {
5974
            AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5975
        }
5976
        else
5977
      #else
5978
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5979
      #endif /* WOLFSSL_ARM32_AES_DISPATCH */
5980
    #else
5981
        Check_CPU_support_HwCrypto(aes);
5982
        if (aes->use_aes_hw_crypto) {
5983
            AES_set_key_AARCH64(userKey, keylen, (byte*)aes->key, dir);
5984
        }
5985
        else
5986
    #endif /* __aarch64__ */
5987
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
5988
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
5989
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
5990
        {
5991
            AES_set_encrypt_key_NEON(userKey, keylen * 8, (byte*)aes->key);
5992
        #ifdef HAVE_AES_DECRYPT
5993
            if (dir == AES_DECRYPTION) {
5994
                AES_invert_key_NEON((byte*)aes->key, aes->rounds);
5995
            }
5996
        #else
5997
            (void)dir;
5998
        #endif
5999
        }
6000
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
6001
          defined(WOLFSSL_ARM32_AES_DISPATCH)
6002
        {
6003
            AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
6004
        #ifdef HAVE_AES_DECRYPT
6005
            if (dir == AES_DECRYPTION) {
6006
                AES_invert_key((byte*)aes->key, aes->rounds);
6007
            }
6008
        #else
6009
            (void)dir;
6010
        #endif
6011
        }
6012
    #endif
6013
        return 0;
6014
#else
6015
6016
    #ifdef WOLFSSL_KCAPI_AES
6017
        XMEMCPY(aes->devKey, userKey, keylen);
6018
        if (aes->init != 0) {
6019
            kcapi_cipher_destroy(aes->handle);
6020
            aes->handle = NULL;
6021
            aes->init = 0;
6022
        }
6023
        (void)dir;
6024
    #endif
6025
6026
4.26k
        if (keylen > sizeof(aes->key)) {
6027
0
            return BAD_FUNC_ARG;
6028
0
        }
6029
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6030
        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
6031
                                  ((psa_algorithm_t)0), dir);
6032
#endif
6033
6034
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
6035
        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
6036
         * instead of SE05x crypto by setting useSWCrypt */
6037
        if (aes->useSWCrypt == 0) {
6038
            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
6039
            if (ret == 0) {
6040
                ret = wc_AesSetIV(aes, iv);
6041
            }
6042
            return ret;
6043
        }
6044
#endif
6045
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
6046
        if (keylen == TA_KEY_TYPE_AES128_SIZE) {
6047
            ret = wc_Microchip_aes_set_key(aes, userKey, keylen, iv, dir);
6048
            if (ret != 0) {
6049
                return ret;
6050
            }
6051
            ret = wc_AesSetIV(aes, iv);
6052
            if (ret != 0) {
6053
                return ret;
6054
            }
6055
        }
6056
#endif
6057
4.26k
        XMEMCPY(aes->key, userKey, keylen);
6058
6059
4.26k
#ifndef WC_AES_BITSLICED
6060
4.26k
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
6061
4.26k
        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
6062
4.26k
        && !defined(MAX3266X_AES)
6063
6064
        /* software */
6065
4.26k
        ByteReverseWords(aes->key, aes->key, keylen);
6066
6067
    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6068
        if (wc_esp32AesSupportedKeyLen(aes)) {
6069
            /* supported lengths don't get reversed */
6070
            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
6071
        }
6072
        else {
6073
            word32* rk = aes->key;
6074
6075
            /* For example, the ESP32-S3 does not support HW for len = 24,
6076
             * so fall back to SW */
6077
        #ifdef DEBUG_WOLFSSL
6078
            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
6079
        #endif
6080
            XMEMCPY(rk, userKey, keylen);
6081
            /* When not ESP32 HW, we need to reverse endianness */
6082
            ByteReverseWords(rk, rk, keylen);
6083
        }
6084
    #endif
6085
6086
    #ifdef WOLFSSL_IMXRT_DCP
6087
        {
6088
            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
6089
            word32 temp = 0;
6090
            if (keylen == 16)
6091
                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
6092
            if (temp != 0)
6093
                return WC_HW_E;
6094
        }
6095
    #endif
6096
4.26k
#endif /* !WC_AES_BITSLICED */
6097
6098
4.26k
#ifdef NEED_AES_TABLES
6099
4.26k
        AesSetKey_C(aes, userKey, keylen, dir);
6100
4.26k
#endif /* NEED_AES_TABLES */
6101
6102
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
6103
        XMEMCPY((byte*)aes->key, userKey, keylen);
6104
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
6105
            ByteReverseWords(aes->key, aes->key, 32);
6106
        }
6107
#endif
6108
6109
    #if defined(WOLFSSL_DEVCRYPTO) && \
6110
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
6111
        /* Release any session already held. The session was created with the
6112
         * previous key, so re-keying must tear it down rather than just mark
6113
         * the context uninitialized, which would orphan the descriptor and
6114
         * leave the stale key in use. */
6115
        wc_DevCryptoFree(&aes->ctx);
6116
        aes->ctx.inited = 0;
6117
        aes->ctx.cfd = -1; /* not set when no session was open */
6118
    #endif
6119
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
6120
    #ifdef WOLFSSL_CHECK_MEM_ZERO
6121
        wc_MemZero_Add("wc_AesSetKeyLocal local", local, sizeof(local));
6122
    #endif
6123
        ForceZero(local, sizeof(local));
6124
    #ifdef WOLFSSL_CHECK_MEM_ZERO
6125
        wc_MemZero_Check(local, sizeof(local));
6126
    #endif
6127
    #endif
6128
4.26k
        return ret;
6129
4.26k
#endif
6130
6131
4.26k
#endif /* !WC_C_DYNAMIC_FALLBACK */
6132
6133
4.26k
    } /* wc_AesSetKeyLocal */
6134
6135
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
6136
            const byte* iv, int dir)
6137
3.66k
    {
6138
3.66k
        if (aes == NULL) {
6139
0
            return BAD_FUNC_ARG;
6140
0
        }
6141
3.66k
        if (keylen > sizeof(aes->key)) {
6142
0
            return BAD_FUNC_ARG;
6143
0
        }
6144
6145
    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
6146
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
6147
        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
6148
        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
6149
            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
6150
            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
6151
        }
6152
        else {
6153
        #if  defined(WOLFSSL_HW_METRICS)
6154
            /* It is interesting to know how many times we could not complete
6155
             * AES in hardware due to unsupported lengths. */
6156
            wc_esp32AesUnupportedLengthCountAdd();
6157
        #endif
6158
        #ifdef DEBUG_WOLFSSL
6159
            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
6160
                           keylen);
6161
        #endif
6162
        }
6163
    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
6164
6165
3.66k
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
6166
6167
3.66k
    } /* wc_AesSetKey() */
6168
6169
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
6170
        /* AES-CTR and AES-DIRECT need to use this for key setup */
6171
        /* This function allows key sizes that are not 128/192/256 bits */
6172
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
6173
                           const byte* iv, int dir)
6174
602
    {
6175
602
        if (aes == NULL) {
6176
0
            return BAD_FUNC_ARG;
6177
0
        }
6178
602
        if (keylen > sizeof(aes->key)) {
6179
0
            return BAD_FUNC_ARG;
6180
0
        }
6181
6182
602
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
6183
602
    }
6184
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
6185
#endif /* wc_AesSetKey block */
6186
6187
6188
/* wc_AesSetIV is shared between software and hardware */
6189
int wc_AesSetIV(Aes* aes, const byte* iv)
6190
4.80k
{
6191
4.80k
    if (aes == NULL)
6192
0
        return BAD_FUNC_ARG;
6193
6194
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
6195
    {
6196
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
6197
        if (ret < 0)
6198
            return ret;
6199
    }
6200
#endif
6201
6202
4.80k
    if (iv)
6203
3.10k
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
6204
1.69k
    else
6205
1.69k
        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
6206
6207
4.80k
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
6208
4.80k
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
6209
4.80k
    defined(WOLFSSL_AES_CTS)
6210
    /* Clear any unused bytes from last cipher op. */
6211
4.80k
    aes->left = 0;
6212
4.80k
#endif
6213
6214
#ifdef WOLFSSL_KCAPI_AES
6215
    /* The kernel keeps the chaining state and takes the IV at stream setup
6216
     * time only, so tear the stream down for the new IV to take effect. It is
6217
     * set up again, from aes->reg, on the next cipher operation. */
6218
    if (aes->init != 0) {
6219
        kcapi_cipher_destroy(aes->handle);
6220
        aes->handle = NULL;
6221
        aes->init = 0;
6222
    }
6223
#endif
6224
6225
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6226
    {
6227
        /* PSA takes the IV at operation setup time only, so an operation
6228
         * already in progress must be aborted for the new IV to take effect. */
6229
        int ret = wc_psa_aes_reset_ctx(aes);
6230
        if (ret != 0)
6231
            return ret;
6232
    }
6233
#endif
6234
6235
4.80k
    return 0;
6236
4.80k
}
6237
6238
#ifdef WOLFSSL_AESNI
6239
6240
#ifdef WC_C_DYNAMIC_FALLBACK
6241
6242
#define VECTOR_REGISTERS_PUSH {                                      \
6243
        int orig_use_aesni = aes->use_aesni;                         \
6244
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
6245
            aes->use_aesni = 0;                                      \
6246
        }                                                            \
6247
        WC_DO_NOTHING
6248
6249
#define VECTOR_REGISTERS_PUSH2(fail_clause) {                        \
6250
        int orig_use_aesni = aes->use_aesni;                         \
6251
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
6252
            aes->use_aesni = 0;                                      \
6253
        }                                                            \
6254
        WC_DO_NOTHING
6255
6256
6257
#define VECTOR_REGISTERS_POP                                         \
6258
        if (aes->use_aesni)                                          \
6259
            RESTORE_VECTOR_REGISTERS();                              \
6260
        else                                                         \
6261
            aes->use_aesni = orig_use_aesni;                         \
6262
    }                                                                \
6263
    WC_DO_NOTHING
6264
6265
#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
6266
6267
#define VECTOR_REGISTERS_PUSH { \
6268
        WC_DO_NOTHING
6269
6270
#define VECTOR_REGISTERS_PUSH2(fail_clause) { \
6271
        WC_DO_NOTHING
6272
6273
#define VECTOR_REGISTERS_POP                                         \
6274
    }                                                                \
6275
    WC_DO_NOTHING
6276
6277
#else
6278
6279
#define VECTOR_REGISTERS_PUSH {                                          \
6280
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
6281
            return ret;                                                  \
6282
        }                                                                \
6283
        WC_DO_NOTHING
6284
6285
#define VECTOR_REGISTERS_PUSH2(fail_clause) {                            \
6286
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
6287
            { fail_clause }                                              \
6288
            return ret;                                                  \
6289
        }                                                                \
6290
        WC_DO_NOTHING
6291
6292
#define VECTOR_REGISTERS_POP \
6293
        if (aes->use_aesni) {                                            \
6294
            RESTORE_VECTOR_REGISTERS();                                  \
6295
        }                                                                \
6296
    }                                                                    \
6297
    WC_DO_NOTHING
6298
6299
#endif
6300
6301
#else /* !WOLFSSL_AESNI */
6302
6303
7.20k
#define VECTOR_REGISTERS_PUSH WC_DO_NOTHING
6304
#define VECTOR_REGISTERS_PUSH2(fail_clause) WC_DO_NOTHING
6305
7.20k
#define VECTOR_REGISTERS_POP WC_DO_NOTHING
6306
6307
#endif /* !WOLFSSL_AESNI */
6308
6309
6310
/* AES-DIRECT */
6311
#if defined(WOLFSSL_AES_DIRECT)
6312
    #if defined(HAVE_COLDFIRE_SEC)
6313
        #error "Coldfire SEC doesn't yet support AES direct"
6314
6315
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6316
        !defined(WOLFSSL_QNX_CAAM)
6317
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6318
6319
    #elif defined(WOLFSSL_AFALG)
6320
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6321
6322
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
6323
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6324
6325
    #else
6326
6327
        /* Allow direct access to one block encrypt */
6328
        /* Note, the in and out args are swapped compared to wc_AesEncrypt(). */
6329
        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
6330
312
        {
6331
312
            int ret;
6332
6333
312
            if (aes == NULL || out == NULL || in == NULL)
6334
0
                return BAD_FUNC_ARG;
6335
312
            if (!WC_AES_KEY_IS_SET(aes)) {
6336
0
                WOLFSSL_MSG("AES key not set");
6337
0
                return MISSING_KEY;
6338
0
            }
6339
312
            VECTOR_REGISTERS_PUSH;
6340
312
            ret = wc_AesEncrypt(aes, in, out);
6341
312
            VECTOR_REGISTERS_POP;
6342
312
            return ret;
6343
312
        }
6344
6345
        /* vector reg save/restore is explicit in all below calls to
6346
         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
6347
         * macro.
6348
         */
6349
609
        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
6350
6351
        #ifdef HAVE_AES_DECRYPT
6352
        /* Allow direct access to one block decrypt */
6353
        /* Note, the in and out args are swapped compared to wc_AesDecrypt(). */
6354
        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
6355
0
        {
6356
0
            int ret;
6357
6358
0
            if (aes == NULL)
6359
0
                return BAD_FUNC_ARG;
6360
0
            if (!WC_AES_KEY_IS_SET(aes)) {
6361
0
                WOLFSSL_MSG("AES key not set");
6362
0
                return MISSING_KEY;
6363
0
            }
6364
0
            VECTOR_REGISTERS_PUSH;
6365
0
            ret = wc_AesDecrypt(aes, in, out);
6366
0
            VECTOR_REGISTERS_POP;
6367
0
            return ret;
6368
0
        }
6369
6370
200
        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
6371
6372
        #endif /* HAVE_AES_DECRYPT */
6373
    #endif /* AES direct block */
6374
#endif /* WOLFSSL_AES_DIRECT */
6375
6376
6377
/* AES-CBC */
6378
#ifdef HAVE_AES_CBC
6379
#if defined(STM32_CRYPTO)
6380
6381
#ifdef WOLFSSL_STM32_BARE
6382
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6383
    {
6384
    #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6385
        if (sz % WC_AES_BLOCK_SIZE) {
6386
            return BAD_LENGTH_E;
6387
        }
6388
    #endif
6389
        if (sz == 0) {
6390
            return 0;
6391
        }
6392
    #ifdef WOLF_CRYPTO_CB
6393
        #ifndef WOLF_CRYPTO_CB_FIND
6394
        if (aes->devId != INVALID_DEVID)
6395
        #endif
6396
        {
6397
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6398
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6399
                return crypto_cb_ret;
6400
            /* fall-through when unavailable (normal-keyed Aes) */
6401
        }
6402
    #endif
6403
        /* DHUK / any crypto-callback device is routed above. wc_Stm32_Aes_Cbc
6404
         * processes whole blocks and ignores any sub-block remainder, matching
6405
         * the SW / CUBEMX CBC backends; define WOLFSSL_AES_CBC_LENGTH_CHECKS
6406
         * (above) to reject a non-block-multiple length with BAD_LENGTH_E. */
6407
        return wc_Stm32_Aes_Cbc(aes, out, in, sz, 1);
6408
    }
6409
    #ifdef HAVE_AES_DECRYPT
6410
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6411
    {
6412
    #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6413
        if (sz % WC_AES_BLOCK_SIZE) {
6414
            return BAD_LENGTH_E;
6415
        }
6416
    #endif
6417
        if (sz == 0) {
6418
            return 0;
6419
        }
6420
    #ifdef WOLF_CRYPTO_CB
6421
        #ifndef WOLF_CRYPTO_CB_FIND
6422
        if (aes->devId != INVALID_DEVID)
6423
        #endif
6424
        {
6425
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6426
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6427
                return crypto_cb_ret;
6428
            /* fall-through when unavailable (normal-keyed Aes) */
6429
        }
6430
    #endif
6431
        /* DHUK / any crypto-callback device is routed above. */
6432
        return wc_Stm32_Aes_Cbc(aes, out, in, sz, 0);
6433
    }
6434
    #endif /* HAVE_AES_DECRYPT */
6435
#elif defined(WOLFSSL_STM32_CUBEMX)
6436
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6437
    {
6438
        int ret = 0;
6439
        CRYP_HandleTypeDef hcryp;
6440
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6441
6442
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6443
        if (sz % WC_AES_BLOCK_SIZE) {
6444
            return BAD_LENGTH_E;
6445
        }
6446
#endif
6447
        if (blocks == 0)
6448
            return 0;
6449
6450
    #ifdef WOLF_CRYPTO_CB
6451
        #ifndef WOLF_CRYPTO_CB_FIND
6452
        if (aes->devId != INVALID_DEVID)
6453
        #endif
6454
        {
6455
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6456
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6457
                return crypto_cb_ret;
6458
            /* fall-through when unavailable (normal-keyed Aes) */
6459
        }
6460
    #endif
6461
6462
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6463
        if (ret != 0)
6464
            return ret;
6465
6466
        ret = wolfSSL_CryptHwMutexLock();
6467
        if (ret != 0) {
6468
            return ret;
6469
        }
6470
6471
    #if defined(STM32_HAL_V2)
6472
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
6473
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
6474
    #elif defined(STM32_CRYPTO_AES_ONLY)
6475
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
6476
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
6477
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6478
    #endif
6479
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6480
        ret = HAL_CRYP_Init(&hcryp);
6481
6482
        if (ret == HAL_OK) {
6483
        #if defined(STM32_HAL_V2)
6484
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
6485
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6486
        #elif defined(STM32_CRYPTO_AES_ONLY)
6487
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
6488
                out, STM32_HAL_TIMEOUT);
6489
        #else
6490
            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
6491
                                        blocks * WC_AES_BLOCK_SIZE,
6492
                                        out, STM32_HAL_TIMEOUT);
6493
        #endif
6494
        }
6495
        if (ret != HAL_OK) {
6496
            ret = WC_TIMEOUT_E;
6497
        }
6498
6499
        /* store iv for next call */
6500
        XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6501
6502
        HAL_CRYP_DeInit(&hcryp);
6503
6504
        wolfSSL_CryptHwMutexUnLock();
6505
        wc_Stm32_Aes_Cleanup();
6506
6507
        return ret;
6508
    }
6509
    #ifdef HAVE_AES_DECRYPT
6510
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6511
    {
6512
        int ret = 0;
6513
        CRYP_HandleTypeDef hcryp;
6514
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6515
6516
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6517
        if (sz % WC_AES_BLOCK_SIZE) {
6518
            return BAD_LENGTH_E;
6519
        }
6520
#endif
6521
        if (blocks == 0)
6522
            return 0;
6523
6524
    #ifdef WOLF_CRYPTO_CB
6525
        #ifndef WOLF_CRYPTO_CB_FIND
6526
        if (aes->devId != INVALID_DEVID)
6527
        #endif
6528
        {
6529
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6530
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6531
                return crypto_cb_ret;
6532
            /* fall-through when unavailable (normal-keyed Aes) */
6533
        }
6534
    #endif
6535
6536
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6537
        if (ret != 0)
6538
            return ret;
6539
6540
        ret = wolfSSL_CryptHwMutexLock();
6541
        if (ret != 0) {
6542
            return ret;
6543
        }
6544
6545
        /* if input and output same will overwrite input iv */
6546
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6547
6548
    #if defined(STM32_HAL_V2)
6549
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
6550
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
6551
    #elif defined(STM32_CRYPTO_AES_ONLY)
6552
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
6553
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
6554
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6555
    #endif
6556
6557
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6558
        ret = HAL_CRYP_Init(&hcryp);
6559
6560
        if (ret == HAL_OK) {
6561
        #if defined(STM32_HAL_V2)
6562
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
6563
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6564
        #elif defined(STM32_CRYPTO_AES_ONLY)
6565
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
6566
                out, STM32_HAL_TIMEOUT);
6567
        #else
6568
            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
6569
                                        blocks * WC_AES_BLOCK_SIZE,
6570
                out, STM32_HAL_TIMEOUT);
6571
        #endif
6572
        }
6573
        if (ret != HAL_OK) {
6574
            ret = WC_TIMEOUT_E;
6575
        }
6576
6577
        /* store iv for next call */
6578
        XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6579
6580
        HAL_CRYP_DeInit(&hcryp);
6581
        wolfSSL_CryptHwMutexUnLock();
6582
        wc_Stm32_Aes_Cleanup();
6583
6584
        return ret;
6585
    }
6586
    #endif /* HAVE_AES_DECRYPT */
6587
6588
#else /* Standard Peripheral Library */
6589
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6590
    {
6591
        int ret;
6592
        word32 *iv;
6593
        CRYP_InitTypeDef cryptInit;
6594
        CRYP_KeyInitTypeDef keyInit;
6595
        CRYP_IVInitTypeDef ivInit;
6596
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6597
6598
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6599
        if (sz % WC_AES_BLOCK_SIZE) {
6600
            return BAD_LENGTH_E;
6601
        }
6602
#endif
6603
        if (blocks == 0)
6604
            return 0;
6605
6606
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6607
        if (ret != 0)
6608
            return ret;
6609
6610
        ret = wolfSSL_CryptHwMutexLock();
6611
        if (ret != 0) {
6612
            return ret;
6613
        }
6614
6615
        /* reset registers to their default values */
6616
        CRYP_DeInit();
6617
6618
        /* set key */
6619
        CRYP_KeyInit(&keyInit);
6620
6621
        /* set iv */
6622
        iv = aes->reg;
6623
        CRYP_IVStructInit(&ivInit);
6624
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
6625
        ivInit.CRYP_IV0Left  = iv[0];
6626
        ivInit.CRYP_IV0Right = iv[1];
6627
        ivInit.CRYP_IV1Left  = iv[2];
6628
        ivInit.CRYP_IV1Right = iv[3];
6629
        CRYP_IVInit(&ivInit);
6630
6631
        /* set direction and mode */
6632
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
6633
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
6634
        CRYP_Init(&cryptInit);
6635
6636
        /* enable crypto processor */
6637
        CRYP_Cmd(ENABLE);
6638
6639
        while (blocks--) {
6640
            /* flush IN/OUT FIFOs */
6641
            CRYP_FIFOFlush();
6642
6643
            wc_Stm32_CrypAesBlock(in, out);
6644
6645
            /* store iv for next call */
6646
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6647
6648
            sz  -= WC_AES_BLOCK_SIZE;
6649
            in  += WC_AES_BLOCK_SIZE;
6650
            out += WC_AES_BLOCK_SIZE;
6651
        }
6652
6653
        /* disable crypto processor */
6654
        CRYP_Cmd(DISABLE);
6655
        wolfSSL_CryptHwMutexUnLock();
6656
        wc_Stm32_Aes_Cleanup();
6657
6658
        return ret;
6659
    }
6660
6661
    #ifdef HAVE_AES_DECRYPT
6662
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6663
    {
6664
        int ret;
6665
        word32 *iv;
6666
        CRYP_InitTypeDef cryptInit;
6667
        CRYP_KeyInitTypeDef keyInit;
6668
        CRYP_IVInitTypeDef ivInit;
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
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6680
        if (ret != 0)
6681
            return ret;
6682
6683
        ret = wolfSSL_CryptHwMutexLock();
6684
        if (ret != 0) {
6685
            return ret;
6686
        }
6687
6688
        /* if input and output same will overwrite input iv */
6689
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6690
6691
        /* reset registers to their default values */
6692
        CRYP_DeInit();
6693
6694
        /* set direction and key */
6695
        CRYP_KeyInit(&keyInit);
6696
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
6697
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
6698
        CRYP_Init(&cryptInit);
6699
6700
        /* enable crypto processor */
6701
        CRYP_Cmd(ENABLE);
6702
6703
        /* wait until key has been prepared */
6704
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6705
6706
        /* set direction and mode */
6707
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
6708
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
6709
        CRYP_Init(&cryptInit);
6710
6711
        /* set iv */
6712
        iv = aes->reg;
6713
        CRYP_IVStructInit(&ivInit);
6714
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
6715
        ivInit.CRYP_IV0Left  = iv[0];
6716
        ivInit.CRYP_IV0Right = iv[1];
6717
        ivInit.CRYP_IV1Left  = iv[2];
6718
        ivInit.CRYP_IV1Right = iv[3];
6719
        CRYP_IVInit(&ivInit);
6720
6721
        /* enable crypto processor */
6722
        CRYP_Cmd(ENABLE);
6723
6724
        while (blocks--) {
6725
            /* flush IN/OUT FIFOs */
6726
            CRYP_FIFOFlush();
6727
6728
            wc_Stm32_CrypAesBlock(in, out);
6729
6730
            /* store iv for next call */
6731
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6732
6733
            in  += WC_AES_BLOCK_SIZE;
6734
            out += WC_AES_BLOCK_SIZE;
6735
        }
6736
6737
        /* disable crypto processor */
6738
        CRYP_Cmd(DISABLE);
6739
        wolfSSL_CryptHwMutexUnLock();
6740
        wc_Stm32_Aes_Cleanup();
6741
6742
        return ret;
6743
    }
6744
    #endif /* HAVE_AES_DECRYPT */
6745
#endif /* WOLFSSL_STM32_CUBEMX */
6746
6747
#elif defined(HAVE_COLDFIRE_SEC)
6748
    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
6749
        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
6750
    {
6751
        #ifdef DEBUG_WOLFSSL
6752
            int i; int stat1, stat2; int ret;
6753
        #endif
6754
6755
        int size;
6756
        volatile int v;
6757
6758
        if ((pi == NULL) || (po == NULL))
6759
            return BAD_FUNC_ARG;    /*wrong pointer*/
6760
6761
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6762
        if (sz % WC_AES_BLOCK_SIZE) {
6763
            return BAD_LENGTH_E;
6764
        }
6765
#endif
6766
6767
        wc_LockMutex(&Mutex_AesSEC);
6768
6769
        /* Set descriptor for SEC */
6770
        secDesc->length1 = 0x0;
6771
        secDesc->pointer1 = NULL;
6772
6773
        secDesc->length2 = WC_AES_BLOCK_SIZE;
6774
        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
6775
6776
        switch(aes->rounds) {
6777
            case 10: secDesc->length3 = 16; break;
6778
            case 12: secDesc->length3 = 24; break;
6779
            case 14: secDesc->length3 = 32; break;
6780
        }
6781
        XMEMCPY(secKey, aes->key, secDesc->length3);
6782
6783
        secDesc->pointer3 = (byte *)secKey;
6784
        secDesc->pointer4 = AESBuffIn;
6785
        secDesc->pointer5 = AESBuffOut;
6786
        secDesc->length6 = 0x0;
6787
        secDesc->pointer6 = NULL;
6788
        secDesc->length7 = 0x0;
6789
        secDesc->pointer7 = NULL;
6790
        secDesc->nextDescriptorPtr = NULL;
6791
6792
        while (sz) {
6793
            secDesc->header = descHeader;
6794
            XMEMCPY(secReg, aes->reg, WC_AES_BLOCK_SIZE);
6795
            if (sz < AES_BUFFER_SIZE) {
6796
                size = sz;
6797
                sz = 0;
6798
            } else {
6799
                size = AES_BUFFER_SIZE;
6800
                sz -= AES_BUFFER_SIZE;
6801
            }
6802
6803
            secDesc->length4 = size;
6804
            secDesc->length5 = size;
6805
6806
            XMEMCPY(AESBuffIn, pi, size);
6807
            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
6808
                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-WC_AES_BLOCK_SIZE]),
6809
                        WC_AES_BLOCK_SIZE);
6810
            }
6811
6812
            /* Point SEC to the location of the descriptor */
6813
            MCF_SEC_FR0 = (uint32)secDesc;
6814
            /* Initialize SEC and wait for encryption to complete */
6815
            MCF_SEC_CCCR0 = 0x0000001a;
6816
            /* poll SISR to determine when channel is complete */
6817
            v=0;
6818
6819
            while ((secDesc->header>> 24) != 0xff) v++;
6820
6821
            #ifdef DEBUG_WOLFSSL
6822
                ret = MCF_SEC_SISRH;
6823
                stat1 = MCF_SEC_AESSR;
6824
                stat2 = MCF_SEC_AESISR;
6825
                if (ret & 0xe0000000) {
6826
                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
6827
                              "AESISR=%08x\n", i, ret, stat1, stat2);
6828
                }
6829
            #endif
6830
6831
            XMEMCPY(po, AESBuffOut, size);
6832
6833
            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
6834
                XMEMCPY((void*)aes->reg, (void*)&(po[size-WC_AES_BLOCK_SIZE]),
6835
                        WC_AES_BLOCK_SIZE);
6836
            } else {
6837
                XMEMCPY((void*)aes->reg, (void*)aes->tmp, WC_AES_BLOCK_SIZE);
6838
            }
6839
6840
            pi += size;
6841
            po += size;
6842
        }
6843
6844
        wc_UnLockMutex(&Mutex_AesSEC);
6845
        return 0;
6846
    }
6847
6848
    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6849
    {
6850
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
6851
    }
6852
6853
    #ifdef HAVE_AES_DECRYPT
6854
    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6855
    {
6856
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
6857
    }
6858
    #endif /* HAVE_AES_DECRYPT */
6859
6860
#elif defined(FREESCALE_LTC)
6861
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6862
    {
6863
        word32 keySize;
6864
        status_t status;
6865
        byte *iv, *enc_key;
6866
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6867
6868
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6869
        if (sz % WC_AES_BLOCK_SIZE) {
6870
            return BAD_LENGTH_E;
6871
        }
6872
#endif
6873
        if (blocks == 0)
6874
            return 0;
6875
6876
        iv      = (byte*)aes->reg;
6877
        enc_key = (byte*)aes->key;
6878
6879
        status = wc_AesGetKeySize(aes, &keySize);
6880
        if (status != 0) {
6881
            return status;
6882
        }
6883
6884
        status = wolfSSL_CryptHwMutexLock();
6885
        if (status != 0)
6886
            return status;
6887
        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6888
            iv, enc_key, keySize);
6889
        wolfSSL_CryptHwMutexUnLock();
6890
6891
        /* store iv for next call */
6892
        if (status == kStatus_Success) {
6893
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6894
        }
6895
6896
        return (status == kStatus_Success) ? 0 : -1;
6897
    }
6898
6899
    #ifdef HAVE_AES_DECRYPT
6900
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6901
    {
6902
        word32 keySize;
6903
        status_t status;
6904
        byte* iv, *dec_key;
6905
        byte temp_block[WC_AES_BLOCK_SIZE];
6906
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6907
6908
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6909
        if (sz % WC_AES_BLOCK_SIZE) {
6910
            return BAD_LENGTH_E;
6911
        }
6912
#endif
6913
        if (blocks == 0)
6914
            return 0;
6915
6916
        iv      = (byte*)aes->reg;
6917
        dec_key = (byte*)aes->key;
6918
6919
        status = wc_AesGetKeySize(aes, &keySize);
6920
        if (status != 0) {
6921
            return status;
6922
        }
6923
6924
        /* get IV for next call */
6925
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6926
6927
        status = wolfSSL_CryptHwMutexLock();
6928
        if (status != 0)
6929
            return status;
6930
        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6931
            iv, dec_key, keySize, kLTC_EncryptKey);
6932
        wolfSSL_CryptHwMutexUnLock();
6933
6934
        /* store IV for next call */
6935
        if (status == kStatus_Success) {
6936
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6937
        }
6938
6939
        return (status == kStatus_Success) ? 0 : -1;
6940
    }
6941
    #endif /* HAVE_AES_DECRYPT */
6942
6943
#elif defined(FREESCALE_MMCAU) && !defined(WOLFSSL_ARMASM)
6944
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6945
    {
6946
        int offset = 0;
6947
        byte *iv;
6948
        byte temp_block[WC_AES_BLOCK_SIZE];
6949
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6950
        int ret;
6951
6952
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6953
        if (sz % WC_AES_BLOCK_SIZE) {
6954
            return BAD_LENGTH_E;
6955
        }
6956
#endif
6957
        if (blocks == 0)
6958
            return 0;
6959
6960
        iv = (byte*)aes->reg;
6961
6962
        while (blocks--) {
6963
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
6964
6965
            /* XOR block with IV for CBC */
6966
            xorbuf(temp_block, iv, WC_AES_BLOCK_SIZE);
6967
6968
            ret = wc_AesEncrypt(aes, temp_block, out + offset);
6969
            if (ret != 0)
6970
                return ret;
6971
6972
            offset += WC_AES_BLOCK_SIZE;
6973
6974
            /* store IV for next block */
6975
            XMEMCPY(iv, out + offset - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6976
        }
6977
6978
        return 0;
6979
    }
6980
    #ifdef HAVE_AES_DECRYPT
6981
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6982
    {
6983
        int ret;
6984
        int offset = 0;
6985
        byte* iv;
6986
        byte temp_block[WC_AES_BLOCK_SIZE];
6987
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6988
6989
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6990
        if (sz % WC_AES_BLOCK_SIZE) {
6991
            return BAD_LENGTH_E;
6992
        }
6993
#endif
6994
        if (blocks == 0)
6995
            return 0;
6996
6997
        iv = (byte*)aes->reg;
6998
6999
        while (blocks--) {
7000
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
7001
7002
            ret = wc_AesDecrypt(aes, in + offset, out + offset);
7003
            if (ret != 0)
7004
                return ret;
7005
7006
            /* XOR block with IV for CBC */
7007
            xorbuf(out + offset, iv, WC_AES_BLOCK_SIZE);
7008
7009
            /* store IV for next block */
7010
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
7011
7012
            offset += WC_AES_BLOCK_SIZE;
7013
        }
7014
        return 0;
7015
    }
7016
    #endif /* HAVE_AES_DECRYPT */
7017
7018
#elif defined(MAX3266X_AES)
7019
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7020
    {
7021
        word32 keySize;
7022
        int status;
7023
        byte *iv;
7024
7025
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
7026
            return BAD_FUNC_ARG;
7027
        }
7028
7029
        /* Always enforce a length check */
7030
        if (sz % WC_AES_BLOCK_SIZE) {
7031
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7032
            return BAD_LENGTH_E;
7033
        #else
7034
            return BAD_FUNC_ARG;
7035
        #endif
7036
        }
7037
        if (sz == 0) {
7038
            return 0;
7039
        }
7040
7041
        iv = (byte*)aes->reg;
7042
        status = wc_AesGetKeySize(aes, &keySize);
7043
        if (status != 0) {
7044
            return status;
7045
        }
7046
7047
        status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
7048
                                        MXC_TPU_MODE_CBC, sz, out,
7049
                                        (unsigned int)keySize);
7050
        /* store iv for next call */
7051
        if (status == 0) {
7052
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7053
        }
7054
        return (status == 0) ? 0 : -1;
7055
    }
7056
7057
    #ifdef HAVE_AES_DECRYPT
7058
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7059
    {
7060
        word32 keySize;
7061
        int status;
7062
        byte *iv;
7063
        byte temp_block[WC_AES_BLOCK_SIZE];
7064
7065
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
7066
            return BAD_FUNC_ARG;
7067
        }
7068
7069
        /* Always enforce a length check */
7070
        if (sz % WC_AES_BLOCK_SIZE) {
7071
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7072
            return BAD_LENGTH_E;
7073
        #else
7074
            return BAD_FUNC_ARG;
7075
        #endif
7076
        }
7077
        if (sz == 0) {
7078
            return 0;
7079
        }
7080
7081
        iv = (byte*)aes->reg;
7082
        status = wc_AesGetKeySize(aes, &keySize);
7083
        if (status != 0) {
7084
            return status;
7085
        }
7086
7087
        /* get IV for next call */
7088
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7089
        status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
7090
                                        MXC_TPU_MODE_CBC, sz, out,
7091
                                        keySize);
7092
7093
        /* store iv for next call */
7094
        if (status == 0) {
7095
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
7096
        }
7097
        return (status == 0) ? 0 : -1;
7098
    }
7099
    #endif /* HAVE_AES_DECRYPT */
7100
7101
7102
7103
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
7104
7105
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7106
    {
7107
        int ret;
7108
7109
        if (aes == NULL)
7110
            return BAD_FUNC_ARG;
7111
7112
        if (!WC_AES_KEY_IS_SET(aes)) {
7113
            WOLFSSL_MSG("AES key not set");
7114
            return MISSING_KEY;
7115
        }
7116
7117
        if (sz == 0)
7118
            return 0;
7119
7120
        /* hardware fails on input that is not a multiple of AES block size */
7121
        if (sz % WC_AES_BLOCK_SIZE != 0) {
7122
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7123
            return BAD_LENGTH_E;
7124
#else
7125
            return BAD_FUNC_ARG;
7126
#endif
7127
        }
7128
7129
        ret = wc_Pic32AesCrypt(
7130
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
7131
            out, in, sz, PIC32_ENCRYPTION,
7132
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
7133
7134
        /* store iv for next call */
7135
        if (ret == 0) {
7136
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7137
        }
7138
7139
        return ret;
7140
    }
7141
    #ifdef HAVE_AES_DECRYPT
7142
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7143
    {
7144
        int ret;
7145
        byte scratch[WC_AES_BLOCK_SIZE];
7146
7147
        if (aes == NULL)
7148
            return BAD_FUNC_ARG;
7149
7150
        if (!WC_AES_KEY_IS_SET(aes)) {
7151
            WOLFSSL_MSG("AES key not set");
7152
            return MISSING_KEY;
7153
        }
7154
7155
        if (sz == 0)
7156
            return 0;
7157
7158
        /* hardware fails on input that is not a multiple of AES block size */
7159
        if (sz % WC_AES_BLOCK_SIZE != 0) {
7160
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7161
            return BAD_LENGTH_E;
7162
#else
7163
            return BAD_FUNC_ARG;
7164
#endif
7165
        }
7166
        XMEMCPY(scratch, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7167
7168
        ret = wc_Pic32AesCrypt(
7169
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
7170
            out, in, sz, PIC32_DECRYPTION,
7171
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
7172
7173
        /* store iv for next call */
7174
        if (ret == 0) {
7175
            XMEMCPY((byte*)aes->reg, scratch, WC_AES_BLOCK_SIZE);
7176
        }
7177
7178
        return ret;
7179
    }
7180
    #endif /* HAVE_AES_DECRYPT */
7181
#elif defined(WOLFSSL_ESP32_CRYPT) && \
7182
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
7183
7184
    /* We'll use SW for fall back:
7185
     *   unsupported key lengths
7186
     *   hardware busy */
7187
    #define NEED_SW_AESCBC
7188
    #define NEED_AESCBC_HW_FALLBACK
7189
7190
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
7191
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7192
    {
7193
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
7194
    }
7195
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7196
    {
7197
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
7198
    }
7199
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
7200
        !defined(WOLFSSL_QNX_CAAM)
7201
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
7202
7203
#elif defined(WOLFSSL_AFALG)
7204
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
7205
7206
#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
7207
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
7208
7209
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
7210
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
7211
7212
#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
7213
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
7214
7215
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
7216
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
7217
7218
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
7219
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
7220
7221
#elif defined(WOLFSSL_PSOC6_CRYPTO)
7222
7223
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7224
    {
7225
        if (aes == NULL)
7226
            return BAD_FUNC_ARG;
7227
        if (!WC_AES_KEY_IS_SET(aes)) {
7228
            WOLFSSL_MSG("AES key not set");
7229
            return MISSING_KEY;
7230
        }
7231
        return wc_Psoc6_Aes_CbcEncrypt(aes, out, in, sz);
7232
    }
7233
7234
    #if defined(HAVE_AES_DECRYPT)
7235
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7236
    {
7237
        if (aes == NULL)
7238
            return BAD_FUNC_ARG;
7239
        if (!WC_AES_KEY_IS_SET(aes)) {
7240
            WOLFSSL_MSG("AES key not set");
7241
            return MISSING_KEY;
7242
        }
7243
        return wc_Psoc6_Aes_CbcDecrypt(aes, out, in, sz);
7244
    }
7245
    #endif /* HAVE_AES_DECRYPT */
7246
7247
#else
7248
    /* Reminder: Some HW implementations may also define this as needed.
7249
     * (e.g. for unsupported key length fallback)  */
7250
    #define NEED_SW_AESCBC
7251
#endif
7252
7253
#ifdef NEED_SW_AESCBC
7254
    /* Software AES - CBC Encrypt */
7255
7256
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7257
441
    {
7258
441
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7259
441
        word32 blocks;
7260
441
        int ret;
7261
441
#endif
7262
7263
441
        if (aes == NULL || out == NULL || in == NULL) {
7264
0
            return BAD_FUNC_ARG;
7265
0
        }
7266
7267
441
        if (sz == 0) {
7268
            /* Keep above the DCP/crypto-cb dispatches: they must not see
7269
             * sz == 0. A missing key is only reported when there is work. */
7270
0
            return 0;
7271
0
        }
7272
7273
441
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7274
441
        blocks = sz / WC_AES_BLOCK_SIZE;
7275
441
#endif
7276
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7277
        if (sz % WC_AES_BLOCK_SIZE) {
7278
            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
7279
            return BAD_LENGTH_E;
7280
        }
7281
#endif
7282
7283
    #ifdef WOLFSSL_IMXRT_DCP
7284
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
7285
        if (aes->keylen == 16)
7286
            return DCPAesCbcEncrypt(aes, out, in, sz);
7287
    #endif
7288
7289
441
    #ifdef WOLF_CRYPTO_CB
7290
441
        #ifndef WOLF_CRYPTO_CB_FIND
7291
441
        if (aes->devId != INVALID_DEVID)
7292
0
        #endif
7293
0
        {
7294
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
7295
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7296
0
                return crypto_cb_ret;
7297
            /* fall-through when unavailable */
7298
0
        }
7299
441
    #endif
7300
7301
        /* Single key guard after all offload dispatches. */
7302
441
        if (!WC_AES_KEY_IS_SET(aes)) {
7303
0
            WOLFSSL_MSG("AES key not set");
7304
0
            return MISSING_KEY;
7305
0
        }
7306
7307
#if defined(WOLFSSL_RISCV_ASM)
7308
        AES_CBC_encrypt_RISCV64(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7309
            (int)aes->rounds);
7310
        (void)blocks;
7311
        (void)ret;
7312
        return 0;
7313
#endif
7314
7315
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
7316
        /* if async and byte count above threshold */
7317
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
7318
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
7319
        #if defined(HAVE_CAVIUM)
7320
            return NitroxAesCbcEncrypt(aes, out, in, sz);
7321
        #elif defined(HAVE_INTEL_QA)
7322
            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
7323
                (const byte*)aes->devKey, aes->keylen,
7324
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7325
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
7326
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
7327
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
7328
                sw->aes.aes = aes;
7329
                sw->aes.out = out;
7330
                sw->aes.in = in;
7331
                sw->aes.sz = sz;
7332
                return WC_PENDING_E;
7333
            }
7334
        #endif
7335
        }
7336
    #endif /* WOLFSSL_ASYNC_CRYPT */
7337
7338
#if defined(WOLFSSL_ARMASM)
7339
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7340
    #if !defined(__aarch64__)
7341
      #ifdef WOLFSSL_ARM32_AES_DISPATCH
7342
        if (aes->use_aes_hw_crypto) {
7343
            AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
7344
                (byte*)aes->key, (int)aes->rounds);
7345
        }
7346
        else
7347
      #else
7348
        AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7349
            (int)aes->rounds);
7350
      #endif /* WOLFSSL_ARM32_AES_DISPATCH */
7351
    #else
7352
        if (aes->use_aes_hw_crypto) {
7353
            AES_CBC_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7354
                (byte*)aes->key, (int)aes->rounds);
7355
        }
7356
        else
7357
    #endif /* __aarch64__ */
7358
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7359
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
7360
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7361
        {
7362
            AES_CBC_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
7363
                aes->rounds, (unsigned char*)aes->reg);
7364
        }
7365
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
7366
          defined(WOLFSSL_ARM32_AES_DISPATCH)
7367
        {
7368
            AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
7369
                aes->rounds, (unsigned char*)aes->reg);
7370
        }
7371
    #endif
7372
        return 0;
7373
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7374
        AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
7375
            aes->rounds, (unsigned char*)aes->reg);
7376
        return 0;
7377
#else
7378
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
7379
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
7380
        if (aes->useSWCrypt == 0) {
7381
            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
7382
                                   kAlgorithm_SSS_AES_CBC);
7383
        }
7384
        else
7385
    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
7386
        if (wc_esp32AesSupportedKeyLen(aes)) {
7387
            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
7388
            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
7389
        }
7390
        else {
7391
            /* For example, the ESP32-S3 does not support HW for len = 24,
7392
             * so fall back to SW */
7393
        #ifdef DEBUG_WOLFSSL
7394
            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
7395
                          "unsupported keylen = %d", aes->keylen);
7396
        #endif
7397
        }
7398
    #elif defined(WOLFSSL_AESNI)
7399
        VECTOR_REGISTERS_PUSH;
7400
        if (aes->use_aesni) {
7401
            #ifdef DEBUG_AESNI
7402
                printf("about to aes cbc encrypt\n");
7403
                printf("in  = %p\n", in);
7404
                printf("out = %p\n", out);
7405
                printf("aes->key = %p\n", aes->key);
7406
                printf("aes->reg = %p\n", aes->reg);
7407
                printf("aes->rounds = %d\n", aes->rounds);
7408
                printf("sz = %d\n", sz);
7409
            #endif
7410
7411
            /* check alignment, decrypt doesn't need alignment */
7412
            if ((wc_ptr_t)in % AESNI_ALIGN) {
7413
            #ifndef NO_WOLFSSL_ALLOC_ALIGN
7414
                byte* tmp = (byte*)XMALLOC(sz + WC_AES_BLOCK_SIZE + AESNI_ALIGN,
7415
                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
7416
                byte* tmp_align;
7417
                if (tmp == NULL)
7418
                    ret = MEMORY_E;
7419
                else {
7420
                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
7421
                    XMEMCPY(tmp_align, in, sz);
7422
                #ifdef WOLFSSL_X86_64_BUILD
7423
                    AesCbcEncryptBlocks(tmp_align, tmp_align, (byte*)aes->reg, sz,
7424
                                        (byte*)aes->key, (int)aes->rounds);
7425
                #else
7426
                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
7427
                                          (byte*)aes->key, (int)aes->rounds);
7428
                #endif
7429
                    /* store iv for next call */
7430
                    XMEMCPY(aes->reg, tmp_align + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7431
7432
                    XMEMCPY(out, tmp_align, sz);
7433
                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
7434
                    ret = 0;
7435
                }
7436
            #else
7437
                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
7438
                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
7439
                ret = BAD_ALIGN_E;
7440
            #endif
7441
            } else {
7442
            #ifdef WOLFSSL_X86_64_BUILD
7443
                AesCbcEncryptBlocks(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7444
                                    (int)aes->rounds);
7445
            #else
7446
                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7447
                                      (int)aes->rounds);
7448
            #endif
7449
                /* store iv for next call */
7450
                XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7451
7452
                ret = 0;
7453
            }
7454
        }
7455
        else
7456
    #endif
7457
441
        {
7458
441
#ifdef WC_AES_HAVE_PREFETCH_ARG
7459
441
            int did_prefetches = 0;
7460
441
#endif
7461
441
            ret = 0;
7462
5.38k
            while (blocks--) {
7463
4.94k
                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
7464
4.94k
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7465
4.94k
                                                (byte*)aes->reg,
7466
4.94k
                                                &did_prefetches);
7467
4.94k
                if (ret != 0)
7468
0
                    break;
7469
4.94k
                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
7470
7471
4.94k
                out += WC_AES_BLOCK_SIZE;
7472
4.94k
                in  += WC_AES_BLOCK_SIZE;
7473
4.94k
            }
7474
441
        }
7475
7476
    #ifdef WOLFSSL_AESNI
7477
        VECTOR_REGISTERS_POP;
7478
    #endif
7479
7480
441
        return ret;
7481
441
#endif
7482
441
    } /* wc_AesCbcEncrypt */
7483
7484
#ifdef HAVE_AES_DECRYPT
7485
    /* Software AES - CBC Decrypt */
7486
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7487
181
    {
7488
181
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7489
181
        word32 blocks;
7490
181
        int ret;
7491
181
#endif
7492
7493
181
        if (aes == NULL || out == NULL || in == NULL) {
7494
0
            return BAD_FUNC_ARG;
7495
0
        }
7496
7497
181
        if (sz == 0) {
7498
            /* Keep above the DCP/crypto-cb dispatches: they must not see
7499
             * sz == 0. A missing key is only reported when there is work. */
7500
0
            return 0;
7501
0
        }
7502
7503
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
7504
        if (wc_esp32AesSupportedKeyLen(aes)) {
7505
            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
7506
            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
7507
        }
7508
        else {
7509
            /* For example, the ESP32-S3 does not support HW for len = 24,
7510
             * so fall back to SW */
7511
        #ifdef DEBUG_WOLFSSL
7512
            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
7513
                          "unsupported keylen = %d", aes->keylen);
7514
        #endif
7515
        }
7516
    #endif
7517
7518
181
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7519
181
        blocks = sz / WC_AES_BLOCK_SIZE;
7520
181
#endif
7521
181
        if (sz % WC_AES_BLOCK_SIZE) {
7522
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7523
            return BAD_LENGTH_E;
7524
#else
7525
0
            return BAD_FUNC_ARG;
7526
0
#endif
7527
0
        }
7528
7529
    #ifdef WOLFSSL_IMXRT_DCP
7530
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
7531
        if (aes->keylen == 16)
7532
            return DCPAesCbcDecrypt(aes, out, in, sz);
7533
    #endif
7534
7535
181
    #ifdef WOLF_CRYPTO_CB
7536
181
        #ifndef WOLF_CRYPTO_CB_FIND
7537
181
        if (aes->devId != INVALID_DEVID)
7538
0
        #endif
7539
0
        {
7540
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
7541
0
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7542
0
                return crypto_cb_ret;
7543
            /* fall-through when unavailable */
7544
0
        }
7545
181
    #endif
7546
7547
        /* Single key guard after all offload dispatches. */
7548
181
        if (!WC_AES_KEY_IS_SET(aes)) {
7549
0
            WOLFSSL_MSG("AES key not set");
7550
0
            return MISSING_KEY;
7551
0
        }
7552
7553
#if defined(WOLFSSL_RISCV_ASM)
7554
        AES_CBC_decrypt_RISCV64(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7555
            (int)aes->rounds);
7556
        (void)blocks;
7557
        (void)ret;
7558
        return 0;
7559
#endif
7560
7561
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
7562
        /* if async and byte count above threshold */
7563
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
7564
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
7565
        #if defined(HAVE_CAVIUM)
7566
            return NitroxAesCbcDecrypt(aes, out, in, sz);
7567
        #elif defined(HAVE_INTEL_QA)
7568
            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
7569
                (const byte*)aes->devKey, aes->keylen,
7570
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7571
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
7572
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
7573
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
7574
                sw->aes.aes = aes;
7575
                sw->aes.out = out;
7576
                sw->aes.in = in;
7577
                sw->aes.sz = sz;
7578
                return WC_PENDING_E;
7579
            }
7580
        #endif
7581
        }
7582
    #endif
7583
7584
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
7585
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
7586
        if (aes->useSWCrypt == 0) {
7587
            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
7588
                                   kAlgorithm_SSS_AES_CBC);
7589
        }
7590
    #endif
7591
7592
#if defined(WOLFSSL_ARMASM)
7593
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7594
    #if !defined(__aarch64__)
7595
      #ifdef WOLFSSL_ARM32_AES_DISPATCH
7596
        if (aes->use_aes_hw_crypto) {
7597
            AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg,
7598
                (byte*)aes->key, (int)aes->rounds);
7599
        }
7600
        else
7601
      #else
7602
        AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7603
            (int)aes->rounds);
7604
      #endif /* WOLFSSL_ARM32_AES_DISPATCH */
7605
    #else
7606
        if (aes->use_aes_hw_crypto) {
7607
            AES_CBC_decrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7608
                (byte*)aes->key, (int)aes->rounds);
7609
        }
7610
        else
7611
    #endif /* !__aarch64__ */
7612
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7613
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
7614
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7615
        if (sz >= 64)
7616
    #endif
7617
        {
7618
            AES_CBC_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
7619
                aes->rounds, (unsigned char*)aes->reg);
7620
        }
7621
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7622
        else
7623
    #endif
7624
    #endif /* __aarch64__ && !WOLFSSL_ARMASM_NO_NEON */
7625
    #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
7626
        defined(WOLFSSL_ARM32_AES_DISPATCH)
7627
    /* WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP drops the base (table) AES in favour
7628
     * of the constant-time NEON one - but only the AArch64 assembly has a NEON
7629
     * AES to replace it with, and only it leaves the base variants out.  The
7630
     * AArch32 assembly always provides them, so the call must be kept there. */
7631
    #if !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP) || !defined(__aarch64__)
7632
        {
7633
            AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
7634
                aes->rounds, (unsigned char*)aes->reg);
7635
        }
7636
    #endif
7637
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO ||
7638
            * WOLFSSL_ARM32_AES_DISPATCH */
7639
        return 0;
7640
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7641
        AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
7642
            aes->rounds, (unsigned char*)aes->reg);
7643
        return 0;
7644
#else
7645
181
        VECTOR_REGISTERS_PUSH;
7646
7647
    #ifdef WOLFSSL_AESNI
7648
        if (aes->use_aesni) {
7649
            #ifdef DEBUG_AESNI
7650
                printf("about to aes cbc decrypt\n");
7651
                printf("in  = %p\n", in);
7652
                printf("out = %p\n", out);
7653
                printf("aes->key = %p\n", aes->key);
7654
                printf("aes->reg = %p\n", aes->reg);
7655
                printf("aes->rounds = %d\n", aes->rounds);
7656
                printf("sz = %d\n", sz);
7657
            #endif
7658
7659
            /* if input and output same will overwrite input iv */
7660
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7661
            #if defined(WOLFSSL_X86_64_BUILD)
7662
            AesCbcDecryptBlocks(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7663
                            (int)aes->rounds);
7664
            #elif defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
7665
            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7666
                            aes->rounds);
7667
            #elif defined(WOLFSSL_AESNI_BY6)
7668
            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7669
                            aes->rounds);
7670
            #else /* WOLFSSL_AESNI_BYx */
7671
            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7672
                            (int)aes->rounds);
7673
            #endif /* WOLFSSL_AESNI_BYx */
7674
            /* store iv for next call */
7675
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7676
            ret = 0;
7677
        }
7678
        else
7679
    #endif
7680
181
        {
7681
181
            ret = 0;
7682
#ifdef WC_AES_BITSLICED
7683
            if (in != out) {
7684
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
7685
7686
                while (blocks > BS_WORD_SIZE) {
7687
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
7688
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7689
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
7690
                              WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
7691
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
7692
                            WC_AES_BLOCK_SIZE);
7693
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7694
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7695
                    blocks -= BS_WORD_SIZE;
7696
                }
7697
                if (blocks > 0) {
7698
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
7699
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7700
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
7701
                              WC_AES_BLOCK_SIZE * (blocks - 1));
7702
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (blocks - 1)),
7703
                            WC_AES_BLOCK_SIZE);
7704
                    blocks = 0;
7705
                }
7706
            }
7707
            else {
7708
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
7709
                int i;
7710
7711
                while (blocks > BS_WORD_SIZE) {
7712
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
7713
                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * WC_AES_BLOCK_SIZE,
7714
                            WC_AES_BLOCK_SIZE);
7715
                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
7716
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
7717
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
7718
                                  WC_AES_BLOCK_SIZE);
7719
                    }
7720
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7721
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7722
7723
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7724
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7725
                    blocks -= BS_WORD_SIZE;
7726
                }
7727
                if (blocks > 0) {
7728
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
7729
                    XMEMCPY(aes->tmp, in + (blocks - 1) * WC_AES_BLOCK_SIZE,
7730
                            WC_AES_BLOCK_SIZE);
7731
                    for (i = blocks-1; i >= 1; i--) {
7732
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
7733
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
7734
                                  WC_AES_BLOCK_SIZE);
7735
                    }
7736
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7737
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7738
7739
                    blocks = 0;
7740
                }
7741
            }
7742
#else
7743
181
#ifdef WC_AES_HAVE_PREFETCH_ARG
7744
181
            {
7745
181
            int did_prefetches = 0;
7746
181
#endif
7747
7.39k
            while (blocks--) {
7748
7.21k
                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
7749
7.21k
                ret = AesDecrypt_preFetchOpt(aes, in, out, &did_prefetches);
7750
7.21k
                if (ret != 0)
7751
0
                    return ret;
7752
7.21k
                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7753
                /* store iv for next call */
7754
7.21k
                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7755
7756
7.21k
                out += WC_AES_BLOCK_SIZE;
7757
7.21k
                in  += WC_AES_BLOCK_SIZE;
7758
7.21k
            }
7759
181
#ifdef WC_AES_HAVE_PREFETCH_ARG
7760
181
            }
7761
181
#endif
7762
181
#endif
7763
181
        }
7764
7765
181
        VECTOR_REGISTERS_POP;
7766
7767
181
        return ret;
7768
181
#endif
7769
181
    }
7770
#endif /* HAVE_AES_DECRYPT */
7771
7772
#endif /* AES-CBC block */
7773
#endif /* HAVE_AES_CBC */
7774
7775
/* AES-CTR */
7776
#if defined(WOLFSSL_AES_COUNTER)
7777
7778
    #ifdef STM32_CRYPTO
7779
        #define NEED_AES_CTR_SOFT
7780
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
7781
7782
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
7783
        {
7784
        #ifdef WOLFSSL_STM32_BARE
7785
            /* CTR per-block transform: produce out = in XOR AES_ECB(counter).
7786
             * ECB-encrypt the counter aes->reg into a keystream block, then XOR
7787
             * with the plaintext 'in'. The caller (XTRANSFORM_AESCTRBLOCK loop)
7788
             * does not XOR and increments aes->reg after this returns. */
7789
            byte ks[WC_AES_BLOCK_SIZE];
7790
            int  ret = wc_Stm32_Aes_Ecb(aes, ks, (const byte*)aes->reg,
7791
                                        WC_AES_BLOCK_SIZE, 1);
7792
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7793
            wc_MemZero_Add("wc_AesCtrEncryptBlock ks", ks, sizeof(ks));
7794
        #endif
7795
            if (ret == 0) {
7796
                xorbufout(out, in, ks, WC_AES_BLOCK_SIZE);
7797
            }
7798
            else {
7799
                /* The CTR loop breaks on this non-zero return; zero the block
7800
                 * so a failed HW ECB does not leave stale/prior plaintext in
7801
                 * the output. */
7802
                ForceZero(out, WC_AES_BLOCK_SIZE);
7803
            }
7804
            ForceZero(ks, sizeof(ks));
7805
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7806
            wc_MemZero_Check(ks, sizeof(ks));
7807
        #endif
7808
            return ret;
7809
        #else
7810
            int ret = 0;
7811
        #ifdef WOLFSSL_STM32_CUBEMX
7812
            CRYP_HandleTypeDef hcryp;
7813
            #ifdef STM32_HAL_V2
7814
            word32 iv[WC_AES_BLOCK_SIZE/sizeof(word32)];
7815
            #endif
7816
        #else
7817
            word32 *iv;
7818
            CRYP_InitTypeDef cryptInit;
7819
            CRYP_KeyInitTypeDef keyInit;
7820
            CRYP_IVInitTypeDef ivInit;
7821
        #endif
7822
7823
        #ifdef WOLFSSL_STM32_CUBEMX
7824
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
7825
            if (ret != 0) {
7826
                return ret;
7827
            }
7828
7829
            ret = wolfSSL_CryptHwMutexLock();
7830
            if (ret != 0) {
7831
                return ret;
7832
            }
7833
7834
        #if defined(STM32_HAL_V2)
7835
            hcryp.Init.Algorithm  = CRYP_AES_CTR;
7836
            ByteReverseWords(iv, aes->reg, WC_AES_BLOCK_SIZE);
7837
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
7838
        #elif defined(STM32_CRYPTO_AES_ONLY)
7839
            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
7840
            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
7841
            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
7842
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
7843
        #else
7844
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
7845
        #endif
7846
            HAL_CRYP_Init(&hcryp);
7847
7848
        #if defined(STM32_HAL_V2)
7849
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, WC_AES_BLOCK_SIZE,
7850
                (uint32_t*)out, STM32_HAL_TIMEOUT);
7851
        #elif defined(STM32_CRYPTO_AES_ONLY)
7852
            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
7853
                out, STM32_HAL_TIMEOUT);
7854
        #else
7855
            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
7856
                out, STM32_HAL_TIMEOUT);
7857
        #endif
7858
            if (ret != HAL_OK) {
7859
                ret = WC_TIMEOUT_E;
7860
            }
7861
            HAL_CRYP_DeInit(&hcryp);
7862
7863
        #else /* Standard Peripheral Library */
7864
            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
7865
            if (ret != 0) {
7866
                return ret;
7867
            }
7868
7869
            ret = wolfSSL_CryptHwMutexLock();
7870
            if (ret != 0) {
7871
                return ret;
7872
            }
7873
7874
            /* reset registers to their default values */
7875
            CRYP_DeInit();
7876
7877
            /* set key */
7878
            CRYP_KeyInit(&keyInit);
7879
7880
            /* set iv */
7881
            iv = aes->reg;
7882
            CRYP_IVStructInit(&ivInit);
7883
            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
7884
            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
7885
            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
7886
            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
7887
            CRYP_IVInit(&ivInit);
7888
7889
            /* set direction and mode */
7890
            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
7891
            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
7892
            CRYP_Init(&cryptInit);
7893
7894
            /* enable crypto processor */
7895
            CRYP_Cmd(ENABLE);
7896
7897
            /* flush IN/OUT FIFOs */
7898
            CRYP_FIFOFlush();
7899
7900
            wc_Stm32_CrypAesBlock(in, out);
7901
7902
            /* disable crypto processor */
7903
            CRYP_Cmd(DISABLE);
7904
        #endif /* WOLFSSL_STM32_CUBEMX */
7905
7906
            wolfSSL_CryptHwMutexUnLock();
7907
            wc_Stm32_Aes_Cleanup();
7908
            return ret;
7909
        #endif /* !WOLFSSL_STM32_BARE */
7910
        }
7911
7912
7913
    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
7914
7915
        #define NEED_AES_CTR_SOFT
7916
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
7917
7918
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
7919
        {
7920
            word32 tmpIv[WC_AES_BLOCK_SIZE / sizeof(word32)];
7921
            XMEMCPY(tmpIv, aes->reg, WC_AES_BLOCK_SIZE);
7922
            return wc_Pic32AesCrypt(
7923
                aes->key, aes->keylen, tmpIv, WC_AES_BLOCK_SIZE,
7924
                out, in, WC_AES_BLOCK_SIZE,
7925
                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
7926
        }
7927
7928
    #elif defined(HAVE_COLDFIRE_SEC)
7929
        #error "Coldfire SEC doesn't currently support AES-CTR mode"
7930
7931
    #elif defined(FREESCALE_LTC)
7932
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7933
        {
7934
            int ret = 0;
7935
            word32 keySize;
7936
            byte *iv, *enc_key;
7937
            byte* tmp;
7938
7939
            if (aes == NULL || out == NULL || in == NULL) {
7940
                return BAD_FUNC_ARG;
7941
            }
7942
7943
            /* consume any unused bytes left in aes->tmp */
7944
            tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7945
            while (aes->left && sz) {
7946
                *(out++) = *(in++) ^ *(tmp++);
7947
                aes->left--;
7948
                sz--;
7949
            }
7950
7951
            if (sz) {
7952
                iv      = (byte*)aes->reg;
7953
                enc_key = (byte*)aes->key;
7954
7955
                ret = wc_AesGetKeySize(aes, &keySize);
7956
                if (ret != 0)
7957
                    return ret;
7958
7959
                ret = wolfSSL_CryptHwMutexLock();
7960
                if (ret != 0)
7961
                    return ret;
7962
                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
7963
                    iv, enc_key, keySize, (byte*)aes->tmp,
7964
                    (uint32_t*)&aes->left);
7965
                wolfSSL_CryptHwMutexUnLock();
7966
            }
7967
7968
            return ret;
7969
        }
7970
7971
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
7972
        !defined(WOLFSSL_QNX_CAAM)
7973
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
7974
7975
    #elif defined(WOLFSSL_AFALG)
7976
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
7977
7978
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
7979
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
7980
7981
    #elif defined(WOLFSSL_ESP32_CRYPT) && \
7982
        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
7983
        /* esp32 doesn't support CRT mode by hw.     */
7984
        /* use aes ecnryption plus sw implementation */
7985
        #define NEED_AES_CTR_SOFT
7986
7987
    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
7988
        /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
7989
7990
    #elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
7991
        /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
7992
7993
    #else
7994
7995
        /* Use software based AES counter */
7996
        #define NEED_AES_CTR_SOFT
7997
    #endif
7998
7999
    #ifdef NEED_AES_CTR_SOFT
8000
        #ifndef WOLFSSL_ARMASM
8001
        /* Increment AES counter */
8002
        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
8003
2.98k
        {
8004
            /* in network byte order so start at end and work back */
8005
2.98k
            int i;
8006
3.65k
            for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
8007
                /* WC_OCTET, not a bare ++: where CHAR_BIT != 8 a byte cell
8008
                 * holds 0x100 and never wraps, so the carry is lost. */
8009
3.65k
                inOutCtr[i] = WC_OCTET(inOutCtr[i] + 1);
8010
3.65k
                if (inOutCtr[i] != 0)  /* we're done unless we overflow */
8011
2.98k
                    return;
8012
3.65k
            }
8013
2.98k
        }
8014
        #endif
8015
8016
        /* Software AES - CTR Encrypt */
8017
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
8018
829
        {
8019
829
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
8020
829
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8021
829
            byte scratch[WC_AES_BLOCK_SIZE];
8022
829
    #endif
8023
829
    #if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
8024
829
            int ret = 0;
8025
829
    #endif
8026
829
            word32 processed;
8027
829
#ifdef WC_AES_HAVE_PREFETCH_ARG
8028
829
            int did_prefetches = 0;
8029
829
#endif
8030
8031
829
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
8032
829
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8033
829
            XMEMSET(scratch, 0, sizeof(scratch));
8034
829
    #endif
8035
8036
829
            if (aes == NULL || out == NULL || in == NULL) {
8037
0
                return BAD_FUNC_ARG;
8038
0
            }
8039
8040
829
            if (sz == 0) {
8041
                /* Keep above the crypto-cb dispatch: it must not see sz == 0.
8042
                 * A missing key is only reported when there is work. */
8043
0
                return 0;
8044
0
            }
8045
8046
829
        #ifdef WOLF_CRYPTO_CB
8047
829
            #ifndef WOLF_CRYPTO_CB_FIND
8048
829
            if (aes->devId != INVALID_DEVID)
8049
0
            #endif
8050
0
            {
8051
0
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
8052
0
                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
8053
0
                    return crypto_cb_ret;
8054
                /* fall-through when unavailable */
8055
0
            }
8056
829
        #endif
8057
8058
            /* Software/HW key schedule required from here on. */
8059
829
            if (!WC_AES_KEY_IS_SET(aes)) {
8060
0
                WOLFSSL_MSG("AES key not set");
8061
0
                return MISSING_KEY;
8062
0
            }
8063
8064
            /* consume any unused bytes left in aes->tmp */
8065
829
            processed = min(aes->left, sz);
8066
829
            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
8067
829
                      processed);
8068
829
            out += processed;
8069
829
            in += processed;
8070
829
            aes->left -= processed;
8071
829
            sz -= processed;
8072
8073
    #if defined(WOLFSSL_RISCV_ASM)
8074
            if (sz > 0) {
8075
                AES_CTR_encrypt_RISCV64(in, out, sz, (byte*)aes->reg,
8076
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left,
8077
                    (int)aes->rounds);
8078
            }
8079
            (void)scratch;
8080
            (void)ret;
8081
            return 0;
8082
    #endif
8083
8084
    #if defined(WOLFSSL_ARMASM)
8085
        #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
8086
            #ifndef __aarch64__
8087
              #ifdef WOLFSSL_ARM32_AES_DISPATCH
8088
            if (aes->use_aes_hw_crypto) {
8089
                AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
8090
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
8091
                return 0;
8092
            }
8093
            else
8094
              #else
8095
            AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
8096
                (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
8097
              #endif /* WOLFSSL_ARM32_AES_DISPATCH */
8098
            #else
8099
            if (aes->use_aes_hw_crypto) {
8100
                AES_CTR_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
8101
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
8102
                return 0;
8103
            }
8104
            else
8105
            #endif /* !__aarch64__ */
8106
        #endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
8107
        #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
8108
            defined(WOLFSSL_ARM32_AES_DISPATCH)
8109
            {
8110
                word32 numBlocks;
8111
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
8112
                /* consume any unused bytes left in aes->tmp */
8113
                while ((aes->left != 0) && (sz != 0)) {
8114
                   *(out++) = *(in++) ^ *(tmp++);
8115
                   aes->left--;
8116
                   sz--;
8117
                }
8118
8119
                /* do as many block size ops as possible */
8120
                numBlocks = sz / WC_AES_BLOCK_SIZE;
8121
                if (numBlocks > 0) {
8122
                #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
8123
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
8124
                    if (sz >= 32)
8125
                #endif
8126
                    {
8127
                        AES_CTR_encrypt_NEON(in, out,
8128
                            numBlocks * WC_AES_BLOCK_SIZE, (byte*)aes->key,
8129
                            aes->rounds, (byte*)aes->reg);
8130
                    }
8131
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
8132
                    else
8133
                #endif
8134
                #endif
8135
                /* Base AES is only left out on AArch64 - see wc_AesCbcDecrypt.
8136
                 */
8137
                #if !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP) || \
8138
                    !defined(__aarch64__)
8139
                    {
8140
                        AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
8141
                            (byte*)aes->key, aes->rounds, (byte*)aes->reg);
8142
                    }
8143
                #endif
8144
8145
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
8146
                    out += numBlocks * WC_AES_BLOCK_SIZE;
8147
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
8148
                }
8149
8150
                /* handle non block size remaining */
8151
                if (sz) {
8152
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
8153
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
8154
8155
                #if defined(__aarch64__) && \
8156
                    !defined(WOLFSSL_ARMASM_NO_NEON) && \
8157
                    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
8158
                    {
8159
                        AES_CTR_encrypt_NEON(zeros, (byte*)aes->tmp,
8160
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
8161
                            (byte*)aes->reg);
8162
                    }
8163
                #else
8164
                    {
8165
                        AES_CTR_encrypt(zeros, (byte*)aes->tmp,
8166
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
8167
                            (byte*)aes->reg);
8168
                    }
8169
                #endif
8170
8171
                    aes->left = WC_AES_BLOCK_SIZE;
8172
                    tmp = (byte*)aes->tmp;
8173
8174
                    while (sz--) {
8175
                        *(out++) = *(in++) ^ *(tmp++);
8176
                        aes->left--;
8177
                    }
8178
                }
8179
            }
8180
        #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
8181
            return 0;
8182
    #elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
8183
            {
8184
                word32 numBlocks;
8185
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
8186
                /* consume any unused bytes left in aes->tmp */
8187
                while ((aes->left != 0) && (sz != 0)) {
8188
                   *(out++) = *(in++) ^ *(tmp++);
8189
                   aes->left--;
8190
                   sz--;
8191
                }
8192
8193
                /* do as many block size ops as possible */
8194
                numBlocks = sz / WC_AES_BLOCK_SIZE;
8195
                if (numBlocks > 0) {
8196
                    AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
8197
                        (byte*)aes->key, aes->rounds, (byte*)aes->reg);
8198
8199
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
8200
                    out += numBlocks * WC_AES_BLOCK_SIZE;
8201
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
8202
                }
8203
8204
                /* handle non block size remaining */
8205
                if (sz) {
8206
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
8207
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
8208
8209
                    AES_CTR_encrypt(zeros, (byte*)aes->tmp,
8210
                        WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
8211
                        (byte*)aes->reg);
8212
8213
                    aes->left = WC_AES_BLOCK_SIZE;
8214
                    tmp = (byte*)aes->tmp;
8215
8216
                    while (sz--) {
8217
                        *(out++) = *(in++) ^ *(tmp++);
8218
                        aes->left--;
8219
                    }
8220
                }
8221
            }
8222
            return 0;
8223
    #else
8224
829
            VECTOR_REGISTERS_PUSH;
8225
8226
        #if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
8227
            if (aes->use_aesni && sz >= WC_AES_BLOCK_SIZE) {
8228
                word32 ctrBlocks = sz / WC_AES_BLOCK_SIZE;
8229
                word32 ctrBytes  = ctrBlocks * WC_AES_BLOCK_SIZE;
8230
                AesCtrEncryptBlocks(in, out, ctrBytes, (byte*)aes->key,
8231
                                    (int)aes->rounds, (byte*)aes->reg);
8232
                in  += ctrBytes;
8233
                out += ctrBytes;
8234
                sz  -= ctrBytes;
8235
                aes->left = 0;
8236
            }
8237
        #endif
8238
8239
829
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
8240
829
            !defined(XTRANSFORM_AESCTRBLOCK)
8241
829
            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
8242
334
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
8243
334
                byte* counter = (byte*)aes->reg;
8244
334
                byte* c = out;
8245
2.32k
                while (blocks--) {
8246
1.99k
                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
8247
1.99k
                    c += WC_AES_BLOCK_SIZE;
8248
1.99k
                    IncrementAesCounter(counter);
8249
1.99k
                }
8250
8251
                /* reset number of blocks and then do encryption */
8252
334
                blocks = sz / WC_AES_BLOCK_SIZE;
8253
334
                ret = wc_AesEcbEncrypt(aes, out, out,
8254
334
                                       WC_AES_BLOCK_SIZE * blocks);
8255
334
                if (ret == 0) {
8256
334
                    xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
8257
334
                    in += WC_AES_BLOCK_SIZE * blocks;
8258
334
                    out += WC_AES_BLOCK_SIZE * blocks;
8259
334
                    sz -= blocks * WC_AES_BLOCK_SIZE;
8260
334
                }
8261
0
                else {
8262
0
                    ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
8263
0
                }
8264
334
            }
8265
495
            else
8266
495
        #endif
8267
495
            {
8268
            #ifdef WOLFSSL_CHECK_MEM_ZERO
8269
                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
8270
                    WC_AES_BLOCK_SIZE);
8271
            #endif
8272
                /* do as many block size ops as possible */
8273
971
                while (sz >= WC_AES_BLOCK_SIZE) {
8274
                #ifdef XTRANSFORM_AESCTRBLOCK
8275
                    ret = XTRANSFORM_AESCTRBLOCK(aes, out, in);
8276
                    if (ret != 0)
8277
                        break;
8278
                #else
8279
476
                    ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
8280
476
                                                    scratch,
8281
476
                                                    &did_prefetches);
8282
476
                    if (ret != 0)
8283
0
                        break;
8284
476
                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
8285
476
                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
8286
476
                #endif
8287
476
                    IncrementAesCounter((byte*)aes->reg);
8288
8289
476
                    out += WC_AES_BLOCK_SIZE;
8290
476
                    in  += WC_AES_BLOCK_SIZE;
8291
476
                    sz  -= WC_AES_BLOCK_SIZE;
8292
476
                    aes->left = 0;
8293
476
                }
8294
495
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
8295
495
            }
8296
8297
            /* handle non block size remaining and store unused byte count in left */
8298
829
            if ((ret == 0) && sz) {
8299
516
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
8300
516
                                                (byte*)aes->tmp,
8301
516
                                                &did_prefetches);
8302
516
                if (ret == 0) {
8303
516
                    IncrementAesCounter((byte*)aes->reg);
8304
516
                    aes->left = WC_AES_BLOCK_SIZE - sz;
8305
516
                    xorbufout(out, in, aes->tmp, sz);
8306
516
                }
8307
516
            }
8308
8309
829
            if (ret < 0)
8310
0
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
8311
8312
        #ifdef WOLFSSL_CHECK_MEM_ZERO
8313
            wc_MemZero_Check(scratch, WC_AES_BLOCK_SIZE);
8314
        #endif
8315
8316
829
            VECTOR_REGISTERS_POP;
8317
8318
829
            return ret;
8319
829
    #endif
8320
829
        }
8321
8322
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
8323
                                        const byte* iv, int dir)
8324
0
        {
8325
0
            if (aes == NULL) {
8326
0
                return BAD_FUNC_ARG;
8327
0
            }
8328
0
            if (len > sizeof(aes->key)) {
8329
0
                return BAD_FUNC_ARG;
8330
0
            }
8331
8332
0
            return wc_AesSetKey(aes, key, len, iv, dir);
8333
0
        }
8334
8335
    #endif /* NEED_AES_CTR_SOFT */
8336
8337
#endif /* WOLFSSL_AES_COUNTER */
8338
8339
#ifndef WC_AES_HAVE_PREFETCH_ARG
8340
    #ifndef AesEncrypt_preFetchOpt
8341
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
8342
            wc_AesEncrypt(aes, inBlock, outBlock)
8343
    #endif
8344
    #ifndef AesDecrypt_preFetchOpt
8345
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
8346
            wc_AesDecrypt(aes, inBlock, outBlock)
8347
    #endif
8348
#endif
8349
8350
/*
8351
 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
8352
 * of two parts in order:
8353
 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
8354
 *      to the implicit IV.
8355
 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
8356
 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
8357
 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
8358
 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
8359
 * block counter during the encryption.
8360
 */
8361
8362
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
8363
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
8364
1.20k
{
8365
1.20k
    int i;
8366
1.64k
    for (i = (int)ctrSz - 1; i >= 0; i--) {
8367
        /* See IncrementAesCounter() on why this masks to an octet. */
8368
1.64k
        ctr[i] = WC_OCTET(ctr[i] + 1);
8369
1.64k
        if (ctr[i] != 0)
8370
1.20k
            break;
8371
1.64k
    }
8372
1.20k
}
8373
#endif /* HAVE_AESGCM || HAVE_AESCCM */
8374
8375
8376
#ifdef HAVE_AESGCM
8377
8378
#ifdef WOLFSSL_AESGCM_STREAM
8379
    /* Access initialization counter data. */
8380
480
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
8381
    /* Access counter data. */
8382
12.7k
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
8383
    /* Access tag data. */
8384
40.9k
    #define AES_TAG(aes)            ((aes)->streamData + 2 * WC_AES_BLOCK_SIZE)
8385
    /* Access last GHASH block. */
8386
    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE)
8387
    /* Access last encrypted block. */
8388
5.39k
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
8389
8390
20.4k
    #define GHASH_ONE_BLOCK     GHASH_ONE_BLOCK_SW
8391
#endif
8392
8393
#if defined(HAVE_COLDFIRE_SEC)
8394
    #error "Coldfire SEC doesn't currently support AES-GCM mode"
8395
8396
#endif
8397
8398
#if !defined(NO_INLINE) && defined(__GNUC__) && !defined(__cplusplus)
8399
/* Inline for callers here in aes.c, but a callable local function for outside
8400
 * callers.  Don't use WC_INLINE unconditionally, because we can't count on
8401
 * correct behavior beyond gcc/clang, and we don't want the the WC_MAYBE_UNUSED
8402
 * attribute in NO_INLINE builds.
8403
 */
8404
WC_INLINE
8405
#endif
8406
1.12k
int wc_local_AesGcmCheckTagSz(word32 authTagSz) {
8407
#ifdef WC_AES_GCM_ALLOW_NONSTANDARD_TAG_LENGTH
8408
    #ifdef HAVE_FIPS
8409
        #error WC_AES_GCM_ALLOW_NONSTANDARD_TAG_LENGTH not allowed with FIPS 140.
8410
    #endif
8411
    wc_static_assert(WOLFSSL_MIN_AUTH_TAG_SZ >= 4);
8412
    if ((authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) ||
8413
        (authTagSz > WC_AES_BLOCK_SIZE))
8414
    {
8415
        WOLFSSL_MSG("AES-GCM unsupported authTagSz");
8416
        return BAD_FUNC_ARG;
8417
    }
8418
    else
8419
        return 0;
8420
#else
8421
    /* A switch is actually better for the optimizer than most hand-rolled
8422
     * equivalents, because it hands the compiler the exact value set and lets
8423
     * it pick the best lowering per WOLFSSL_MIN_AUTH_TAG_SZ configuration.
8424
     */
8425
1.12k
    switch (authTagSz) {
8426
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 4
8427
    case 4:
8428
#endif
8429
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 8
8430
    case 8:
8431
#endif
8432
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 12
8433
0
    case 12:
8434
0
#endif
8435
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 13
8436
0
    case 13:
8437
0
#endif
8438
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 14
8439
0
    case 14:
8440
0
#endif
8441
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 15
8442
0
    case 15:
8443
0
#endif
8444
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 16
8445
1.09k
    case 16:
8446
1.09k
#endif
8447
1.09k
        return 0;
8448
26
    default:
8449
26
        WOLFSSL_MSG("AES-GCM unsupported authTagSz");
8450
26
        return BAD_FUNC_ARG;
8451
1.12k
    }
8452
1.12k
#endif
8453
1.12k
}
8454
8455
#if defined(WOLFSSL_AFALG)
8456
    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
8457
8458
#elif defined(WOLFSSL_KCAPI_AES)
8459
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
8460
8461
#elif defined(WOLFSSL_DEVCRYPTO_AES)
8462
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
8463
8464
#else /* software + AESNI implementation */
8465
8466
#if !defined(FREESCALE_LTC_AES_GCM)
8467
#if (!(defined(__aarch64__) && defined(WOLFSSL_ARMASM))) || \
8468
    defined(WOLFSSL_AESGCM_STREAM)
8469
static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
8470
43.6k
{
8471
43.6k
    int i;
8472
8473
    /* in network byte order so start at end and work back */
8474
43.7k
    for (i = WC_AES_BLOCK_SIZE - 1; i >= WC_AES_BLOCK_SIZE - CTR_SZ; i--) {
8475
        /* See IncrementAesCounter() on why this masks to an octet. */
8476
43.7k
        inOutCtr[i] = WC_OCTET(inOutCtr[i] + 1);
8477
43.7k
        if (inOutCtr[i] != 0)  /* we're done unless we overflow */
8478
43.6k
            return;
8479
43.7k
    }
8480
43.6k
}
8481
#endif
8482
#endif /* !FREESCALE_LTC_AES_GCM */
8483
8484
/* Alignment for the GHASH tag held on the stack.
8485
 *
8486
 * The tag is a byte array to the C code, but the assembly implementations
8487
 * transfer it a machine word at a time - the AArch32 and Thumb-2
8488
 * GCM_gmult_len write it back with stm, which faults on an unaligned address
8489
 * whatever SCTLR.A says - so it has to be aligned to the word size of the
8490
 * platform rather than left at the natural alignment of a byte array. */
8491
#ifdef WC_64BIT_CPU
8492
614
    #define ALIGN_GCM_TAG   ALIGN8
8493
#else
8494
    #define ALIGN_GCM_TAG   ALIGN4
8495
#endif
8496
8497
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8498
8499
static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
8500
2.18k
{
8501
    /* Multiply the sz by 8.  CHAR_BIT * sizeof, not 8 * sizeof: sizeof counts
8502
     * cells, so the latter is a 16-bit width where CHAR_BIT == 16. */
8503
2.18k
    word32 szHi = (sz >> (CHAR_BIT * sizeof(sz) - 3));
8504
2.18k
    sz <<= 3;
8505
8506
    /* WC_OCTET, not (byte): the cast keeps the full cell where CHAR_BIT != 8,
8507
     * so a 60-octet ciphertext (480 bits) would store 0x1E0 in buf[7]. */
8508
2.18k
    buf[0] = WC_OCTET(szHi >> 24);
8509
2.18k
    buf[1] = WC_OCTET(szHi >> 16);
8510
2.18k
    buf[2] = WC_OCTET(szHi >>  8);
8511
2.18k
    buf[3] = WC_OCTET(szHi);
8512
2.18k
    buf[4] = WC_OCTET(sz >> 24);
8513
2.18k
    buf[5] = WC_OCTET(sz >> 16);
8514
2.18k
    buf[6] = WC_OCTET(sz >>  8);
8515
2.18k
    buf[7] = WC_OCTET(sz);
8516
2.18k
}
8517
8518
8519
static WC_INLINE void RIGHTSHIFTX(byte* x)
8520
3.50k
{
8521
3.50k
    int i;
8522
3.50k
    int carryIn = 0;
8523
3.50k
    volatile byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
8524
8525
59.5k
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
8526
56.0k
        int carryOut = (x[i] & 0x01) << 7;
8527
56.0k
        x[i] = (byte) ((x[i] >> 1) | carryIn);
8528
56.0k
        carryIn = carryOut;
8529
56.0k
    }
8530
3.50k
    x[0] ^= borrow;
8531
3.50k
}
8532
8533
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
8534
8535
8536
#ifdef GCM_TABLE
8537
8538
void GenerateM0(Gcm* gcm)
8539
{
8540
    int i, j;
8541
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
8542
8543
    XMEMCPY(m[128], gcm->H, WC_AES_BLOCK_SIZE);
8544
8545
    for (i = 64; i > 0; i /= 2) {
8546
        XMEMCPY(m[i], m[i*2], WC_AES_BLOCK_SIZE);
8547
        RIGHTSHIFTX(m[i]);
8548
    }
8549
8550
    for (i = 2; i < 256; i *= 2) {
8551
        for (j = 1; j < i; j++) {
8552
            XMEMCPY(m[i+j], m[i], WC_AES_BLOCK_SIZE);
8553
            xorbuf(m[i+j], m[j], WC_AES_BLOCK_SIZE);
8554
        }
8555
    }
8556
8557
#if defined(WOLFSSL_PPC64_ASM)
8558
    for (i = 1; i < 256; i++) {
8559
        word64* m64 = (word64*)gcm->M0[i];
8560
        m64[0] = ByteReverseWord64(m64[0]);
8561
        m64[1] = ByteReverseWord64(m64[1]);
8562
    }
8563
#endif
8564
    XMEMSET(m[0], 0, WC_AES_BLOCK_SIZE);
8565
}
8566
8567
#elif defined(GCM_TABLE_4BIT)
8568
8569
#if !defined(WC_16BIT_CPU)
8570
static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
8571
18.6k
{
8572
18.6k
    int i;
8573
298k
    for (i = 15; i > 0; i--)
8574
280k
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
8575
18.6k
    r8[0] = (byte)(z8[0] >> 4);
8576
18.6k
}
8577
#endif
8578
8579
void GenerateM0(Gcm* gcm)
8580
1.16k
{
8581
1.16k
#if !defined(WC_16BIT_CPU)
8582
1.16k
    int i;
8583
1.16k
#endif
8584
1.16k
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
8585
8586
    /* 0 times -> 0x0 */
8587
1.16k
    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
8588
    /* 1 times -> 0x8 */
8589
1.16k
    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
8590
    /* 2 times -> 0x4 */
8591
1.16k
    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
8592
1.16k
    RIGHTSHIFTX(m[0x4]);
8593
    /* 4 times -> 0x2 */
8594
1.16k
    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
8595
1.16k
    RIGHTSHIFTX(m[0x2]);
8596
    /* 8 times -> 0x1 */
8597
1.16k
    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
8598
1.16k
    RIGHTSHIFTX(m[0x1]);
8599
8600
    /* 0x3 */
8601
1.16k
    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
8602
1.16k
    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
8603
8604
    /* 0x5 -> 0x7 */
8605
1.16k
    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
8606
1.16k
    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
8607
1.16k
    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
8608
1.16k
    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
8609
1.16k
    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
8610
1.16k
    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
8611
8612
    /* 0x9 -> 0xf */
8613
1.16k
    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
8614
1.16k
    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
8615
1.16k
    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
8616
1.16k
    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
8617
1.16k
    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
8618
1.16k
    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
8619
1.16k
    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
8620
1.16k
    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
8621
1.16k
    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
8622
1.16k
    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
8623
1.16k
    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
8624
1.16k
    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
8625
1.16k
    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
8626
1.16k
    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
8627
8628
1.16k
#if !defined(WC_16BIT_CPU)
8629
19.8k
    for (i = 0; i < 16; i++) {
8630
18.6k
        Shift4_M0(m[16+i], m[i]);
8631
18.6k
    }
8632
1.16k
#endif
8633
8634
/* The 32-bit base assembly GHASH (GCM_gmult_len) consumes the M0 table with
8635
 * byte-reversed words, so apply that whenever it is compiled in: a no-crypto
8636
 * build, or a crypto build that keeps the base fallback for run-time selection
8637
 * (WOLFSSL_ARM32_AES_DISPATCH).  On AArch64 only the no-crypto build uses the
8638
 * M0-table GHASH (the crypto/NEON path hashes H directly). */
8639
#if defined(WOLFSSL_ARMASM) && (defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
8640
    defined(WOLFSSL_ARM32_AES_DISPATCH))
8641
    for (i = 0; i < 32; i++) {
8642
    #if !defined(__aarch64__)
8643
        word32* m32 = (word32*)gcm->M0[i];
8644
        m32[0] = ByteReverseWord32(m32[0]);
8645
        m32[1] = ByteReverseWord32(m32[1]);
8646
        m32[2] = ByteReverseWord32(m32[2]);
8647
        m32[3] = ByteReverseWord32(m32[3]);
8648
    #else
8649
        word64* m64 = (word64*)gcm->M0[i];
8650
        m64[0] = ByteReverseWord64(m64[0]);
8651
        m64[1] = ByteReverseWord64(m64[1]);
8652
    #endif
8653
    }
8654
#endif
8655
1.16k
}
8656
8657
#endif /* GCM_TABLE */
8658
8659
#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
8660
    #define HAVE_INTEL_AVX1
8661
    #ifndef NO_AVX2_SUPPORT
8662
        #define HAVE_INTEL_AVX2
8663
    #endif
8664
    #ifdef WOLFSSL_X86_64_BUILD
8665
        #ifndef NO_VAES_SUPPORT
8666
            #define HAVE_INTEL_VAES
8667
        #endif
8668
        #ifndef NO_AVX512_SUPPORT
8669
            #define HAVE_INTEL_AVX512
8670
        #endif
8671
    #endif
8672
#endif
8673
8674
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \
8675
    defined(WC_C_DYNAMIC_FALLBACK)
8676
void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m)
8677
                           XASM_LINK("GCM_generate_m0_aesni");
8678
#ifdef HAVE_INTEL_AVX1
8679
void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m)
8680
                          XASM_LINK("GCM_generate_m0_avx1");
8681
#endif
8682
#ifdef HAVE_INTEL_AVX2
8683
void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
8684
                          XASM_LINK("GCM_generate_m0_avx2");
8685
#endif
8686
#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */
8687
8688
#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
8689
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) && defined(HAVE_AESGCM)
8690
/* Reflect the bits of each byte of a hash subkey, in place.
8691
 *
8692
 * AES_GCM_set_key_AARCH32 produces H in reflected form - what the PMULL bulk
8693
 * assembly wants - but the portable GHASH used for AES-GCM streaming needs
8694
 * plain H.  So the stored aes->gcm.H is un-reflected once at key set, and each
8695
 * bulk assembly call reflects its own copy.  The operation is its own inverse,
8696
 * so the same function serves both directions.
8697
 *
8698
 * @param [in, out] h  Hash subkey to reflect.
8699
 */
8700
static WC_INLINE void GcmReflectH(byte* h)
8701
{
8702
    int i;
8703
    int j;
8704
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
8705
        byte b = h[i];
8706
        byte r = 0;
8707
        for (j = 0; j < 8; j++) {
8708
            r = (byte)((r << 1) | (b & 1));
8709
            b >>= 1;
8710
        }
8711
        h[i] = r;
8712
    }
8713
}
8714
#endif
8715
8716
/* Software AES - GCM SetKey */
8717
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
8718
1.16k
{
8719
1.16k
    int  ret;
8720
1.16k
    byte iv[WC_AES_BLOCK_SIZE];
8721
8722
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
8723
        byte   local[32];
8724
        word32 localSz = 32;
8725
8726
        if (len == (16 + WC_CAAM_BLOB_SZ) ||
8727
          len == (24 + WC_CAAM_BLOB_SZ) ||
8728
          len == (32 + WC_CAAM_BLOB_SZ)) {
8729
            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
8730
                 return BAD_FUNC_ARG;
8731
            }
8732
8733
            /* set local values */
8734
            key = local;
8735
            len = localSz;
8736
        }
8737
    #endif
8738
8739
1.16k
    if (!((len == 16) || (len == 24) || (len == 32)))
8740
0
        return BAD_FUNC_ARG;
8741
8742
1.16k
    if (aes == NULL || key == NULL) {
8743
#ifdef WOLFSSL_IMX6_CAAM_BLOB
8744
#ifdef WOLFSSL_CHECK_MEM_ZERO
8745
        wc_MemZero_Add("wc_AesGcmSetKey local", local, sizeof(local));
8746
#endif
8747
        ForceZero(local, sizeof(local));
8748
#ifdef WOLFSSL_CHECK_MEM_ZERO
8749
        wc_MemZero_Check(local, sizeof(local));
8750
#endif
8751
#endif
8752
0
        return BAD_FUNC_ARG;
8753
0
    }
8754
#ifdef OPENSSL_EXTRA
8755
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
8756
    aes->gcm.aadLen = 0;
8757
#endif
8758
1.16k
    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
8759
1.16k
    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
8760
#ifdef WOLF_CRYPTO_CB_ONLY_AES
8761
    /* do key scheduling so that ECB-only devices can still do GCM */
8762
    if (ret == 0) {
8763
        ret = wc_CryptoCb_AesEcbEncrypt(aes, aes->gcm.H, iv, WC_AES_BLOCK_SIZE);
8764
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8765
        if (ret == 0)
8766
            GenerateM0(&aes->gcm);
8767
#endif
8768
    }
8769
    return ret;
8770
#endif
8771
1.16k
#ifdef WOLFSSL_AESGCM_STREAM
8772
1.16k
    aes->gcmKeySet = 1;
8773
1.16k
#endif
8774
    #if defined(WOLFSSL_SECO_CAAM)
8775
        if (aes->devId == WOLFSSL_SECO_DEVID) {
8776
            return ret;
8777
        }
8778
    #endif /* WOLFSSL_SECO_CAAM */
8779
8780
    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
8781
        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
8782
        return ret;
8783
    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
8784
8785
/* GCM setup needs one AES block encrypt of the all-zero IV to generate
8786
 * the hash subkey H. STM32_CRYPTO stores only the raw key (no expanded
8787
 * key schedule), so the ARMASM AES_ECB_encrypt helpers used here cannot
8788
 * be used. Excluding STM32_CRYPTO from this block falls back to the
8789
 * non-ARMASM wc_AesEncrypt implementation, which on STM32 routes to
8790
 * CRYP. */
8791
#if defined(WOLFSSL_ARMASM) && !defined(STM32_CRYPTO)
8792
    if (ret == 0) {
8793
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
8794
    #if !defined(__aarch64__)
8795
      #ifdef WOLFSSL_ARM32_AES_DISPATCH
8796
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
8797
            AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H,
8798
                aes->rounds);
8799
            /* Undo the reflection the assembly applied, so the stored H is
8800
             * plain H for the portable streaming GHASH and for GenerateM0
8801
             * below.  Each bulk assembly call reflects its own copy. */
8802
            GcmReflectH(aes->gcm.H);
8803
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8804
            GenerateM0(&aes->gcm);
8805
        #endif
8806
        }
8807
        else
8808
      #else
8809
        AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
8810
        /* Undo the reflection the assembly applied, so the stored H is plain
8811
         * H for the portable streaming GHASH and for GenerateM0 below.  Each
8812
         * bulk assembly call reflects its own copy. */
8813
        GcmReflectH(aes->gcm.H);
8814
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8815
        GenerateM0(&aes->gcm);
8816
        #endif
8817
      #endif /* WOLFSSL_ARM32_AES_DISPATCH */
8818
    #else
8819
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
8820
            AES_GCM_set_key_AARCH64(iv, (byte*)aes->key, aes->gcm.H,
8821
                aes->rounds);
8822
        }
8823
        else
8824
    #endif /* !__aarch64__ */
8825
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
8826
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
8827
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
8828
        {
8829
            AES_ECB_encrypt_NEON(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
8830
                (const unsigned char*)aes->key, aes->rounds);
8831
        }
8832
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
8833
      defined(WOLFSSL_ARM32_AES_DISPATCH)
8834
        {
8835
            AES_ECB_encrypt(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
8836
                (const unsigned char*)aes->key, aes->rounds);
8837
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8838
            GenerateM0(&aes->gcm);
8839
        #endif /* GCM_TABLE */
8840
        }
8841
#endif
8842
    }
8843
#else
8844
1.16k
#if !defined(FREESCALE_LTC_AES_GCM) && !defined(WOLFSSL_PSOC6_CRYPTO)
8845
8846
8847
#ifdef WOLF_CRYPTO_CB_AES_SETKEY
8848
    if ((ret == 0) && (aes->devId != INVALID_DEVID && aes->devCtx != NULL)) {
8849
        /* SE owns key - skip H and M table generation */
8850
    }
8851
    else
8852
#endif
8853
1.16k
    if (ret == 0) {
8854
1.16k
        VECTOR_REGISTERS_PUSH;
8855
8856
#if defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM) && \
8857
    !defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
8858
        /* Compute H reflected for the carryless-multiply GHASH; the scalar
8859
         * GHASH uses no M0 table.  (Vector crypto supersedes scalar and needs H
8860
         * unreflected, so it falls through to the generic E(0) path below.) */
8861
        AES_GCM_set_key_RISCV64(iv, (byte*)aes->key, aes->gcm.H,
8862
            (int)aes->rounds);
8863
#else
8864
        /* Generate H = AES_Encrypt(key, 0^128) */
8865
1.16k
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
8866
8867
1.16k
        if (ret == 0) {
8868
1.16k
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8869
    #if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT)
8870
            if (aes->use_aesni) {
8871
        #if defined(WC_C_DYNAMIC_FALLBACK)
8872
            #ifdef HAVE_INTEL_AVX2
8873
                if (IS_INTEL_AVX2(intel_flags)) {
8874
                    GCM_generate_m0_avx2(aes->gcm.H,
8875
                        (byte*)aes->gcm.M0);
8876
                }
8877
                else
8878
            #endif
8879
            #if defined(HAVE_INTEL_AVX1)
8880
                if (IS_INTEL_AVX1(intel_flags)) {
8881
                    GCM_generate_m0_avx1(aes->gcm.H,
8882
                        (byte*)aes->gcm.M0);
8883
                }
8884
                else
8885
            #endif
8886
                {
8887
                    GCM_generate_m0_aesni(aes->gcm.H,
8888
                        (byte*)aes->gcm.M0);
8889
                }
8890
        #endif /* WC_C_DYNAMIC_FALLBACK */
8891
            }
8892
            else
8893
    #endif /* AESNI */
8894
1.16k
            {
8895
1.16k
                GenerateM0(&aes->gcm);
8896
1.16k
            }
8897
1.16k
#endif /* GCM_TABLE || GCM_TABLE_4BIT */
8898
1.16k
        }
8899
1.16k
#endif /* WOLFSSL_RISCV_SCALAR_CRYPTO_ASM */
8900
8901
1.16k
        VECTOR_REGISTERS_POP;
8902
1.16k
    }
8903
1.16k
#endif /* !FREESCALE_LTC_AES_GCM && !WOLFSSL_PSOC6_CRYPTO */
8904
1.16k
#endif
8905
8906
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
8907
    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
8908
#endif
8909
8910
1.16k
#ifdef WOLF_CRYPTO_CB
8911
1.16k
    if (aes->devId != INVALID_DEVID) {
8912
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
8913
        if (aes->devCtx != NULL) {
8914
            /* SE owns key - don't copy to devKey */
8915
        }
8916
        else
8917
    #endif
8918
0
        {
8919
0
            XMEMCPY(aes->devKey, key, len);
8920
0
        }
8921
0
    }
8922
1.16k
#endif
8923
8924
#ifdef WOLFSSL_IMX6_CAAM_BLOB
8925
#ifdef WOLFSSL_CHECK_MEM_ZERO
8926
    wc_MemZero_Add("wc_AesGcmSetKey local", local, sizeof(local));
8927
#endif
8928
    ForceZero(local, sizeof(local));
8929
#ifdef WOLFSSL_CHECK_MEM_ZERO
8930
    wc_MemZero_Check(local, sizeof(local));
8931
#endif
8932
#endif
8933
1.16k
    return ret;
8934
1.16k
}
8935
8936
8937
#ifdef WOLFSSL_AESNI
8938
8939
void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
8940
                     const unsigned char* addt, const unsigned char* ivec,
8941
                     unsigned char *tag, word32 nbytes,
8942
                     word32 abytes, word32 ibytes,
8943
                     word32 tbytes, const unsigned char* key, int nr)
8944
                     XASM_LINK("AES_GCM_encrypt_aesni");
8945
#ifdef HAVE_INTEL_AVX1
8946
void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
8947
                          const unsigned char* addt, const unsigned char* ivec,
8948
                          unsigned char *tag, word32 nbytes,
8949
                          word32 abytes, word32 ibytes,
8950
                          word32 tbytes, const unsigned char* key,
8951
                          int nr)
8952
                          XASM_LINK("AES_GCM_encrypt_avx1");
8953
#ifdef HAVE_INTEL_AVX2
8954
void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
8955
                          const unsigned char* addt, const unsigned char* ivec,
8956
                          unsigned char *tag, word32 nbytes,
8957
                          word32 abytes, word32 ibytes,
8958
                          word32 tbytes, const unsigned char* key,
8959
                          int nr)
8960
                          XASM_LINK("AES_GCM_encrypt_avx2");
8961
#ifdef HAVE_INTEL_AVX512
8962
void AES_GCM_encrypt_avx512(const unsigned char *in, unsigned char *out,
8963
                          const unsigned char* addt, const unsigned char* ivec,
8964
                          unsigned char *tag, word32 nbytes,
8965
                          word32 abytes, word32 ibytes,
8966
                          word32 tbytes, const unsigned char* key,
8967
                          int nr)
8968
                          XASM_LINK("AES_GCM_encrypt_avx512");
8969
#endif
8970
#ifdef HAVE_INTEL_VAES
8971
void AES_GCM_encrypt_vaes(const unsigned char *in, unsigned char *out,
8972
                          const unsigned char* addt, const unsigned char* ivec,
8973
                          unsigned char *tag, word32 nbytes,
8974
                          word32 abytes, word32 ibytes,
8975
                          word32 tbytes, const unsigned char* key,
8976
                          int nr)
8977
                          XASM_LINK("AES_GCM_encrypt_vaes");
8978
#endif
8979
#endif /* HAVE_INTEL_AVX2 */
8980
#endif /* HAVE_INTEL_AVX1 */
8981
8982
#ifdef HAVE_AES_DECRYPT
8983
void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
8984
                     const unsigned char* addt, const unsigned char* ivec,
8985
                     const unsigned char *tag, word32 nbytes, word32 abytes,
8986
                     word32 ibytes, word32 tbytes, const unsigned char* key,
8987
                     int nr, int* res)
8988
                     XASM_LINK("AES_GCM_decrypt_aesni");
8989
#ifdef HAVE_INTEL_AVX1
8990
void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
8991
                          const unsigned char* addt, const unsigned char* ivec,
8992
                          const unsigned char *tag, word32 nbytes,
8993
                          word32 abytes, word32 ibytes, word32 tbytes,
8994
                          const unsigned char* key, int nr, int* res)
8995
                          XASM_LINK("AES_GCM_decrypt_avx1");
8996
#ifdef HAVE_INTEL_AVX2
8997
void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
8998
                          const unsigned char* addt, const unsigned char* ivec,
8999
                          const unsigned char *tag, word32 nbytes,
9000
                          word32 abytes, word32 ibytes, word32 tbytes,
9001
                          const unsigned char* key, int nr, int* res)
9002
                          XASM_LINK("AES_GCM_decrypt_avx2");
9003
#ifdef HAVE_INTEL_AVX512
9004
void AES_GCM_decrypt_avx512(const unsigned char *in, unsigned char *out,
9005
                          const unsigned char* addt, const unsigned char* ivec,
9006
                          const unsigned char *tag, word32 nbytes,
9007
                          word32 abytes, word32 ibytes, word32 tbytes,
9008
                          const unsigned char* key, int nr, int* res)
9009
                          XASM_LINK("AES_GCM_decrypt_avx512");
9010
#endif
9011
#ifdef HAVE_INTEL_VAES
9012
void AES_GCM_decrypt_vaes(const unsigned char *in, unsigned char *out,
9013
                          const unsigned char* addt, const unsigned char* ivec,
9014
                          const unsigned char *tag, word32 nbytes,
9015
                          word32 abytes, word32 ibytes, word32 tbytes,
9016
                          const unsigned char* key, int nr, int* res)
9017
                          XASM_LINK("AES_GCM_decrypt_vaes");
9018
#endif
9019
#endif /* HAVE_INTEL_AVX2 */
9020
#endif /* HAVE_INTEL_AVX1 */
9021
#endif /* HAVE_AES_DECRYPT */
9022
9023
#endif /* WOLFSSL_AESNI */
9024
9025
#if defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM) && defined(HAVE_AESGCM) && \
9026
    !defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
9027
/* GHASH using the RISC-V scalar carryless-multiply (Zbc) helper.  Vector crypto
9028
 * supersedes it (fused vghsh/vgmul), so this scalar path yields when both are on.
9029
 *
9030
 * H is stored reflected by AES_GCM_set_key_RISCV64, which is the form
9031
 * GHASH_RISCV64 expects.  GHASH_RISCV64(x, h, in, blocks) computes, for each
9032
 * 16-byte block, x = (x ^ block) * H in GF(2^128) (reflecting x in/out so the
9033
 * caller sees the standard domain).  A single padded/length block is therefore
9034
 * just GHASH_RISCV64(x, h, block, 1) - no software GMULT or M0 table is needed.
9035
 *
9036
 * @param [in]  gcm  GCM object.
9037
 * @param [in]  a    Additional Authentication Data (AAD).
9038
 * @param [in]  aSz  Length of AAD in bytes.
9039
 * @param [in]  c    Cipher text.
9040
 * @param [in]  cSz  Length of cipher text in bytes.
9041
 * @param [out] s    Hash result.
9042
 * @param [in]  sSz  Number of bytes to output.
9043
 */
9044
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9045
    word32 cSz, byte* s, word32 sSz)
9046
{
9047
    ALIGN8 byte x[WC_AES_BLOCK_SIZE];
9048
    ALIGN8 byte scratch[WC_AES_BLOCK_SIZE];
9049
    word32 blocks, partial;
9050
    byte* h = gcm->H;
9051
9052
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9053
9054
    /* Hash in A, the Additional Authentication Data */
9055
    if (aSz != 0 && a != NULL) {
9056
        blocks = aSz / WC_AES_BLOCK_SIZE;
9057
        partial = aSz % WC_AES_BLOCK_SIZE;
9058
        if (blocks > 0) {
9059
            GHASH_RISCV64(x, h, a, blocks);
9060
            a += blocks * WC_AES_BLOCK_SIZE;
9061
        }
9062
        if (partial != 0) {
9063
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9064
            XMEMCPY(scratch, a, partial);
9065
            GHASH_RISCV64(x, h, scratch, 1);
9066
        }
9067
    }
9068
9069
    /* Hash in C, the Ciphertext */
9070
    if (cSz != 0 && c != NULL) {
9071
        blocks = cSz / WC_AES_BLOCK_SIZE;
9072
        partial = cSz % WC_AES_BLOCK_SIZE;
9073
        if (blocks > 0) {
9074
            GHASH_RISCV64(x, h, c, blocks);
9075
            c += blocks * WC_AES_BLOCK_SIZE;
9076
        }
9077
        if (partial != 0) {
9078
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9079
            XMEMCPY(scratch, c, partial);
9080
            GHASH_RISCV64(x, h, scratch, 1);
9081
        }
9082
    }
9083
9084
    /* Hash in the lengths of A and C in bits */
9085
    FlattenSzInBits(&scratch[0], aSz);
9086
    FlattenSzInBits(&scratch[8], cSz);
9087
    GHASH_RISCV64(x, h, scratch, 1);
9088
9089
    /* Copy the result into s. */
9090
    XMEMCPY(s, x, sSz);
9091
}
9092
9093
#ifdef WOLFSSL_AESGCM_STREAM
9094
/* No extra initialization for the carryless-multiply implementation.
9095
 *
9096
 * @param [in] aes  AES GCM object.
9097
 */
9098
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9099
9100
/* GHASH one block of data into the streaming tag.
9101
 *
9102
 * x = (tag ^ block) * H using the carryless-multiply helper (reflected H).
9103
 *
9104
 * @param [in, out] aes    AES GCM object.
9105
 * @param [in]      block  Block of AAD or cipher text.
9106
 */
9107
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
9108
    GHASH_RISCV64(AES_TAG(aes), (aes)->gcm.H, block, 1)
9109
#endif /* WOLFSSL_AESGCM_STREAM */
9110
9111
#define HAVE_GHASH
9112
#elif defined(GCM_SMALL)
9113
static void GMULT(byte* X, byte* Y)
9114
{
9115
    byte Z[WC_AES_BLOCK_SIZE];
9116
    byte V[WC_AES_BLOCK_SIZE];
9117
    int i, j;
9118
9119
    XMEMSET(Z, 0, WC_AES_BLOCK_SIZE);
9120
    XMEMCPY(V, X, WC_AES_BLOCK_SIZE);
9121
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++)
9122
    {
9123
        byte y = Y[i];
9124
        for (j = 0; j < 8; j++)
9125
        {
9126
            if (y & 0x80) {
9127
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
9128
            }
9129
9130
            RIGHTSHIFTX(V);
9131
            y = y << 1;
9132
        }
9133
    }
9134
    XMEMCPY(X, Z, WC_AES_BLOCK_SIZE);
9135
}
9136
9137
9138
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9139
    word32 cSz, byte* s, word32 sSz)
9140
{
9141
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
9142
    byte scratch[WC_AES_BLOCK_SIZE];
9143
    word32 blocks, partial;
9144
    byte* h;
9145
9146
    h = gcm->H;
9147
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9148
9149
    /* Hash in A, the Additional Authentication Data */
9150
    if (aSz != 0 && a != NULL) {
9151
        blocks = aSz / WC_AES_BLOCK_SIZE;
9152
        partial = aSz % WC_AES_BLOCK_SIZE;
9153
        while (blocks--) {
9154
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
9155
            GMULT(x, h);
9156
            a += WC_AES_BLOCK_SIZE;
9157
        }
9158
        if (partial != 0) {
9159
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9160
            XMEMCPY(scratch, a, partial);
9161
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9162
            GMULT(x, h);
9163
        }
9164
    }
9165
9166
    /* Hash in C, the Ciphertext */
9167
    if (cSz != 0 && c != NULL) {
9168
        blocks = cSz / WC_AES_BLOCK_SIZE;
9169
        partial = cSz % WC_AES_BLOCK_SIZE;
9170
        while (blocks--) {
9171
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
9172
            GMULT(x, h);
9173
            c += WC_AES_BLOCK_SIZE;
9174
        }
9175
        if (partial != 0) {
9176
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9177
            XMEMCPY(scratch, c, partial);
9178
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9179
            GMULT(x, h);
9180
        }
9181
    }
9182
9183
    /* Hash in the lengths of A and C in bits */
9184
    FlattenSzInBits(&scratch[0], aSz);
9185
    FlattenSzInBits(&scratch[8], cSz);
9186
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9187
    GMULT(x, h);
9188
9189
    /* Copy the result into s. */
9190
    XMEMCPY(s, x, sSz);
9191
}
9192
9193
#ifdef WOLFSSL_AESGCM_STREAM
9194
/* No extra initialization for small implementation.
9195
 *
9196
 * @param [in] aes  AES GCM object.
9197
 */
9198
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9199
9200
/* GHASH one block of data..
9201
 *
9202
 * XOR block into tag and GMULT with H.
9203
 *
9204
 * @param [in, out] aes    AES GCM object.
9205
 * @param [in]      block  Block of AAD or cipher text.
9206
 */
9207
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9208
    do {                                                \
9209
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
9210
        GMULT(AES_TAG(aes), (aes)->gcm.H);              \
9211
    }                                                   \
9212
    while (0)
9213
#endif /* WOLFSSL_AESGCM_STREAM */
9214
9215
#if defined(WOLFSSL_ARMASM) && (!defined(__aarch64__) || \
9216
    defined(WOLFSSL_ARMASM_NO_NEON))
9217
/* Unused when the batch GHASH is done in assembly (32-bit ARMv8 crypto), which
9218
 * only pulls in the streaming software GMULT. */
9219
static WC_MAYBE_UNUSED void GCM_gmult_len_armasm_C(
9220
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
9221
{
9222
    byte Z[AES_BLOCK_SIZE];
9223
    byte V[AES_BLOCK_SIZE];
9224
    int i;
9225
    int j;
9226
9227
    while (len >= AES_BLOCK_SIZE) {
9228
        xorbuf(x, a, AES_BLOCK_SIZE);
9229
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
9230
        XMEMCPY(V, x, AES_BLOCK_SIZE);
9231
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
9232
            byte y = h[i];
9233
            for (j = 0; j < 8; j++) {
9234
                if (y & 0x80) {
9235
                    xorbuf(Z, V, AES_BLOCK_SIZE);
9236
                }
9237
                RIGHTSHIFTX(V);
9238
                y = y << 1;
9239
            }
9240
        }
9241
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
9242
        len -= AES_BLOCK_SIZE;
9243
        a += AES_BLOCK_SIZE;
9244
    }
9245
}
9246
9247
#define GCM_GMULT_LEN(gcm, x, a, len) \
9248
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
9249
#elif defined(WOLFSSL_ARMASM)
9250
#define GCM_GMULT_LEN(gcm, x, a, len) \
9251
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
9252
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
9253
static void GCM_gmult_len_armasm_C(
9254
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
9255
{
9256
    byte Z[AES_BLOCK_SIZE];
9257
    byte V[AES_BLOCK_SIZE];
9258
    int i;
9259
    int j;
9260
9261
    while (len >= AES_BLOCK_SIZE) {
9262
        xorbuf(x, a, AES_BLOCK_SIZE);
9263
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
9264
        XMEMCPY(V, x, AES_BLOCK_SIZE);
9265
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
9266
            byte y = h[i];
9267
            for (j = 0; j < 8; j++) {
9268
                if (y & 0x80) {
9269
                    xorbuf(Z, V, AES_BLOCK_SIZE);
9270
                }
9271
                RIGHTSHIFTX(V);
9272
                y = y << 1;
9273
            }
9274
        }
9275
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
9276
        len -= AES_BLOCK_SIZE;
9277
        a += AES_BLOCK_SIZE;
9278
    }
9279
}
9280
9281
#define GCM_GMULT_LEN(gcm, x, a, len) \
9282
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
9283
#endif
9284
9285
#elif defined(GCM_TABLE)
9286
9287
/* ARM assembly.  A 32-bit run-time dispatch build is deliberately not here: the
9288
 * generated AArch32 GHASH is for the 4-bit table, not this 256-entry one.  It
9289
 * gets a C GCM_GMULT_LEN() built on GMULT() below. */
9290
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
9291
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
9292
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
9293
#define GCM_GMULT_LEN(gcm, x, a, len) \
9294
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
9295
#else
9296
#define GCM_GMULT_LEN(gcm, x, a, len) \
9297
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9298
#endif
9299
#elif defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
9300
#define GCM_GMULT_LEN(gcm, x, a, len) \
9301
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9302
#else
9303
ALIGN16 static const byte R[256][2] = {
9304
    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
9305
    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
9306
    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
9307
    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
9308
    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
9309
    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
9310
    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
9311
    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
9312
    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
9313
    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
9314
    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
9315
    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
9316
    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
9317
    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
9318
    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
9319
    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
9320
    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
9321
    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
9322
    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
9323
    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
9324
    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
9325
    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
9326
    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
9327
    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
9328
    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
9329
    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
9330
    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
9331
    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
9332
    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
9333
    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
9334
    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
9335
    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
9336
    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
9337
    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
9338
    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
9339
    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
9340
    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
9341
    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
9342
    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
9343
    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
9344
    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
9345
    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
9346
    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
9347
    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
9348
    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
9349
    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
9350
    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
9351
    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
9352
    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
9353
    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
9354
    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
9355
    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
9356
    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
9357
    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
9358
    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
9359
    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
9360
    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
9361
    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
9362
    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
9363
    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
9364
    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
9365
    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
9366
    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
9367
    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
9368
9369
9370
static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE])
9371
{
9372
#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
9373
    int i, j;
9374
    byte Z[WC_AES_BLOCK_SIZE];
9375
    byte a;
9376
9377
    XMEMSET(Z, 0, sizeof(Z));
9378
9379
    for (i = 15; i > 0; i--) {
9380
        xorbuf(Z, m[x[i]], WC_AES_BLOCK_SIZE);
9381
        a = Z[15];
9382
9383
        for (j = 15; j > 0; j--) {
9384
            Z[j] = Z[j-1];
9385
        }
9386
9387
        Z[0]  = R[a][0];
9388
        Z[1] ^= R[a][1];
9389
    }
9390
    xorbuf(Z, m[x[0]], WC_AES_BLOCK_SIZE);
9391
9392
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
9393
#elif defined(WC_32BIT_CPU)
9394
#ifndef WOLFSSL_USE_ALIGN
9395
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
9396
    byte a;
9397
    word32* pZ;
9398
    word32* pm;
9399
    word32* px = (word32*)(x);
9400
    int i;
9401
9402
    pZ = (word32*)(Z + 15 + 1);
9403
    pm = (word32*)(m[x[15]]);
9404
    pZ[0] = pm[0];
9405
    pZ[1] = pm[1];
9406
    pZ[2] = pm[2];
9407
    pZ[3] = pm[3];
9408
    a = Z[16 + 15];
9409
    Z[15]  = R[a][0];
9410
    Z[16] ^= R[a][1];
9411
    for (i = 14; i > 0; i--) {
9412
        pZ = (word32*)(Z + i + 1);
9413
        pm = (word32*)(m[x[i]]);
9414
        pZ[0] ^= pm[0];
9415
        pZ[1] ^= pm[1];
9416
        pZ[2] ^= pm[2];
9417
        pZ[3] ^= pm[3];
9418
        a = Z[16 + i];
9419
        Z[i]    = R[a][0];
9420
        Z[i+1] ^= R[a][1];
9421
    }
9422
    pZ = (word32*)(Z + 1);
9423
    pm = (word32*)(m[x[0]]);
9424
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
9425
    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
9426
#else
9427
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
9428
    byte a;
9429
    int i;
9430
9431
    XMEMCPY(Z + 16, m[x[15]], WC_AES_BLOCK_SIZE);
9432
    a = Z[16 + 15];
9433
    Z[15]  = R[a][0];
9434
    Z[16] ^= R[a][1];
9435
    for (i = 14; i > 0; i--) {
9436
        xorbuf(Z + i + 1, m[x[i]], WC_AES_BLOCK_SIZE);
9437
        a = Z[16 + i];
9438
        Z[i]    = R[a][0];
9439
        Z[i+1] ^= R[a][1];
9440
    }
9441
    xorbuf(Z + 1, m[x[0]], WC_AES_BLOCK_SIZE);
9442
    XMEMCPY(x, Z + 1, WC_AES_BLOCK_SIZE);
9443
#endif
9444
#else
9445
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
9446
    byte a;
9447
    word64* pZ;
9448
    word64* pm;
9449
    word64* px = (word64*)(x);
9450
    int i;
9451
9452
    pZ = (word64*)(Z + 15 + 1);
9453
    pm = (word64*)(m[x[15]]);
9454
    pZ[0] = pm[0];
9455
    pZ[1] = pm[1];
9456
    a = Z[16 + 15];
9457
    Z[15]  = R[a][0];
9458
    Z[16] ^= R[a][1];
9459
    for (i = 14; i > 0; i--) {
9460
        pZ = (word64*)(Z + i + 1);
9461
        pm = (word64*)(m[x[i]]);
9462
        pZ[0] ^= pm[0];
9463
        pZ[1] ^= pm[1];
9464
        a = Z[16 + i];
9465
        Z[i]    = R[a][0];
9466
        Z[i+1] ^= R[a][1];
9467
    }
9468
    pZ = (word64*)(Z + 1);
9469
    pm = (word64*)(m[x[0]]);
9470
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
9471
#endif
9472
}
9473
#endif
9474
9475
#if defined(WOLFSSL_ARM32_AES_DISPATCH) && !defined(GCM_GMULT_LEN)
9476
/* A 32-bit Arm run-time dispatch build reaches AES_GCM_encrypt_ASM() and
9477
 * AES_GCM_decrypt_ASM() on a CPU without the crypto extension, and they call
9478
 * GCM_GMULT_LEN() unconditionally.  The generated AArch32 GHASH assembly only
9479
 * handles the 4-bit table, so hash the blocks with the 256-entry GMULT(). */
9480
static void GCM_gmult_len_table_C(byte* x, byte m[256][WC_AES_BLOCK_SIZE],
9481
    const unsigned char* a, unsigned long len)
9482
{
9483
    while (len >= WC_AES_BLOCK_SIZE) {
9484
        xorbuf(x, a, WC_AES_BLOCK_SIZE);
9485
        GMULT(x, m);
9486
        len -= WC_AES_BLOCK_SIZE;
9487
        a += WC_AES_BLOCK_SIZE;
9488
    }
9489
}
9490
9491
#define GCM_GMULT_LEN(gcm, x, a, len) \
9492
    GCM_gmult_len_table_C(x, (gcm)->M0, a, len)
9493
#endif
9494
9495
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9496
    word32 cSz, byte* s, word32 sSz)
9497
{
9498
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
9499
    byte scratch[WC_AES_BLOCK_SIZE];
9500
    word32 blocks, partial;
9501
9502
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9503
9504
    /* Hash in A, the Additional Authentication Data */
9505
    if (aSz != 0 && a != NULL) {
9506
        blocks = aSz / WC_AES_BLOCK_SIZE;
9507
        partial = aSz % WC_AES_BLOCK_SIZE;
9508
    #ifdef GCM_GMULT_LEN
9509
        if (blocks > 0) {
9510
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
9511
            a += blocks * WC_AES_BLOCK_SIZE;
9512
        }
9513
        if (partial != 0) {
9514
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9515
            XMEMCPY(scratch, a, partial);
9516
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9517
        }
9518
    #else
9519
        while (blocks--) {
9520
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
9521
            GMULT(x, gcm->M0);
9522
            a += WC_AES_BLOCK_SIZE;
9523
        }
9524
        if (partial != 0) {
9525
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9526
            XMEMCPY(scratch, a, partial);
9527
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9528
            GMULT(x, gcm->M0);
9529
        }
9530
    #endif
9531
    }
9532
9533
    /* Hash in C, the Ciphertext */
9534
    if (cSz != 0 && c != NULL) {
9535
        blocks = cSz / WC_AES_BLOCK_SIZE;
9536
        partial = cSz % WC_AES_BLOCK_SIZE;
9537
    #ifdef GCM_GMULT_LEN
9538
        if (blocks > 0) {
9539
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
9540
            c += blocks * WC_AES_BLOCK_SIZE;
9541
        }
9542
        if (partial != 0) {
9543
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9544
            XMEMCPY(scratch, c, partial);
9545
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9546
        }
9547
    #else
9548
        while (blocks--) {
9549
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
9550
            GMULT(x, gcm->M0);
9551
            c += WC_AES_BLOCK_SIZE;
9552
        }
9553
        if (partial != 0) {
9554
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9555
            XMEMCPY(scratch, c, partial);
9556
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9557
            GMULT(x, gcm->M0);
9558
        }
9559
    #endif
9560
    }
9561
9562
    /* Hash in the lengths of A and C in bits */
9563
    FlattenSzInBits(&scratch[0], aSz);
9564
    FlattenSzInBits(&scratch[8], cSz);
9565
#ifdef GCM_GMULT_LEN
9566
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9567
#else
9568
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9569
    GMULT(x, gcm->M0);
9570
#endif
9571
9572
    /* Copy the result into s. */
9573
    XMEMCPY(s, x, sSz);
9574
}
9575
9576
#ifdef WOLFSSL_AESGCM_STREAM
9577
/* No extra initialization for table implementation.
9578
 *
9579
 * @param [in] aes  AES GCM object.
9580
 */
9581
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9582
9583
#ifdef GCM_GMULT_LEN
9584
/* GHASH one block of data.
9585
 *
9586
 * Defer to the length-based implementation with a length of one block - it
9587
 * does the XOR into the tag as well as the multiply.
9588
 *
9589
 * @param [in, out] aes    AES GCM object.
9590
 * @param [in]      block  Block of AAD or cipher text.
9591
 */
9592
#define GHASH_ONE_BLOCK_SW(aes, block)                                  \
9593
   GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
9594
#else
9595
/* GHASH one block of data..
9596
 *
9597
 * XOR block into tag and GMULT with H using pre-computed table.
9598
 *
9599
 * @param [in, out] aes    AES GCM object.
9600
 * @param [in]      block  Block of AAD or cipher text.
9601
 */
9602
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9603
    do {                                                \
9604
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
9605
        GMULT(AES_TAG(aes), aes->gcm.M0);               \
9606
    }                                                   \
9607
    while (0)
9608
#endif
9609
#endif /* WOLFSSL_AESGCM_STREAM */
9610
/* end GCM_TABLE */
9611
#elif defined(GCM_TABLE_4BIT)
9612
/* ARM assembly */
9613
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
9614
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
9615
    defined(WOLFSSL_ARM32_AES_DISPATCH))
9616
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
9617
#define GCM_GMULT_LEN(gcm, x, a, len) \
9618
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
9619
#define GMULT(x, m)                                                      \
9620
    GCM_gmult_NEON(x, (const byte**)m)
9621
#else
9622
#define GCM_GMULT_LEN(gcm, x, a, len) \
9623
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9624
#define GMULT(x, m)                                                      \
9625
    GCM_gmult(x, (const byte**)m)
9626
#endif
9627
9628
/* PPC64 assembly */
9629
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
9630
#define GCM_GMULT_LEN(gcm, x, a, len)                                    \
9631
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9632
#define GMULT(x, m)                                                      \
9633
    GCM_gmult(x, (const byte**)m)
9634
9635
#else
9636
/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
9637
 *  R shifts right a reverse bit pair of bytes such that:
9638
 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
9639
 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
9640
 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
9641
 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
9642
 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
9643
 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
9644
 *  To calculate te rest, XOR result for each bit.
9645
 *   e.g. 6 = 4 ^ 2 => 48,c0
9646
 *
9647
 * Second half is same values rotated by 4-bits.
9648
 */
9649
#if defined(WC_16BIT_CPU)
9650
static const byte R[16][2] = {
9651
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
9652
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
9653
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
9654
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
9655
};
9656
#elif defined(BIG_ENDIAN_ORDER)
9657
static const word16 R[32] = {
9658
          0x0000,       0x1c20,       0x3840,       0x2460,
9659
          0x7080,       0x6ca0,       0x48c0,       0x54e0,
9660
          0xe100,       0xfd20,       0xd940,       0xc560,
9661
          0x9180,       0x8da0,       0xa9c0,       0xb5e0,
9662
9663
          0x0000,       0x01c2,       0x0384,       0x0246,
9664
          0x0708,       0x06ca,       0x048c,       0x054e,
9665
          0x0e10,       0x0fd2,       0x0d94,       0x0c56,
9666
          0x0918,       0x08da,       0x0a9c,       0x0b5e,
9667
};
9668
#else
9669
static const word16 R[32] = {
9670
          0x0000,       0x201c,       0x4038,       0x6024,
9671
          0x8070,       0xa06c,       0xc048,       0xe054,
9672
          0x00e1,       0x20fd,       0x40d9,       0x60c5,
9673
          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
9674
9675
          0x0000,       0xc201,       0x8403,       0x4602,
9676
          0x0807,       0xca06,       0x8c04,       0x4e05,
9677
          0x100e,       0xd20f,       0x940d,       0x560c,
9678
          0x1809,       0xda08,       0x9c0a,       0x5e0b,
9679
};
9680
#endif
9681
9682
/* Multiply in GF(2^128) defined by polynomial:
9683
 *   x^128 + x^7 + x^2 + x^1 + 1.
9684
 *
9685
 * H: hash key = encrypt(key, 0)
9686
 * x = x * H in field
9687
 *
9688
 * x: cumulative result
9689
 * m: 4-bit table
9690
 *    [0..15] * H
9691
 */
9692
#if defined(WC_16BIT_CPU)
9693
static void GMULT(byte *x, byte m[16][WC_AES_BLOCK_SIZE])
9694
{
9695
    int i, j, n;
9696
    byte Z[WC_AES_BLOCK_SIZE];
9697
    byte a;
9698
9699
    XMEMSET(Z, 0, sizeof(Z));
9700
9701
    for (i = 15; i >= 0; i--) {
9702
        for (n = 0; n < 2; n++) {
9703
            if (n == 0)
9704
                xorbuf(Z, m[x[i] & 0xf], WC_AES_BLOCK_SIZE);
9705
            else {
9706
                xorbuf(Z, m[x[i] >> 4], WC_AES_BLOCK_SIZE);
9707
                if (i == 0)
9708
                    break;
9709
            }
9710
            a = Z[15] & 0xf;
9711
9712
            for (j = 15; j > 0; j--)
9713
                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
9714
            Z[0] >>= 4;
9715
9716
            Z[0] ^= R[a][0];
9717
            Z[1] ^= R[a][1];
9718
        }
9719
    }
9720
9721
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
9722
}
9723
#elif defined(WC_32BIT_CPU) && defined(BIG_ENDIAN_ORDER)
9724
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9725
{
9726
    int i;
9727
    word32 z8[4] = {0, 0, 0, 0};
9728
    byte a;
9729
    word32* x8 = (word32*)x;
9730
    word32* m8;
9731
    byte xi;
9732
9733
    for (i = 15; i > 0; i--) {
9734
        xi = x[i];
9735
9736
        /* XOR in (msn * H) */
9737
        m8 = (word32*)m[xi & 0xf];
9738
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9739
9740
        /* Cache top byte for remainder calculations - lost in rotate. */
9741
        a = (byte)(z8[3] & 0xff);
9742
9743
        /* Rotate Z by 8-bits */
9744
        z8[3] = (z8[2] << 24) | (z8[3] >> 8);
9745
        z8[2] = (z8[1] << 24) | (z8[2] >> 8);
9746
        z8[1] = (z8[0] << 24) | (z8[1] >> 8);
9747
        z8[0] >>= 8;
9748
9749
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9750
        z8[0] ^= ((word32)R[16 + (a & 0xf)]) << 16;
9751
9752
        xi >>= 4;
9753
        /* XOR in next significant nibble (XORed with H) * remainder */
9754
        m8 = (word32*)m[xi];
9755
        a ^= (byte)(m8[3] >> 12) & 0xf;
9756
        a ^= (byte)((m8[3] << 4) & 0xf0);
9757
        z8[0] ^= ((word32)R[a >> 4]) << 16;
9758
9759
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9760
        m8 = (word32*)m[16 + xi];
9761
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
9762
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
9763
    }
9764
9765
    xi = x[0];
9766
9767
    /* XOR in most significant nibble * H */
9768
    m8 = (word32*)m[xi & 0xf];
9769
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9770
9771
    /* Cache top byte for remainder calculations - lost in rotate. */
9772
    a = (byte)(z8[3] & 0x0f);
9773
9774
    z8[3] = (z8[2] << 28) | (z8[3] >> 4);
9775
    z8[2] = (z8[1] << 28) | (z8[2] >> 4);
9776
    z8[1] = (z8[0] << 28) | (z8[1] >> 4);
9777
    z8[0] >>= 4;
9778
9779
    /* XOR in most significant nibble * remainder */
9780
    z8[0] ^= ((word32)R[a]) << 16;
9781
    /* XOR in next significant nibble * H */
9782
    m8 = (word32*)m[xi >> 4];
9783
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9784
9785
    /* Write back result. */
9786
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
9787
}
9788
#elif defined(WC_32BIT_CPU)
9789
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9790
{
9791
    int i;
9792
    word32 z8[4] = {0, 0, 0, 0};
9793
    byte a;
9794
    word32* x8 = (word32*)x;
9795
    word32* m8;
9796
    byte xi;
9797
    word32 n7, n6, n5, n4, n3, n2, n1, n0;
9798
9799
    for (i = 15; i > 0; i--) {
9800
        xi = x[i];
9801
9802
        /* XOR in (msn * H) */
9803
        m8 = (word32*)m[xi & 0xf];
9804
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9805
9806
        /* Cache top byte for remainder calculations - lost in rotate. */
9807
        a = (byte)(z8[3] >> 24);
9808
9809
        /* Rotate Z by 8-bits */
9810
        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
9811
        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
9812
        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
9813
        z8[0] <<= 8;
9814
9815
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9816
        z8[0] ^= (word32)R[16 + (a & 0xf)];
9817
9818
        xi >>= 4;
9819
        /* XOR in next significant nibble (XORed with H) * remainder */
9820
        m8 = (word32*)m[xi];
9821
        a ^= (byte)(m8[3] >> 20);
9822
        z8[0] ^= (word32)R[a >> 4];
9823
9824
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9825
        m8 = (word32*)m[16 + xi];
9826
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
9827
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
9828
    }
9829
9830
    xi = x[0];
9831
9832
    /* XOR in most significant nibble * H */
9833
    m8 = (word32*)m[xi & 0xf];
9834
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9835
9836
    /* Cache top byte for remainder calculations - lost in rotate. */
9837
    a = (z8[3] >> 24) & 0xf;
9838
9839
    /* Rotate z by 4-bits */
9840
    n7 = z8[3] & 0xf0f0f0f0ULL;
9841
    n6 = z8[3] & 0x0f0f0f0fULL;
9842
    n5 = z8[2] & 0xf0f0f0f0ULL;
9843
    n4 = z8[2] & 0x0f0f0f0fULL;
9844
    n3 = z8[1] & 0xf0f0f0f0ULL;
9845
    n2 = z8[1] & 0x0f0f0f0fULL;
9846
    n1 = z8[0] & 0xf0f0f0f0ULL;
9847
    n0 = z8[0] & 0x0f0f0f0fULL;
9848
    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
9849
    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
9850
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
9851
    z8[0] = (n1 >> 4) | (n0 << 12);
9852
9853
    /* XOR in most significant nibble * remainder */
9854
    z8[0] ^= (word32)R[a];
9855
    /* XOR in next significant nibble * H */
9856
    m8 = (word32*)m[xi >> 4];
9857
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9858
9859
    /* Write back result. */
9860
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
9861
}
9862
#elif defined(WC_64BIT_CPU) && defined(BIG_ENDIAN_ORDER)
9863
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9864
{
9865
    int i;
9866
    word64 z8[2] = {0, 0};
9867
    byte a;
9868
    word64* x8 = (word64*)x;
9869
    word64* m8;
9870
    byte xi;
9871
9872
    for (i = 15; i > 0; i--) {
9873
        xi = x[i];
9874
9875
        /* XOR in (msn * H) */
9876
        m8 = (word64*)m[xi & 0xf];
9877
        z8[0] ^= m8[0];
9878
        z8[1] ^= m8[1];
9879
9880
        /* Cache top byte for remainder calculations - lost in rotate. */
9881
        a = (byte)(z8[1] & 0xff);
9882
9883
        /* Rotate Z by 8-bits */
9884
        z8[1] = (z8[0] << 56) | (z8[1] >> 8);
9885
        z8[0] >>= 8;
9886
9887
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9888
        m8 = (word64*)m[16 + (xi >> 4)];
9889
        z8[0] ^= m8[0];
9890
        z8[1] ^= m8[1];
9891
9892
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9893
        z8[0] ^= ((word64)R[16 + (a & 0xf)]) << 48;
9894
        /* XOR in next significant nibble (XORed with H) * remainder */
9895
        m8 = (word64*)m[xi >> 4];
9896
        a ^= (byte)(m8[1] >> 12) & 0xf;
9897
        a ^= (byte)((m8[1] << 4) & 0xf0);
9898
        z8[0] ^= ((word64)R[a >> 4]) << 48;
9899
    }
9900
9901
    xi = x[0];
9902
9903
    /* XOR in most significant nibble * H */
9904
    m8 = (word64*)m[xi & 0xf];
9905
    z8[0] ^= m8[0];
9906
    z8[1] ^= m8[1];
9907
9908
    /* Cache top byte for remainder calculations - lost in rotate. */
9909
    a = (byte)(z8[1] & 0x0f);
9910
9911
    /* Rotate z by 4-bits */
9912
    z8[1] = (z8[0] << 60) | (z8[1] >> 4);
9913
    z8[0] >>= 4;
9914
9915
    /* XOR in next significant nibble * H */
9916
    m8 = (word64*)m[xi >> 4];
9917
    z8[0] ^= m8[0];
9918
    z8[1] ^= m8[1];
9919
    /* XOR in most significant nibble * remainder */
9920
    z8[0] ^= ((word64)R[a]) << 48;
9921
9922
    /* Write back result. */
9923
    x8[0] = z8[0];
9924
    x8[1] = z8[1];
9925
}
9926
#else
9927
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9928
52.5k
{
9929
52.5k
    int i;
9930
52.5k
    word64 z8[2] = {0, 0};
9931
52.5k
    byte a;
9932
52.5k
    word64* x8 = (word64*)x;
9933
52.5k
    word64* m8;
9934
52.5k
    word64 n0, n1, n2, n3;
9935
52.5k
    byte xi;
9936
9937
841k
    for (i = 15; i > 0; i--) {
9938
788k
        xi = x[i];
9939
9940
        /* XOR in (msn * H) */
9941
788k
        m8 = (word64*)m[xi & 0xf];
9942
788k
        z8[0] ^= m8[0];
9943
788k
        z8[1] ^= m8[1];
9944
9945
        /* Cache top byte for remainder calculations - lost in rotate. */
9946
788k
        a = (byte)(z8[1] >> 56);
9947
9948
        /* Rotate Z by 8-bits */
9949
788k
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
9950
788k
        z8[0] <<= 8;
9951
9952
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9953
788k
        m8 = (word64*)m[16 + (xi >> 4)];
9954
788k
        z8[0] ^= m8[0];
9955
788k
        z8[1] ^= m8[1];
9956
9957
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9958
788k
        z8[0] ^= (word64)R[16 + (a & 0xf)];
9959
        /* XOR in next significant nibble (XORed with H) * remainder */
9960
788k
        m8 = (word64*)m[xi >> 4];
9961
788k
        a ^= (byte)(m8[1] >> 52);
9962
788k
        z8[0] ^= (word64)R[a >> 4];
9963
788k
    }
9964
9965
52.5k
    xi = x[0];
9966
9967
    /* XOR in most significant nibble * H */
9968
52.5k
    m8 = (word64*)m[xi & 0xf];
9969
52.5k
    z8[0] ^= m8[0];
9970
52.5k
    z8[1] ^= m8[1];
9971
9972
    /* Cache top byte for remainder calculations - lost in rotate. */
9973
52.5k
    a = (z8[1] >> 56) & 0xf;
9974
9975
    /* Rotate z by 4-bits */
9976
52.5k
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
9977
52.5k
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
9978
52.5k
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
9979
52.5k
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
9980
52.5k
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
9981
52.5k
    z8[0] = (n1 >> 4) | (n0 << 12);
9982
9983
    /* XOR in next significant nibble * H */
9984
52.5k
    m8 = (word64*)m[xi >> 4];
9985
52.5k
    z8[0] ^= m8[0];
9986
52.5k
    z8[1] ^= m8[1];
9987
    /* XOR in most significant nibble * remainder */
9988
52.5k
    z8[0] ^= (word64)R[a];
9989
9990
    /* Write back result. */
9991
52.5k
    x8[0] = z8[0];
9992
52.5k
    x8[1] = z8[1];
9993
52.5k
}
9994
#endif
9995
#endif
9996
9997
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9998
    word32 cSz, byte* s, word32 sSz)
9999
614
{
10000
614
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
10001
614
    byte scratch[WC_AES_BLOCK_SIZE];
10002
614
    word32 blocks, partial;
10003
10004
614
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
10005
10006
    /* Hash in A, the Additional Authentication Data */
10007
614
    if (aSz != 0 && a != NULL) {
10008
614
        blocks = aSz / WC_AES_BLOCK_SIZE;
10009
614
        partial = aSz % WC_AES_BLOCK_SIZE;
10010
    #ifdef GCM_GMULT_LEN
10011
        if (blocks > 0) {
10012
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
10013
            a += blocks * WC_AES_BLOCK_SIZE;
10014
        }
10015
        if (partial != 0) {
10016
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10017
            XMEMCPY(scratch, a, partial);
10018
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
10019
        }
10020
    #else
10021
614
        while (blocks--) {
10022
0
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
10023
0
            GMULT(x, gcm->M0);
10024
0
            a += WC_AES_BLOCK_SIZE;
10025
0
        }
10026
614
        if (partial != 0) {
10027
614
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10028
614
            XMEMCPY(scratch, a, partial);
10029
614
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
10030
614
            GMULT(x, gcm->M0);
10031
614
        }
10032
614
    #endif
10033
614
    }
10034
10035
    /* Hash in C, the Ciphertext */
10036
614
    if (cSz != 0 && c != NULL) {
10037
610
        blocks = cSz / WC_AES_BLOCK_SIZE;
10038
610
        partial = cSz % WC_AES_BLOCK_SIZE;
10039
    #ifdef GCM_GMULT_LEN
10040
        if (blocks > 0) {
10041
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
10042
            c += blocks * WC_AES_BLOCK_SIZE;
10043
        }
10044
        if (partial != 0) {
10045
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10046
            XMEMCPY(scratch, c, partial);
10047
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
10048
        }
10049
    #else
10050
30.8k
        while (blocks--) {
10051
30.2k
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
10052
30.2k
            GMULT(x, gcm->M0);
10053
30.2k
            c += WC_AES_BLOCK_SIZE;
10054
30.2k
        }
10055
610
        if (partial != 0) {
10056
604
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10057
604
            XMEMCPY(scratch, c, partial);
10058
604
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
10059
604
            GMULT(x, gcm->M0);
10060
604
        }
10061
610
    #endif
10062
610
    }
10063
10064
    /* Hash in the lengths of A and C in bits */
10065
614
    FlattenSzInBits(&scratch[0], aSz);
10066
614
    FlattenSzInBits(&scratch[8], cSz);
10067
#ifdef GCM_GMULT_LEN
10068
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
10069
#else
10070
614
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
10071
614
    GMULT(x, gcm->M0);
10072
614
#endif
10073
10074
    /* Copy the result into s. */
10075
614
    XMEMCPY(s, x, sSz);
10076
614
}
10077
10078
#ifdef WOLFSSL_AESGCM_STREAM
10079
/* No extra initialization for 4-bit table implementation.
10080
 *
10081
 * @param [in] aes  AES GCM object.
10082
 */
10083
1.86k
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
10084
10085
#ifdef GCM_GMULT_LEN
10086
/* GHASH one block of data.
10087
 *
10088
 * Defer to the length-based implementation with a length of one block - it
10089
 * does the XOR into the tag as well as the multiply.
10090
 *
10091
 * @param [in, out] aes    AES GCM object.
10092
 * @param [in]      block  Block of AAD or cipher text.
10093
 */
10094
#define GHASH_ONE_BLOCK_SW(aes, block)                                  \
10095
   GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
10096
#else
10097
/* GHASH one block of data.
10098
 *
10099
 * XOR block into tag and GMULT with H using pre-computed table.
10100
 *
10101
 * @param [in, out] aes    AES GCM object.
10102
 * @param [in]      block  Block of AAD or cipher text.
10103
 */
10104
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
10105
20.4k
    do {                                                \
10106
20.4k
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
10107
20.4k
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
10108
20.4k
    }                                                   \
10109
20.4k
    while (0)
10110
#endif
10111
#endif /* WOLFSSL_AESGCM_STREAM */
10112
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
10113
10114
#if !defined(FREESCALE_LTC_AES_GCM)
10115
static void GMULT(word64* X, word64* Y)
10116
{
10117
    word64 Z[2] = {0,0};
10118
    word64 V[2];
10119
    int i, j;
10120
    word64 v1;
10121
    V[0] = X[0];  V[1] = X[1];
10122
10123
    for (i = 0; i < 2; i++)
10124
    {
10125
        word64 y = Y[i];
10126
        for (j = 0; j < 64; j++)
10127
        {
10128
#ifndef AES_GCM_GMULT_NCT
10129
            word64 mask = 0 - (y >> 63);
10130
            Z[0] ^= V[0] & mask;
10131
            Z[1] ^= V[1] & mask;
10132
#else
10133
            if (y & 0x8000000000000000ULL) {
10134
                Z[0] ^= V[0];
10135
                Z[1] ^= V[1];
10136
            }
10137
#endif
10138
10139
            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
10140
            V[1] >>= 1;
10141
            V[1] |= V[0] << 63;
10142
            V[0] >>= 1;
10143
            V[0] ^= v1;
10144
            y <<= 1;
10145
        }
10146
    }
10147
    X[0] = Z[0];
10148
    X[1] = Z[1];
10149
}
10150
10151
10152
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
10153
    word32 cSz, byte* s, word32 sSz)
10154
{
10155
    word64 x[2] = {0,0};
10156
    word32 blocks, partial;
10157
    word64 bigH[2];
10158
10159
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
10160
    #ifdef LITTLE_ENDIAN_ORDER
10161
        ByteReverseWords64(bigH, bigH, WC_AES_BLOCK_SIZE);
10162
    #endif
10163
10164
    /* Hash in A, the Additional Authentication Data */
10165
    if (aSz != 0 && a != NULL) {
10166
        word64 bigA[2];
10167
        blocks = aSz / WC_AES_BLOCK_SIZE;
10168
        partial = aSz % WC_AES_BLOCK_SIZE;
10169
        while (blocks--) {
10170
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
10171
            #ifdef LITTLE_ENDIAN_ORDER
10172
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
10173
            #endif
10174
            x[0] ^= bigA[0];
10175
            x[1] ^= bigA[1];
10176
            GMULT(x, bigH);
10177
            a += WC_AES_BLOCK_SIZE;
10178
        }
10179
        if (partial != 0) {
10180
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
10181
            XMEMCPY(bigA, a, partial);
10182
            #ifdef LITTLE_ENDIAN_ORDER
10183
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
10184
            #endif
10185
            x[0] ^= bigA[0];
10186
            x[1] ^= bigA[1];
10187
            GMULT(x, bigH);
10188
        }
10189
#ifdef OPENSSL_EXTRA
10190
        /* store AAD partial tag for next call */
10191
        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
10192
        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
10193
        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
10194
        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
10195
#endif
10196
    }
10197
10198
    /* Hash in C, the Ciphertext */
10199
    if (cSz != 0 && c != NULL) {
10200
        word64 bigC[2];
10201
        blocks = cSz / WC_AES_BLOCK_SIZE;
10202
        partial = cSz % WC_AES_BLOCK_SIZE;
10203
#ifdef OPENSSL_EXTRA
10204
        /* Start from last AAD partial tag */
10205
        if(gcm->aadLen) {
10206
            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
10207
            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
10208
         }
10209
#endif
10210
        while (blocks--) {
10211
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
10212
            #ifdef LITTLE_ENDIAN_ORDER
10213
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
10214
            #endif
10215
            x[0] ^= bigC[0];
10216
            x[1] ^= bigC[1];
10217
            GMULT(x, bigH);
10218
            c += WC_AES_BLOCK_SIZE;
10219
        }
10220
        if (partial != 0) {
10221
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
10222
            XMEMCPY(bigC, c, partial);
10223
            #ifdef LITTLE_ENDIAN_ORDER
10224
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
10225
            #endif
10226
            x[0] ^= bigC[0];
10227
            x[1] ^= bigC[1];
10228
            GMULT(x, bigH);
10229
        }
10230
    }
10231
10232
    /* Hash in the lengths in bits of A and C */
10233
    {
10234
        word64 len[2];
10235
        len[0] = aSz; len[1] = cSz;
10236
#ifdef OPENSSL_EXTRA
10237
        if (gcm->aadLen)
10238
            len[0] = (word64)gcm->aadLen;
10239
#endif
10240
        /* Lengths are in bytes. Convert to bits. */
10241
        len[0] *= 8;
10242
        len[1] *= 8;
10243
10244
        x[0] ^= len[0];
10245
        x[1] ^= len[1];
10246
        GMULT(x, bigH);
10247
    }
10248
    #ifdef LITTLE_ENDIAN_ORDER
10249
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
10250
    #endif
10251
    XMEMCPY(s, x, sSz);
10252
}
10253
#endif /* !FREESCALE_LTC_AES_GCM */
10254
10255
#ifdef WOLFSSL_AESGCM_STREAM
10256
10257
#ifdef LITTLE_ENDIAN_ORDER
10258
10259
/* No extra initialization for small implementation.
10260
 *
10261
 * @param [in] aes  AES GCM object.
10262
 */
10263
#define GHASH_INIT_EXTRA(aes)                                               \
10264
    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, WC_AES_BLOCK_SIZE)
10265
10266
/* GHASH one block of data..
10267
 *
10268
 * XOR block into tag and GMULT with H.
10269
 *
10270
 * @param [in, out] aes    AES GCM object.
10271
 * @param [in]      block  Block of AAD or cipher text.
10272
 */
10273
#define GHASH_ONE_BLOCK_SW(aes, block)                              \
10274
    do {                                                            \
10275
        word64* x = (word64*)AES_TAG(aes);                          \
10276
        word64* h = (word64*)aes->gcm.H;                            \
10277
        word64 block64[2];                                          \
10278
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);                 \
10279
        ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE);    \
10280
        x[0] ^= block64[0];                                         \
10281
        x[1] ^= block64[1];                                         \
10282
        GMULT(x, h);                                                \
10283
    }                                                               \
10284
    while (0)
10285
10286
#ifdef OPENSSL_EXTRA
10287
/* GHASH in AAD and cipher text lengths in bits.
10288
 *
10289
 * Convert tag back to little-endian.
10290
 *
10291
 * @param [in, out] aes  AES GCM object.
10292
 */
10293
#define GHASH_LEN_BLOCK(aes)                            \
10294
    do {                                                \
10295
        word64* x = (word64*)AES_TAG(aes);              \
10296
        word64* h = (word64*)aes->gcm.H;                \
10297
        word64 len[2];                                  \
10298
        len[0] = aes->aSz; len[1] = aes->cSz;           \
10299
        if (aes->gcm.aadLen)                            \
10300
            len[0] = (word64)aes->gcm.aadLen;           \
10301
        /* Lengths are in bytes. Convert to bits. */    \
10302
        len[0] *= 8;                                    \
10303
        len[1] *= 8;                                    \
10304
                                                        \
10305
        x[0] ^= len[0];                                 \
10306
        x[1] ^= len[1];                                 \
10307
        GMULT(x, h);                                    \
10308
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
10309
    }                                                   \
10310
    while (0)
10311
#else
10312
/* GHASH in AAD and cipher text lengths in bits.
10313
 *
10314
 * Convert tag back to little-endian.
10315
 *
10316
 * @param [in, out] aes  AES GCM object.
10317
 */
10318
#define GHASH_LEN_BLOCK(aes)                            \
10319
    do {                                                \
10320
        word64* x = (word64*)AES_TAG(aes);              \
10321
        word64* h = (word64*)aes->gcm.H;                \
10322
        word64 len[2];                                  \
10323
        len[0] = aes->aSz; len[1] = aes->cSz;           \
10324
        /* Lengths are in bytes. Convert to bits. */    \
10325
        len[0] *= 8;                                    \
10326
        len[1] *= 8;                                    \
10327
                                                        \
10328
        x[0] ^= len[0];                                 \
10329
        x[1] ^= len[1];                                 \
10330
        GMULT(x, h);                                    \
10331
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
10332
    }                                                   \
10333
    while (0)
10334
#endif
10335
10336
#else
10337
10338
/* No extra initialization for small implementation.
10339
 *
10340
 * @param [in] aes  AES GCM object.
10341
 */
10342
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
10343
10344
/* GHASH one block of data..
10345
 *
10346
 * XOR block into tag and GMULT with H.
10347
 *
10348
 * @param [in, out] aes    AES GCM object.
10349
 * @param [in]      block  Block of AAD or cipher text.
10350
 */
10351
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
10352
    do {                                                \
10353
        word64* x = (word64*)AES_TAG(aes);              \
10354
        word64* h = (word64*)aes->gcm.H;                \
10355
        word64 block64[2];                              \
10356
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);        \
10357
        x[0] ^= block64[0];                             \
10358
        x[1] ^= block64[1];                             \
10359
        GMULT(x, h);                                    \
10360
    }                                                   \
10361
    while (0)
10362
10363
#ifdef OPENSSL_EXTRA
10364
/* GHASH in AAD and cipher text lengths in bits.
10365
 *
10366
 * Convert tag back to little-endian.
10367
 *
10368
 * @param [in, out] aes  AES GCM object.
10369
 */
10370
#define GHASH_LEN_BLOCK(aes)                            \
10371
    do {                                                \
10372
        word64* x = (word64*)AES_TAG(aes);              \
10373
        word64* h = (word64*)aes->gcm.H;                \
10374
        word64 len[2];                                  \
10375
        len[0] = aes->aSz; len[1] = aes->cSz;           \
10376
        if (aes->gcm.aadLen)                            \
10377
            len[0] = (word64)aes->gcm.aadLen;           \
10378
        /* Lengths are in bytes. Convert to bits. */    \
10379
        len[0] *= 8;                                    \
10380
        len[1] *= 8;                                    \
10381
                                                        \
10382
        x[0] ^= len[0];                                 \
10383
        x[1] ^= len[1];                                 \
10384
        GMULT(x, h);                                    \
10385
    }                                                   \
10386
    while (0)
10387
#else
10388
/* GHASH in AAD and cipher text lengths in bits.
10389
 *
10390
 * Convert tag back to little-endian.
10391
 *
10392
 * @param [in, out] aes  AES GCM object.
10393
 */
10394
#define GHASH_LEN_BLOCK(aes)                            \
10395
    do {                                                \
10396
        word64* x = (word64*)AES_TAG(aes);              \
10397
        word64* h = (word64*)aes->gcm.H;                \
10398
        word64 len[2];                                  \
10399
        len[0] = aes->aSz; len[1] = aes->cSz;           \
10400
        /* Lengths are in bytes. Convert to bits. */    \
10401
        len[0] *= 8;                                    \
10402
        len[1] *= 8;                                    \
10403
                                                        \
10404
        x[0] ^= len[0];                                 \
10405
        x[1] ^= len[1];                                 \
10406
        GMULT(x, h);                                    \
10407
    }                                                   \
10408
    while (0)
10409
#endif
10410
10411
#endif /* !LITTLE_ENDIAN_ORDER */
10412
10413
#endif /* WOLFSSL_AESGCM_STREAM */
10414
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
10415
#else /* GCM_WORD32 */
10416
10417
static void GMULT(word32* X, word32* Y)
10418
{
10419
    word32 Z[4] = {0,0,0,0};
10420
    word32 V[4];
10421
    int i, j;
10422
10423
    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
10424
10425
    for (i = 0; i < 4; i++)
10426
    {
10427
        word32 y = Y[i];
10428
        for (j = 0; j < 32; j++)
10429
        {
10430
            if (y & 0x80000000) {
10431
                Z[0] ^= V[0];
10432
                Z[1] ^= V[1];
10433
                Z[2] ^= V[2];
10434
                Z[3] ^= V[3];
10435
            }
10436
10437
            if (V[3] & 0x00000001) {
10438
                V[3] >>= 1;
10439
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
10440
                V[2] >>= 1;
10441
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
10442
                V[1] >>= 1;
10443
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
10444
                V[0] >>= 1;
10445
                V[0] ^= 0xE1000000;
10446
            } else {
10447
                V[3] >>= 1;
10448
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
10449
                V[2] >>= 1;
10450
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
10451
                V[1] >>= 1;
10452
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
10453
                V[0] >>= 1;
10454
            }
10455
            y <<= 1;
10456
        }
10457
    }
10458
    X[0] = Z[0];
10459
    X[1] = Z[1];
10460
    X[2] = Z[2];
10461
    X[3] = Z[3];
10462
}
10463
10464
10465
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
10466
    word32 cSz, byte* s, word32 sSz)
10467
{
10468
    word32 x[4] = {0,0,0,0};
10469
    word32 blocks, partial;
10470
    word32 bigH[4];
10471
10472
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
10473
    #ifdef LITTLE_ENDIAN_ORDER
10474
        ByteReverseWords(bigH, bigH, WC_AES_BLOCK_SIZE);
10475
    #endif
10476
10477
    /* Hash in A, the Additional Authentication Data */
10478
    if (aSz != 0 && a != NULL) {
10479
        word32 bigA[4];
10480
        blocks = aSz / WC_AES_BLOCK_SIZE;
10481
        partial = aSz % WC_AES_BLOCK_SIZE;
10482
        while (blocks--) {
10483
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
10484
            #ifdef LITTLE_ENDIAN_ORDER
10485
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
10486
            #endif
10487
            x[0] ^= bigA[0];
10488
            x[1] ^= bigA[1];
10489
            x[2] ^= bigA[2];
10490
            x[3] ^= bigA[3];
10491
            GMULT(x, bigH);
10492
            a += WC_AES_BLOCK_SIZE;
10493
        }
10494
        if (partial != 0) {
10495
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
10496
            XMEMCPY(bigA, a, partial);
10497
            #ifdef LITTLE_ENDIAN_ORDER
10498
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
10499
            #endif
10500
            x[0] ^= bigA[0];
10501
            x[1] ^= bigA[1];
10502
            x[2] ^= bigA[2];
10503
            x[3] ^= bigA[3];
10504
            GMULT(x, bigH);
10505
        }
10506
    }
10507
10508
    /* Hash in C, the Ciphertext */
10509
    if (cSz != 0 && c != NULL) {
10510
        word32 bigC[4];
10511
        blocks = cSz / WC_AES_BLOCK_SIZE;
10512
        partial = cSz % WC_AES_BLOCK_SIZE;
10513
        while (blocks--) {
10514
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
10515
            #ifdef LITTLE_ENDIAN_ORDER
10516
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
10517
            #endif
10518
            x[0] ^= bigC[0];
10519
            x[1] ^= bigC[1];
10520
            x[2] ^= bigC[2];
10521
            x[3] ^= bigC[3];
10522
            GMULT(x, bigH);
10523
            c += WC_AES_BLOCK_SIZE;
10524
        }
10525
        if (partial != 0) {
10526
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
10527
            XMEMCPY(bigC, c, partial);
10528
            #ifdef LITTLE_ENDIAN_ORDER
10529
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
10530
            #endif
10531
            x[0] ^= bigC[0];
10532
            x[1] ^= bigC[1];
10533
            x[2] ^= bigC[2];
10534
            x[3] ^= bigC[3];
10535
            GMULT(x, bigH);
10536
        }
10537
    }
10538
10539
    /* Hash in the lengths in bits of A and C */
10540
    {
10541
        word32 len[4];
10542
10543
        /* Lengths are in bytes. Convert to bits. */
10544
        len[0] = (aSz >> (CHAR_BIT*sizeof(aSz) - 3));
10545
        len[1] = aSz << 3;
10546
        len[2] = (cSz >> (CHAR_BIT*sizeof(cSz) - 3));
10547
        len[3] = cSz << 3;
10548
10549
        x[0] ^= len[0];
10550
        x[1] ^= len[1];
10551
        x[2] ^= len[2];
10552
        x[3] ^= len[3];
10553
        GMULT(x, bigH);
10554
    }
10555
    #ifdef LITTLE_ENDIAN_ORDER
10556
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
10557
    #endif
10558
    XMEMCPY(s, x, sSz);
10559
}
10560
10561
#ifdef WOLFSSL_AESGCM_STREAM
10562
#ifdef LITTLE_ENDIAN_ORDER
10563
/* Little-endian 32-bit word implementation requires byte reversal of H.
10564
 *
10565
 * H is all-zeros block encrypted with key.
10566
 *
10567
 * @param [in, out] aes  AES GCM object.
10568
 */
10569
#define GHASH_INIT_EXTRA(aes) \
10570
    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, WC_AES_BLOCK_SIZE)
10571
10572
/* GHASH one block of data..
10573
 *
10574
 * XOR block, in big-endian form, into tag and GMULT with H.
10575
 *
10576
 * @param [in, out] aes    AES GCM object.
10577
 * @param [in]      block  Block of AAD or cipher text.
10578
 */
10579
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
10580
    do {                                                        \
10581
        word32* x = (word32*)AES_TAG(aes);                      \
10582
        word32* h = (word32*)aes->gcm.H;                        \
10583
        word32 bigEnd[4];                                       \
10584
        XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE);              \
10585
        ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE);    \
10586
        x[0] ^= bigEnd[0];                                      \
10587
        x[1] ^= bigEnd[1];                                      \
10588
        x[2] ^= bigEnd[2];                                      \
10589
        x[3] ^= bigEnd[3];                                      \
10590
        GMULT(x, h);                                            \
10591
    }                                                           \
10592
    while (0)
10593
10594
/* GHASH in AAD and cipher text lengths in bits.
10595
 *
10596
 * Convert tag back to little-endian.
10597
 *
10598
 * @param [in, out] aes  AES GCM object.
10599
 */
10600
#define GHASH_LEN_BLOCK(aes)                                \
10601
    do {                                                    \
10602
        word32 len[4];                                      \
10603
        word32* x = (word32*)AES_TAG(aes);                  \
10604
        word32* h = (word32*)aes->gcm.H;                    \
10605
        len[0] = (aes->aSz >> (CHAR_BIT*sizeof(aes->aSz) - 3));    \
10606
        len[1] = aes->aSz << 3;                             \
10607
        len[2] = (aes->cSz >> (CHAR_BIT*sizeof(aes->cSz) - 3));    \
10608
        len[3] = aes->cSz << 3;                             \
10609
        x[0] ^= len[0];                                     \
10610
        x[1] ^= len[1];                                     \
10611
        x[2] ^= len[2];                                     \
10612
        x[3] ^= len[3];                                     \
10613
        GMULT(x, h);                                        \
10614
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);          \
10615
    }                                                       \
10616
    while (0)
10617
#else
10618
/* No extra initialization for 32-bit word implementation.
10619
 *
10620
 * @param [in] aes  AES GCM object.
10621
 */
10622
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
10623
10624
/* GHASH one block of data..
10625
 *
10626
 * XOR block into tag and GMULT with H.
10627
 *
10628
 * @param [in, out] aes    AES GCM object.
10629
 * @param [in]      block  Block of AAD or cipher text.
10630
 */
10631
#define GHASH_ONE_BLOCK_SW(aes, block)                      \
10632
    do {                                                    \
10633
        word32* x = (word32*)AES_TAG(aes);                  \
10634
        word32* h = (word32*)aes->gcm.H;                    \
10635
        word32 block32[4];                                  \
10636
        XMEMCPY(block32, block, WC_AES_BLOCK_SIZE);         \
10637
        x[0] ^= block32[0];                                 \
10638
        x[1] ^= block32[1];                                 \
10639
        x[2] ^= block32[2];                                 \
10640
        x[3] ^= block32[3];                                 \
10641
        GMULT(x, h);                                        \
10642
    }                                                       \
10643
    while (0)
10644
10645
/* GHASH in AAD and cipher text lengths in bits.
10646
 *
10647
 * @param [in, out] aes  AES GCM object.
10648
 */
10649
#define GHASH_LEN_BLOCK(aes)                                \
10650
    do {                                                    \
10651
        word32 len[4];                                      \
10652
        word32* x = (word32*)AES_TAG(aes);                  \
10653
        word32* h = (word32*)aes->gcm.H;                    \
10654
        len[0] = (aes->aSz >> (CHAR_BIT*sizeof(aes->aSz) - 3));    \
10655
        len[1] = aes->aSz << 3;                             \
10656
        len[2] = (aes->cSz >> (CHAR_BIT*sizeof(aes->cSz) - 3));    \
10657
        len[3] = aes->cSz << 3;                             \
10658
        x[0] ^= len[0];                                     \
10659
        x[1] ^= len[1];                                     \
10660
        x[2] ^= len[2];                                     \
10661
        x[3] ^= len[3];                                     \
10662
        GMULT(x, h);                                        \
10663
    }                                                       \
10664
    while (0)
10665
#endif /* LITTLE_ENDIAN_ORDER */
10666
#endif /* WOLFSSL_AESGCM_STREAM */
10667
#endif /* end GCM_WORD32 */
10668
10669
#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
10670
#ifdef WOLFSSL_AESGCM_STREAM
10671
#ifndef GHASH_LEN_BLOCK
10672
/* Hash in the lengths of the AAD and cipher text in bits.
10673
 *
10674
 * Default implementation.
10675
 *
10676
 * @param [in, out] aes  AES GCM object.
10677
 */
10678
#define GHASH_LEN_BLOCK(aes)                      \
10679
480
    do {                                          \
10680
480
        byte scratch[WC_AES_BLOCK_SIZE];          \
10681
480
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
10682
480
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
10683
480
        GHASH_ONE_BLOCK(aes, scratch);            \
10684
480
    }                                             \
10685
480
    while (0)
10686
#endif
10687
10688
/* Initialize a GHASH for streaming operations.
10689
 *
10690
 * @param [in, out] aes  AES GCM object.
10691
 */
10692
1.38k
static void GHASH_INIT(Aes* aes) {
10693
    /* Set tag to all zeros as initial value. */
10694
1.38k
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
10695
    /* Reset counts of AAD and cipher text. */
10696
1.38k
    aes->aOver = 0;
10697
1.38k
    aes->cOver = 0;
10698
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10699
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10700
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10701
        ; /* Don't do extra initialization. */
10702
    }
10703
    else
10704
#endif
10705
1.38k
    {
10706
        /* Extra initialization based on implementation. */
10707
1.38k
        GHASH_INIT_EXTRA(aes);
10708
1.38k
    }
10709
1.38k
}
10710
10711
/* Update the GHASH with AAD and/or cipher text.
10712
 *
10713
 * @param [in,out] aes   AES GCM object.
10714
 * @param [in]     a     Additional authentication data buffer.
10715
 * @param [in]     aSz   Size of data in AAD buffer.
10716
 * @param [in]     c     Cipher text buffer.
10717
 * @param [in]     cSz   Size of data in cipher text buffer.
10718
 */
10719
static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
10720
    word32 cSz)
10721
8.28k
{
10722
8.28k
    word32 blocks;
10723
8.28k
    word32 partial;
10724
10725
    /* Hash in A, the Additional Authentication Data */
10726
8.28k
    if (aSz != 0 && a != NULL) {
10727
        /* Update count of AAD we have hashed. */
10728
677
        aes->aSz += aSz;
10729
        /* Check if we have unprocessed data. */
10730
677
        if (aes->aOver > 0) {
10731
            /* Calculate amount we can use - fill up the block. */
10732
441
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10733
441
            if (sz > aSz) {
10734
229
                sz = (byte)aSz;
10735
229
            }
10736
            /* Copy extra into last GHASH block array and update count. */
10737
441
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
10738
441
            aes->aOver = (byte)(aes->aOver + sz);
10739
441
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
10740
                /* We have filled up the block and can process. */
10741
212
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10742
                /* Reset count. */
10743
212
                aes->aOver = 0;
10744
212
            }
10745
            /* Used up some data. */
10746
441
            aSz -= sz;
10747
441
            a += sz;
10748
441
        }
10749
10750
        /* Calculate number of blocks of AAD and the leftover. */
10751
677
        blocks = aSz / WC_AES_BLOCK_SIZE;
10752
677
        partial = aSz % WC_AES_BLOCK_SIZE;
10753
        /* GHASH full blocks now. */
10754
7.50k
        while (blocks--) {
10755
6.82k
            GHASH_ONE_BLOCK(aes, a);
10756
6.82k
            a += WC_AES_BLOCK_SIZE;
10757
6.82k
        }
10758
677
        if (partial != 0) {
10759
            /* Cache the partial block. */
10760
401
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
10761
401
            aes->aOver = (byte)partial;
10762
401
        }
10763
677
    }
10764
8.28k
    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
10765
        /* No more AAD coming and we have a partial block. */
10766
        /* Fill the rest of the block with zeros. */
10767
43
        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10768
43
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
10769
        /* GHASH last AAD block. */
10770
43
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10771
        /* Clear partial count for next time through. */
10772
43
        aes->aOver = 0;
10773
43
    }
10774
10775
    /* Hash in C, the Ciphertext */
10776
8.28k
    if (cSz != 0 && c != NULL) {
10777
        /* Update count of cipher text we have hashed. */
10778
761
        aes->cSz += cSz;
10779
761
        if (aes->cOver > 0) {
10780
            /* Calculate amount we can use - fill up the block. */
10781
420
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
10782
420
            if (sz > cSz) {
10783
235
                sz = (byte)cSz;
10784
235
            }
10785
420
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
10786
            /* Update count of unused encrypted counter. */
10787
420
            aes->cOver = (byte)(aes->cOver + sz);
10788
420
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
10789
                /* We have filled up the block and can process. */
10790
185
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10791
                /* Reset count. */
10792
185
                aes->cOver = 0;
10793
185
            }
10794
            /* Used up some data. */
10795
420
            cSz -= sz;
10796
420
            c += sz;
10797
420
        }
10798
10799
        /* Calculate number of blocks of cipher text and the leftover. */
10800
761
        blocks = cSz / WC_AES_BLOCK_SIZE;
10801
761
        partial = cSz % WC_AES_BLOCK_SIZE;
10802
        /* GHASH full blocks now. */
10803
13.1k
        while (blocks--) {
10804
12.3k
            GHASH_ONE_BLOCK(aes, c);
10805
12.3k
            c += WC_AES_BLOCK_SIZE;
10806
12.3k
        }
10807
761
        if (partial != 0) {
10808
            /* Cache the partial block. */
10809
420
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
10810
420
            aes->cOver = (byte)partial;
10811
420
        }
10812
761
    }
10813
8.28k
}
10814
10815
/* Finalize the GHASH calculation.
10816
 *
10817
 * Complete hashing cipher text and hash the AAD and cipher text lengths.
10818
 *
10819
 * @param [in, out] aes  AES GCM object.
10820
 * @param [out]     s    Authentication tag.
10821
 * @param [in]      sSz  Size of authentication tag required.
10822
 */
10823
static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
10824
480
{
10825
    /* AAD block incomplete when > 0 */
10826
480
    byte over = aes->aOver;
10827
10828
480
    if (aes->cOver > 0) {
10829
        /* Cipher text block incomplete. */
10830
217
        over = aes->cOver;
10831
217
    }
10832
480
    if (over > 0) {
10833
        /* Zeroize the unused part of the block. */
10834
356
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
10835
356
            (size_t)WC_AES_BLOCK_SIZE - over);
10836
        /* Hash the last block of cipher text. */
10837
356
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10838
356
    }
10839
    /* Hash in the lengths of AAD and cipher text in bits */
10840
480
    GHASH_LEN_BLOCK(aes);
10841
    /* Copy the result into s. */
10842
480
    XMEMCPY(s, AES_TAG(aes), sSz);
10843
    /* reset aes->gcm.H in case of reuse */
10844
480
    GHASH_INIT_EXTRA(aes);
10845
480
}
10846
#endif /* WOLFSSL_AESGCM_STREAM */
10847
10848
10849
#ifdef FREESCALE_LTC_AES_GCM
10850
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10851
                   const byte* iv, word32 ivSz,
10852
                   byte* authTag, word32 authTagSz,
10853
                   const byte* authIn, word32 authInSz)
10854
{
10855
    status_t status;
10856
    word32 keySize;
10857
10858
    /* argument checks */
10859
    if (aes == NULL || ivSz == 0) {
10860
        return BAD_FUNC_ARG;
10861
    }
10862
10863
    status = wc_local_AesGcmCheckTagSz(authTagSz);
10864
    if (status != 0)
10865
        return status;
10866
10867
    status = wc_AesGetKeySize(aes, &keySize);
10868
    if (status)
10869
        return status;
10870
10871
    status = wolfSSL_CryptHwMutexLock();
10872
    if (status != 0)
10873
        return status;
10874
10875
    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
10876
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
10877
    wolfSSL_CryptHwMutexUnLock();
10878
10879
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
10880
}
10881
10882
#else
10883
10884
#ifdef STM32_CRYPTO_AES_GCM
10885
10886
/* The Cube HAL always transfers the GCM auth header to the peripheral one
10887
 * 32-bit word at a time, including the trailing partial word (ST advisory
10888
 * SA0076), and casts the header pointer to uint32_t*, so the buffer it is
10889
 * handed must be both zero padded up to a word and word aligned -- even
10890
 * where STM_CRYPT_HEADER_WIDTH is 1 and the header size is in bytes.
10891
 * authPadSz is the length reported to the HAL and is deliberately not
10892
 * changed here, so the GHASH length block, and with it the hardware tag,
10893
 * is unaffected.
10894
 * tmpBuf is a caller supplied word aligned scratch buffer, used when it is
10895
 * large enough, otherwise the padded copy is allocated and *wasAlloc is set
10896
 * so the caller frees it. When no padding or realignment is needed
10897
 * *authInPadded aliases authIn and no copy is made.
10898
 * Returns 0 on success, MEMORY_E or BAD_FUNC_ARG on failure. */
10899
static WARN_UNUSED_RESULT int wc_AesGcmAuthPad_STM32(Aes* aes,
10900
    const byte* authIn, word32 authInSz, word32 authPadSz,
10901
    word32* tmpBuf, word32 tmpBufSz, byte** authInPadded, int* wasAlloc)
10902
{
10903
    word32 padWidth = (word32)STM_CRYPT_HEADER_PAD_WIDTH;
10904
    word32 authBufSz;
10905
10906
    *wasAlloc = 0;
10907
10908
    /* the HAL reads the larger of the two, and some HAL work arounds leave
10909
     * authPadSz smaller than authInSz, so cover both */
10910
    authBufSz = authPadSz;
10911
    if (authBufSz < authInSz) {
10912
        authBufSz = authInSz;
10913
    }
10914
    if (authBufSz > (WOLFSSL_MAX_32BIT - padWidth)) {
10915
        return BAD_FUNC_ARG; /* the round up below would wrap */
10916
    }
10917
    if ((authBufSz % padWidth) != 0) {
10918
        authBufSz += padWidth - (authBufSz % padWidth);
10919
    }
10920
    if ((authBufSz == authInSz) &&
10921
            (((wc_ptr_t)authIn % sizeof(word32)) == 0)) {
10922
        /* whole number of words and word aligned, the HAL can read it */
10923
        *authInPadded = (byte*)authIn;
10924
        return 0;
10925
    }
10926
10927
    if (authBufSz <= tmpBufSz) {
10928
        *authInPadded = (byte*)tmpBuf;
10929
    }
10930
    else {
10931
        *authInPadded = (byte*)XMALLOC(authBufSz, aes->heap,
10932
            DYNAMIC_TYPE_TMP_BUFFER);
10933
        if (*authInPadded == NULL) {
10934
            return MEMORY_E;
10935
        }
10936
        *wasAlloc = 1;
10937
    }
10938
    XMEMSET(*authInPadded, 0, authBufSz);
10939
    if (authIn != NULL) {
10940
        XMEMCPY(*authInPadded, authIn, authInSz);
10941
    }
10942
    return 0;
10943
}
10944
10945
/* this function supports inline encrypt */
10946
/* Not static: the CubeMX crypto-callback device (port/st/stm32.c) calls this to
10947
 * service AES-GCM in-callback on the HAL engine. */
10948
WOLFSSL_LOCAL WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
10949
                                  Aes* aes, byte* out, const byte* in, word32 sz,
10950
                                  const byte* iv, word32 ivSz,
10951
                                  byte* authTag, word32 authTagSz,
10952
                                  const byte* authIn, word32 authInSz)
10953
{
10954
    int ret;
10955
#ifdef WOLFSSL_STM32_CUBEMX
10956
    CRYP_HandleTypeDef hcryp;
10957
#else
10958
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
10959
#endif
10960
    word32 keySize;
10961
#ifdef WOLFSSL_STM32_CUBEMX
10962
    int status = HAL_OK;
10963
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10964
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
10965
#else
10966
    int status = SUCCESS;
10967
#endif
10968
    word32 partial = sz % WC_AES_BLOCK_SIZE;
10969
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
10970
    word32 ctrInit[WC_AES_BLOCK_SIZE/sizeof(word32)];
10971
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10972
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10973
    byte* authInPadded = NULL;
10974
    word32 authPadSz;
10975
    int wasAlloc = 0, useSwGhash = 0;
10976
10977
    ret = wc_AesGetKeySize(aes, &keySize);
10978
    if (ret != 0)
10979
        return ret;
10980
10981
#ifdef WOLFSSL_STM32_CUBEMX
10982
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
10983
    if (ret != 0)
10984
        return ret;
10985
#endif
10986
10987
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
10988
    if (ivSz == GCM_NONCE_MID_SZ) {
10989
        byte* pCtr = (byte*)ctr;
10990
        XMEMCPY(ctr, iv, ivSz);
10991
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
10992
    }
10993
    else {
10994
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
10995
    }
10996
    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
10997
10998
    /* Authentication buffer */
10999
#if STM_CRYPT_HEADER_WIDTH == 1
11000
    authPadSz = 0; /* CubeHAL supports byte mode */
11001
#else
11002
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
11003
#endif
11004
#ifdef WOLFSSL_STM32MP13
11005
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
11006
     * minimum of 16 bytes for the auth */
11007
    if ((authInSz > 0) && (authInSz < 16)) {
11008
        authPadSz = 16 - authInSz;
11009
    }
11010
#endif
11011
    if (authPadSz != 0) {
11012
        if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) {
11013
            authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
11014
        }
11015
    }
11016
    else {
11017
        authPadSz = authInSz;
11018
    }
11019
    /* Zero pad and word align the buffer the HAL reads the auth header
11020
     * from (SA0076). authPadSz, the length reported to the HAL, is
11021
     * unchanged, so the hardware tag is unaffected. */
11022
    ret = wc_AesGcmAuthPad_STM32(aes, authIn, authInSz, authPadSz,
11023
        authhdr, (word32)sizeof(authhdr), &authInPadded, &wasAlloc);
11024
    if (ret != 0) {
11025
        wc_Stm32_Aes_Cleanup();
11026
        return ret;
11027
    }
11028
11029
    /* for cases where hardware cannot be used for authTag calculate it */
11030
    /* if IV is not 12 calculate GHASH using software */
11031
    if (ivSz != GCM_NONCE_MID_SZ
11032
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
11033
        /* or hardware that does not support partial block */
11034
        || sz == 0 || partial != 0
11035
    #endif
11036
    #if STM_CRYPT_HEADER_WIDTH == 4
11037
        /* or authIn is not a multiple of 4  */
11038
        || authPadSz != authInSz
11039
    #endif
11040
    ) {
11041
        useSwGhash = 1;
11042
    }
11043
11044
    /* Hardware requires counter + 1 */
11045
    IncrementGcmCounter((byte*)ctr);
11046
11047
    ret = wolfSSL_CryptHwMutexLock();
11048
    if (ret != 0) {
11049
        if (wasAlloc) {
11050
            XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11051
        }
11052
        wc_Stm32_Aes_Cleanup();
11053
        return ret;
11054
    }
11055
11056
#ifdef WOLFSSL_STM32_CUBEMX
11057
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11058
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
11059
11060
#if defined(STM32_HAL_V2)
11061
    hcryp.Init.Algorithm = CRYP_AES_GCM;
11062
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
11063
    #ifdef CRYP_KEYIVCONFIG_ONCE
11064
    /* allows repeated calls to HAL_CRYP_Encrypt */
11065
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
11066
    #endif
11067
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
11068
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11069
    HAL_CRYP_Init(&hcryp);
11070
11071
    #ifndef CRYP_KEYIVCONFIG_ONCE
11072
    /* GCM payload phase - can handle partial blocks */
11073
    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
11074
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
11075
    #else
11076
    /* GCM payload phase - blocks */
11077
    if (blocks) {
11078
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
11079
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
11080
    }
11081
    /* GCM payload phase - partial remainder */
11082
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11083
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11084
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11085
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
11086
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
11087
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11088
    }
11089
    #endif
11090
    if (status == HAL_OK && !useSwGhash) {
11091
        /* Compute the authTag */
11092
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
11093
            STM32_HAL_TIMEOUT);
11094
    }
11095
#elif defined(STM32_CRYPTO_AES_ONLY)
11096
    /* Set the CRYP parameters */
11097
    hcryp.Init.HeaderSize = authPadSz;
11098
    if (authPadSz == 0)
11099
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
11100
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
11101
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
11102
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
11103
    HAL_CRYP_Init(&hcryp);
11104
11105
    /* GCM init phase */
11106
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11107
    if (status == HAL_OK) {
11108
        /* GCM header phase */
11109
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
11110
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11111
    }
11112
    if (status == HAL_OK) {
11113
        /* GCM payload phase - blocks */
11114
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
11115
        if (blocks) {
11116
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
11117
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11118
        }
11119
    }
11120
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
11121
        /* GCM payload phase - partial remainder */
11122
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11123
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11124
        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
11125
                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
11126
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11127
    }
11128
    if (status == HAL_OK && !useSwGhash) {
11129
        /* GCM final phase */
11130
        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
11131
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
11132
    }
11133
#else
11134
    hcryp.Init.HeaderSize = authPadSz;
11135
    HAL_CRYP_Init(&hcryp);
11136
    if (blocks) {
11137
        /* GCM payload phase - blocks */
11138
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
11139
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11140
    }
11141
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11142
        /* GCM payload phase - partial remainder */
11143
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11144
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11145
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
11146
            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
11147
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11148
    }
11149
    if (status == HAL_OK && !useSwGhash) {
11150
        /* Compute the authTag */
11151
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
11152
    }
11153
#endif
11154
11155
    if (status != HAL_OK)
11156
        ret = AES_GCM_AUTH_E;
11157
    HAL_CRYP_DeInit(&hcryp);
11158
11159
#else /* Standard Peripheral Library */
11160
    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
11161
    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
11162
                         (uint8_t*)keyCopy,      keySize * 8,
11163
                         (uint8_t*)in,           sz,
11164
                         (uint8_t*)authInPadded, authInSz,
11165
                         (uint8_t*)out,          (uint8_t*)tag);
11166
    if (status != SUCCESS)
11167
        ret = AES_GCM_AUTH_E;
11168
#endif /* WOLFSSL_STM32_CUBEMX */
11169
    wolfSSL_CryptHwMutexUnLock();
11170
    wc_Stm32_Aes_Cleanup();
11171
11172
    if (ret == 0) {
11173
        /* return authTag */
11174
        if (authTag) {
11175
            if (useSwGhash) {
11176
                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
11177
                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
11178
                if (ret == 0) {
11179
                    xorbuf(authTag, tag, authTagSz);
11180
                }
11181
            }
11182
            else {
11183
                /* use hardware calculated tag */
11184
                XMEMCPY(authTag, tag, authTagSz);
11185
            }
11186
        }
11187
    }
11188
11189
    /* Free memory */
11190
    if (wasAlloc) {
11191
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11192
    }
11193
11194
    return ret;
11195
}
11196
11197
#endif /* STM32_CRYPTO_AES_GCM */
11198
11199
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11200
#ifdef WOLFSSL_AESNI
11201
/* For performance reasons, this code needs to be not inlined. */
11202
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
11203
                      Aes* aes, byte* out, const byte* in, word32 sz,
11204
                      const byte* iv, word32 ivSz,
11205
                      byte* authTag, word32 authTagSz,
11206
                      const byte* authIn, word32 authInSz);
11207
#else
11208
static
11209
#endif
11210
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
11211
                      Aes* aes, byte* out, const byte* in, word32 sz,
11212
                      const byte* iv, word32 ivSz,
11213
                      byte* authTag, word32 authTagSz,
11214
                      const byte* authIn, word32 authInSz)
11215
{
11216
    int ret = 0;
11217
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
11218
    word32 partial = sz % WC_AES_BLOCK_SIZE;
11219
    const byte* p = in;
11220
    byte* c = out;
11221
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
11222
    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
11223
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
11224
#ifdef WC_AES_HAVE_PREFETCH_ARG
11225
    int did_prefetches = 0;
11226
#endif
11227
11228
    if (ivSz == GCM_NONCE_MID_SZ) {
11229
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
11230
        XMEMCPY(counter, iv, ivSz);
11231
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
11232
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
11233
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
11234
    }
11235
    else {
11236
        /* Counter is GHASH of IV. */
11237
#ifdef OPENSSL_EXTRA
11238
        word32 aadTemp = aes->gcm.aadLen;
11239
        aes->gcm.aadLen = 0;
11240
#endif
11241
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
11242
#ifdef OPENSSL_EXTRA
11243
        aes->gcm.aadLen = aadTemp;
11244
#endif
11245
    }
11246
    XMEMCPY(initialCounter, counter, WC_AES_BLOCK_SIZE);
11247
11248
#ifdef WOLFSSL_PIC32MZ_CRYPT
11249
    if (blocks) {
11250
        /* use initial IV for HW, but don't use it below */
11251
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
11252
11253
        ret = wc_Pic32AesCrypt(
11254
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
11255
            out, in, (blocks * WC_AES_BLOCK_SIZE),
11256
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
11257
        if (ret != 0)
11258
            return ret;
11259
    }
11260
    /* process remainder using partial handling */
11261
#endif
11262
11263
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
11264
    /* some hardware acceleration can gain performance from doing AES encryption
11265
     * of the whole buffer at once */
11266
    if (c != p && blocks > 0) { /* can not handle inline encryption */
11267
        while (blocks--) {
11268
            IncrementGcmCounter(counter);
11269
            XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
11270
            c += WC_AES_BLOCK_SIZE;
11271
        }
11272
11273
        /* reset number of blocks and then do encryption */
11274
        blocks = sz / WC_AES_BLOCK_SIZE;
11275
        ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
11276
        if (ret != 0) {
11277
            ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
11278
            return ret;
11279
        }
11280
        xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
11281
        p += WC_AES_BLOCK_SIZE * blocks;
11282
    }
11283
    else
11284
#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
11285
    {
11286
        while (blocks--) {
11287
            IncrementGcmCounter(counter);
11288
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
11289
            ret = AesEncrypt_preFetchOpt(aes, counter, scratch,
11290
                                            &did_prefetches);
11291
            if (ret != 0)
11292
                return ret;
11293
            xorbufout(c, scratch, p, WC_AES_BLOCK_SIZE);
11294
        #endif
11295
            p += WC_AES_BLOCK_SIZE;
11296
            c += WC_AES_BLOCK_SIZE;
11297
        }
11298
    }
11299
11300
    if (partial != 0) {
11301
        IncrementGcmCounter(counter);
11302
        ret = AesEncrypt_preFetchOpt(aes, counter, scratch, &did_prefetches);
11303
        if (ret != 0)
11304
            return ret;
11305
        xorbufout(c, scratch, p, partial);
11306
    }
11307
    if (authTag) {
11308
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
11309
        ret = AesEncrypt_preFetchOpt(aes, initialCounter, scratch,
11310
                                        &did_prefetches);
11311
        if (ret != 0)
11312
            return ret;
11313
        xorbuf(authTag, scratch, authTagSz);
11314
#ifdef OPENSSL_EXTRA
11315
        if (!in && !sz)
11316
            /* store AAD size for next call */
11317
            aes->gcm.aadLen = authInSz;
11318
#endif
11319
    }
11320
11321
    return ret;
11322
}
11323
#elif (defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
11324
      defined(WOLFSSL_ARM32_AES_DISPATCH) || \
11325
      (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11326
static int AES_GCM_encrypt_ASM(Aes* aes, byte* out, const byte* in,
11327
    word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
11328
    const byte* authIn, word32 authInSz)
11329
{
11330
    word32 blocks;
11331
    word32 partial;
11332
    byte counter[WC_AES_BLOCK_SIZE];
11333
    byte initialCounter[WC_AES_BLOCK_SIZE];
11334
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
11335
    byte scratch[WC_AES_BLOCK_SIZE];
11336
11337
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
11338
    if (ivSz == GCM_NONCE_MID_SZ) {
11339
        XMEMCPY(initialCounter, iv, ivSz);
11340
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
11341
    }
11342
    else {
11343
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
11344
    }
11345
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
11346
11347
    /* Hash in the Additional Authentication Data */
11348
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
11349
    if (authInSz != 0 && authIn != NULL) {
11350
        blocks = authInSz / WC_AES_BLOCK_SIZE;
11351
        partial = authInSz % WC_AES_BLOCK_SIZE;
11352
        if (blocks > 0) {
11353
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
11354
            authIn += blocks * WC_AES_BLOCK_SIZE;
11355
        }
11356
        if (partial != 0) {
11357
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11358
            XMEMCPY(scratch, authIn, partial);
11359
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11360
        }
11361
    }
11362
11363
    /* do as many blocks as possible */
11364
    blocks = sz / WC_AES_BLOCK_SIZE;
11365
    partial = sz % WC_AES_BLOCK_SIZE;
11366
    if (blocks > 0) {
11367
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
11368
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11369
        if (sz >= 32)
11370
    #endif
11371
        {
11372
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
11373
                (const unsigned char*)aes->key, aes->rounds, counter);
11374
        }
11375
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11376
        else
11377
    #endif
11378
    #endif
11379
    /* Base AES is only left out on AArch64 - see wc_AesCbcDecrypt. */
11380
    #if !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP) || !defined(__aarch64__)
11381
        {
11382
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
11383
                (const unsigned char*)aes->key, aes->rounds, counter);
11384
        }
11385
    #endif
11386
        GCM_GMULT_LEN(&aes->gcm, x, out, blocks * WC_AES_BLOCK_SIZE);
11387
        in += blocks * WC_AES_BLOCK_SIZE;
11388
        out += blocks * WC_AES_BLOCK_SIZE;
11389
    }
11390
    /* take care of partial block sizes leftover */
11391
    if (partial != 0) {
11392
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
11393
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
11394
        {
11395
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
11396
                (const unsigned char*)aes->key, aes->rounds, counter);
11397
        }
11398
    #else
11399
        {
11400
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
11401
                (const unsigned char*)aes->key, aes->rounds, counter);
11402
        }
11403
    #endif
11404
        XMEMCPY(out, scratch, partial);
11405
11406
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11407
        XMEMCPY(scratch, out, partial);
11408
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11409
    }
11410
11411
    /* Hash in the lengths of A and C in bits */
11412
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11413
    FlattenSzInBits(&scratch[0], authInSz);
11414
    FlattenSzInBits(&scratch[8], sz);
11415
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11416
    if (authTagSz > WC_AES_BLOCK_SIZE) {
11417
        XMEMCPY(authTag, x, WC_AES_BLOCK_SIZE);
11418
    }
11419
    else {
11420
        /* authTagSz can be smaller than WC_AES_BLOCK_SIZE */
11421
        XMEMCPY(authTag, x, authTagSz);
11422
    }
11423
11424
    /* Auth tag calculation. */
11425
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
11426
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
11427
    {
11428
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
11429
            (const unsigned char*)aes->key, aes->rounds);
11430
    }
11431
#else
11432
    {
11433
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
11434
            (const unsigned char*)aes->key, aes->rounds);
11435
    }
11436
#endif
11437
    xorbuf(authTag, scratch, authTagSz);
11438
11439
    return 0;
11440
}
11441
#endif
11442
11443
#if defined(WOLFSSL_RISCV_ASM)
11444
/* Pointer passed as "H" to the RISC-V GCM asm.  Scalar/vector crypto use the
11445
 * raw hash subkey gcm.H.  Base (software GHASH) uses the precomputed M0 table
11446
 * for GCM_TABLE/GCM_TABLE_4BIT, but gcm.H for the table-free GCM_WORD32/
11447
 * GCM_SMALL builds (which have no M0 member). */
11448
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) || \
11449
    defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
11450
    #define AES_GCM_H_PTR(aes) ((aes)->gcm.H)
11451
#elif defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
11452
    #define AES_GCM_H_PTR(aes) ((byte*)(aes)->gcm.M0)
11453
#else
11454
    #define AES_GCM_H_PTR(aes) ((byte*)(aes)->gcm.H)
11455
#endif
11456
#endif /* WOLFSSL_RISCV_ASM */
11457
11458
/* Software AES - GCM Encrypt */
11459
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
11460
                   const byte* iv, word32 ivSz,
11461
                   byte* authTag, word32 authTagSz,
11462
                   const byte* authIn, word32 authInSz)
11463
527
{
11464
527
    int ret;
11465
11466
    /* argument checks */
11467
    /* If sz is non-zero, both in and out must be set; if sz is 0, in and
11468
     * out are don't cares (GMAC case), matching wc_AesGcmDecrypt. */
11469
527
    if (aes == NULL || iv == NULL || ivSz == 0 ||
11470
527
        (sz != 0 && (in == NULL || out == NULL)) ||
11471
527
        authTag == NULL ||
11472
527
        ((authInSz > 0) && (authIn == NULL)))
11473
0
    {
11474
0
        return BAD_FUNC_ARG;
11475
0
    }
11476
11477
527
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
11478
527
    if (ret != 0)
11479
0
        return ret;
11480
11481
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
11482
    if (ivSz < GCM_NONCE_MID_SZ)
11483
        return FIPS_BAD_VALUE_E;
11484
#endif
11485
11486
527
#ifdef WOLF_CRYPTO_CB
11487
527
    #ifndef WOLF_CRYPTO_CB_FIND
11488
527
    if (aes->devId != INVALID_DEVID)
11489
0
    #endif
11490
0
    {
11491
0
        int crypto_cb_ret =
11492
0
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
11493
0
                                      authTagSz, authIn, authInSz);
11494
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11495
0
            return crypto_cb_ret;
11496
        /* fall-through when unavailable */
11497
0
    }
11498
527
#endif
11499
11500
    /* Software/HW key schedule (and hash subkey H) required from here on. */
11501
527
    if (!WC_AES_KEY_IS_SET(aes)) {
11502
0
        WOLFSSL_MSG("AES key not set");
11503
0
        return MISSING_KEY;
11504
0
    }
11505
11506
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
11507
    /* if async and byte count above threshold */
11508
    /* only 12-byte IV is supported in HW */
11509
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
11510
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
11511
    #if defined(HAVE_CAVIUM)
11512
        #ifdef HAVE_CAVIUM_V
11513
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
11514
            return NitroxAesGcmEncrypt(aes, out, in, sz,
11515
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
11516
                authTag, authTagSz, authIn, authInSz);
11517
        }
11518
        #endif
11519
    #elif defined(HAVE_INTEL_QA)
11520
        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
11521
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
11522
            authTag, authTagSz, authIn, authInSz);
11523
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
11524
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
11525
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
11526
            sw->aes.aes = aes;
11527
            sw->aes.out = out;
11528
            sw->aes.in = in;
11529
            sw->aes.sz = sz;
11530
            sw->aes.iv = iv;
11531
            sw->aes.ivSz = ivSz;
11532
            sw->aes.authTag = authTag;
11533
            sw->aes.authTagSz = authTagSz;
11534
            sw->aes.authIn = authIn;
11535
            sw->aes.authInSz = authInSz;
11536
            return WC_PENDING_E;
11537
        }
11538
    #endif
11539
    }
11540
#endif /* WOLFSSL_ASYNC_CRYPT */
11541
11542
#ifdef WOLFSSL_SILABS_SE_ACCEL
11543
    return wc_AesGcmEncrypt_silabs(
11544
        aes, out, in, sz,
11545
        iv, ivSz,
11546
        authTag, authTagSz,
11547
        authIn, authInSz);
11548
#endif
11549
11550
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
11551
#ifndef TA_AES_GCM_MAX_DATA_SIZE
11552
    #define TA_AES_GCM_MAX_DATA_SIZE 996u
11553
#endif
11554
    if (aes != NULL &&
11555
        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
11556
        ivSz == TA_AES_GCM_IV_LENGTH &&
11557
        authTagSz == TA_AES_GCM_TAG_LENGTH &&
11558
        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
11559
        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
11560
        return wc_Microchip_AesGcmEncrypt(
11561
            aes, out, in, sz,
11562
            iv, ivSz,
11563
            authTag, authTagSz,
11564
            authIn, authInSz);
11565
    }
11566
#endif
11567
11568
/* Not under WOLF_CRYPTO_CB_ONLY_AES: that mode leaves aes->key empty (the key
11569
 * lives in aes->devKey), so the HW GCM must be reached through the STM32
11570
 * crypto-callback device, which stages the key first. */
11571
#if defined(WOLFSSL_STM32_BARE) && defined(STM32_CRYPTO) && \
11572
    !defined(WOLF_CRYPTO_CB_ONLY_AES)
11573
    ret = wc_Stm32_Aes_Gcm(aes, out, in, sz, iv, ivSz,
11574
                           authTag, authTagSz,
11575
                           authIn, authInSz, 1 /* enc */);
11576
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11577
        return ret;
11578
    /* fall through to SW GCM (still uses HW AES via wc_AesEncrypt) */
11579
#endif /* WOLFSSL_STM32_BARE && STM32_CRYPTO && !WOLF_CRYPTO_CB_ONLY_AES */
11580
11581
11582
#ifdef STM32_CRYPTO_AES_GCM
11583
    return wc_AesGcmEncrypt_STM32(
11584
        aes, out, in, sz, iv, ivSz,
11585
        authTag, authTagSz, authIn, authInSz);
11586
#endif /* STM32_CRYPTO_AES_GCM */
11587
11588
#if defined(WOLFSSL_PSOC6_CRYPTO)
11589
    return wc_Psoc6_Aes_GcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
11590
                                   authTagSz, authIn, authInSz);
11591
#endif /* WOLFSSL_PSOC6_CRYPTO */
11592
11593
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) || \
11594
    defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
11595
    AES_GCM_encrypt_RISCV64(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
11596
        authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
11597
        (int)aes->rounds);
11598
    return 0;
11599
#elif defined(WOLFSSL_RISCV_ASM)
11600
    AES_GCM_encrypt_RISCV64(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
11601
        authInSz, (byte*)aes->key, AES_GCM_H_PTR(aes), (byte*)aes->tmp,
11602
        (byte*)aes->reg, (int)aes->rounds);
11603
    return 0;
11604
#endif
11605
11606
527
    VECTOR_REGISTERS_PUSH;
11607
11608
#if defined(WOLFSSL_ARMASM)
11609
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
11610
#if !defined(__aarch64__)
11611
  #ifdef WOLFSSL_ARM32_AES_DISPATCH
11612
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11613
        /* Reflect a copy of H into the form the PMULL assembly wants - the
11614
         * stored H must stay un-reflected for the portable GHASH. */
11615
        byte h[WC_AES_BLOCK_SIZE];
11616
11617
        XMEMCPY(h, aes->gcm.H, WC_AES_BLOCK_SIZE);
11618
        GcmReflectH(h);
11619
        AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
11620
            authIn, authInSz, (byte*)aes->key, h, (byte*)aes->tmp,
11621
            (byte*)aes->reg, aes->rounds);
11622
        ForceZero(h, sizeof(h));
11623
        ret = 0;
11624
    }
11625
    else
11626
  #else
11627
    {
11628
        /* Reflect a copy of H into the form the PMULL assembly wants - the
11629
         * stored H must stay un-reflected for the portable GHASH. */
11630
        byte h[WC_AES_BLOCK_SIZE];
11631
11632
        XMEMCPY(h, aes->gcm.H, WC_AES_BLOCK_SIZE);
11633
        GcmReflectH(h);
11634
        AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
11635
            authIn, authInSz, (byte*)aes->key, h, (byte*)aes->tmp,
11636
            (byte*)aes->reg, aes->rounds);
11637
        ForceZero(h, sizeof(h));
11638
    }
11639
    ret = 0;
11640
  #endif /* WOLFSSL_ARM32_AES_DISPATCH */
11641
#else
11642
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11643
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11644
        if (aes->use_sha3_hw_crypto) {
11645
            AES_GCM_encrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
11646
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11647
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
11648
        }
11649
        else
11650
    #endif
11651
        {
11652
            AES_GCM_encrypt_AARCH64(in, out, sz, iv, ivSz, authTag, authTagSz,
11653
                authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
11654
                (byte*)aes->reg, aes->rounds);
11655
        }
11656
        ret = 0;
11657
    }
11658
    else
11659
#endif /* !__aarch64__ */
11660
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
11661
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
11662
    defined(WOLFSSL_ARM32_AES_DISPATCH)
11663
    {
11664
        ret = AES_GCM_encrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
11665
            authTagSz, authIn, authInSz);
11666
    }
11667
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO ||
11668
        * WOLFSSL_ARM32_AES_DISPATCH */
11669
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11670
    ret = AES_GCM_encrypt_ASM(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11671
        authIn, authInSz);
11672
#else
11673
#ifdef WOLFSSL_AESNI
11674
    if (aes->use_aesni) {
11675
#ifdef HAVE_INTEL_AVX512
11676
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11677
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11678
            AES_GCM_encrypt_avx512(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11679
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11680
            ret = 0;
11681
        }
11682
        else
11683
#endif
11684
#ifdef HAVE_INTEL_VAES
11685
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11686
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11687
            AES_GCM_encrypt_vaes(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11688
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11689
            ret = 0;
11690
        }
11691
        else
11692
#endif
11693
#ifdef HAVE_INTEL_AVX2
11694
        if (IS_INTEL_AVX2(intel_flags)) {
11695
            AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11696
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11697
            ret = 0;
11698
        }
11699
        else
11700
#endif
11701
#if defined(HAVE_INTEL_AVX1)
11702
        if (IS_INTEL_AVX1(intel_flags)) {
11703
            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11704
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11705
            ret = 0;
11706
        } else
11707
#endif
11708
        {
11709
            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11710
                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
11711
            ret = 0;
11712
        }
11713
    }
11714
    else
11715
#endif /* WOLFSSL_AESNI */
11716
527
    {
11717
527
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11718
527
                                authIn, authInSz);
11719
527
    }
11720
527
#endif
11721
11722
527
    VECTOR_REGISTERS_POP;
11723
11724
527
    return ret;
11725
527
}
11726
#endif
11727
11728
11729
/* AES GCM Decrypt */
11730
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
11731
#ifdef FREESCALE_LTC_AES_GCM
11732
int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
11733
                   const byte* iv, word32 ivSz,
11734
                   const byte* authTag, word32 authTagSz,
11735
                   const byte* authIn, word32 authInSz)
11736
{
11737
    int ret;
11738
    word32 keySize;
11739
    status_t status;
11740
11741
    /* argument checks */
11742
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
11743
     * in and out are don't cares, as this is is the GMAC case. */
11744
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
11745
        authTag == NULL || ivSz == 0 ||
11746
        ((authInSz > 0) && (authIn == NULL)))
11747
    {
11748
        return BAD_FUNC_ARG;
11749
    }
11750
11751
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
11752
    if (ret != 0)
11753
        return ret;
11754
11755
    ret = wc_AesGetKeySize(aes, &keySize);
11756
    if (ret != 0) {
11757
        return ret;
11758
    }
11759
11760
    status = wolfSSL_CryptHwMutexLock();
11761
    if (status != 0)
11762
        return status;
11763
11764
    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
11765
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
11766
    wolfSSL_CryptHwMutexUnLock();
11767
11768
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
11769
}
11770
11771
#else
11772
11773
#ifdef STM32_CRYPTO_AES_GCM
11774
/* this function supports inline decrypt */
11775
/* Not static: called by the CubeMX crypto-callback device (see encrypt). */
11776
WOLFSSL_LOCAL WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
11777
                                  Aes* aes, byte* out,
11778
                                  const byte* in, word32 sz,
11779
                                  const byte* iv, word32 ivSz,
11780
                                  const byte* authTag, word32 authTagSz,
11781
                                  const byte* authIn, word32 authInSz)
11782
{
11783
    int ret;
11784
#ifdef WOLFSSL_STM32_CUBEMX
11785
    int status = HAL_OK;
11786
    CRYP_HandleTypeDef hcryp;
11787
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
11788
#else
11789
    int status = SUCCESS;
11790
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
11791
#endif
11792
    word32 keySize;
11793
    word32 partial = sz % WC_AES_BLOCK_SIZE;
11794
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
11795
    word32 tagExpected[WC_AES_BLOCK_SIZE/sizeof(word32)];
11796
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
11797
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
11798
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
11799
    byte* authInPadded = NULL;
11800
    word32 authPadSz;
11801
    int wasAlloc = 0, tagComputed = 0;
11802
11803
    ret = wc_AesGetKeySize(aes, &keySize);
11804
    if (ret != 0)
11805
        return ret;
11806
11807
#ifdef WOLFSSL_STM32_CUBEMX
11808
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
11809
    if (ret != 0)
11810
        return ret;
11811
#endif
11812
11813
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
11814
    if (ivSz == GCM_NONCE_MID_SZ) {
11815
        byte* pCtr = (byte*)ctr;
11816
        XMEMCPY(ctr, iv, ivSz);
11817
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
11818
    }
11819
    else {
11820
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
11821
    }
11822
11823
    /* Make copy of expected authTag, which could get corrupted in some
11824
     * Cube HAL versions without proper partial block support.
11825
     * For TLS blocks the authTag is after the output buffer, so save it */
11826
    XMEMCPY(tagExpected, authTag, authTagSz);
11827
11828
    /* Authentication buffer */
11829
#if STM_CRYPT_HEADER_WIDTH == 1
11830
    authPadSz = 0; /* CubeHAL supports byte mode */
11831
#else
11832
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
11833
#endif
11834
#ifdef WOLFSSL_STM32MP13
11835
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
11836
     * minimum of 16 bytes for the auth */
11837
    if ((authInSz > 0) && (authInSz < 16)) {
11838
        authPadSz = 16 - authInSz;
11839
    }
11840
#else
11841
    if (authPadSz != 0) {
11842
        authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
11843
    }
11844
    else {
11845
        authPadSz = authInSz;
11846
    }
11847
#endif
11848
11849
    /* for cases where hardware cannot be used for authTag calculate it */
11850
    /* if IV is not 12 calculate GHASH using software */
11851
    if (ivSz != GCM_NONCE_MID_SZ
11852
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
11853
        /* or hardware that does not support partial block */
11854
        || sz == 0 || partial != 0
11855
    #endif
11856
    #if STM_CRYPT_HEADER_WIDTH == 4
11857
        /* or authIn is not a multiple of 4  */
11858
        || authPadSz != authInSz
11859
    #endif
11860
    ) {
11861
        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
11862
        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
11863
        if (ret != 0) {
11864
            wc_Stm32_Aes_Cleanup();
11865
            return ret;
11866
        }
11867
        xorbuf(tag, partialBlock, sizeof(tag));
11868
        tagComputed = 1;
11869
    }
11870
11871
    /* Zero pad and word align the buffer the HAL reads the auth header
11872
     * from (SA0076). authPadSz, the length reported to the HAL, is
11873
     * unchanged, so the hardware tag is unaffected.
11874
     * This must NOT be gated on !tagComputed. tagComputed only selects
11875
     * who produces the tag; hcryp.Init.Header and HeaderSize are still
11876
     * handed to the HAL below and are still read during the header phase
11877
     * of the payload call, which the HAL runs whether or not we later ask
11878
     * it for the tag. The over read happens on the software tag path too. */
11879
    ret = wc_AesGcmAuthPad_STM32(aes, authIn, authInSz, authPadSz,
11880
        authhdr, (word32)sizeof(authhdr), &authInPadded, &wasAlloc);
11881
    if (ret != 0) {
11882
        wc_Stm32_Aes_Cleanup();
11883
        return ret;
11884
    }
11885
11886
    /* Hardware requires counter + 1 */
11887
    IncrementGcmCounter((byte*)ctr);
11888
11889
    ret = wolfSSL_CryptHwMutexLock();
11890
    if (ret != 0) {
11891
        if (wasAlloc) {
11892
            XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11893
        }
11894
        wc_Stm32_Aes_Cleanup();
11895
        return ret;
11896
    }
11897
11898
#ifdef WOLFSSL_STM32_CUBEMX
11899
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11900
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
11901
11902
#if defined(STM32_HAL_V2)
11903
    hcryp.Init.Algorithm = CRYP_AES_GCM;
11904
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
11905
    #ifdef CRYP_KEYIVCONFIG_ONCE
11906
    /* allows repeated calls to HAL_CRYP_Decrypt */
11907
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
11908
    #endif
11909
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
11910
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11911
    HAL_CRYP_Init(&hcryp);
11912
11913
    #ifndef CRYP_KEYIVCONFIG_ONCE
11914
    /* GCM payload phase - can handle partial blocks */
11915
    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
11916
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
11917
    #else
11918
    /* GCM payload phase - blocks */
11919
    if (blocks) {
11920
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
11921
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
11922
    }
11923
    /* GCM payload phase - partial remainder */
11924
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11925
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11926
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11927
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
11928
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
11929
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11930
    }
11931
    #endif
11932
    if (status == HAL_OK && !tagComputed) {
11933
        /* Compute the authTag */
11934
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
11935
            STM32_HAL_TIMEOUT);
11936
    }
11937
#elif defined(STM32_CRYPTO_AES_ONLY)
11938
    /* Set the CRYP parameters */
11939
    hcryp.Init.HeaderSize = authPadSz;
11940
    if (authPadSz == 0)
11941
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
11942
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
11943
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
11944
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
11945
    HAL_CRYP_Init(&hcryp);
11946
11947
    /* GCM init phase */
11948
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11949
    if (status == HAL_OK) {
11950
        /* GCM header phase */
11951
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
11952
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11953
    }
11954
    if (status == HAL_OK) {
11955
        /* GCM payload phase - blocks */
11956
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
11957
        if (blocks) {
11958
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
11959
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11960
        }
11961
    }
11962
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
11963
        /* GCM payload phase - partial remainder */
11964
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11965
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11966
        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
11967
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
11968
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11969
    }
11970
    if (status == HAL_OK && tagComputed == 0) {
11971
        /* GCM final phase */
11972
        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
11973
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
11974
    }
11975
#else
11976
    hcryp.Init.HeaderSize = authPadSz;
11977
    HAL_CRYP_Init(&hcryp);
11978
    if (blocks) {
11979
        /* GCM payload phase - blocks */
11980
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
11981
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11982
    }
11983
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11984
        /* GCM payload phase - partial remainder */
11985
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11986
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11987
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
11988
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
11989
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11990
    }
11991
    if (status == HAL_OK && tagComputed == 0) {
11992
        /* Compute the authTag */
11993
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
11994
    }
11995
#endif
11996
11997
    if (status != HAL_OK)
11998
        ret = AES_GCM_AUTH_E;
11999
12000
    HAL_CRYP_DeInit(&hcryp);
12001
12002
#else /* Standard Peripheral Library */
12003
    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
12004
12005
    /* Input size and auth size need to be the actual sizes, even though
12006
     * they are not block aligned, because this length (in bits) is used
12007
     * in the final GHASH. */
12008
    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
12009
    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
12010
                         (uint8_t*)keyCopy,      keySize * 8,
12011
                         (uint8_t*)in,           sz,
12012
                         (uint8_t*)authInPadded, authInSz,
12013
                         (uint8_t*)out,          (uint8_t*)partialBlock);
12014
    if (status != SUCCESS)
12015
        ret = AES_GCM_AUTH_E;
12016
    if (tagComputed == 0)
12017
        XMEMCPY(tag, partialBlock, authTagSz);
12018
#endif /* WOLFSSL_STM32_CUBEMX */
12019
    wolfSSL_CryptHwMutexUnLock();
12020
    wc_Stm32_Aes_Cleanup();
12021
12022
    /* Check authentication tag */
12023
    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
12024
        ret = AES_GCM_AUTH_E;
12025
    }
12026
12027
    /* Free memory */
12028
    if (wasAlloc) {
12029
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
12030
    }
12031
12032
    return ret;
12033
}
12034
12035
#endif /* STM32_CRYPTO_AES_GCM */
12036
12037
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
12038
#ifdef WOLFSSL_AESNI
12039
/* For performance reasons, this code needs to be not inlined. */
12040
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
12041
                      Aes* aes, byte* out, const byte* in, word32 sz,
12042
                      const byte* iv, word32 ivSz,
12043
                      const byte* authTag, word32 authTagSz,
12044
                      const byte* authIn, word32 authInSz);
12045
#else
12046
static
12047
#endif
12048
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
12049
                      Aes* aes, byte* out, const byte* in, word32 sz,
12050
                      const byte* iv, word32 ivSz,
12051
                      const byte* authTag, word32 authTagSz,
12052
                      const byte* authIn, word32 authInSz)
12053
0
{
12054
0
    int ret;
12055
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
12056
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
12057
0
    const byte* c = in;
12058
0
    byte* p = out;
12059
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
12060
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
12061
0
    ALIGN16 byte Tprime[WC_AES_BLOCK_SIZE];
12062
0
    ALIGN16 byte EKY0[WC_AES_BLOCK_SIZE];
12063
0
    volatile sword32 res;
12064
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
12065
0
    byte mask;
12066
0
    word32 i;
12067
0
#endif
12068
12069
0
    if (ivSz == GCM_NONCE_MID_SZ) {
12070
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
12071
0
        XMEMCPY(counter, iv, ivSz);
12072
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
12073
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
12074
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
12075
0
    }
12076
0
    else {
12077
        /* Counter is GHASH of IV. */
12078
#ifdef OPENSSL_EXTRA
12079
        word32 aadTemp = aes->gcm.aadLen;
12080
        aes->gcm.aadLen = 0;
12081
#endif
12082
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
12083
#ifdef OPENSSL_EXTRA
12084
        aes->gcm.aadLen = aadTemp;
12085
#endif
12086
0
    }
12087
12088
    /* Calc the authTag again using received auth data and the cipher text */
12089
0
    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
12090
0
    ret = wc_AesEncrypt(aes, counter, EKY0);
12091
0
    if (ret != 0)
12092
0
        return ret;
12093
0
    xorbuf(Tprime, EKY0, sizeof(Tprime));
12094
#ifdef WC_AES_GCM_DEC_AUTH_EARLY
12095
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
12096
     * the pairwise bytes in the strings.
12097
     */
12098
    res = ConstantCompare(authTag, Tprime, authTagSz);
12099
    /* convert positive retval from ConstantCompare() to all-1s word, in
12100
     * constant time.
12101
     */
12102
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
12103
    ret = res & AES_GCM_AUTH_E;
12104
    if (ret != 0)
12105
        return ret;
12106
#endif
12107
12108
#ifdef OPENSSL_EXTRA
12109
    if (!out) {
12110
        /* authenticated, non-confidential data */
12111
        /* store AAD size for next call */
12112
        aes->gcm.aadLen = authInSz;
12113
    }
12114
#endif
12115
12116
#if defined(WOLFSSL_PIC32MZ_CRYPT)
12117
    if (blocks) {
12118
        /* use initial IV for HW, but don't use it below */
12119
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
12120
12121
        ret = wc_Pic32AesCrypt(
12122
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
12123
            out, in, (blocks * WC_AES_BLOCK_SIZE),
12124
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
12125
        if (ret != 0)
12126
            return ret;
12127
    }
12128
    /* process remainder using partial handling */
12129
#endif
12130
12131
0
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
12132
    /* some hardware acceleration can gain performance from doing AES encryption
12133
     * of the whole buffer at once */
12134
0
    if (c != p && blocks > 0) { /* can not handle inline decryption */
12135
0
        while (blocks--) {
12136
0
            IncrementGcmCounter(counter);
12137
0
            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
12138
0
            p += WC_AES_BLOCK_SIZE;
12139
0
        }
12140
12141
        /* reset number of blocks and then do encryption */
12142
0
        blocks = sz / WC_AES_BLOCK_SIZE;
12143
12144
0
        ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
12145
0
        if (ret != 0) {
12146
0
            ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
12147
0
            return ret;
12148
0
        }
12149
0
        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
12150
0
        c += WC_AES_BLOCK_SIZE * blocks;
12151
0
    }
12152
0
    else
12153
0
#endif /* HAVE_AES_ECB && !PIC32MZ */
12154
0
    {
12155
0
        while (blocks--) {
12156
0
            IncrementGcmCounter(counter);
12157
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
12158
0
            ret = wc_AesEncrypt(aes, counter, scratch);
12159
0
            if (ret != 0)
12160
0
                return ret;
12161
0
            xorbufout(p, scratch, c, WC_AES_BLOCK_SIZE);
12162
0
        #endif
12163
0
            p += WC_AES_BLOCK_SIZE;
12164
0
            c += WC_AES_BLOCK_SIZE;
12165
0
        }
12166
0
    }
12167
12168
0
    if (partial != 0) {
12169
0
        IncrementGcmCounter(counter);
12170
0
        ret = wc_AesEncrypt(aes, counter, scratch);
12171
0
        if (ret != 0)
12172
0
            return ret;
12173
0
        xorbuf(scratch, c, partial);
12174
0
        XMEMCPY(p, scratch, partial);
12175
0
    }
12176
12177
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
12178
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
12179
     * the pairwise bytes in the strings.
12180
     */
12181
0
    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
12182
    /* convert positive retval from ConstantCompare() to all-1s word, in
12183
     * constant time.
12184
     */
12185
0
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
12186
    /* now use res as a mask for constant time return of ret, unless tag
12187
     * mismatch, whereupon AES_GCM_AUTH_E is returned.
12188
     */
12189
0
    ret = (ret & ~res);
12190
0
    ret |= (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
12191
    /* Mask the output on auth failure instead of branching, to keep the tag
12192
     * compare constant time. res is all-ones on mismatch, zero on match. A
12193
     * single vectorizable pass is cheaper than folding the mask into the
12194
     * decrypt loop. Not needed for WC_AES_GCM_DEC_AUTH_EARLY: there the tag is
12195
     * checked before decryption, so out is never written on a mismatch. */
12196
0
    mask = (byte)res;
12197
0
    for (i = 0; i < sz; i++) {
12198
0
        out[i] &= (byte)~mask;
12199
0
    }
12200
0
#endif
12201
0
    return ret;
12202
0
}
12203
#elif (defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
12204
      defined(WOLFSSL_ARM32_AES_DISPATCH) || \
12205
      (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
12206
static int AES_GCM_decrypt_ASM(Aes* aes, byte* out, const byte* in,
12207
    word32 sz, const byte* iv, word32 ivSz, const byte* authTag,
12208
    word32 authTagSz, const byte* authIn, word32 authInSz)
12209
{
12210
    word32 blocks;
12211
    word32 partial;
12212
    byte counter[WC_AES_BLOCK_SIZE];
12213
    byte initialCounter[WC_AES_BLOCK_SIZE];
12214
    byte scratch[WC_AES_BLOCK_SIZE];
12215
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
12216
12217
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
12218
    if (ivSz == GCM_NONCE_MID_SZ) {
12219
        XMEMCPY(initialCounter, iv, ivSz);
12220
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
12221
    }
12222
    else {
12223
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
12224
    }
12225
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
12226
12227
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
12228
    /* Hash in the Additional Authentication Data */
12229
    if (authInSz != 0 && authIn != NULL) {
12230
        blocks = authInSz / WC_AES_BLOCK_SIZE;
12231
        partial = authInSz % WC_AES_BLOCK_SIZE;
12232
        if (blocks > 0) {
12233
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
12234
            authIn += blocks * WC_AES_BLOCK_SIZE;
12235
        }
12236
        if (partial != 0) {
12237
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
12238
            XMEMCPY(scratch, authIn, partial);
12239
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
12240
        }
12241
    }
12242
12243
    blocks = sz / WC_AES_BLOCK_SIZE;
12244
    partial = sz % WC_AES_BLOCK_SIZE;
12245
    /* do as many blocks as possible */
12246
    if (blocks > 0) {
12247
        GCM_GMULT_LEN(&aes->gcm, x, in, blocks * WC_AES_BLOCK_SIZE);
12248
12249
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
12250
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
12251
        if (sz >= 32)
12252
    #endif
12253
        {
12254
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
12255
                (const unsigned char*)aes->key, aes->rounds, counter);
12256
        }
12257
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
12258
        else
12259
    #endif
12260
    #endif
12261
    /* Base AES is only left out on AArch64 - see wc_AesCbcDecrypt. */
12262
    #if !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP) || !defined(__aarch64__)
12263
        {
12264
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
12265
                (const unsigned char*)aes->key, aes->rounds, counter);
12266
        }
12267
    #endif
12268
        in += blocks * WC_AES_BLOCK_SIZE;
12269
        out += blocks * WC_AES_BLOCK_SIZE;
12270
    }
12271
    if (partial != 0) {
12272
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
12273
        XMEMCPY(scratch, in, partial);
12274
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
12275
12276
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
12277
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
12278
        {
12279
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
12280
                (const unsigned char*)aes->key, aes->rounds, counter);
12281
        }
12282
    #else
12283
        {
12284
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
12285
                (const unsigned char*)aes->key, aes->rounds, counter);
12286
        }
12287
    #endif
12288
        XMEMCPY(out, scratch, partial);
12289
    }
12290
12291
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
12292
    FlattenSzInBits(&scratch[0], authInSz);
12293
    FlattenSzInBits(&scratch[8], sz);
12294
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
12295
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
12296
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
12297
    {
12298
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
12299
            (const unsigned char*)aes->key, aes->rounds);
12300
    }
12301
#else
12302
    {
12303
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
12304
            (const unsigned char*)aes->key, aes->rounds);
12305
    }
12306
#endif
12307
    xorbuf(x, scratch, authTagSz);
12308
    if (authTag != NULL) {
12309
        if (ConstantCompare(authTag, x, authTagSz) != 0) {
12310
            return AES_GCM_AUTH_E;
12311
        }
12312
    }
12313
12314
    return 0;
12315
}
12316
#endif
12317
12318
/* Software AES - GCM Decrypt */
12319
int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
12320
                     const byte* iv, word32 ivSz,
12321
                     const byte* authTag, word32 authTagSz,
12322
                     const byte* authIn, word32 authInSz)
12323
87
{
12324
87
    int ret;
12325
#ifdef WOLFSSL_AESNI
12326
    int res = WC_NO_ERR_TRACE(AES_GCM_AUTH_E);
12327
#endif
12328
12329
    /* argument checks */
12330
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
12331
     * in and out are don't cares, as this is is the GMAC case. */
12332
87
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
12333
87
        authTag == NULL || ivSz == 0)
12334
0
    {
12335
0
        return BAD_FUNC_ARG;
12336
0
    }
12337
12338
87
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
12339
87
    if (ret != 0)
12340
0
        return ret;
12341
12342
    /* No FIPS check on ivSz in decrypt mode -- SP 800-38D IV
12343
     * construction requirements bind encryption only; decryption must
12344
     * accept externally generated IVs of any supported length.
12345
     */
12346
12347
87
#ifdef WOLF_CRYPTO_CB
12348
87
    #ifndef WOLF_CRYPTO_CB_FIND
12349
87
    if (aes->devId != INVALID_DEVID)
12350
0
    #endif
12351
0
    {
12352
0
        int crypto_cb_ret =
12353
0
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
12354
0
                                      authTag, authTagSz, authIn, authInSz);
12355
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
12356
0
            return crypto_cb_ret;
12357
        /* fall-through when unavailable */
12358
0
    }
12359
87
#endif
12360
12361
    /* Software/HW key schedule (and hash subkey H) required from here on. */
12362
87
    if (!WC_AES_KEY_IS_SET(aes)) {
12363
0
        WOLFSSL_MSG("AES key not set");
12364
0
        return MISSING_KEY;
12365
0
    }
12366
12367
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
12368
    /* if async and byte count above threshold */
12369
    /* only 12-byte IV is supported in HW */
12370
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
12371
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
12372
    #if defined(HAVE_CAVIUM)
12373
        #ifdef HAVE_CAVIUM_V
12374
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
12375
            return NitroxAesGcmDecrypt(aes, out, in, sz,
12376
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
12377
                authTag, authTagSz, authIn, authInSz);
12378
        }
12379
        #endif
12380
    #elif defined(HAVE_INTEL_QA)
12381
        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
12382
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
12383
            authTag, authTagSz, authIn, authInSz);
12384
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
12385
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
12386
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
12387
            sw->aes.aes = aes;
12388
            sw->aes.out = out;
12389
            sw->aes.in = in;
12390
            sw->aes.sz = sz;
12391
            sw->aes.iv = iv;
12392
            sw->aes.ivSz = ivSz;
12393
            sw->aes.authTag = (byte*)authTag;
12394
            sw->aes.authTagSz = authTagSz;
12395
            sw->aes.authIn = authIn;
12396
            sw->aes.authInSz = authInSz;
12397
            return WC_PENDING_E;
12398
        }
12399
    #endif
12400
    }
12401
#endif /* WOLFSSL_ASYNC_CRYPT */
12402
12403
#ifdef WOLFSSL_SILABS_SE_ACCEL
12404
    return wc_AesGcmDecrypt_silabs(
12405
        aes, out, in, sz, iv, ivSz,
12406
        authTag, authTagSz, authIn, authInSz);
12407
12408
#endif
12409
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
12410
#ifndef TA_AES_GCM_MAX_DATA_SIZE
12411
    #define TA_AES_GCM_MAX_DATA_SIZE 996u
12412
#endif
12413
    if (aes != NULL &&
12414
        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
12415
        ivSz == TA_AES_GCM_IV_LENGTH &&
12416
        authTagSz == TA_AES_GCM_TAG_LENGTH &&
12417
        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
12418
        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
12419
        return wc_Microchip_AesGcmDecrypt(
12420
            aes, out, in, sz, iv, ivSz,
12421
            authTag, authTagSz, authIn, authInSz);
12422
    }
12423
#endif
12424
12425
#if defined(WOLFSSL_STM32_BARE) && defined(STM32_CRYPTO) && \
12426
    !defined(WOLF_CRYPTO_CB_ONLY_AES)
12427
    /* BARE: HW GCM decrypt-verify on both AES IPs -- the TinyAES GCM engine
12428
     * (H5/U5/L5/U3/WBA/...) and the CRYP IP (F2/F4/F7/H7/MP13), the latter
12429
     * validated on NUCLEO-F439ZI against the SP 800-38D vectors;
12430
     * otherwise wc_Stm32_Aes_Gcm returns CRYPTOCB_UNAVAILABLE and the well-tested
12431
     * SW path runs (its AES blocks still on HW via wc_AesEncrypt). The received
12432
     * tag is verified inside wc_Stm32_Aes_Gcm (const cast: it compares, never
12433
     * writes, on the decrypt path). Excluded under WOLF_CRYPTO_CB_ONLY_AES for
12434
     * the same reason as the encrypt path above -- the key is only in
12435
     * aes->devKey there, so HW GCM must go through the crypto-cb device. */
12436
    ret = wc_Stm32_Aes_Gcm(aes, out, in, sz, iv, ivSz,
12437
                           (byte*)authTag, authTagSz,
12438
                           authIn, authInSz, 0 /* dec */);
12439
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
12440
        return ret;
12441
    /* fall through to SW GCM decrypt */
12442
#endif /* WOLFSSL_STM32_BARE && STM32_CRYPTO && !WOLF_CRYPTO_CB_ONLY_AES */
12443
12444
#ifdef STM32_CRYPTO_AES_GCM
12445
    /* The STM standard peripheral library API's doesn't support partial blocks */
12446
    return wc_AesGcmDecrypt_STM32(
12447
        aes, out, in, sz, iv, ivSz,
12448
        authTag, authTagSz, authIn, authInSz);
12449
#endif /* STM32_CRYPTO_AES_GCM */
12450
12451
#if defined(WOLFSSL_PSOC6_CRYPTO)
12452
    return wc_Psoc6_Aes_GcmDecrypt(aes, out, in, sz, iv, ivSz, authTag,
12453
                                   authTagSz, authIn, authInSz);
12454
#endif /* WOLFSSL_PSOC6_CRYPTO */
12455
12456
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) || \
12457
    defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
12458
    return AES_GCM_decrypt_RISCV64((byte*)in, out, sz, iv, ivSz, authTag,
12459
        authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
12460
        (byte*)aes->tmp, (byte*)aes->reg, (int)aes->rounds);
12461
#elif defined(WOLFSSL_RISCV_ASM)
12462
    return AES_GCM_decrypt_RISCV64((byte*)in, out, sz, iv, ivSz, authTag,
12463
        authTagSz, authIn, authInSz, (byte*)aes->key, AES_GCM_H_PTR(aes),
12464
        (byte*)aes->tmp, (byte*)aes->reg, (int)aes->rounds);
12465
#endif
12466
12467
87
    VECTOR_REGISTERS_PUSH;
12468
12469
#if defined(WOLFSSL_ARMASM)
12470
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
12471
#ifndef __aarch64__
12472
  #ifdef WOLFSSL_ARM32_AES_DISPATCH
12473
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto)
12474
  #endif
12475
    {
12476
    #ifdef OPENSSL_EXTRA
12477
        word32 reg[WC_AES_BLOCK_SIZE / sizeof(word32)];
12478
    #endif
12479
        /* Reflect a copy of H into the form the PMULL assembly wants - the
12480
         * stored H must stay un-reflected for the portable GHASH. */
12481
        byte h[WC_AES_BLOCK_SIZE];
12482
12483
    #ifdef OPENSSL_EXTRA
12484
        XMEMCPY(reg, aes->reg, sizeof(reg));
12485
    #endif
12486
        XMEMCPY(h, aes->gcm.H, WC_AES_BLOCK_SIZE);
12487
        GcmReflectH(h);
12488
        ret = AES_GCM_decrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
12489
            authIn, authInSz, (byte*)aes->key, h, (byte*)aes->tmp,
12490
            (byte*)aes->reg, aes->rounds);
12491
        ForceZero(h, sizeof(h));
12492
    #ifdef OPENSSL_EXTRA
12493
        XMEMCPY(aes->reg, reg, sizeof(reg));
12494
    #endif
12495
    }
12496
  #ifdef WOLFSSL_ARM32_AES_DISPATCH
12497
    else
12498
  #endif
12499
#else
12500
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12501
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12502
        if (aes->use_sha3_hw_crypto) {
12503
            ret = AES_GCM_decrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
12504
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
12505
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
12506
        }
12507
        else
12508
    #endif
12509
        {
12510
            ret = AES_GCM_decrypt_AARCH64(in, out, sz, iv, ivSz, authTag,
12511
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
12512
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
12513
        }
12514
    }
12515
    else
12516
#endif /* !__aarch64__ */
12517
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
12518
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
12519
    defined(WOLFSSL_ARM32_AES_DISPATCH)
12520
    {
12521
        ret = AES_GCM_decrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
12522
            authTagSz, authIn, authInSz);
12523
    }
12524
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO ||
12525
        * WOLFSSL_ARM32_AES_DISPATCH */
12526
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
12527
    {
12528
        ret = AES_GCM_decrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
12529
            authTagSz, authIn, authInSz);
12530
    }
12531
#else
12532
#ifdef WOLFSSL_AESNI
12533
    if (aes->use_aesni) {
12534
#ifdef HAVE_INTEL_AVX512
12535
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
12536
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12537
            AES_GCM_decrypt_avx512(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12538
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12539
            if (res == 0)
12540
                ret = AES_GCM_AUTH_E;
12541
            else
12542
                ret = 0;
12543
        }
12544
        else
12545
#endif
12546
#ifdef HAVE_INTEL_VAES
12547
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
12548
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12549
            AES_GCM_decrypt_vaes(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12550
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12551
            if (res == 0)
12552
                ret = AES_GCM_AUTH_E;
12553
            else
12554
                ret = 0;
12555
        }
12556
        else
12557
#endif
12558
#ifdef HAVE_INTEL_AVX2
12559
        if (IS_INTEL_AVX2(intel_flags)) {
12560
            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12561
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12562
            if (res == 0)
12563
                ret = AES_GCM_AUTH_E;
12564
            else
12565
                ret = 0;
12566
        }
12567
        else
12568
#endif
12569
#if defined(HAVE_INTEL_AVX1)
12570
        if (IS_INTEL_AVX1(intel_flags)) {
12571
            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12572
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12573
            if (res == 0)
12574
                ret = AES_GCM_AUTH_E;
12575
            else
12576
                ret = 0;
12577
        }
12578
        else
12579
#endif
12580
        {
12581
            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12582
                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12583
            if (res == 0)
12584
                ret = AES_GCM_AUTH_E;
12585
            else
12586
                ret = 0;
12587
        }
12588
    }
12589
    else
12590
#endif /* WOLFSSL_AESNI */
12591
87
    {
12592
87
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
12593
87
                                                             authIn, authInSz);
12594
87
    }
12595
87
#endif
12596
12597
87
    VECTOR_REGISTERS_POP;
12598
12599
87
    return ret;
12600
87
}
12601
#endif
12602
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
12603
12604
#ifdef WOLFSSL_AESGCM_STREAM
12605
12606
/* Initialize the AES GCM cipher with an IV. C implementation.
12607
 *
12608
 * @param [in, out] aes   AES object.
12609
 * @param [in]      iv    IV/nonce buffer.
12610
 * @param [in]      ivSz  Length of IV/nonce data.
12611
 */
12612
static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
12613
1.38k
{
12614
1.38k
    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
12615
1.38k
    int ret;
12616
12617
1.38k
    if (ivSz == GCM_NONCE_MID_SZ) {
12618
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
12619
1.38k
        XMEMCPY(counter, iv, ivSz);
12620
1.38k
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
12621
1.38k
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
12622
1.38k
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
12623
1.38k
    }
12624
0
    else {
12625
        /* Counter is GHASH of IV. */
12626
    #ifdef OPENSSL_EXTRA
12627
        word32 aadTemp = aes->gcm.aadLen;
12628
        aes->gcm.aadLen = 0;
12629
    #endif
12630
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
12631
    #ifdef OPENSSL_EXTRA
12632
        aes->gcm.aadLen = aadTemp;
12633
    #endif
12634
0
    }
12635
12636
    /* Copy in the counter for use with cipher. */
12637
1.38k
    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
12638
    /* Encrypt initial counter into a buffer for GCM. */
12639
1.38k
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
12640
1.38k
    if (ret != 0)
12641
0
        return ret;
12642
    /* Reset state fields. */
12643
1.38k
    aes->over = 0;
12644
1.38k
    aes->aSz = 0;
12645
1.38k
    aes->cSz = 0;
12646
    /* Initialization for GHASH. */
12647
1.38k
    GHASH_INIT(aes);
12648
12649
1.38k
    return 0;
12650
1.38k
}
12651
12652
/* Update the AES GCM cipher with data. C implementation.
12653
 *
12654
 * Only enciphers data.
12655
 *
12656
 * @param [in, out] aes  AES object.
12657
 * @param [in]      out  Cipher text or plaintext buffer.
12658
 * @param [in]      in   Plaintext or cipher text buffer.
12659
 * @param [in]      sz   Length of data.
12660
 */
12661
static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
12662
    Aes* aes, byte* out, const byte* in, word32 sz)
12663
8.28k
{
12664
8.28k
    word32 blocks;
12665
8.28k
    word32 partial;
12666
8.28k
    int ret;
12667
12668
    /* Check if previous encrypted block was not used up. */
12669
8.28k
    if (aes->over > 0) {
12670
4.49k
        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
12671
4.49k
        if (pSz > sz) pSz = (byte)sz;
12672
12673
        /* Use some/all of last encrypted block. */
12674
4.49k
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
12675
4.49k
        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
12676
12677
        /* Some data used. */
12678
4.49k
        sz  -= pSz;
12679
4.49k
        in  += pSz;
12680
4.49k
        out += pSz;
12681
4.49k
    }
12682
12683
    /* Calculate the number of blocks needing to be encrypted and any leftover.
12684
     */
12685
8.28k
    blocks  = sz / WC_AES_BLOCK_SIZE;
12686
8.28k
    partial = sz & (WC_AES_BLOCK_SIZE - 1);
12687
12688
8.28k
#if defined(HAVE_AES_ECB)
12689
    /* Some hardware acceleration can gain performance from doing AES encryption
12690
     * of the whole buffer at once.
12691
     * Overwrites the cipher text before using plaintext - no inline encryption.
12692
     */
12693
8.28k
    if ((out != in) && blocks > 0) {
12694
159
        word32 b;
12695
        /* Place incrementing counter blocks into cipher text. */
12696
9.05k
        for (b = 0; b < blocks; b++) {
12697
8.89k
            IncrementGcmCounter(AES_COUNTER(aes));
12698
8.89k
            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
12699
8.89k
        }
12700
12701
        /* Encrypt counter blocks. */
12702
159
        ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
12703
159
        if (ret != 0) {
12704
0
            ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
12705
0
            return ret;
12706
0
        }
12707
        /* XOR in plaintext. */
12708
159
        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
12709
        /* Skip over processed data. */
12710
159
        in += WC_AES_BLOCK_SIZE * blocks;
12711
159
        out += WC_AES_BLOCK_SIZE * blocks;
12712
159
    }
12713
8.12k
    else
12714
8.12k
#endif /* HAVE_AES_ECB */
12715
8.12k
    {
12716
        /* Encrypt block by block. */
12717
11.6k
        while (blocks--) {
12718
3.47k
            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
12719
3.47k
            IncrementGcmCounter(AES_COUNTER(aes));
12720
            /* Encrypt counter into a buffer. */
12721
3.47k
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
12722
3.47k
            if (ret != 0)
12723
0
                return ret;
12724
            /* XOR plain text into encrypted counter into cipher text buffer. */
12725
3.47k
            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
12726
            /* Data complete. */
12727
3.47k
            in  += WC_AES_BLOCK_SIZE;
12728
3.47k
            out += WC_AES_BLOCK_SIZE;
12729
3.47k
        }
12730
8.12k
    }
12731
12732
8.28k
    if (partial != 0) {
12733
        /* Generate an extra block and use up as much as needed. */
12734
420
        IncrementGcmCounter(AES_COUNTER(aes));
12735
        /* Encrypt counter into cache. */
12736
420
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
12737
420
        if (ret != 0)
12738
0
            return ret;
12739
        /* XOR plain text into encrypted counter into cipher text buffer. */
12740
420
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
12741
        /* Keep amount of encrypted block used. */
12742
420
        aes->over = (byte)partial;
12743
420
    }
12744
12745
8.28k
    return 0;
12746
8.28k
}
12747
12748
/* Calculates authentication tag for AES GCM. C implementation.
12749
 *
12750
 * @param [in, out] aes        AES object.
12751
 * @param [out]     authTag    Buffer to store authentication tag in.
12752
 * @param [in]      authTagSz  Length of tag to create.
12753
 */
12754
static WARN_UNUSED_RESULT int AesGcmFinal_C(
12755
    Aes* aes, byte* authTag, word32 authTagSz)
12756
480
{
12757
    /* Calculate authentication tag. */
12758
480
    GHASH_FINAL(aes, authTag, authTagSz);
12759
    /* XOR in as much of encrypted counter as is required. */
12760
480
    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
12761
#ifdef OPENSSL_EXTRA
12762
    /* store AAD size for next call */
12763
    aes->gcm.aadLen = aes->aSz;
12764
#endif
12765
    /* Zeroize last block to protect sensitive data. */
12766
480
    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
12767
12768
480
    return 0;
12769
480
}
12770
12771
#ifdef WOLFSSL_AESNI
12772
12773
#ifdef __cplusplus
12774
    extern "C" {
12775
#endif
12776
12777
/* Assembly code implementations in: aes_gcm_asm.S */
12778
#ifdef HAVE_INTEL_AVX2
12779
extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
12780
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12781
    unsigned char* counter, unsigned char* initCtr);
12782
#ifdef HAVE_INTEL_AVX512
12783
extern void AES_GCM_init_avx512(const unsigned char* key, int nr,
12784
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12785
    unsigned char* counter, unsigned char* initCtr);
12786
#endif
12787
#ifdef HAVE_INTEL_VAES
12788
extern void AES_GCM_init_vaes(const unsigned char* key, int nr,
12789
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12790
    unsigned char* counter, unsigned char* initCtr);
12791
#endif
12792
extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
12793
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12794
#ifdef HAVE_INTEL_AVX512
12795
extern void AES_GCM_aad_update_avx512(const unsigned char* addt,
12796
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12797
#endif
12798
#ifdef HAVE_INTEL_VAES
12799
extern void AES_GCM_aad_update_vaes(const unsigned char* addt,
12800
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12801
#endif
12802
extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
12803
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12804
#ifdef HAVE_INTEL_AVX512
12805
extern void AES_GCM_encrypt_block_avx512(const unsigned char* key, int nr,
12806
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12807
#endif
12808
#ifdef HAVE_INTEL_VAES
12809
extern void AES_GCM_encrypt_block_vaes(const unsigned char* key, int nr,
12810
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12811
#endif
12812
extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
12813
    unsigned char* tag, unsigned char* h);
12814
#ifdef HAVE_INTEL_AVX512
12815
extern void AES_GCM_ghash_block_avx512(const unsigned char* data,
12816
    unsigned char* tag, unsigned char* h);
12817
#endif
12818
#ifdef HAVE_INTEL_VAES
12819
extern void AES_GCM_ghash_block_vaes(const unsigned char* data,
12820
    unsigned char* tag, unsigned char* h);
12821
#endif
12822
12823
extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
12824
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12825
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12826
#ifdef HAVE_INTEL_AVX512
12827
extern void AES_GCM_encrypt_update_avx512(const unsigned char* key, int nr,
12828
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12829
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12830
#endif
12831
#ifdef HAVE_INTEL_VAES
12832
extern void AES_GCM_encrypt_update_vaes(const unsigned char* key, int nr,
12833
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12834
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12835
#endif
12836
extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
12837
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12838
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12839
#ifdef HAVE_INTEL_AVX512
12840
extern void AES_GCM_encrypt_final_avx512(unsigned char* tag,
12841
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12842
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12843
#endif
12844
#ifdef HAVE_INTEL_VAES
12845
extern void AES_GCM_encrypt_final_vaes(unsigned char* tag,
12846
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12847
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12848
#endif
12849
#endif
12850
#ifdef HAVE_INTEL_AVX1
12851
extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
12852
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12853
    unsigned char* counter, unsigned char* initCtr);
12854
extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
12855
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12856
extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
12857
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12858
extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
12859
    unsigned char* tag, unsigned char* h);
12860
12861
extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
12862
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12863
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12864
extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
12865
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12866
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12867
#endif
12868
extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
12869
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12870
    unsigned char* counter, unsigned char* initCtr);
12871
extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
12872
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12873
extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
12874
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12875
extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
12876
    unsigned char* tag, unsigned char* h);
12877
12878
extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
12879
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12880
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12881
extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
12882
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12883
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12884
12885
#ifdef __cplusplus
12886
    } /* extern "C" */
12887
#endif
12888
12889
/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
12890
 *
12891
 * @param [in, out] aes   AES object.
12892
 * @param [in]      iv    IV/nonce buffer.
12893
 * @param [in]      ivSz  Length of IV/nonce data.
12894
 */
12895
static WARN_UNUSED_RESULT int AesGcmInit_aesni(
12896
    Aes* aes, const byte* iv, word32 ivSz)
12897
{
12898
    ASSERT_SAVED_VECTOR_REGISTERS();
12899
12900
    /* Reset state fields. */
12901
    aes->over = 0;
12902
    aes->aSz = 0;
12903
    aes->cSz = 0;
12904
    /* Set tag to all zeros as initial value. */
12905
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
12906
    /* Reset counts of AAD and cipher text. */
12907
    aes->aOver = 0;
12908
    aes->cOver = 0;
12909
12910
#ifdef HAVE_INTEL_AVX512
12911
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12912
        AES_GCM_init_avx512((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12913
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12914
    }
12915
    else
12916
#endif
12917
#ifdef HAVE_INTEL_VAES
12918
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12919
        AES_GCM_init_vaes((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12920
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12921
    }
12922
    else
12923
#endif
12924
#ifdef HAVE_INTEL_AVX2
12925
    if (IS_INTEL_AVX2(intel_flags)) {
12926
        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12927
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12928
    }
12929
    else
12930
#endif
12931
#ifdef HAVE_INTEL_AVX1
12932
    if (IS_INTEL_AVX1(intel_flags)) {
12933
        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12934
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12935
    }
12936
    else
12937
#endif
12938
    {
12939
        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12940
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12941
    }
12942
12943
    return 0;
12944
}
12945
12946
/* Update the AES GCM for encryption with authentication data.
12947
 *
12948
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
12949
 *
12950
 * @param [in, out] aes   AES object.
12951
 * @param [in]      a     Buffer holding authentication data.
12952
 * @param [in]      aSz   Length of authentication data in bytes.
12953
 * @param [in]      endA  Whether no more authentication data is expected.
12954
 */
12955
static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
12956
    Aes* aes, const byte* a, word32 aSz, int endA)
12957
{
12958
    word32 blocks;
12959
    int partial;
12960
12961
    ASSERT_SAVED_VECTOR_REGISTERS();
12962
12963
    if (aSz != 0 && a != NULL) {
12964
        /* Total count of AAD updated. */
12965
        aes->aSz += aSz;
12966
        /* Check if we have unprocessed data. */
12967
        if (aes->aOver > 0) {
12968
            /* Calculate amount we can use - fill up the block. */
12969
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
12970
            if (sz > aSz) {
12971
                sz = (byte)aSz;
12972
            }
12973
            /* Copy extra into last GHASH block array and update count. */
12974
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
12975
            aes->aOver = (byte)(aes->aOver + sz);
12976
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
12977
                /* We have filled up the block and can process. */
12978
#ifdef HAVE_INTEL_AVX512
12979
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12980
                    AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12981
                                             aes->gcm.H);
12982
                }
12983
                else
12984
#endif
12985
#ifdef HAVE_INTEL_VAES
12986
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12987
                    AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12988
                                             aes->gcm.H);
12989
                }
12990
                else
12991
#endif
12992
            #ifdef HAVE_INTEL_AVX2
12993
                if (IS_INTEL_AVX2(intel_flags)) {
12994
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12995
                                             aes->gcm.H);
12996
                }
12997
                else
12998
            #endif
12999
            #ifdef HAVE_INTEL_AVX1
13000
                if (IS_INTEL_AVX1(intel_flags)) {
13001
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
13002
                                             aes->gcm.H);
13003
                }
13004
                else
13005
            #endif
13006
                {
13007
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
13008
                                              aes->gcm.H);
13009
                }
13010
                /* Reset count. */
13011
                aes->aOver = 0;
13012
            }
13013
            /* Used up some data. */
13014
            aSz -= sz;
13015
            a += sz;
13016
        }
13017
13018
        /* Calculate number of blocks of AAD and the leftover. */
13019
        blocks = aSz / WC_AES_BLOCK_SIZE;
13020
        partial = aSz % WC_AES_BLOCK_SIZE;
13021
        if (blocks > 0) {
13022
            /* GHASH full blocks now. */
13023
#ifdef HAVE_INTEL_AVX512
13024
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13025
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13026
                AES_GCM_aad_update_avx512(a, blocks * WC_AES_BLOCK_SIZE,
13027
                                        AES_TAG(aes), aes->gcm.H);
13028
            }
13029
            else
13030
#endif
13031
#ifdef HAVE_INTEL_VAES
13032
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13033
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13034
                AES_GCM_aad_update_vaes(a, blocks * WC_AES_BLOCK_SIZE,
13035
                                        AES_TAG(aes), aes->gcm.H);
13036
            }
13037
            else
13038
#endif
13039
        #ifdef HAVE_INTEL_AVX2
13040
            if (IS_INTEL_AVX2(intel_flags)) {
13041
                AES_GCM_aad_update_avx2(a, blocks * WC_AES_BLOCK_SIZE,
13042
                                        AES_TAG(aes), aes->gcm.H);
13043
            }
13044
            else
13045
        #endif
13046
        #ifdef HAVE_INTEL_AVX1
13047
            if (IS_INTEL_AVX1(intel_flags)) {
13048
                AES_GCM_aad_update_avx1(a, blocks * WC_AES_BLOCK_SIZE,
13049
                                        AES_TAG(aes), aes->gcm.H);
13050
            }
13051
            else
13052
        #endif
13053
            {
13054
                AES_GCM_aad_update_aesni(a, blocks * WC_AES_BLOCK_SIZE,
13055
                                         AES_TAG(aes), aes->gcm.H);
13056
            }
13057
            /* Skip over to end of AAD blocks. */
13058
            a += blocks * WC_AES_BLOCK_SIZE;
13059
        }
13060
        if (partial != 0) {
13061
            /* Cache the partial block. */
13062
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
13063
            aes->aOver = (byte)partial;
13064
        }
13065
    }
13066
    if (endA && (aes->aOver > 0)) {
13067
        /* No more AAD coming and we have a partial block. */
13068
        /* Fill the rest of the block with zeros. */
13069
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
13070
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
13071
        /* GHASH last AAD block. */
13072
#ifdef HAVE_INTEL_AVX512
13073
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13074
            AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
13075
                                     aes->gcm.H);
13076
        }
13077
        else
13078
#endif
13079
#ifdef HAVE_INTEL_VAES
13080
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13081
            AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
13082
                                     aes->gcm.H);
13083
        }
13084
        else
13085
#endif
13086
    #ifdef HAVE_INTEL_AVX2
13087
        if (IS_INTEL_AVX2(intel_flags)) {
13088
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
13089
                                     aes->gcm.H);
13090
        }
13091
        else
13092
    #endif
13093
    #ifdef HAVE_INTEL_AVX1
13094
        if (IS_INTEL_AVX1(intel_flags)) {
13095
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
13096
                                     aes->gcm.H);
13097
        }
13098
        else
13099
    #endif
13100
        {
13101
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
13102
                                      aes->gcm.H);
13103
        }
13104
        /* Clear partial count for next time through. */
13105
        aes->aOver = 0;
13106
    }
13107
13108
    return 0;
13109
}
13110
13111
/* Update the AES GCM for encryption with data and/or authentication data.
13112
 *
13113
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
13114
 *
13115
 * @param [in, out] aes  AES object.
13116
 * @param [out]     c    Buffer to hold cipher text.
13117
 * @param [in]      p    Buffer holding plaintext.
13118
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13119
 * @param [in]      a    Buffer holding authentication data.
13120
 * @param [in]      aSz  Length of authentication data in bytes.
13121
 */
13122
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
13123
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
13124
{
13125
    word32 blocks;
13126
    int partial;
13127
    int ret;
13128
13129
    ASSERT_SAVED_VECTOR_REGISTERS();
13130
13131
    /* Hash in A, the Authentication Data */
13132
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
13133
    if (ret != 0)
13134
        return ret;
13135
13136
    /* Encrypt plaintext and Hash in C, the Cipher text */
13137
    if (cSz != 0 && c != NULL) {
13138
        /* Update count of cipher text we have hashed. */
13139
        aes->cSz += cSz;
13140
        if (aes->cOver > 0) {
13141
            /* Calculate amount we can use - fill up the block. */
13142
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13143
            if (sz > cSz) {
13144
                sz = (byte)cSz;
13145
            }
13146
            /* Encrypt some of the plaintext. */
13147
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
13148
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13149
            /* Update count of unused encrypted counter. */
13150
            aes->cOver = (byte)(aes->cOver + sz);
13151
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13152
                /* We have filled up the block and can process. */
13153
#ifdef HAVE_INTEL_AVX512
13154
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13155
                    AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
13156
                                             aes->gcm.H);
13157
                }
13158
                else
13159
#endif
13160
#ifdef HAVE_INTEL_VAES
13161
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13162
                    AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
13163
                                             aes->gcm.H);
13164
                }
13165
                else
13166
#endif
13167
            #ifdef HAVE_INTEL_AVX2
13168
                if (IS_INTEL_AVX2(intel_flags)) {
13169
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
13170
                                             aes->gcm.H);
13171
                }
13172
                else
13173
            #endif
13174
            #ifdef HAVE_INTEL_AVX1
13175
                if (IS_INTEL_AVX1(intel_flags)) {
13176
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
13177
                                             aes->gcm.H);
13178
                }
13179
                else
13180
            #endif
13181
                {
13182
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
13183
                                              aes->gcm.H);
13184
                }
13185
                /* Reset count. */
13186
                aes->cOver = 0;
13187
            }
13188
            /* Used up some data. */
13189
            cSz -= sz;
13190
            p += sz;
13191
            c += sz;
13192
        }
13193
13194
        /* Calculate number of blocks of plaintext and the leftover. */
13195
        blocks = cSz / WC_AES_BLOCK_SIZE;
13196
        partial = cSz % WC_AES_BLOCK_SIZE;
13197
        if (blocks > 0) {
13198
            /* Encrypt and GHASH full blocks now. */
13199
#ifdef HAVE_INTEL_AVX512
13200
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13201
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13202
                AES_GCM_encrypt_update_avx512((byte*)aes->key, (int)aes->rounds,
13203
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13204
                    AES_COUNTER(aes));
13205
            }
13206
            else
13207
#endif
13208
#ifdef HAVE_INTEL_VAES
13209
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13210
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13211
                AES_GCM_encrypt_update_vaes((byte*)aes->key, (int)aes->rounds,
13212
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13213
                    AES_COUNTER(aes));
13214
            }
13215
            else
13216
#endif
13217
        #ifdef HAVE_INTEL_AVX2
13218
            if (IS_INTEL_AVX2(intel_flags)) {
13219
                AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
13220
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13221
                    AES_COUNTER(aes));
13222
            }
13223
            else
13224
        #endif
13225
        #ifdef HAVE_INTEL_AVX1
13226
            if (IS_INTEL_AVX1(intel_flags)) {
13227
                AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
13228
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13229
                    AES_COUNTER(aes));
13230
            }
13231
            else
13232
        #endif
13233
            {
13234
                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
13235
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13236
                    AES_COUNTER(aes));
13237
            }
13238
            /* Skip over to end of blocks. */
13239
            p += blocks * WC_AES_BLOCK_SIZE;
13240
            c += blocks * WC_AES_BLOCK_SIZE;
13241
        }
13242
        if (partial != 0) {
13243
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
13244
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13245
#ifdef HAVE_INTEL_AVX512
13246
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13247
                AES_GCM_encrypt_block_avx512((byte*)aes->key, (int)aes->rounds,
13248
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13249
            }
13250
            else
13251
#endif
13252
#ifdef HAVE_INTEL_VAES
13253
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13254
                AES_GCM_encrypt_block_vaes((byte*)aes->key, (int)aes->rounds,
13255
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13256
            }
13257
            else
13258
#endif
13259
        #ifdef HAVE_INTEL_AVX2
13260
            if (IS_INTEL_AVX2(intel_flags)) {
13261
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
13262
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13263
            }
13264
            else
13265
        #endif
13266
        #ifdef HAVE_INTEL_AVX1
13267
            if (IS_INTEL_AVX1(intel_flags)) {
13268
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
13269
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13270
            }
13271
            else
13272
        #endif
13273
            {
13274
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
13275
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13276
            }
13277
            /* XOR the remaining plaintext to calculate cipher text.
13278
             * Keep cipher text for GHASH of last partial block.
13279
             */
13280
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
13281
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
13282
            /* Update count of the block used. */
13283
            aes->cOver = (byte)partial;
13284
        }
13285
    }
13286
    return 0;
13287
}
13288
13289
/* Finalize the AES GCM for encryption and calculate the authentication tag.
13290
 *
13291
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
13292
 *
13293
 * @param [in, out] aes        AES object.
13294
 * @param [in]      authTag    Buffer to hold authentication tag.
13295
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13296
 * @return  0 on success.
13297
 */
13298
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
13299
    Aes* aes, byte* authTag, word32 authTagSz)
13300
{
13301
    /* AAD block incomplete when > 0 */
13302
    byte over = aes->aOver;
13303
13304
    ASSERT_SAVED_VECTOR_REGISTERS();
13305
13306
    if (aes->cOver > 0) {
13307
        /* Cipher text block incomplete. */
13308
        over = aes->cOver;
13309
    }
13310
    if (over > 0) {
13311
        /* Fill the rest of the block with zeros. */
13312
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
13313
        /* GHASH last cipher block. */
13314
#ifdef HAVE_INTEL_AVX512
13315
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13316
            AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
13317
                                     aes->gcm.H);
13318
        }
13319
        else
13320
#endif
13321
#ifdef HAVE_INTEL_VAES
13322
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13323
            AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
13324
                                     aes->gcm.H);
13325
        }
13326
        else
13327
#endif
13328
    #ifdef HAVE_INTEL_AVX2
13329
        if (IS_INTEL_AVX2(intel_flags)) {
13330
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
13331
                                     aes->gcm.H);
13332
        }
13333
        else
13334
    #endif
13335
    #ifdef HAVE_INTEL_AVX1
13336
        if (IS_INTEL_AVX1(intel_flags)) {
13337
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
13338
                                     aes->gcm.H);
13339
        }
13340
        else
13341
    #endif
13342
        {
13343
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
13344
                                      aes->gcm.H);
13345
        }
13346
    }
13347
    /* Calculate the authentication tag. */
13348
#ifdef HAVE_INTEL_AVX512
13349
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13350
        AES_GCM_encrypt_final_avx512(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13351
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13352
    }
13353
    else
13354
#endif
13355
#ifdef HAVE_INTEL_VAES
13356
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13357
        AES_GCM_encrypt_final_vaes(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13358
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13359
    }
13360
    else
13361
#endif
13362
#ifdef HAVE_INTEL_AVX2
13363
    if (IS_INTEL_AVX2(intel_flags)) {
13364
        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13365
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13366
    }
13367
    else
13368
#endif
13369
#ifdef HAVE_INTEL_AVX1
13370
    if (IS_INTEL_AVX1(intel_flags)) {
13371
        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13372
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13373
    }
13374
    else
13375
#endif
13376
    {
13377
        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13378
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13379
    }
13380
13381
    return 0;
13382
}
13383
13384
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
13385
13386
#ifdef __cplusplus
13387
    extern "C" {
13388
#endif
13389
13390
/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
13391
#ifdef HAVE_INTEL_AVX2
13392
extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
13393
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13394
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13395
#ifdef HAVE_INTEL_AVX512
13396
extern void AES_GCM_decrypt_update_avx512(const unsigned char* key, int nr,
13397
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13398
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13399
#endif
13400
#ifdef HAVE_INTEL_VAES
13401
extern void AES_GCM_decrypt_update_vaes(const unsigned char* key, int nr,
13402
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13403
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13404
#endif
13405
extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
13406
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13407
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13408
#ifdef HAVE_INTEL_AVX512
13409
extern void AES_GCM_decrypt_final_avx512(unsigned char* tag,
13410
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13411
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13412
#endif
13413
#ifdef HAVE_INTEL_VAES
13414
extern void AES_GCM_decrypt_final_vaes(unsigned char* tag,
13415
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13416
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13417
#endif
13418
#endif
13419
#ifdef HAVE_INTEL_AVX1
13420
extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
13421
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13422
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13423
extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
13424
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13425
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13426
#endif
13427
extern void AES_GCM_decrypt_update_aesni(const unsigned char* key, int nr,
13428
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13429
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13430
extern void AES_GCM_decrypt_final_aesni(unsigned char* tag,
13431
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13432
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13433
13434
#ifdef __cplusplus
13435
    } /* extern "C" */
13436
#endif
13437
13438
/* Update the AES GCM for decryption with data and/or authentication data.
13439
 *
13440
 * @param [in, out] aes  AES object.
13441
 * @param [out]     p    Buffer to hold plaintext.
13442
 * @param [in]      c    Buffer holding cipher text.
13443
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13444
 * @param [in]      a    Buffer holding authentication data.
13445
 * @param [in]      aSz  Length of authentication data in bytes.
13446
 */
13447
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
13448
    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
13449
{
13450
    word32 blocks;
13451
    int partial;
13452
    int ret;
13453
13454
    ASSERT_SAVED_VECTOR_REGISTERS();
13455
13456
    /* Hash in A, the Authentication Data */
13457
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
13458
    if (ret != 0)
13459
        return ret;
13460
13461
    /* Hash in C, the Cipher text, and decrypt. */
13462
    if (cSz != 0 && p != NULL) {
13463
        /* Update count of cipher text we have hashed. */
13464
        aes->cSz += cSz;
13465
        if (aes->cOver > 0) {
13466
            /* Calculate amount we can use - fill up the block. */
13467
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13468
            if (sz > cSz) {
13469
                sz = (byte)cSz;
13470
            }
13471
            /* Keep a copy of the cipher text for GHASH. */
13472
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
13473
            /* Decrypt some of the cipher text. */
13474
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
13475
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13476
            /* Update count of unused encrypted counter. */
13477
            aes->cOver = (byte)(aes->cOver + sz);
13478
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13479
                /* We have filled up the block and can process. */
13480
#ifdef HAVE_INTEL_AVX512
13481
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13482
                    AES_GCM_ghash_block_avx512(AES_LASTBLOCK(aes), AES_TAG(aes),
13483
                                             aes->gcm.H);
13484
                }
13485
                else
13486
#endif
13487
#ifdef HAVE_INTEL_VAES
13488
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13489
                    AES_GCM_ghash_block_vaes(AES_LASTBLOCK(aes), AES_TAG(aes),
13490
                                             aes->gcm.H);
13491
                }
13492
                else
13493
#endif
13494
            #ifdef HAVE_INTEL_AVX2
13495
                if (IS_INTEL_AVX2(intel_flags)) {
13496
                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
13497
                                             aes->gcm.H);
13498
                }
13499
                else
13500
            #endif
13501
            #ifdef HAVE_INTEL_AVX1
13502
                if (IS_INTEL_AVX1(intel_flags)) {
13503
                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
13504
                                             aes->gcm.H);
13505
                }
13506
                else
13507
            #endif
13508
                {
13509
                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
13510
                                              aes->gcm.H);
13511
                }
13512
                /* Reset count. */
13513
                aes->cOver = 0;
13514
            }
13515
            /* Used up some data. */
13516
            cSz -= sz;
13517
            c += sz;
13518
            p += sz;
13519
        }
13520
13521
        /* Calculate number of blocks of plaintext and the leftover. */
13522
        blocks = cSz / WC_AES_BLOCK_SIZE;
13523
        partial = cSz % WC_AES_BLOCK_SIZE;
13524
        if (blocks > 0) {
13525
            /* Decrypt and GHASH full blocks now. */
13526
#ifdef HAVE_INTEL_AVX512
13527
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13528
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13529
                AES_GCM_decrypt_update_avx512((byte*)aes->key, (int)aes->rounds,
13530
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13531
                    AES_COUNTER(aes));
13532
            }
13533
            else
13534
#endif
13535
#ifdef HAVE_INTEL_VAES
13536
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13537
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13538
                AES_GCM_decrypt_update_vaes((byte*)aes->key, (int)aes->rounds,
13539
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13540
                    AES_COUNTER(aes));
13541
            }
13542
            else
13543
#endif
13544
        #ifdef HAVE_INTEL_AVX2
13545
            if (IS_INTEL_AVX2(intel_flags)) {
13546
                AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
13547
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13548
                    AES_COUNTER(aes));
13549
            }
13550
            else
13551
        #endif
13552
        #ifdef HAVE_INTEL_AVX1
13553
            if (IS_INTEL_AVX1(intel_flags)) {
13554
                AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
13555
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13556
                    AES_COUNTER(aes));
13557
            }
13558
            else
13559
        #endif
13560
            {
13561
                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
13562
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13563
                    AES_COUNTER(aes));
13564
            }
13565
            /* Skip over to end of blocks. */
13566
            c += blocks * WC_AES_BLOCK_SIZE;
13567
            p += blocks * WC_AES_BLOCK_SIZE;
13568
        }
13569
        if (partial != 0) {
13570
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
13571
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13572
#ifdef HAVE_INTEL_AVX512
13573
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13574
                AES_GCM_encrypt_block_avx512((byte*)aes->key, (int)aes->rounds,
13575
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13576
            }
13577
            else
13578
#endif
13579
#ifdef HAVE_INTEL_VAES
13580
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13581
                AES_GCM_encrypt_block_vaes((byte*)aes->key, (int)aes->rounds,
13582
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13583
            }
13584
            else
13585
#endif
13586
        #ifdef HAVE_INTEL_AVX2
13587
            if (IS_INTEL_AVX2(intel_flags)) {
13588
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
13589
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13590
            }
13591
            else
13592
        #endif
13593
        #ifdef HAVE_INTEL_AVX1
13594
            if (IS_INTEL_AVX1(intel_flags)) {
13595
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
13596
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13597
            }
13598
            else
13599
        #endif
13600
            {
13601
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
13602
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13603
            }
13604
            /* Keep cipher text for GHASH of last partial block. */
13605
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
13606
            /* XOR the remaining cipher text to calculate plaintext. */
13607
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
13608
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
13609
            /* Update count of the block used. */
13610
            aes->cOver = (byte)partial;
13611
        }
13612
    }
13613
13614
    return 0;
13615
}
13616
13617
/* Finalize the AES GCM for decryption and check the authentication tag.
13618
 *
13619
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
13620
 *
13621
 * @param [in, out] aes        AES object.
13622
 * @param [in]      authTag    Buffer holding authentication tag.
13623
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13624
 * @return  0 on success.
13625
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
13626
 *          value.
13627
 */
13628
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
13629
    Aes* aes, const byte* authTag, word32 authTagSz)
13630
{
13631
    int ret = 0;
13632
    int res;
13633
    /* AAD block incomplete when > 0 */
13634
    byte over = aes->aOver;
13635
    byte *lastBlock = AES_LASTGBLOCK(aes);
13636
13637
    ASSERT_SAVED_VECTOR_REGISTERS();
13638
13639
    if (aes->cOver > 0) {
13640
        /* Cipher text block incomplete. */
13641
        over = aes->cOver;
13642
        lastBlock = AES_LASTBLOCK(aes);
13643
    }
13644
    if (over > 0) {
13645
        /* Zeroize the unused part of the block. */
13646
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
13647
        /* Hash the last block of cipher text. */
13648
#ifdef HAVE_INTEL_AVX512
13649
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13650
            AES_GCM_ghash_block_avx512(lastBlock, AES_TAG(aes), aes->gcm.H);
13651
        }
13652
        else
13653
#endif
13654
#ifdef HAVE_INTEL_VAES
13655
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13656
            AES_GCM_ghash_block_vaes(lastBlock, AES_TAG(aes), aes->gcm.H);
13657
        }
13658
        else
13659
#endif
13660
    #ifdef HAVE_INTEL_AVX2
13661
        if (IS_INTEL_AVX2(intel_flags)) {
13662
            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
13663
        }
13664
        else
13665
    #endif
13666
    #ifdef HAVE_INTEL_AVX1
13667
        if (IS_INTEL_AVX1(intel_flags)) {
13668
            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
13669
        }
13670
        else
13671
    #endif
13672
        {
13673
            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
13674
        }
13675
    }
13676
    /* Calculate and compare the authentication tag. */
13677
#ifdef HAVE_INTEL_AVX512
13678
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13679
        AES_GCM_decrypt_final_avx512(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13680
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13681
    }
13682
    else
13683
#endif
13684
#ifdef HAVE_INTEL_VAES
13685
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13686
        AES_GCM_decrypt_final_vaes(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13687
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13688
    }
13689
    else
13690
#endif
13691
#ifdef HAVE_INTEL_AVX2
13692
    if (IS_INTEL_AVX2(intel_flags)) {
13693
        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13694
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13695
    }
13696
    else
13697
#endif
13698
#ifdef HAVE_INTEL_AVX1
13699
    if (IS_INTEL_AVX1(intel_flags)) {
13700
        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13701
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13702
    }
13703
    else
13704
#endif
13705
    {
13706
        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13707
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13708
    }
13709
13710
    /* Return error code when calculated doesn't match input. */
13711
    if (res == 0) {
13712
        ret = AES_GCM_AUTH_E;
13713
    }
13714
    return ret;
13715
}
13716
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
13717
#endif /* WOLFSSL_AESNI */
13718
13719
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13720
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13721
/* Initialize the AES GCM cipher with an IV. Aarch64 HW Crypto implementations.
13722
 *
13723
 * @param [in, out] aes   AES object.
13724
 * @param [in]      iv    IV/nonce buffer.
13725
 * @param [in]      ivSz  Length of IV/nonce data.
13726
 */
13727
static WARN_UNUSED_RESULT int AesGcmInit_AARCH64(Aes* aes, const byte* iv,
13728
    word32 ivSz)
13729
{
13730
    /* Reset state fields. */
13731
    aes->over = 0;
13732
    aes->aSz = 0;
13733
    aes->cSz = 0;
13734
    /* Set tag to all zeros as initial value. */
13735
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
13736
    /* Reset counts of AAD and cipher text. */
13737
    aes->aOver = 0;
13738
    aes->cOver = 0;
13739
13740
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13741
    if (aes->use_sha3_hw_crypto) {
13742
        AES_GCM_init_AARCH64_EOR3((byte*)aes->key, (int)aes->rounds, iv, ivSz,
13743
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
13744
    }
13745
    else
13746
#endif
13747
    {
13748
        AES_GCM_init_AARCH64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
13749
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
13750
    }
13751
13752
    return 0;
13753
}
13754
13755
/* Update the AES GCM for encryption with authentication data.
13756
 *
13757
 * Implementation uses AARCH64 optimized assembly code.
13758
 *
13759
 * @param [in, out] aes   AES object.
13760
 * @param [in]      a     Buffer holding authentication data.
13761
 * @param [in]      aSz   Length of authentication data in bytes.
13762
 * @param [in]      endA  Whether no more authentication data is expected.
13763
 */
13764
static WARN_UNUSED_RESULT int AesGcmAadUpdate_AARCH64(
13765
    Aes* aes, const byte* a, word32 aSz, int endA)
13766
{
13767
    word32 blocks;
13768
    int partial;
13769
13770
    if (aSz != 0 && a != NULL) {
13771
        /* Total count of AAD updated. */
13772
        aes->aSz += aSz;
13773
        /* Check if we have unprocessed data. */
13774
        if (aes->aOver > 0) {
13775
            /* Calculate amount we can use - fill up the block. */
13776
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
13777
            if (sz > aSz) {
13778
                sz = (byte)aSz;
13779
            }
13780
            /* Copy extra into last GHASH block array and update count. */
13781
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
13782
            aes->aOver = (byte)(aes->aOver + sz);
13783
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
13784
                /* We have filled up the block and can process. */
13785
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13786
                if (aes->use_sha3_hw_crypto) {
13787
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13788
                        AES_TAG(aes), aes->gcm.H);
13789
                }
13790
                else
13791
            #endif
13792
                {
13793
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13794
                        AES_TAG(aes), aes->gcm.H);
13795
                }
13796
                /* Reset count. */
13797
                aes->aOver = 0;
13798
            }
13799
            /* Used up some data. */
13800
            aSz -= sz;
13801
            a += sz;
13802
        }
13803
13804
        /* Calculate number of blocks of AAD and the leftover. */
13805
        blocks = aSz / WC_AES_BLOCK_SIZE;
13806
        partial = aSz % WC_AES_BLOCK_SIZE;
13807
        if (blocks > 0) {
13808
            /* GHASH full blocks now. */
13809
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13810
            if (aes->use_sha3_hw_crypto) {
13811
                AES_GCM_aad_update_AARCH64_EOR3(a, blocks * WC_AES_BLOCK_SIZE,
13812
                    AES_TAG(aes), aes->gcm.H);
13813
            }
13814
            else
13815
        #endif
13816
            {
13817
                AES_GCM_aad_update_AARCH64(a, blocks * WC_AES_BLOCK_SIZE,
13818
                    AES_TAG(aes), aes->gcm.H);
13819
            }
13820
            /* Skip over to end of AAD blocks. */
13821
            a += blocks * WC_AES_BLOCK_SIZE;
13822
        }
13823
        if (partial != 0) {
13824
            /* Cache the partial block. */
13825
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
13826
            aes->aOver = (byte)partial;
13827
        }
13828
    }
13829
    if (endA && (aes->aOver > 0)) {
13830
        /* No more AAD coming and we have a partial block. */
13831
        /* Fill the rest of the block with zeros. */
13832
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
13833
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
13834
        /* GHASH last AAD block. */
13835
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13836
        if (aes->use_sha3_hw_crypto) {
13837
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13838
                AES_TAG(aes), aes->gcm.H);
13839
        }
13840
        else
13841
    #endif
13842
        {
13843
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13844
                AES_TAG(aes), aes->gcm.H);
13845
        }
13846
        /* Clear partial count for next time through. */
13847
        aes->aOver = 0;
13848
    }
13849
13850
    return 0;
13851
}
13852
13853
/* Update the AES GCM for encryption with data and/or authentication data.
13854
 *
13855
 * Implementation uses AARCH64 optimized assembly code.
13856
 *
13857
 * @param [in, out] aes  AES object.
13858
 * @param [out]     c    Buffer to hold cipher text.
13859
 * @param [in]      p    Buffer holding plaintext.
13860
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13861
 * @param [in]      a    Buffer holding authentication data.
13862
 * @param [in]      aSz  Length of authentication data in bytes.
13863
 */
13864
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_AARCH64(
13865
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
13866
{
13867
    word32 blocks;
13868
    int partial;
13869
    int ret;
13870
13871
    /* Hash in A, the Authentication Data */
13872
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, (cSz > 0) && (c != NULL));
13873
    if (ret != 0)
13874
        return ret;
13875
13876
    /* Encrypt plaintext and Hash in C, the Cipher text */
13877
    if (cSz != 0 && c != NULL) {
13878
        /* Update count of cipher text we have hashed. */
13879
        aes->cSz += cSz;
13880
        if (aes->cOver > 0) {
13881
            /* Calculate amount we can use - fill up the block. */
13882
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13883
            if (sz > cSz) {
13884
                sz = (byte)cSz;
13885
            }
13886
            /* Encrypt some of the plaintext. */
13887
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
13888
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13889
            /* Update count of unused encrypted counter. */
13890
            aes->cOver = (byte)(aes->cOver + sz);
13891
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13892
                /* We have filled up the block and can process. */
13893
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13894
                if (aes->use_sha3_hw_crypto) {
13895
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13896
                        AES_TAG(aes), aes->gcm.H);
13897
                }
13898
                else
13899
            #endif
13900
                {
13901
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13902
                        AES_TAG(aes), aes->gcm.H);
13903
                }
13904
                /* Reset count. */
13905
                aes->cOver = 0;
13906
            }
13907
            /* Used up some data. */
13908
            cSz -= sz;
13909
            p += sz;
13910
            c += sz;
13911
        }
13912
13913
        /* Calculate number of blocks of plaintext and the leftover. */
13914
        blocks = cSz / WC_AES_BLOCK_SIZE;
13915
        partial = cSz % WC_AES_BLOCK_SIZE;
13916
        if (blocks > 0) {
13917
            /* Encrypt and GHASH full blocks now. */
13918
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13919
            if (aes->use_sha3_hw_crypto) {
13920
                AES_GCM_encrypt_update_AARCH64_EOR3((byte*)aes->key,
13921
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
13922
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13923
            }
13924
            else
13925
        #endif
13926
            {
13927
                AES_GCM_encrypt_update_AARCH64((byte*)aes->key,
13928
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
13929
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13930
            }
13931
            /* Skip over to end of blocks. */
13932
            p += blocks * WC_AES_BLOCK_SIZE;
13933
            c += blocks * WC_AES_BLOCK_SIZE;
13934
        }
13935
        if (partial != 0) {
13936
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
13937
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13938
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13939
            if (aes->use_sha3_hw_crypto) {
13940
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
13941
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
13942
                    AES_COUNTER(aes));
13943
            }
13944
            else
13945
        #endif
13946
            {
13947
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
13948
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13949
            }
13950
            /* XOR the remaining plaintext to calculate cipher text.
13951
             * Keep cipher text for GHASH of last partial block.
13952
             */
13953
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
13954
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
13955
            /* Update count of the block used. */
13956
            aes->cOver = (byte)partial;
13957
        }
13958
    }
13959
    return 0;
13960
}
13961
13962
/* Finalize the AES GCM for encryption and calculate the authentication tag.
13963
 *
13964
 * Calls ARCH64 optimized assembly code.
13965
 *
13966
 * @param [in, out] aes        AES object.
13967
 * @param [in]      authTag    Buffer to hold authentication tag.
13968
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13969
 * @return  0 on success.
13970
 */
13971
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_AARCH64(Aes* aes,
13972
    byte* authTag, word32 authTagSz)
13973
{
13974
    /* AAD block incomplete when > 0 */
13975
    byte over = aes->aOver;
13976
13977
    ASSERT_SAVED_VECTOR_REGISTERS();
13978
13979
    if (aes->cOver > 0) {
13980
        /* Cipher text block incomplete. */
13981
        over = aes->cOver;
13982
    }
13983
    if (over > 0) {
13984
        /* Fill the rest of the block with zeros. */
13985
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
13986
            (size_t)WC_AES_BLOCK_SIZE - over);
13987
        /* GHASH last cipher block. */
13988
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13989
        if (aes->use_sha3_hw_crypto) {
13990
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes), AES_TAG(aes),
13991
                aes->gcm.H);
13992
        }
13993
        else
13994
    #endif
13995
        {
13996
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes), AES_TAG(aes),
13997
                aes->gcm.H);
13998
        }
13999
    }
14000
    /* Calculate the authentication tag. */
14001
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14002
    if (aes->use_sha3_hw_crypto) {
14003
        AES_GCM_encrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
14004
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
14005
    }
14006
    else
14007
#endif
14008
    {
14009
        AES_GCM_encrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
14010
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
14011
    }
14012
14013
    return 0;
14014
}
14015
14016
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
14017
/* Update the AES GCM for decryption with data and/or authentication data.
14018
 *
14019
 * @param [in, out] aes  AES object.
14020
 * @param [out]     p    Buffer to hold plaintext.
14021
 * @param [in]      c    Buffer holding cipher text.
14022
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
14023
 * @param [in]      a    Buffer holding authentication data.
14024
 * @param [in]      aSz  Length of authentication data in bytes.
14025
 */
14026
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_AARCH64(Aes* aes, byte* p,
14027
    const byte* c, word32 cSz, const byte* a, word32 aSz)
14028
{
14029
    word32 blocks;
14030
    int partial;
14031
    int ret;
14032
14033
    /* Hash in A, the Authentication Data */
14034
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, cSz > 0);
14035
    if (ret != 0)
14036
        return ret;
14037
14038
    /* Hash in C, the Cipher text, and decrypt. */
14039
    if (cSz != 0 && p != NULL) {
14040
        /* Update count of cipher text we have hashed. */
14041
        aes->cSz += cSz;
14042
        if (aes->cOver > 0) {
14043
            /* Calculate amount we can use - fill up the block. */
14044
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
14045
            if (sz > cSz) {
14046
                sz = (byte)cSz;
14047
            }
14048
            /* Keep a copy of the cipher text for GHASH. */
14049
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
14050
            /* Decrypt some of the cipher text. */
14051
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
14052
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
14053
            /* Update count of unused encrypted counter. */
14054
            aes->cOver = (byte)(aes->cOver + sz);
14055
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
14056
                /* We have filled up the block and can process. */
14057
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14058
                if (aes->use_sha3_hw_crypto) {
14059
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTBLOCK(aes),
14060
                        AES_TAG(aes), aes->gcm.H);
14061
                }
14062
                else
14063
            #endif
14064
                {
14065
                    AES_GCM_ghash_block_AARCH64(AES_LASTBLOCK(aes),
14066
                        AES_TAG(aes), aes->gcm.H);
14067
                }
14068
                /* Reset count. */
14069
                aes->cOver = 0;
14070
            }
14071
            /* Used up some data. */
14072
            cSz -= sz;
14073
            c += sz;
14074
            p += sz;
14075
        }
14076
14077
        /* Calculate number of blocks of plaintext and the leftover. */
14078
        blocks = cSz / WC_AES_BLOCK_SIZE;
14079
        partial = cSz % WC_AES_BLOCK_SIZE;
14080
        if (blocks > 0) {
14081
            /* Decrypt and GHASH full blocks now. */
14082
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14083
            if (aes->use_sha3_hw_crypto) {
14084
                AES_GCM_decrypt_update_AARCH64_EOR3((byte*)aes->key,
14085
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
14086
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
14087
            }
14088
            else
14089
        #endif
14090
            {
14091
                AES_GCM_decrypt_update_AARCH64((byte*)aes->key,
14092
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
14093
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
14094
            }
14095
            /* Skip over to end of blocks. */
14096
            c += blocks * WC_AES_BLOCK_SIZE;
14097
            p += blocks * WC_AES_BLOCK_SIZE;
14098
        }
14099
        if (partial != 0) {
14100
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
14101
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
14102
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14103
            if (aes->use_sha3_hw_crypto) {
14104
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
14105
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
14106
                    AES_COUNTER(aes));
14107
            }
14108
            else
14109
        #endif
14110
            {
14111
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
14112
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
14113
            }
14114
            /* Keep cipher text for GHASH of last partial block. */
14115
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
14116
            /* XOR the remaining cipher text to calculate plaintext. */
14117
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
14118
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
14119
            /* Update count of the block used. */
14120
            aes->cOver = (byte)partial;
14121
        }
14122
    }
14123
14124
    return 0;
14125
}
14126
14127
/* Finalize the AES GCM for decryption and check the authentication tag.
14128
 *
14129
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
14130
 *
14131
 * @param [in, out] aes        AES object.
14132
 * @param [in]      authTag    Buffer holding authentication tag.
14133
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14134
 * @return  0 on success.
14135
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
14136
 *          value.
14137
 */
14138
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_AARCH64(
14139
    Aes* aes, const byte* authTag, word32 authTagSz)
14140
{
14141
    int ret = 0;
14142
    int res;
14143
    /* AAD block incomplete when > 0 */
14144
    byte over = aes->aOver;
14145
    byte *lastBlock = AES_LASTGBLOCK(aes);
14146
14147
    ASSERT_SAVED_VECTOR_REGISTERS();
14148
14149
    if (aes->cOver > 0) {
14150
        /* Cipher text block incomplete. */
14151
        over = aes->cOver;
14152
        lastBlock = AES_LASTBLOCK(aes);
14153
    }
14154
    if (over > 0) {
14155
        /* Zeroize the unused part of the block. */
14156
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
14157
        /* Hash the last block of cipher text. */
14158
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14159
        if (aes->use_sha3_hw_crypto) {
14160
            AES_GCM_ghash_block_AARCH64_EOR3(lastBlock, AES_TAG(aes),
14161
                aes->gcm.H);
14162
        }
14163
        else
14164
    #endif
14165
        {
14166
            AES_GCM_ghash_block_AARCH64(lastBlock, AES_TAG(aes), aes->gcm.H);
14167
        }
14168
    }
14169
    /* Calculate and compare the authentication tag. */
14170
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14171
    if (aes->use_sha3_hw_crypto) {
14172
        AES_GCM_decrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
14173
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
14174
    }
14175
    else
14176
#endif
14177
    {
14178
        AES_GCM_decrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
14179
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
14180
    }
14181
14182
    /* Return error code when calculated doesn't match input. */
14183
    if (res == 0) {
14184
        ret = AES_GCM_AUTH_E;
14185
    }
14186
    return ret;
14187
}
14188
#endif
14189
#endif
14190
14191
/* AES_GCM_H_PTR is defined earlier (before wc_AesGcmEncrypt). */
14192
#if defined(WOLFSSL_RISCV_ASM) && defined(WOLFSSL_AESGCM_STREAM)
14193
14194
static WARN_UNUSED_RESULT int AesGcmInit_RISCV64(Aes* aes, const byte* iv,
14195
    word32 ivSz)
14196
{
14197
    /* Reset state fields. */
14198
    aes->over = 0;
14199
    aes->aSz = 0;
14200
    aes->cSz = 0;
14201
    /* Set tag to all zeros as initial value. */
14202
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
14203
    /* Reset counts of AAD and cipher text. */
14204
    aes->aOver = 0;
14205
    aes->cOver = 0;
14206
14207
    {
14208
        AES_GCM_init_RISCV64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
14209
            AES_GCM_H_PTR(aes), AES_COUNTER(aes), AES_INITCTR(aes));
14210
    }
14211
14212
    return 0;
14213
}
14214
14215
/* Update the AES GCM for encryption with authentication data.
14216
 *
14217
 * Implementation uses RISC-V optimized assembly code.
14218
 *
14219
 * @param [in, out] aes   AES object.
14220
 * @param [in]      a     Buffer holding authentication data.
14221
 * @param [in]      aSz   Length of authentication data in bytes.
14222
 * @param [in]      endA  Whether no more authentication data is expected.
14223
 */
14224
static WARN_UNUSED_RESULT int AesGcmAadUpdate_RISCV64(
14225
    Aes* aes, const byte* a, word32 aSz, int endA)
14226
{
14227
    word32 blocks;
14228
    int partial;
14229
14230
    if (aSz != 0 && a != NULL) {
14231
        /* Total count of AAD updated. */
14232
        aes->aSz += aSz;
14233
        /* Check if we have unprocessed data. */
14234
        if (aes->aOver > 0) {
14235
            /* Calculate amount we can use - fill up the block. */
14236
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
14237
            if (sz > aSz) {
14238
                sz = (byte)aSz;
14239
            }
14240
            /* Copy extra into last GHASH block array and update count. */
14241
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
14242
            aes->aOver = (byte)(aes->aOver + sz);
14243
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
14244
                /* We have filled up the block and can process. */
14245
                {
14246
                    AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes),
14247
                        AES_TAG(aes), AES_GCM_H_PTR(aes));
14248
                }
14249
                /* Reset count. */
14250
                aes->aOver = 0;
14251
            }
14252
            /* Used up some data. */
14253
            aSz -= sz;
14254
            a += sz;
14255
        }
14256
14257
        /* Calculate number of blocks of AAD and the leftover. */
14258
        blocks = aSz / WC_AES_BLOCK_SIZE;
14259
        partial = aSz % WC_AES_BLOCK_SIZE;
14260
        if (blocks > 0) {
14261
            /* GHASH full blocks now. */
14262
            {
14263
                AES_GCM_aad_update_RISCV64(a, blocks * WC_AES_BLOCK_SIZE,
14264
                    AES_TAG(aes), AES_GCM_H_PTR(aes));
14265
            }
14266
            /* Skip over to end of AAD blocks. */
14267
            a += blocks * WC_AES_BLOCK_SIZE;
14268
        }
14269
        if (partial != 0) {
14270
            /* Cache the partial block. */
14271
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
14272
            aes->aOver = (byte)partial;
14273
        }
14274
    }
14275
    if (endA && (aes->aOver > 0)) {
14276
        /* No more AAD coming and we have a partial block. */
14277
        /* Fill the rest of the block with zeros. */
14278
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
14279
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
14280
        /* GHASH last AAD block. */
14281
        {
14282
            AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes),
14283
                AES_TAG(aes), AES_GCM_H_PTR(aes));
14284
        }
14285
        /* Clear partial count for next time through. */
14286
        aes->aOver = 0;
14287
    }
14288
14289
    return 0;
14290
}
14291
14292
/* Update the AES GCM for encryption with data and/or authentication data.
14293
 *
14294
 * Implementation uses RISC-V optimized assembly code.
14295
 *
14296
 * @param [in, out] aes  AES object.
14297
 * @param [out]     c    Buffer to hold cipher text.
14298
 * @param [in]      p    Buffer holding plaintext.
14299
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
14300
 * @param [in]      a    Buffer holding authentication data.
14301
 * @param [in]      aSz  Length of authentication data in bytes.
14302
 */
14303
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_RISCV64(
14304
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
14305
{
14306
    word32 blocks;
14307
    int partial;
14308
    int ret;
14309
14310
    /* Hash in A, the Authentication Data */
14311
    ret = AesGcmAadUpdate_RISCV64(aes, a, aSz, (cSz > 0) && (c != NULL));
14312
    if (ret != 0)
14313
        return ret;
14314
14315
    /* Encrypt plaintext and Hash in C, the Cipher text */
14316
    if (cSz != 0 && c != NULL) {
14317
        /* Update count of cipher text we have hashed. */
14318
        aes->cSz += cSz;
14319
        if (aes->cOver > 0) {
14320
            /* Calculate amount we can use - fill up the block. */
14321
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
14322
            if (sz > cSz) {
14323
                sz = (byte)cSz;
14324
            }
14325
            /* Encrypt some of the plaintext. */
14326
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
14327
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
14328
            /* Update count of unused encrypted counter. */
14329
            aes->cOver = (byte)(aes->cOver + sz);
14330
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
14331
                /* We have filled up the block and can process. */
14332
                {
14333
                    AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes),
14334
                        AES_TAG(aes), AES_GCM_H_PTR(aes));
14335
                }
14336
                /* Reset count. */
14337
                aes->cOver = 0;
14338
            }
14339
            /* Used up some data. */
14340
            cSz -= sz;
14341
            p += sz;
14342
            c += sz;
14343
        }
14344
14345
        /* Calculate number of blocks of plaintext and the leftover. */
14346
        blocks = cSz / WC_AES_BLOCK_SIZE;
14347
        partial = cSz % WC_AES_BLOCK_SIZE;
14348
        if (blocks > 0) {
14349
            /* Encrypt and GHASH full blocks now. */
14350
            {
14351
                AES_GCM_encrypt_update_RISCV64((byte*)aes->key,
14352
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
14353
                    AES_TAG(aes), AES_GCM_H_PTR(aes), AES_COUNTER(aes));
14354
            }
14355
            /* Skip over to end of blocks. */
14356
            p += blocks * WC_AES_BLOCK_SIZE;
14357
            c += blocks * WC_AES_BLOCK_SIZE;
14358
        }
14359
        if (partial != 0) {
14360
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
14361
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
14362
            {
14363
                AES_GCM_encrypt_block_RISCV64((byte*)aes->key, (int)aes->rounds,
14364
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
14365
            }
14366
            /* XOR the remaining plaintext to calculate cipher text.
14367
             * Keep cipher text for GHASH of last partial block.
14368
             */
14369
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
14370
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
14371
            /* Update count of the block used. */
14372
            aes->cOver = (byte)partial;
14373
        }
14374
    }
14375
    return 0;
14376
}
14377
14378
/* Finalize the AES GCM for encryption and calculate the authentication tag.
14379
 *
14380
 * Calls ARCH64 optimized assembly code.
14381
 *
14382
 * @param [in, out] aes        AES object.
14383
 * @param [in]      authTag    Buffer to hold authentication tag.
14384
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14385
 * @return  0 on success.
14386
 */
14387
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_RISCV64(Aes* aes,
14388
    byte* authTag, word32 authTagSz)
14389
{
14390
    /* AAD block incomplete when > 0 */
14391
    byte over = aes->aOver;
14392
14393
14394
    if (aes->cOver > 0) {
14395
        /* Cipher text block incomplete. */
14396
        over = aes->cOver;
14397
    }
14398
    if (over > 0) {
14399
        /* Fill the rest of the block with zeros. */
14400
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
14401
            (size_t)WC_AES_BLOCK_SIZE - over);
14402
        /* GHASH last cipher block. */
14403
        {
14404
            AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes), AES_TAG(aes),
14405
                AES_GCM_H_PTR(aes));
14406
        }
14407
    }
14408
    /* Calculate the authentication tag. */
14409
    {
14410
        AES_GCM_encrypt_final_RISCV64(AES_TAG(aes), authTag, authTagSz,
14411
            aes->cSz, aes->aSz, AES_GCM_H_PTR(aes), AES_INITCTR(aes));
14412
    }
14413
14414
    return 0;
14415
}
14416
14417
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
14418
/* Update the AES GCM for decryption with data and/or authentication data.
14419
 *
14420
 * @param [in, out] aes  AES object.
14421
 * @param [out]     p    Buffer to hold plaintext.
14422
 * @param [in]      c    Buffer holding cipher text.
14423
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
14424
 * @param [in]      a    Buffer holding authentication data.
14425
 * @param [in]      aSz  Length of authentication data in bytes.
14426
 */
14427
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_RISCV64(Aes* aes, byte* p,
14428
    const byte* c, word32 cSz, const byte* a, word32 aSz)
14429
{
14430
    word32 blocks;
14431
    int partial;
14432
    int ret;
14433
14434
    /* Hash in A, the Authentication Data */
14435
    ret = AesGcmAadUpdate_RISCV64(aes, a, aSz, cSz > 0);
14436
    if (ret != 0)
14437
        return ret;
14438
14439
    /* Hash in C, the Cipher text, and decrypt. */
14440
    if (cSz != 0 && p != NULL) {
14441
        /* Update count of cipher text we have hashed. */
14442
        aes->cSz += cSz;
14443
        if (aes->cOver > 0) {
14444
            /* Calculate amount we can use - fill up the block. */
14445
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
14446
            if (sz > cSz) {
14447
                sz = (byte)cSz;
14448
            }
14449
            /* Keep a copy of the cipher text for GHASH. */
14450
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
14451
            /* Decrypt some of the cipher text. */
14452
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
14453
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
14454
            /* Update count of unused encrypted counter. */
14455
            aes->cOver = (byte)(aes->cOver + sz);
14456
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
14457
                /* We have filled up the block and can process. */
14458
                {
14459
                    AES_GCM_ghash_block_RISCV64(AES_LASTBLOCK(aes),
14460
                        AES_TAG(aes), AES_GCM_H_PTR(aes));
14461
                }
14462
                /* Reset count. */
14463
                aes->cOver = 0;
14464
            }
14465
            /* Used up some data. */
14466
            cSz -= sz;
14467
            c += sz;
14468
            p += sz;
14469
        }
14470
14471
        /* Calculate number of blocks of plaintext and the leftover. */
14472
        blocks = cSz / WC_AES_BLOCK_SIZE;
14473
        partial = cSz % WC_AES_BLOCK_SIZE;
14474
        if (blocks > 0) {
14475
            /* Decrypt and GHASH full blocks now. */
14476
            {
14477
                AES_GCM_decrypt_update_RISCV64((byte*)aes->key,
14478
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
14479
                    AES_TAG(aes), AES_GCM_H_PTR(aes), AES_COUNTER(aes));
14480
            }
14481
            /* Skip over to end of blocks. */
14482
            c += blocks * WC_AES_BLOCK_SIZE;
14483
            p += blocks * WC_AES_BLOCK_SIZE;
14484
        }
14485
        if (partial != 0) {
14486
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
14487
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
14488
            {
14489
                AES_GCM_encrypt_block_RISCV64((byte*)aes->key, (int)aes->rounds,
14490
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
14491
            }
14492
            /* Keep cipher text for GHASH of last partial block. */
14493
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
14494
            /* XOR the remaining cipher text to calculate plaintext. */
14495
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
14496
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
14497
            /* Update count of the block used. */
14498
            aes->cOver = (byte)partial;
14499
        }
14500
    }
14501
14502
    return 0;
14503
}
14504
14505
/* Finalize the AES GCM for decryption and check the authentication tag.
14506
 *
14507
 * Implementation uses RISC-V optimized assembly code.
14508
 *
14509
 * @param [in, out] aes        AES object.
14510
 * @param [in]      authTag    Buffer holding authentication tag.
14511
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14512
 * @return  0 on success.
14513
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
14514
 *          value.
14515
 */
14516
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_RISCV64(
14517
    Aes* aes, const byte* authTag, word32 authTagSz)
14518
{
14519
    int ret = 0;
14520
    int res;
14521
    /* AAD block incomplete when > 0 */
14522
    byte over = aes->aOver;
14523
    byte *lastBlock = AES_LASTGBLOCK(aes);
14524
14525
14526
    if (aes->cOver > 0) {
14527
        /* Cipher text block incomplete. */
14528
        over = aes->cOver;
14529
        lastBlock = AES_LASTBLOCK(aes);
14530
    }
14531
    if (over > 0) {
14532
        /* Zeroize the unused part of the block. */
14533
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
14534
        /* Hash the last block of cipher text. */
14535
        {
14536
            AES_GCM_ghash_block_RISCV64(lastBlock, AES_TAG(aes), AES_GCM_H_PTR(aes));
14537
        }
14538
    }
14539
    /* Calculate and compare the authentication tag. */
14540
    {
14541
        AES_GCM_decrypt_final_RISCV64(AES_TAG(aes), authTag, authTagSz,
14542
            aes->cSz, aes->aSz, AES_GCM_H_PTR(aes), AES_INITCTR(aes), &res);
14543
    }
14544
14545
    /* Return error code when calculated doesn't match input. */
14546
    if (res == 0) {
14547
        ret = AES_GCM_AUTH_E;
14548
    }
14549
    return ret;
14550
}
14551
#endif
14552
#endif /* WOLFSSL_RISCV_ASM && WOLFSSL_AESGCM_STREAM */
14553
14554
/* Initialize an AES GCM cipher for encryption or decryption.
14555
 *
14556
 * Must call wc_AesInit() before calling this function.
14557
 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
14558
 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
14559
 *
14560
 * @param [in, out] aes   AES object.
14561
 * @param [in]      key   Buffer holding key.
14562
 * @param [in]      len   Length of key in bytes.
14563
 * @param [in]      iv    Buffer holding IV/nonce.
14564
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14565
 * @return  0 on success.
14566
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
14567
 *          is NULL, or the IV is NULL and no previous IV has been set.
14568
 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
14569
 */
14570
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
14571
    word32 ivSz)
14572
1.38k
{
14573
1.38k
    int ret = 0;
14574
14575
    /* Check validity of parameters. */
14576
1.38k
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
14577
1.38k
            ((ivSz == 0) && (iv != NULL)) ||
14578
1.38k
            ((ivSz > 0) && (iv == NULL))) {
14579
0
        ret = BAD_FUNC_ARG;
14580
0
    }
14581
14582
1.38k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
14583
1.38k
    if ((ret == 0) && (aes->streamData == NULL)) {
14584
        /* Allocate buffers for streaming. */
14585
591
        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
14586
591
        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
14587
591
                                                              DYNAMIC_TYPE_AES);
14588
591
        if (aes->streamData == NULL) {
14589
0
            ret = MEMORY_E;
14590
0
        }
14591
591
    }
14592
1.38k
#endif
14593
14594
    /* Set the key if passed in. */
14595
1.38k
    if ((ret == 0) && (key != NULL)) {
14596
591
        ret = wc_AesGcmSetKey(aes, key, len);
14597
591
    }
14598
14599
#if defined(WOLFSSL_ARM32_AES_DISPATCH) && defined(WOLFSSL_AESGCM_STREAM)
14600
    /* Streaming AES-GCM drives the counter through the base AES_ECB_encrypt,
14601
     * which needs the base key schedule, and there is no AES_GCM_init AArch32
14602
     * assembly - so an object entering the streaming API has to move to the
14603
     * base implementation.  Doing it here rather than in wc_AesGcmSetKey()
14604
     * leaves one-shot AES-GCM on the crypto extension in builds that merely
14605
     * compile the streaming API in.
14606
     *
14607
     * Only the key schedule needs rebuilding: wc_AesGcmSetKey() stores gcm.H
14608
     * un-reflected whichever path computed it, and the tables derived from it
14609
     * with it, so the hashing state carries over as-is.  Round key 0 of either
14610
     * schedule is the cipher key itself, so the base schedule is rebuilt in
14611
     * place without keeping a copy of the key. */
14612
    if ((ret == 0) && aes->use_aes_hw_crypto) {
14613
        byte rawKey[AES_MAX_KEY_SIZE / 8];
14614
14615
        XMEMCPY(rawKey, aes->key, aes->keylen);
14616
        aes->use_aes_hw_crypto = 0;
14617
        aes->use_pmull_hw_crypto = 0;
14618
        AES_set_encrypt_key(rawKey, (word32)aes->keylen * 8, (byte*)aes->key);
14619
        ForceZero(rawKey, sizeof(rawKey));
14620
    }
14621
#endif
14622
14623
1.38k
    if (ret == 0) {
14624
1.38k
        if (iv != NULL) {
14625
1.38k
            if (ivSz <= WC_AES_BLOCK_SIZE) {
14626
                /* Set the IV passed in if it is smaller than a block. */
14627
1.38k
                XMEMMOVE((byte*)aes->reg, iv, ivSz);
14628
1.38k
                aes->nonceSz = ivSz;
14629
1.38k
            }
14630
0
            else {
14631
                /* FIPS short-nonce detection depends on aes->nonceSz == 0
14632
                 * signifying that supplied ivSz > WC_AES_BLOCK_SIZE.
14633
                 */
14634
0
                aes->nonceSz = 0;
14635
0
            }
14636
1.38k
        }
14637
0
        else {
14638
            /* No IV passed in, check for cached IV. */
14639
0
            if (aes->nonceSz != 0) {
14640
                /* Use the cached copy. */
14641
0
                iv = (byte*)aes->reg;
14642
0
                ivSz = aes->nonceSz;
14643
0
            }
14644
0
        }
14645
14646
1.38k
        if (iv != NULL) {
14647
            /* Initialize with the IV. */
14648
14649
        #ifdef WOLFSSL_AESNI
14650
            if (aes->use_aesni) {
14651
                ret = SAVE_VECTOR_REGISTERS2();
14652
                if (ret == 0) {
14653
                    ret = AesGcmInit_aesni(aes, iv, ivSz);
14654
                    RESTORE_VECTOR_REGISTERS();
14655
                }
14656
                else {
14657
#ifdef WC_C_DYNAMIC_FALLBACK
14658
                    aes->use_aesni = 0;
14659
                    ret = AesGcmInit_C(aes, iv, ivSz);
14660
#else
14661
                    return ret;
14662
#endif
14663
                }
14664
            }
14665
            else
14666
        #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14667
              !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14668
            if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14669
                ret = AesGcmInit_AARCH64(aes, iv, ivSz);
14670
            }
14671
            else
14672
        #elif defined(WOLFSSL_RISCV_ASM)
14673
            ret = AesGcmInit_RISCV64(aes, iv, ivSz);
14674
            if (0)
14675
        #endif /* WOLFSSL_AESNI */
14676
1.38k
            {
14677
1.38k
                ret = AesGcmInit_C(aes, iv, ivSz);
14678
1.38k
            }
14679
14680
1.38k
            if (ret == 0)
14681
1.38k
                aes->nonceSet = 1;
14682
1.38k
        }
14683
1.38k
    }
14684
14685
1.38k
    return ret;
14686
1.38k
}
14687
14688
/* Initialize an AES GCM cipher for encryption.
14689
 *
14690
 * Must call wc_AesInit() before calling this function.
14691
 *
14692
 * @param [in, out] aes   AES object.
14693
 * @param [in]      key   Buffer holding key.
14694
 * @param [in]      len   Length of key in bytes.
14695
 * @param [in]      iv    Buffer holding IV/nonce.
14696
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14697
 * @return  0 on success.
14698
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
14699
 *          is NULL, or the IV is NULL and no previous IV has been set.
14700
 */
14701
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
14702
    word32 ivSz)
14703
0
{
14704
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
14705
    /* Note iv is an optional arg to wc_AesGcmEncryptInit(), so we tolerate zero ivSz
14706
     * here.
14707
     */
14708
    if ((ivSz > 0) && (ivSz < GCM_NONCE_MID_SZ))
14709
        return FIPS_BAD_VALUE_E;
14710
#endif
14711
14712
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
14713
0
}
14714
14715
/* Initialize an AES GCM cipher for encryption. Get IV.
14716
 *
14717
 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
14718
 * function.
14719
 * Must call wc_AesInit() before calling this function.
14720
 *
14721
 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
14722
 *
14723
 * @param [in, out] aes   AES object.
14724
 * @param [in]      key   Buffer holding key.
14725
 * @param [in]      len   Length of key in bytes.
14726
 * @param [in]      iv    Buffer holding IV/nonce.
14727
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14728
 * @return  0 on success.
14729
 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
14730
 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
14731
 *          nonce size.
14732
 */
14733
int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
14734
    word32 ivOutSz)
14735
0
{
14736
0
    int ret;
14737
14738
    /* Check validity of parameters. */
14739
0
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
14740
0
        ret = BAD_FUNC_ARG;
14741
0
    }
14742
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
14743
    else if (ivOutSz < GCM_NONCE_MID_SZ) {
14744
        ret = FIPS_BAD_VALUE_E;
14745
    }
14746
#endif
14747
0
    else {
14748
        /* Copy out the IV including generated part for decryption. */
14749
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
14750
        /* Initialize AES GCM cipher with key and cached Iv. */
14751
0
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
14752
0
    }
14753
14754
0
    return ret;
14755
0
}
14756
14757
/* Update the AES GCM for encryption with data and/or authentication data. */
14758
int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
14759
    const byte* authIn, word32 authInSz)
14760
5.28k
{
14761
5.28k
    int ret = 0;
14762
14763
    /* Check validity of parameters. */
14764
5.28k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
14765
721
            ((out == NULL) || (in == NULL)))) {
14766
0
        ret = BAD_FUNC_ARG;
14767
0
    }
14768
14769
    /* Check key has been set. */
14770
5.28k
    if ((ret == 0) && (!aes->gcmKeySet)) {
14771
0
        ret = MISSING_KEY;
14772
0
    }
14773
    /* Check IV has been set. */
14774
5.28k
    if ((ret == 0) && (!aes->nonceSet)) {
14775
0
        ret = MISSING_IV;
14776
0
    }
14777
14778
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
14779
    if ((ret == 0) && (aes->nonceSz != 0) && (aes->nonceSz < GCM_NONCE_MID_SZ))
14780
        ret = FIPS_BAD_VALUE_E;
14781
#endif
14782
14783
    /* Prevent overflow of aes->cSz and ->aSz.  Per NIST SP 800-38D section
14784
     * 5.2.1.1, the maximum allowed ciphertext limit is 2^32 - 2 blocks, but we
14785
     * currently pass around the cumulative sizes in bytes as word32s, so we
14786
     * can't currently support the maximum allowed.
14787
     */
14788
5.28k
    if ((ret == 0) &&
14789
5.28k
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
14790
5.28k
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
14791
0
    {
14792
0
        ret = AES_GCM_OVERFLOW_E;
14793
0
    }
14794
14795
5.28k
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
14796
339
        aes->invokeCtr[0]++;
14797
339
        if (aes->invokeCtr[0] == 0) {
14798
0
            aes->invokeCtr[1]++;
14799
0
            if (aes->invokeCtr[1] == 0)
14800
0
                ret = AES_GCM_OVERFLOW_E;
14801
0
        }
14802
339
    }
14803
14804
5.28k
    if (ret == 0) {
14805
        /* Encrypt with AAD and/or plaintext. */
14806
14807
    #ifdef WOLFSSL_AESNI
14808
        if (aes->use_aesni) {
14809
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14810
            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
14811
            RESTORE_VECTOR_REGISTERS();
14812
        }
14813
        else
14814
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14815
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14816
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14817
            ret = AesGcmEncryptUpdate_AARCH64(aes, out, in, sz, authIn,
14818
                authInSz);
14819
        }
14820
        else
14821
    #elif defined(WOLFSSL_RISCV_ASM)
14822
        ret = AesGcmEncryptUpdate_RISCV64(aes, out, in, sz, authIn, authInSz);
14823
        if (0)
14824
    #endif
14825
5.28k
        {
14826
            /* Encrypt the plaintext. */
14827
5.28k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
14828
5.28k
            if (ret == 0) {
14829
                /* Update the authentication tag with any authentication data and the
14830
                 * new cipher text. */
14831
5.28k
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
14832
5.28k
            }
14833
5.28k
        }
14834
5.28k
    }
14835
14836
5.28k
    return ret;
14837
5.28k
}
14838
14839
/* Finalize the AES GCM for encryption and return the authentication tag.
14840
 *
14841
 * Must set key and IV before calling this function.
14842
 * Must call wc_AesGcmInit() before calling this function.
14843
 *
14844
 * @param [in, out] aes        AES object.
14845
 * @param [out]     authTag    Buffer to hold authentication tag.
14846
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14847
 * @return  0 on success.
14848
 */
14849
int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
14850
280
{
14851
280
    int ret = 0;
14852
14853
    /* Check validity of parameters. */
14854
280
    if ((aes == NULL) || (authTag == NULL)) {
14855
0
        ret = BAD_FUNC_ARG;
14856
0
    }
14857
14858
280
    if (ret == 0)
14859
280
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
14860
14861
    /* Check key has been set. */
14862
280
    if ((ret == 0) && (!aes->gcmKeySet)) {
14863
0
        ret = MISSING_KEY;
14864
0
    }
14865
    /* Check IV has been set. */
14866
280
    if ((ret == 0) && (!aes->nonceSet)) {
14867
0
        ret = MISSING_IV;
14868
0
    }
14869
14870
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
14871
    if ((ret == 0) && (aes->nonceSz != 0) && (aes->nonceSz < GCM_NONCE_MID_SZ))
14872
        ret = FIPS_BAD_VALUE_E;
14873
#endif
14874
14875
280
    if (ret == 0) {
14876
        /* Calculate authentication tag. */
14877
    #ifdef WOLFSSL_AESNI
14878
        if (aes->use_aesni) {
14879
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14880
            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
14881
            RESTORE_VECTOR_REGISTERS();
14882
        }
14883
        else
14884
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14885
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14886
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14887
            ret = AesGcmEncryptFinal_AARCH64(aes, authTag, authTagSz);
14888
        }
14889
        else
14890
    #elif defined(WOLFSSL_RISCV_ASM)
14891
        ret = AesGcmEncryptFinal_RISCV64(aes, authTag, authTagSz);
14892
        if (0)
14893
    #endif
14894
280
        {
14895
280
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
14896
280
        }
14897
280
    }
14898
14899
280
    if ((ret == 0) && aes->ctrSet) {
14900
280
        IncCtr((byte*)aes->reg, aes->nonceSz);
14901
280
    }
14902
14903
280
    return ret;
14904
280
}
14905
14906
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
14907
/* Initialize an AES GCM cipher for decryption.
14908
 *
14909
 * Must call wc_AesInit() before calling this function.
14910
 *
14911
 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
14912
 * instead.
14913
 *
14914
 * @param [in, out] aes   AES object.
14915
 * @param [in]      key   Buffer holding key.
14916
 * @param [in]      len   Length of key in bytes.
14917
 * @param [in]      iv    Buffer holding IV/nonce.
14918
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14919
 * @return  0 on success.
14920
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
14921
 *          is NULL, or the IV is NULL and no previous IV has been set.
14922
 */
14923
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
14924
    word32 ivSz)
14925
0
{
14926
    /*
14927
     * There is no FIPS check on ivSz in decrypt mode -- SP
14928
     * 800-38D IV construction requirements bind encryption only; decryption
14929
     * must accept externally generated IVs of any supported length.
14930
     */
14931
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
14932
0
}
14933
14934
/* Update the AES GCM for decryption with data and/or authentication data. */
14935
int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
14936
    const byte* authIn, word32 authInSz)
14937
2.99k
{
14938
2.99k
    int ret = 0;
14939
14940
    /* Check validity of parameters. */
14941
2.99k
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
14942
40
            ((out == NULL) || (in == NULL)))) {
14943
0
        ret = BAD_FUNC_ARG;
14944
0
    }
14945
14946
    /* Check key has been set. */
14947
2.99k
    if ((ret == 0) && (!aes->gcmKeySet)) {
14948
0
        ret = MISSING_KEY;
14949
0
    }
14950
    /* Check IV has been set. */
14951
2.99k
    if ((ret == 0) && (!aes->nonceSet)) {
14952
0
        ret = MISSING_IV;
14953
0
    }
14954
14955
    /* Prevent overflow of aes->cSz and ->aSz.  Per NIST SP 800-38D section
14956
     * 5.2.1.1, the maximum allowed ciphertext limit is 2^32 - 2 blocks, but we
14957
     * currently pass around the cumulative sizes in bytes as word32s, so we
14958
     * can't currently support the maximum allowed.
14959
     */
14960
2.99k
    if ((ret == 0) &&
14961
2.99k
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
14962
2.99k
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
14963
0
    {
14964
0
        ret = AES_GCM_OVERFLOW_E;
14965
0
    }
14966
14967
2.99k
    if (ret == 0) {
14968
        /* Decrypt with AAD and/or cipher text. */
14969
    #ifdef WOLFSSL_AESNI
14970
        if (aes->use_aesni) {
14971
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14972
            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
14973
            RESTORE_VECTOR_REGISTERS();
14974
        }
14975
        else
14976
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14977
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14978
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14979
            ret = AesGcmDecryptUpdate_AARCH64(aes, out, in, sz, authIn,
14980
                authInSz);
14981
        }
14982
        else
14983
    #elif defined(WOLFSSL_RISCV_ASM)
14984
        ret = AesGcmDecryptUpdate_RISCV64(aes, out, in, sz, authIn, authInSz);
14985
        if (0)
14986
    #endif
14987
2.99k
        {
14988
            /* Update the authentication tag with any authentication data and
14989
             * cipher text. */
14990
2.99k
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
14991
            /* Decrypt the cipher text. */
14992
2.99k
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
14993
2.99k
        }
14994
2.99k
    }
14995
14996
2.99k
    return ret;
14997
2.99k
}
14998
14999
/* Finalize the AES GCM for decryption and check the authentication tag.
15000
 *
15001
 * Must set key and IV before calling this function.
15002
 * Must call wc_AesGcmInit() before calling this function.
15003
 *
15004
 * @param [in, out] aes        AES object.
15005
 * @param [in]      authTag    Buffer holding authentication tag.
15006
 * @param [in]      authTagSz  Length of authentication tag in bytes.
15007
 * @return  0 on success.
15008
 */
15009
int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
15010
226
{
15011
226
    int ret = 0;
15012
15013
    /* Check validity of parameters. */
15014
226
    if ((aes == NULL) || (authTag == NULL)) {
15015
0
        ret = BAD_FUNC_ARG;
15016
0
    }
15017
15018
226
    if (ret == 0)
15019
226
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
15020
15021
    /* Check key has been set. */
15022
226
    if ((ret == 0) && (!aes->gcmKeySet)) {
15023
0
        ret = MISSING_KEY;
15024
0
    }
15025
    /* Check IV has been set. */
15026
226
    if ((ret == 0) && (!aes->nonceSet)) {
15027
0
        ret = MISSING_IV;
15028
0
    }
15029
15030
226
    if (ret == 0) {
15031
        /* Calculate authentication tag and compare with one passed in.. */
15032
    #ifdef WOLFSSL_AESNI
15033
        if (aes->use_aesni) {
15034
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15035
            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
15036
            RESTORE_VECTOR_REGISTERS();
15037
        }
15038
        else
15039
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
15040
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15041
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
15042
            ret = AesGcmDecryptFinal_AARCH64(aes, authTag, authTagSz);
15043
        }
15044
        else
15045
    #elif defined(WOLFSSL_RISCV_ASM)
15046
        ret = AesGcmDecryptFinal_RISCV64(aes, authTag, authTagSz);
15047
        if (0)
15048
    #endif
15049
200
        {
15050
200
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
15051
            /* Calculate authentication tag. */
15052
200
            ret = AesGcmFinal_C(aes, calcTag, WC_AES_BLOCK_SIZE);
15053
200
            if (ret == 0) {
15054
                /* Check calculated tag matches the one passed in. */
15055
200
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
15056
190
                    ret = AES_GCM_AUTH_E;
15057
190
                }
15058
200
            }
15059
200
        }
15060
200
    }
15061
15062
226
    return ret;
15063
226
}
15064
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
15065
#endif /* WOLFSSL_AESGCM_STREAM */
15066
#endif /* WOLFSSL_XILINX_CRYPT */
15067
#endif /* end of block for AESGCM implementation selection */
15068
15069
15070
/* Common to all, abstract functions that build off of lower level AESGCM
15071
 * functions */
15072
#ifndef WC_NO_RNG
15073
15074
1.40k
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
15075
1.40k
    return (ivSz == GCM_NONCE_MIN_SZ ||
15076
1.40k
            ivSz == GCM_NONCE_MID_SZ ||
15077
0
            ivSz == GCM_NONCE_MAX_SZ);
15078
1.40k
}
15079
15080
15081
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
15082
1.40k
{
15083
1.40k
    int ret = 0;
15084
15085
1.40k
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
15086
0
        ret = BAD_FUNC_ARG;
15087
0
    }
15088
15089
1.40k
    if (ret == 0) {
15090
1.40k
        XMEMCPY((byte*)aes->reg, iv, ivSz);
15091
15092
        /* If the IV is 96, allow for a 2^64 invocation counter.
15093
         * For any other size for the nonce, limit the invocation
15094
         * counter to 32-bits. (SP 800-38D 8.3) */
15095
1.40k
        aes->invokeCtr[0] = 0;
15096
1.40k
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
15097
1.40k
    #ifdef WOLFSSL_AESGCM_STREAM
15098
1.40k
        aes->ctrSet = 1;
15099
1.40k
    #endif
15100
1.40k
        aes->nonceSz = ivSz;
15101
1.40k
    }
15102
15103
1.40k
    return ret;
15104
1.40k
}
15105
15106
15107
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
15108
                   const byte* ivFixed, word32 ivFixedSz,
15109
                   WC_RNG* rng)
15110
0
{
15111
0
    int ret = 0;
15112
15113
0
    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
15114
0
        (ivFixed == NULL && ivFixedSz != 0) ||
15115
0
        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
15116
15117
0
        ret = BAD_FUNC_ARG;
15118
0
    }
15119
15120
0
    if (ret == 0) {
15121
0
        byte* iv = (byte*)aes->reg;
15122
15123
0
        if (ivFixedSz)
15124
0
            XMEMCPY(iv, ivFixed, ivFixedSz);
15125
15126
0
        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
15127
0
    }
15128
15129
0
    if (ret == 0) {
15130
        /* If the IV is 96, allow for a 2^64 invocation counter.
15131
         * For any other size for the nonce, limit the invocation
15132
         * counter to 32-bits. (SP 800-38D 8.3) */
15133
0
        aes->invokeCtr[0] = 0;
15134
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
15135
0
    #ifdef WOLFSSL_AESGCM_STREAM
15136
0
        aes->ctrSet = 1;
15137
0
    #endif
15138
0
        aes->nonceSz = ivSz;
15139
0
    }
15140
15141
0
    return ret;
15142
0
}
15143
15144
15145
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
15146
                        byte* ivOut, word32 ivOutSz,
15147
                        byte* authTag, word32 authTagSz,
15148
                        const byte* authIn, word32 authInSz)
15149
527
{
15150
527
    int ret = 0;
15151
15152
527
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
15153
527
        ivOut == NULL || ivOutSz != aes->nonceSz ||
15154
527
        (authIn == NULL && authInSz != 0)) {
15155
15156
0
        ret = BAD_FUNC_ARG;
15157
0
    }
15158
15159
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
15160
    if ((ret == 0) && (ivOutSz < GCM_NONCE_MID_SZ))
15161
        ret = FIPS_BAD_VALUE_E;
15162
#endif
15163
15164
527
    if (ret == 0) {
15165
527
        aes->invokeCtr[0]++;
15166
527
        if (aes->invokeCtr[0] == 0) {
15167
0
            aes->invokeCtr[1]++;
15168
0
            if (aes->invokeCtr[1] == 0)
15169
0
                ret = AES_GCM_OVERFLOW_E;
15170
0
        }
15171
527
    }
15172
15173
527
    if (ret == 0) {
15174
        /* Pass the encrypt its nonce out of ivOut rather than aes->reg. Some
15175
         * backends use aes->reg as scratch space, and an asynchronous backend
15176
         * keeps the pointer until the operation completes, so aes->reg is not
15177
         * a stable place to hold the nonce being consumed. */
15178
527
        XMEMCPY(ivOut, aes->reg, ivOutSz);
15179
527
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
15180
527
                               ivOut, ivOutSz,
15181
527
                               authTag, authTagSz,
15182
527
                               authIn, authInSz);
15183
        /* Put the nonce back unconditionally - a backend may have left scratch
15184
         * data in aes->reg - so a failed encrypt leaves the counter on the
15185
         * nonce it did not consume rather than on backend leftovers. */
15186
527
        XMEMCPY(aes->reg, ivOut, ivOutSz);
15187
        /* A nonce handed to an asynchronous backend has been consumed even
15188
         * though the operation has not finished yet - the counter must still
15189
         * advance or the next record would reuse this nonce. */
15190
527
        if (ret == 0 || ret == WC_NO_ERR_TRACE(WC_PENDING_E))
15191
527
            IncCtr((byte*)aes->reg, ivOutSz);
15192
527
    }
15193
15194
527
    return ret;
15195
527
}
15196
15197
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
15198
            const byte* authIn, word32 authInSz,
15199
            byte* authTag, word32 authTagSz, WC_RNG* rng)
15200
0
{
15201
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
15202
0
    int ret;
15203
15204
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
15205
0
        authTag == NULL || authTagSz == 0 || rng == NULL) {
15206
15207
0
        return BAD_FUNC_ARG;
15208
0
    }
15209
15210
0
#ifdef WOLFSSL_SMALL_STACK
15211
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
15212
#else
15213
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15214
#endif
15215
0
    if (ret != 0)
15216
0
        return ret;
15217
15218
0
    ret = wc_AesGcmSetKey(aes, key, keySz);
15219
0
    if (ret == 0)
15220
0
        ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
15221
0
    if (ret == 0)
15222
0
        ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
15223
0
                                  authTag, authTagSz, authIn, authInSz);
15224
15225
0
#ifdef WOLFSSL_SMALL_STACK
15226
0
    wc_AesDelete(aes, NULL);
15227
#else
15228
    wc_AesFree(aes);
15229
#endif
15230
15231
0
    return ret;
15232
0
}
15233
15234
int wc_GmacVerify(const byte* key, word32 keySz,
15235
                  const byte* iv, word32 ivSz,
15236
                  const byte* authIn, word32 authInSz,
15237
                  const byte* authTag, word32 authTagSz)
15238
0
{
15239
0
    int ret;
15240
0
#ifdef HAVE_AES_DECRYPT
15241
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
15242
15243
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
15244
0
        authTag == NULL || authTagSz == 0 || authTagSz > WC_AES_BLOCK_SIZE) {
15245
15246
0
        return BAD_FUNC_ARG;
15247
0
    }
15248
15249
0
#ifdef WOLFSSL_SMALL_STACK
15250
0
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
15251
#else
15252
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15253
#endif
15254
0
    if (ret == 0) {
15255
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
15256
0
        if (ret == 0)
15257
0
            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
15258
0
                                  authTag, authTagSz, authIn, authInSz);
15259
15260
0
    }
15261
0
#ifdef WOLFSSL_SMALL_STACK
15262
0
    wc_AesDelete(aes, NULL);
15263
#else
15264
    wc_AesFree(aes);
15265
#endif
15266
#else
15267
    (void)key;
15268
    (void)keySz;
15269
    (void)iv;
15270
    (void)ivSz;
15271
    (void)authIn;
15272
    (void)authInSz;
15273
    (void)authTag;
15274
    (void)authTagSz;
15275
    ret = NOT_COMPILED_IN;
15276
#endif
15277
0
    return ret;
15278
0
}
15279
15280
#endif /* WC_NO_RNG */
15281
15282
15283
int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
15284
0
{
15285
0
    if (gmac == NULL || key == NULL) {
15286
0
        return BAD_FUNC_ARG;
15287
0
    }
15288
0
    return wc_AesGcmSetKey(&gmac->aes, key, len);
15289
0
}
15290
15291
15292
/* Note, wc_GmacUpdate() is not a streaming API, it's a one-shot calculation of
15293
 * the authTag.
15294
 */
15295
int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
15296
                              const byte* authIn, word32 authInSz,
15297
                              byte* authTag, word32 authTagSz)
15298
0
{
15299
0
    if (gmac == NULL) {
15300
0
        return BAD_FUNC_ARG;
15301
0
    }
15302
15303
0
    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
15304
0
                                         authTag, authTagSz, authIn, authInSz);
15305
0
}
15306
15307
#endif /* HAVE_AESGCM */
15308
15309
#ifdef HAVE_AESCCM
15310
15311
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
15312
258
{
15313
258
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
15314
0
        return BAD_FUNC_ARG;
15315
15316
258
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
15317
258
}
15318
15319
15320
/* Checks if the tag size is an accepted value based on RFC 3610 section 2
15321
 * returns 0 if tag size is ok
15322
 */
15323
int wc_AesCcmCheckTagSize(int sz)
15324
428
{
15325
    /* values here are from RFC 3610 section 2 */
15326
428
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
15327
194
            && sz != 16) {
15328
0
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
15329
0
        return BAD_FUNC_ARG;
15330
0
    }
15331
428
    return 0;
15332
428
}
15333
15334
#if defined(HAVE_COLDFIRE_SEC)
15335
    #error "Coldfire SEC doesn't currently support AES-CCM mode"
15336
15337
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
15338
        !defined(WOLFSSL_QNX_CAAM)
15339
    /* implemented in wolfcrypt/src/port/caam_aes.c */
15340
15341
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
15342
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
15343
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15344
                   const byte* nonce, word32 nonceSz,
15345
                   byte* authTag, word32 authTagSz,
15346
                   const byte* authIn, word32 authInSz)
15347
{
15348
    return wc_AesCcmEncrypt_silabs(
15349
        aes, out, in, inSz,
15350
        nonce, nonceSz,
15351
        authTag, authTagSz,
15352
        authIn, authInSz);
15353
}
15354
15355
#ifdef HAVE_AES_DECRYPT
15356
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15357
                   const byte* nonce, word32 nonceSz,
15358
                   const byte* authTag, word32 authTagSz,
15359
                   const byte* authIn, word32 authInSz)
15360
{
15361
    return wc_AesCcmDecrypt_silabs(
15362
        aes, out, in, inSz,
15363
        nonce, nonceSz,
15364
        authTag, authTagSz,
15365
        authIn, authInSz);
15366
}
15367
#endif
15368
#elif defined(FREESCALE_LTC)
15369
15370
/* return 0 on success */
15371
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15372
                   const byte* nonce, word32 nonceSz,
15373
                   byte* authTag, word32 authTagSz,
15374
                   const byte* authIn, word32 authInSz)
15375
{
15376
    byte *key;
15377
    word32 keySize;
15378
    status_t status;
15379
15380
    /* sanity check on arguments */
15381
    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
15382
     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
15383
     * don't allow it here either.
15384
     */
15385
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
15386
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
15387
        return BAD_FUNC_ARG;
15388
    }
15389
15390
    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
15391
        return BAD_FUNC_ARG;
15392
    }
15393
15394
    key = (byte*)aes->key;
15395
15396
    status = wc_AesGetKeySize(aes, &keySize);
15397
    if (status != 0) {
15398
        return status;
15399
    }
15400
15401
    {
15402
        word32 lenSz = (word32)WC_AES_BLOCK_SIZE - 1U - nonceSz;
15403
        /* With a large nonce, B[] runs out of room to represent inSz, and beyond
15404
         * that, the counter itself can wrap.
15405
         */
15406
        if ((lenSz < sizeof(inSz)) &&
15407
            (inSz >= ((word32)1 << (lenSz * 8))))
15408
        {
15409
            return AES_CCM_OVERFLOW_E;
15410
        }
15411
    }
15412
15413
    status = wolfSSL_CryptHwMutexLock();
15414
    if (status != 0)
15415
        return status;
15416
15417
    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
15418
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
15419
    wolfSSL_CryptHwMutexUnLock();
15420
15421
    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
15422
}
15423
15424
#ifdef HAVE_AES_DECRYPT
15425
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15426
                   const byte* nonce, word32 nonceSz,
15427
                   const byte* authTag, word32 authTagSz,
15428
                   const byte* authIn, word32 authInSz)
15429
{
15430
    byte *key;
15431
    word32 keySize;
15432
    status_t status;
15433
15434
    /* sanity check on arguments */
15435
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
15436
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
15437
        return BAD_FUNC_ARG;
15438
    }
15439
15440
    key = (byte*)aes->key;
15441
15442
    status = wc_AesGetKeySize(aes, &keySize);
15443
    if (status != 0) {
15444
        return status;
15445
    }
15446
15447
    {
15448
        word32 lenSz = (word32)WC_AES_BLOCK_SIZE - 1U - nonceSz;
15449
        /* With a large nonce, B[] runs out of room to represent inSz, and beyond
15450
         * that, the counter itself can wrap.
15451
         */
15452
        if ((lenSz < sizeof(inSz)) &&
15453
            (inSz >= ((word32)1 << (lenSz * 8))))
15454
        {
15455
            return AES_CCM_OVERFLOW_E;
15456
        }
15457
    }
15458
15459
    status = wolfSSL_CryptHwMutexLock();
15460
    if (status != 0)
15461
        return status;
15462
    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
15463
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
15464
    wolfSSL_CryptHwMutexUnLock();
15465
15466
    if (status != kStatus_Success) {
15467
        XMEMSET(out, 0, inSz);
15468
        return AES_CCM_AUTH_E;
15469
    }
15470
    return 0;
15471
}
15472
#endif /* HAVE_AES_DECRYPT */
15473
15474
#else
15475
15476
/* Software CCM */
15477
static WARN_UNUSED_RESULT int roll_x(
15478
    Aes* aes, const byte* in, word32 inSz, byte* out)
15479
427
{
15480
427
    int ret;
15481
15482
    /* process the bulk of the data */
15483
20.6k
    while (inSz >= WC_AES_BLOCK_SIZE) {
15484
20.1k
        xorbuf(out, in, WC_AES_BLOCK_SIZE);
15485
20.1k
        in += WC_AES_BLOCK_SIZE;
15486
20.1k
        inSz -= WC_AES_BLOCK_SIZE;
15487
15488
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
15489
         * roll_x() after the AES cache lines are already hot -- no need to
15490
         * absorb additional prefetch overhead here.
15491
         */
15492
20.1k
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
15493
20.1k
        if (ret != 0)
15494
0
            return ret;
15495
20.1k
    }
15496
15497
    /* process remainder of the data */
15498
427
    if (inSz > 0) {
15499
424
        xorbuf(out, in, inSz);
15500
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
15501
         * roll_x() after the AES cache lines are already hot -- no need to
15502
         * absorb additional prefetch overhead here.
15503
         */
15504
424
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
15505
424
        if (ret != 0)
15506
0
            return ret;
15507
424
    }
15508
15509
427
    return 0;
15510
427
}
15511
15512
static WARN_UNUSED_RESULT int roll_auth(
15513
    Aes* aes, const byte* in, word32 inSz, byte* out)
15514
428
{
15515
428
    word32 authLenSz;
15516
428
    word32 remainder;
15517
428
    int ret;
15518
15519
    /* encode the length in.  WC_OCTET, not (byte): the cast keeps the whole
15520
     * cell where CHAR_BIT != 8, so any length above 0xFF would XOR stray bits
15521
     * into the CBC-MAC input block. */
15522
428
    if (inSz <= 0xFEFF) {
15523
428
        authLenSz = 2;
15524
428
        out[0] ^= WC_OCTET(inSz >> 8);
15525
428
        out[1] ^= WC_OCTET(inSz);
15526
428
    }
15527
0
    else {
15528
0
        authLenSz = 6;
15529
0
        out[0] ^= 0xFF;
15530
0
        out[1] ^= 0xFE;
15531
0
        out[2] ^= WC_OCTET(inSz >> 24);
15532
0
        out[3] ^= WC_OCTET(inSz >> 16);
15533
0
        out[4] ^= WC_OCTET(inSz >>  8);
15534
0
        out[5] ^= WC_OCTET(inSz);
15535
0
    }
15536
    /* Note, the protocol handles auth data up to 2^64, but we are
15537
     * using 32-bit sizes right now, so the bigger data isn't handled
15538
     * else {}
15539
     */
15540
15541
    /* start fill out the rest of the first block */
15542
428
    remainder = WC_AES_BLOCK_SIZE - authLenSz;
15543
428
    if (inSz >= remainder) {
15544
        /* plenty of bulk data to fill the remainder of this block */
15545
0
        xorbuf(out + authLenSz, in, remainder);
15546
0
        inSz -= remainder;
15547
0
        in += remainder;
15548
0
    }
15549
428
    else {
15550
        /* not enough bulk data, copy what is available, and pad zero */
15551
428
        xorbuf(out + authLenSz, in, inSz);
15552
428
        inSz = 0;
15553
428
    }
15554
    /* wc_AesCcmEncrypt() and wc_AesCcmDecrypt() only call roll_auth() after the
15555
     * AES cache lines are already hot -- no need to absorb additional prefetch
15556
     * overhead here.
15557
     */
15558
428
    ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
15559
15560
428
    if ((ret == 0) && (inSz > 0)) {
15561
0
        ret = roll_x(aes, in, inSz, out);
15562
0
    }
15563
15564
428
    return ret;
15565
428
}
15566
15567
15568
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
15569
20.1k
{
15570
20.1k
    word32 i;
15571
15572
20.2k
    for (i = 0; i < lenSz; i++) {
15573
        /* See IncrementAesCounter(): a bare ++byte leaves 0x100 in the cell
15574
         * and never carries. */
15575
20.2k
        B[WC_AES_BLOCK_SIZE - 1 - i] =
15576
20.2k
            WC_OCTET(B[WC_AES_BLOCK_SIZE - 1 - i] + 1);
15577
20.2k
        if (B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
15578
20.2k
    }
15579
20.1k
}
15580
15581
#ifdef WOLFSSL_AESNI
15582
static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
15583
{
15584
    word32 i;
15585
15586
    /* B+1 = B */
15587
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 1, B, WC_AES_BLOCK_SIZE);
15588
    /* B+2,B+3 = B,B+1 */
15589
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 2, B, WC_AES_BLOCK_SIZE * 2);
15590
15591
    for (i = 0; i < lenSz; i++) {
15592
        if (++B[WC_AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
15593
    }
15594
    B[WC_AES_BLOCK_SIZE * 3 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 3 - 1] + 2U);
15595
    if (B[WC_AES_BLOCK_SIZE * 3 - 1] < 2U) {
15596
        for (i = 1; i < lenSz; i++) {
15597
            if (++B[WC_AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
15598
        }
15599
    }
15600
    B[WC_AES_BLOCK_SIZE * 4 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 4 - 1] + 3U);
15601
    if (B[WC_AES_BLOCK_SIZE * 4 - 1] < 3U) {
15602
        for (i = 1; i < lenSz; i++) {
15603
            if (++B[WC_AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
15604
        }
15605
    }
15606
}
15607
15608
static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
15609
{
15610
    word32 i;
15611
15612
    B[WC_AES_BLOCK_SIZE - 1] = (byte)(B[WC_AES_BLOCK_SIZE - 1] + 4U);
15613
    if (B[WC_AES_BLOCK_SIZE - 1] < 4U) {
15614
        for (i = 1; i < lenSz; i++) {
15615
            if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) break;
15616
        }
15617
    }
15618
}
15619
#endif
15620
15621
/* Software AES - CCM Encrypt */
15622
/* return 0 on success */
15623
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15624
                   const byte* nonce, word32 nonceSz,
15625
                   byte* authTag, word32 authTagSz,
15626
                   const byte* authIn, word32 authInSz)
15627
393
{
15628
#ifdef WOLFSSL_AESNI
15629
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
15630
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
15631
#else
15632
393
    byte A[WC_AES_BLOCK_SIZE];
15633
393
    byte B[WC_AES_BLOCK_SIZE];
15634
393
#endif
15635
393
    byte lenSz;
15636
393
    word32 i;
15637
393
    byte mask = 0xFF;
15638
393
    const word32 wordSz = (word32)sizeof(word32);
15639
393
    int ret;
15640
15641
    /* sanity check on arguments */
15642
393
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
15643
393
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
15644
393
            authTagSz > WC_AES_BLOCK_SIZE)
15645
0
        return BAD_FUNC_ARG;
15646
15647
    /* Sanity check on authIn to prevent segfault in xorbuf() where
15648
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
15649
393
    if (authIn == NULL && authInSz > 0)
15650
0
        return BAD_FUNC_ARG;
15651
15652
    /* sanity check on tag size */
15653
393
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
15654
0
        return BAD_FUNC_ARG;
15655
0
    }
15656
15657
393
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
15658
15659
    /* With a large nonce, B[] runs out of room to represent inSz, and beyond
15660
     * that, the counter itself can wrap.
15661
     */
15662
393
    if ((lenSz < sizeof(inSz)) &&
15663
393
        (inSz >= ((word32)1 << (lenSz * 8))))
15664
0
    {
15665
0
        return AES_CCM_OVERFLOW_E;
15666
0
    }
15667
15668
393
#ifdef WOLF_CRYPTO_CB
15669
393
    #ifndef WOLF_CRYPTO_CB_FIND
15670
393
    if (aes->devId != INVALID_DEVID)
15671
0
    #endif
15672
0
    {
15673
0
        int crypto_cb_ret =
15674
0
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
15675
0
                                      authTag, authTagSz, authIn, authInSz);
15676
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15677
0
            return crypto_cb_ret;
15678
        /* fall-through when unavailable */
15679
0
    }
15680
393
#endif
15681
15682
    /* Software/HW key schedule required from here on. */
15683
393
    if (!WC_AES_KEY_IS_SET(aes)) {
15684
0
        WOLFSSL_MSG("AES key not set");
15685
0
        return MISSING_KEY;
15686
0
    }
15687
15688
393
    XMEMSET(A, 0, sizeof(A));
15689
393
    XMEMCPY(B+1, nonce, nonceSz);
15690
15691
393
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
15692
393
                  + (8 * (((byte)authTagSz - 2) / 2))
15693
393
                  + (lenSz - 1));
15694
1.57k
    for (i = 0; i < lenSz; i++) {
15695
1.17k
        if (mask && i >= wordSz)
15696
0
            mask = 0x00;
15697
1.17k
        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
15698
1.17k
    }
15699
15700
#ifdef WOLFSSL_CHECK_MEM_ZERO
15701
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
15702
#endif
15703
15704
393
    VECTOR_REGISTERS_PUSH;
15705
    /* note this wc_AesEncrypt() will perform cache prefetches if needed, so
15706
     * that the later encrypt ops don't need to.
15707
     */
15708
393
    ret = wc_AesEncrypt(aes, B, A);
15709
#ifdef WOLFSSL_CHECK_MEM_ZERO
15710
    if (ret == 0)
15711
        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
15712
#endif
15713
15714
393
    if ((ret == 0) && (authInSz > 0))
15715
393
        ret = roll_auth(aes, authIn, authInSz, A);
15716
15717
393
    if ((ret == 0) && (inSz > 0))
15718
393
        ret = roll_x(aes, in, inSz, A);
15719
15720
393
    if (ret == 0) {
15721
393
        XMEMCPY(authTag, A, authTagSz);
15722
15723
393
        B[0] = (byte)(lenSz - 1U);
15724
1.57k
        for (i = 0; i < lenSz; i++)
15725
1.17k
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15726
393
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15727
393
    }
15728
15729
393
    if (ret == 0) {
15730
393
        xorbuf(authTag, A, authTagSz);
15731
393
        B[15] = 1;
15732
393
    }
15733
#ifdef WOLFSSL_AESNI
15734
    if ((ret == 0) && aes->use_aesni) {
15735
        while (inSz >= WC_AES_BLOCK_SIZE * 4) {
15736
            AesCcmCtrIncSet4(B, lenSz);
15737
15738
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
15739
                            (int)aes->rounds);
15740
15741
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
15742
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE * 4);
15743
15744
            inSz -= WC_AES_BLOCK_SIZE * 4;
15745
            in += WC_AES_BLOCK_SIZE * 4;
15746
            out += WC_AES_BLOCK_SIZE * 4;
15747
15748
            AesCcmCtrInc4(B, lenSz);
15749
        }
15750
    }
15751
#endif
15752
393
    if (ret == 0) {
15753
15.6k
        while (inSz >= WC_AES_BLOCK_SIZE) {
15754
15.2k
            ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15755
15.2k
            if (ret != 0)
15756
0
                break;
15757
15.2k
            xorbuf(A, in, WC_AES_BLOCK_SIZE);
15758
15.2k
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
15759
15760
15.2k
            AesCcmCtrInc(B, lenSz);
15761
15.2k
            inSz -= WC_AES_BLOCK_SIZE;
15762
15.2k
            in += WC_AES_BLOCK_SIZE;
15763
15.2k
            out += WC_AES_BLOCK_SIZE;
15764
15.2k
        }
15765
393
    }
15766
393
    if ((ret == 0) && (inSz > 0)) {
15767
393
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15768
393
    }
15769
393
    if ((ret == 0) && (inSz > 0)) {
15770
393
        xorbuf(A, in, inSz);
15771
393
        XMEMCPY(out, A, inSz);
15772
393
    }
15773
15774
393
    ForceZero(A, sizeof(A));
15775
393
    ForceZero(B, sizeof(B));
15776
15777
#ifdef WOLFSSL_CHECK_MEM_ZERO
15778
    wc_MemZero_Check(A, sizeof(A));
15779
    wc_MemZero_Check(B, sizeof(B));
15780
#endif
15781
15782
393
    VECTOR_REGISTERS_POP;
15783
15784
393
    return ret;
15785
393
}
15786
15787
#ifdef HAVE_AES_DECRYPT
15788
/* Software AES - CCM Decrypt */
15789
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15790
                   const byte* nonce, word32 nonceSz,
15791
                   const byte* authTag, word32 authTagSz,
15792
                   const byte* authIn, word32 authInSz)
15793
35
{
15794
#ifdef WOLFSSL_AESNI
15795
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
15796
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
15797
#else
15798
35
    byte A[WC_AES_BLOCK_SIZE];
15799
35
    byte B[WC_AES_BLOCK_SIZE];
15800
35
#endif
15801
35
    byte* o;
15802
35
    byte lenSz;
15803
35
    word32 i, oSz;
15804
35
    byte mask = 0xFF;
15805
35
    const word32 wordSz = (word32)sizeof(word32);
15806
35
    int ret = 0;
15807
35
#ifdef WC_AES_HAVE_PREFETCH_ARG
15808
35
    int did_prefetches = 0;
15809
35
#endif
15810
15811
    /* sanity check on arguments */
15812
35
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
15813
35
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
15814
35
        authTagSz > WC_AES_BLOCK_SIZE)
15815
0
        return BAD_FUNC_ARG;
15816
15817
    /* Sanity check on authIn to prevent segfault in xorbuf() where
15818
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
15819
35
    if (authIn == NULL && authInSz > 0)
15820
0
        return BAD_FUNC_ARG;
15821
15822
    /* sanity check on tag size */
15823
35
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
15824
0
        return BAD_FUNC_ARG;
15825
0
    }
15826
15827
35
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
15828
15829
    /* With a large nonce, B[] runs out of room to represent inSz, and beyond
15830
     * that, the counter itself can wrap.
15831
     */
15832
35
    if ((lenSz < sizeof(inSz)) &&
15833
35
        (inSz >= ((word32)1 << (lenSz * 8))))
15834
0
    {
15835
0
        return AES_CCM_OVERFLOW_E;
15836
0
    }
15837
15838
35
#ifdef WOLF_CRYPTO_CB
15839
35
    #ifndef WOLF_CRYPTO_CB_FIND
15840
35
    if (aes->devId != INVALID_DEVID)
15841
0
    #endif
15842
0
    {
15843
0
        int crypto_cb_ret =
15844
0
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
15845
0
            authTag, authTagSz, authIn, authInSz);
15846
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15847
0
            return crypto_cb_ret;
15848
        /* fall-through when unavailable */
15849
0
    }
15850
35
#endif
15851
15852
    /* Software/HW key schedule required from here on. */
15853
35
    if (!WC_AES_KEY_IS_SET(aes)) {
15854
0
        WOLFSSL_MSG("AES key not set");
15855
0
        return MISSING_KEY;
15856
0
    }
15857
15858
35
    o = out;
15859
35
    oSz = inSz;
15860
35
    XMEMSET(A, 0, sizeof A);
15861
35
    XMEMCPY(B+1, nonce, nonceSz);
15862
15863
35
    B[0] = (byte)(lenSz - 1U);
15864
140
    for (i = 0; i < lenSz; i++)
15865
105
        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15866
35
    B[15] = 1;
15867
15868
#ifdef WOLFSSL_CHECK_MEM_ZERO
15869
    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
15870
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
15871
#endif
15872
15873
35
    VECTOR_REGISTERS_PUSH;
15874
15875
#ifdef WOLFSSL_AESNI
15876
    if (aes->use_aesni) {
15877
        while (oSz >= WC_AES_BLOCK_SIZE * 4) {
15878
            AesCcmCtrIncSet4(B, lenSz);
15879
15880
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
15881
                            (int)aes->rounds);
15882
15883
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
15884
            XMEMCPY(o, A, WC_AES_BLOCK_SIZE * 4);
15885
15886
            oSz -= WC_AES_BLOCK_SIZE * 4;
15887
            in += WC_AES_BLOCK_SIZE * 4;
15888
            o += WC_AES_BLOCK_SIZE * 4;
15889
15890
            AesCcmCtrInc4(B, lenSz);
15891
        }
15892
    }
15893
#endif
15894
15895
4.97k
    while (oSz >= WC_AES_BLOCK_SIZE) {
15896
4.94k
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15897
4.94k
        if (ret != 0)
15898
0
            break;
15899
4.94k
        xorbuf(A, in, WC_AES_BLOCK_SIZE);
15900
4.94k
        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
15901
4.94k
        AesCcmCtrInc(B, lenSz);
15902
4.94k
        oSz -= WC_AES_BLOCK_SIZE;
15903
4.94k
        in += WC_AES_BLOCK_SIZE;
15904
4.94k
        o += WC_AES_BLOCK_SIZE;
15905
4.94k
    }
15906
15907
    /* oSz, not inSz, is the count of bytes left after the block loop above --
15908
     * inSz is kept pristine here for the CBC-MAC phase below. */
15909
35
    if ((ret == 0) && (oSz > 0))
15910
31
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15911
15912
35
    if ((ret == 0) && (oSz > 0)) {
15913
31
        xorbuf(A, in, oSz);
15914
31
        XMEMCPY(o, A, oSz);
15915
31
    }
15916
15917
35
    if (ret == 0) {
15918
35
        o = out;
15919
35
        oSz = inSz;
15920
15921
35
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
15922
35
                      + (8 * (((byte)authTagSz - 2) / 2))
15923
35
                      + (lenSz - 1));
15924
140
        for (i = 0; i < lenSz; i++) {
15925
105
            if (mask && i >= wordSz)
15926
0
                mask = 0x00;
15927
105
            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
15928
105
        }
15929
15930
35
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15931
35
    }
15932
15933
35
    if (ret == 0) {
15934
35
        if (authInSz > 0)
15935
35
            ret = roll_auth(aes, authIn, authInSz, A);
15936
35
    }
15937
35
    if ((ret == 0) && (inSz > 0))
15938
34
        ret = roll_x(aes, o, oSz, A);
15939
15940
35
    if (ret == 0) {
15941
35
        B[0] = (byte)(lenSz - 1U);
15942
140
        for (i = 0; i < lenSz; i++)
15943
105
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15944
35
        ret = AesEncrypt_preFetchOpt(aes, B, B, &did_prefetches);
15945
35
    }
15946
15947
35
    if (ret == 0)
15948
35
        xorbuf(A, B, authTagSz);
15949
15950
35
    if (ret == 0) {
15951
35
        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
15952
            /* If the authTag check fails, don't keep the decrypted data.
15953
             * Unfortunately, you need the decrypted data to calculate the
15954
             * check value. */
15955
            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
15956
                        defined(ACVP_VECTOR_TESTING)
15957
            WOLFSSL_MSG("Preserve output for vector responses");
15958
            #else
15959
35
            if (inSz > 0)
15960
34
                XMEMSET(out, 0, inSz);
15961
35
            #endif
15962
35
            ret = AES_CCM_AUTH_E;
15963
35
        }
15964
35
    }
15965
15966
35
    ForceZero(A, sizeof(A));
15967
35
    ForceZero(B, sizeof(B));
15968
35
    o = NULL;
15969
15970
#ifdef WOLFSSL_CHECK_MEM_ZERO
15971
    wc_MemZero_Check(A, sizeof(A));
15972
    wc_MemZero_Check(B, sizeof(B));
15973
#endif
15974
15975
35
    VECTOR_REGISTERS_POP;
15976
15977
35
    return ret;
15978
35
}
15979
15980
#endif /* HAVE_AES_DECRYPT */
15981
#endif /* software CCM */
15982
15983
/* abstract functions that call lower level AESCCM functions */
15984
#ifndef WC_NO_RNG
15985
15986
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
15987
393
{
15988
393
    int ret = 0;
15989
15990
393
    if (aes == NULL || nonce == NULL ||
15991
393
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
15992
15993
0
        ret = BAD_FUNC_ARG;
15994
0
    }
15995
15996
393
    if (ret == 0) {
15997
393
        XMEMCPY(aes->reg, nonce, nonceSz);
15998
393
        aes->nonceSz = nonceSz;
15999
16000
        /* Invocation counter should be 2^61 */
16001
393
        aes->invokeCtr[0] = 0;
16002
393
        aes->invokeCtr[1] = 0xE0000000;
16003
393
    }
16004
16005
393
    return ret;
16006
393
}
16007
16008
16009
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
16010
                        byte* ivOut, word32 ivOutSz,
16011
                        byte* authTag, word32 authTagSz,
16012
                        const byte* authIn, word32 authInSz)
16013
393
{
16014
393
    int ret = 0;
16015
16016
393
    if (aes == NULL || out == NULL ||
16017
393
        (in == NULL && sz != 0) ||
16018
393
        ivOut == NULL ||
16019
393
        (authIn == NULL && authInSz != 0) ||
16020
393
        (ivOutSz != aes->nonceSz)) {
16021
16022
0
        ret = BAD_FUNC_ARG;
16023
0
    }
16024
16025
393
    if (ret == 0) {
16026
393
        aes->invokeCtr[0]++;
16027
393
        if (aes->invokeCtr[0] == 0) {
16028
0
            aes->invokeCtr[1]++;
16029
0
            if (aes->invokeCtr[1] == 0)
16030
0
                ret = AES_CCM_OVERFLOW_E;
16031
0
        }
16032
393
    }
16033
16034
393
    if (ret == 0) {
16035
        /* Keep the nonce being consumed in ivOut rather than aes->reg - see
16036
         * wc_AesGcmEncrypt_ex() for why aes->reg is not a stable holder. */
16037
393
        XMEMCPY(ivOut, aes->reg, aes->nonceSz);
16038
393
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
16039
393
                               ivOut, aes->nonceSz,
16040
393
                               authTag, authTagSz,
16041
393
                               authIn, authInSz);
16042
        /* Put the nonce back unconditionally - see wc_AesGcmEncrypt_ex(). */
16043
393
        XMEMCPY(aes->reg, ivOut, aes->nonceSz);
16044
        /* Advance past a nonce handed to a backend that defers the work - it
16045
         * has been consumed even though the operation has not finished. */
16046
393
        if (ret == 0 || ret == WC_NO_ERR_TRACE(WC_PENDING_E))
16047
393
            IncCtr((byte*)aes->reg, aes->nonceSz);
16048
393
    }
16049
16050
393
    return ret;
16051
393
}
16052
16053
#endif /* WC_NO_RNG */
16054
16055
#endif /* HAVE_AESCCM */
16056
16057
#ifndef WC_NO_CONSTRUCTORS
16058
16059
0
#define AES_NEW_INIT_PLAIN  0
16060
#ifdef WOLF_PRIVATE_KEY_ID
16061
0
#define AES_NEW_INIT_ID     1
16062
0
#define AES_NEW_INIT_LABEL  2
16063
#endif
16064
16065
static Aes* _AesNew_common(void* heap, int devId, int *result_code,
16066
                            int aesInitType, unsigned char* id,
16067
                            int idLen, const char* label)
16068
0
{
16069
0
    int ret;
16070
0
    Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
16071
0
    if (aes == NULL) {
16072
0
        ret = MEMORY_E;
16073
0
    }
16074
0
    else {
16075
0
        switch (aesInitType) {
16076
0
#ifdef WOLF_PRIVATE_KEY_ID
16077
0
        case AES_NEW_INIT_ID:
16078
0
            if (id == NULL || idLen == 0 || label != NULL) {
16079
0
                ret = BAD_FUNC_ARG;
16080
0
            }
16081
0
            else {
16082
0
                ret = wc_AesInit_Id(aes, id, idLen, heap, devId);
16083
0
            }
16084
0
            break;
16085
0
        case AES_NEW_INIT_LABEL:
16086
0
            if (label == NULL || id != NULL || idLen != 0) {
16087
0
                ret = BAD_FUNC_ARG;
16088
0
            }
16089
0
            else {
16090
0
                ret = wc_AesInit_Label(aes, label, heap, devId);
16091
0
            }
16092
0
            break;
16093
0
#endif
16094
0
        default:
16095
0
            if (id != NULL || idLen != 0 || label != NULL) {
16096
0
                ret = BAD_FUNC_ARG;
16097
0
            }
16098
0
            else {
16099
0
                ret = wc_AesInit(aes, heap, devId);
16100
0
            }
16101
0
            break;
16102
0
        }
16103
0
        if (ret != 0) {
16104
0
            XFREE(aes, heap, DYNAMIC_TYPE_AES);
16105
0
            aes = NULL;
16106
0
        }
16107
0
    }
16108
0
    (void)aesInitType;
16109
0
    (void)id;
16110
0
    (void)idLen;
16111
0
    (void)label;
16112
16113
0
    if (result_code != NULL) {
16114
0
        *result_code = ret;
16115
0
    }
16116
16117
0
    return aes;
16118
0
}
16119
16120
Aes* wc_AesNew(void* heap, int devId, int *result_code)
16121
0
{
16122
0
    return _AesNew_common(heap, devId, result_code,
16123
0
                          AES_NEW_INIT_PLAIN, NULL, 0, NULL);
16124
0
}
16125
16126
#ifdef WOLF_PRIVATE_KEY_ID
16127
Aes* wc_AesNew_Id(unsigned char* id, int len, void* heap, int devId,
16128
                   int *result_code)
16129
0
{
16130
0
    return _AesNew_common(heap, devId, result_code,
16131
0
                          AES_NEW_INIT_ID, id, len, NULL);
16132
0
}
16133
16134
Aes* wc_AesNew_Label(const char* label, void* heap, int devId,
16135
                      int *result_code)
16136
0
{
16137
0
    return _AesNew_common(heap, devId, result_code,
16138
0
                          AES_NEW_INIT_LABEL, NULL, 0, label);
16139
0
}
16140
#endif /* WOLF_PRIVATE_KEY_ID */
16141
16142
int wc_AesDelete(Aes *aes, Aes** aes_p)
16143
0
{
16144
0
    void* heap;
16145
0
    if (aes == NULL)
16146
0
        return BAD_FUNC_ARG;
16147
0
    heap = aes->heap;
16148
0
    wc_AesFree(aes);
16149
0
    XFREE(aes, heap, DYNAMIC_TYPE_AES);
16150
0
    if (aes_p != NULL)
16151
0
        *aes_p = NULL;
16152
0
    return 0;
16153
0
}
16154
#endif /* !WC_NO_CONSTRUCTORS */
16155
16156
/* Initialize Aes */
16157
int wc_AesInit(Aes* aes, void* heap, int devId)
16158
4.70k
{
16159
4.70k
    int ret = 0;
16160
16161
4.70k
    if (aes == NULL)
16162
0
        return BAD_FUNC_ARG;
16163
16164
4.70k
    XMEMSET(aes, 0, sizeof(*aes));
16165
16166
4.70k
    aes->heap = heap;
16167
16168
4.70k
#if defined(WOLF_CRYPTO_CB)
16169
4.70k
    aes->devId = devId;
16170
4.70k
    aes->devCtx = NULL;
16171
#else
16172
    (void)devId;
16173
#endif
16174
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
16175
    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
16176
                                                        aes->heap, devId);
16177
#endif /* WOLFSSL_ASYNC_CRYPT */
16178
16179
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
16180
    aes->alFd = WC_SOCK_NOTSET;
16181
    aes->rdFd = WC_SOCK_NOTSET;
16182
#endif
16183
#if defined(WOLFSSL_DEVCRYPTO) && \
16184
   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
16185
    aes->ctx.cfd    = -1;
16186
    aes->ctx.inited = 0;
16187
#endif
16188
#if defined(WOLFSSL_IMXRT_DCP)
16189
    DCPAesInit(aes);
16190
#endif
16191
16192
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
16193
    ret = wc_psa_aes_init(aes);
16194
#endif
16195
16196
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
16197
    if (ret == 0)
16198
        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
16199
#endif
16200
16201
4.70k
    return ret;
16202
4.70k
}
16203
16204
#ifdef WOLF_PRIVATE_KEY_ID
16205
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
16206
0
{
16207
0
    int ret = 0;
16208
16209
0
    if (aes == NULL || (id == NULL && len > 0))
16210
0
        ret = BAD_FUNC_ARG;
16211
0
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
16212
0
        ret = BUFFER_E;
16213
16214
0
    if (ret == 0)
16215
0
        ret = wc_AesInit(aes, heap, devId);
16216
0
    if (ret == 0 && id != NULL && len != 0) {
16217
0
        XMEMCPY(aes->id, id, (size_t)len);
16218
0
        aes->idLen = len;
16219
0
        aes->labelLen = 0;
16220
        /* keyInstalled stays 0: the key lives on the device, not in the
16221
         * software schedule. See the field comment in aes.h. */
16222
0
    }
16223
16224
0
    return ret;
16225
0
}
16226
16227
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
16228
0
{
16229
0
    int ret = 0;
16230
0
    size_t labelLen = 0;
16231
16232
0
    if (aes == NULL || label == NULL)
16233
0
        ret = BAD_FUNC_ARG;
16234
0
    if (ret == 0) {
16235
0
        labelLen = XSTRLEN(label);
16236
0
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
16237
0
            ret = BUFFER_E;
16238
0
    }
16239
16240
0
    if (ret == 0)
16241
0
        ret = wc_AesInit(aes, heap, devId);
16242
0
    if (ret == 0) {
16243
0
        XMEMCPY(aes->label, label, labelLen);
16244
0
        aes->labelLen = (int)labelLen;
16245
0
        aes->idLen = 0;
16246
        /* keyInstalled stays 0: see wc_AesInit_Id() above. */
16247
0
    }
16248
16249
0
    return ret;
16250
0
}
16251
#endif
16252
16253
/* Free Aes resources */
16254
void wc_AesFree(Aes* aes)
16255
354k
{
16256
354k
    if (aes == NULL) {
16257
350k
        return;
16258
350k
    }
16259
16260
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
16261
    #ifndef WOLF_CRYPTO_CB_FIND
16262
    if (aes->devId != INVALID_DEVID)
16263
    #endif
16264
    {
16265
        int ret = wc_CryptoCb_Free(aes->devId, WC_ALGO_TYPE_CIPHER,
16266
                                   WC_CIPHER_AES, 0, aes);
16267
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
16268
        aes->devCtx = NULL;  /* Clear device context handle */
16269
    #endif
16270
        /* This path skips the ForceZero below, so clear the flag here or a
16271
         * reused context passes the key-set guard with a freed key. */
16272
        aes->keyInstalled = 0;
16273
        /* If callback wants standard free, it can set devId to INVALID_DEVID.
16274
         * Otherwise assume the callback handled cleanup. */
16275
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16276
            return;
16277
        /* fall-through when unavailable */
16278
    }
16279
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
16280
16281
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
16282
    {
16283
        int ret = wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
16284
        if (ret != 0)
16285
            WOLFSSL_DEBUG_PRINTF("ERROR: wc_AesFree(): wc_debug_CipherLifecycleFree() returned %d.\n", ret);
16286
    }
16287
#endif
16288
16289
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
16290
    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
16291
#endif /* WOLFSSL_ASYNC_CRYPT */
16292
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
16293
    if (aes->rdFd > 0) { /* negative is error case */
16294
        close(aes->rdFd);
16295
        aes->rdFd = WC_SOCK_NOTSET;
16296
    }
16297
    if (aes->alFd > 0) {
16298
        close(aes->alFd);
16299
        aes->alFd = WC_SOCK_NOTSET;
16300
    }
16301
#endif /* WOLFSSL_AFALG */
16302
#ifdef WOLFSSL_KCAPI_AES
16303
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
16304
    if (aes->init == 1) {
16305
        kcapi_cipher_destroy(aes->handle);
16306
    }
16307
    aes->init = 0;
16308
    aes->handle = NULL;
16309
#endif
16310
#if defined(WOLFSSL_DEVCRYPTO) && \
16311
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
16312
    wc_DevCryptoFree(&aes->ctx);
16313
#endif
16314
4.70k
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
16315
4.70k
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
16316
4.70k
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
16317
4.70k
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
16318
4.70k
#endif
16319
#if defined(WOLFSSL_IMXRT_DCP)
16320
    DCPAesFree(aes);
16321
#endif
16322
4.70k
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
16323
4.70k
    !defined(WOLFSSL_AESNI)
16324
4.70k
    if (aes->streamData != NULL) {
16325
591
        ForceZero(aes->streamData, aes->streamData_sz);
16326
591
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
16327
591
        aes->streamData = NULL;
16328
591
    }
16329
4.70k
#endif
16330
16331
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
16332
    if (aes->useSWCrypt == 0) {
16333
        se050_aes_free(aes);
16334
    }
16335
#endif
16336
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
16337
    wc_Microchip_aes_free(aes);
16338
#endif
16339
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
16340
    wc_psa_aes_free(aes);
16341
#endif
16342
16343
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
16344
    wc_MAXQ10XX_AesFree(aes);
16345
#endif
16346
16347
#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
16348
    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
16349
    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
16350
    wc_fspsm_Aesfree(aes);
16351
#endif
16352
16353
4.70k
    ForceZero(aes, sizeof(Aes));
16354
16355
#ifdef WOLFSSL_CHECK_MEM_ZERO
16356
    wc_MemZero_Check(aes, sizeof(Aes));
16357
#endif
16358
4.70k
}
16359
16360
int wc_AesGetKeySize(Aes* aes, word32* keySize)
16361
0
{
16362
0
    int ret = 0;
16363
16364
0
    if (aes == NULL || keySize == NULL) {
16365
0
        return BAD_FUNC_ARG;
16366
0
    }
16367
16368
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
16369
    return wc_psa_aes_get_key_size(aes, keySize);
16370
#endif
16371
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
16372
    *keySize = aes->ctx.key.keySize;
16373
    return ret;
16374
#endif
16375
0
    switch (aes->rounds) {
16376
0
#ifdef WOLFSSL_AES_128
16377
0
    case 10:
16378
0
        *keySize = 16;
16379
0
        break;
16380
0
#endif
16381
0
#ifdef WOLFSSL_AES_192
16382
0
    case 12:
16383
0
        *keySize = 24;
16384
0
        break;
16385
0
#endif
16386
0
#ifdef WOLFSSL_AES_256
16387
0
    case 14:
16388
0
        *keySize = 32;
16389
0
        break;
16390
0
#endif
16391
0
    default:
16392
0
        *keySize = 0;
16393
0
        ret = BAD_FUNC_ARG;
16394
0
    }
16395
16396
0
    return ret;
16397
0
}
16398
16399
#endif /* !WOLFSSL_TI_CRYPT */
16400
16401
/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
16402
 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
16403
 */
16404
#ifndef VECTOR_REGISTERS_PUSH
16405
    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
16406
#endif
16407
#ifndef VECTOR_REGISTERS_POP
16408
    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
16409
#endif
16410
16411
#ifdef HAVE_AES_ECB
16412
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
16413
        !defined(WOLFSSL_QNX_CAAM)
16414
    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
16415
16416
#elif defined(WOLFSSL_AFALG)
16417
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
16418
    #define _AesEcbEncrypt(aes, out, in, sz) wc_AesEcbEncrypt(aes, out, in, sz)
16419
    #ifdef HAVE_AES_DECRYPT
16420
        #define _AesEcbDecrypt(aes, out, in, sz) \
16421
                                            wc_AesEcbDecrypt(aes, out, in, sz)
16422
    #endif
16423
16424
#elif defined(WOLFSSL_DEVCRYPTO_AES)
16425
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
16426
16427
#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
16428
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
16429
16430
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
16431
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
16432
16433
#elif defined(MAX3266X_AES)
16434
16435
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16436
{
16437
    int status;
16438
    word32 keySize;
16439
16440
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16441
        return BAD_FUNC_ARG;
16442
16443
    status = wc_AesGetKeySize(aes, &keySize);
16444
    if (status != 0) {
16445
        return status;
16446
    }
16447
16448
    status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key,
16449
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
16450
16451
    return status;
16452
}
16453
16454
#ifdef HAVE_AES_DECRYPT
16455
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16456
{
16457
    int status;
16458
    word32 keySize;
16459
16460
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16461
        return BAD_FUNC_ARG;
16462
16463
    status = wc_AesGetKeySize(aes, &keySize);
16464
    if (status != 0) {
16465
        return status;
16466
    }
16467
16468
    status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key,
16469
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
16470
16471
    return status;
16472
}
16473
#endif /* HAVE_AES_DECRYPT */
16474
16475
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
16476
16477
/* Software AES - ECB */
16478
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16479
{
16480
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16481
        return BAD_FUNC_ARG;
16482
16483
    return AES_ECB_encrypt(aes, in, out, sz);
16484
}
16485
16486
16487
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16488
{
16489
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16490
        return BAD_FUNC_ARG;
16491
16492
    return AES_ECB_decrypt(aes, in, out, sz);
16493
}
16494
16495
#elif defined(WOLFSSL_PSOC6_CRYPTO)
16496
16497
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16498
{
16499
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16500
        return BAD_FUNC_ARG;
16501
    if (!WC_AES_KEY_IS_SET(aes)) {
16502
        WOLFSSL_MSG("AES key not set");
16503
        return MISSING_KEY;
16504
    }
16505
16506
    return wc_Psoc6_Aes_EcbEncrypt(aes, out, in, sz);
16507
}
16508
16509
#define _AesEcbEncrypt(aes, out, in, sz) wc_AesEcbEncrypt(aes, out, in, sz)
16510
16511
#ifdef HAVE_AES_DECRYPT
16512
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16513
{
16514
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16515
        return BAD_FUNC_ARG;
16516
    if (!WC_AES_KEY_IS_SET(aes)) {
16517
        WOLFSSL_MSG("AES key not set");
16518
        return MISSING_KEY;
16519
    }
16520
16521
    return wc_Psoc6_Aes_EcbDecrypt(aes, out, in, sz);
16522
}
16523
16524
#define _AesEcbDecrypt(aes, out, in, sz) wc_AesEcbDecrypt(aes, out, in, sz)
16525
#endif /* HAVE_AES_DECRYPT */
16526
16527
#else
16528
16529
/* Software AES - ECB */
16530
static WARN_UNUSED_RESULT int _AesEcbEncrypt(
16531
    Aes* aes, byte* out, const byte* in, word32 sz)
16532
779
{
16533
779
    int ret = 0;
16534
16535
779
#ifdef WOLF_CRYPTO_CB
16536
779
    #ifndef WOLF_CRYPTO_CB_FIND
16537
779
    if (aes->devId != INVALID_DEVID)
16538
126
    #endif
16539
126
    {
16540
126
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
16541
126
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16542
0
            return ret;
16543
126
        ret = 0;
16544
        /* fall-through when unavailable */
16545
126
    }
16546
779
#endif
16547
#ifdef WOLF_CRYPTO_CB_ONLY_AES
16548
    /* No software fallback: the per-block loop below would only re-invoke
16549
     * cryptocb ECB and propagate UNAVAILABLE; short-circuit instead. */
16550
    return NO_VALID_DEVID;
16551
#endif
16552
#ifdef WOLFSSL_IMXRT_DCP
16553
    if (aes->keylen == 16)
16554
        return DCPAesEcbEncrypt(aes, out, in, sz);
16555
#endif
16556
16557
    /* Software key schedule required from here on. */
16558
779
    if (!WC_AES_KEY_IS_SET(aes)) {
16559
0
        WOLFSSL_MSG("AES key not set");
16560
0
        return MISSING_KEY;
16561
0
    }
16562
16563
779
    VECTOR_REGISTERS_PUSH;
16564
16565
#if defined(WOLFSSL_RISCV_ASM)
16566
    AES_encrypt_blocks_RISCV64(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16567
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16568
#ifdef WOLFSSL_ARM32_AES_DISPATCH
16569
    if (aes->use_aes_hw_crypto) {
16570
        AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key,
16571
            (int)aes->rounds);
16572
    }
16573
    else {
16574
        AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key,
16575
            aes->rounds);
16576
    }
16577
#elif !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16578
    AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16579
#else
16580
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
16581
#endif
16582
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16583
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16584
    if (aes->use_aes_hw_crypto) {
16585
        AES_encrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
16586
            (int)aes->rounds);
16587
    }
16588
    else
16589
#endif
16590
#if !defined(WOLFSSL_ARMASM_NO_NEON)
16591
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16592
    if (sz >= 32)
16593
#endif
16594
    {
16595
        AES_ECB_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
16596
            aes->rounds);
16597
    }
16598
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16599
    else
16600
#endif
16601
#endif
16602
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16603
    {
16604
        AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key,
16605
            aes->rounds);
16606
    }
16607
#endif
16608
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
16609
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
16610
    ret = 0;
16611
#else
16612
#ifdef WOLFSSL_AESNI
16613
    if (aes->use_aesni) {
16614
    #ifdef WOLFSSL_X86_64_BUILD
16615
        AesEcbEncryptBlocks(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16616
    #else
16617
        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16618
    #endif
16619
    }
16620
    else
16621
#endif
16622
779
    {
16623
779
#if defined(NEED_AES_TABLES)
16624
779
        AesEncryptBlocks_C(aes, in, out, sz);
16625
#else
16626
        word32 i;
16627
#ifdef WC_AES_HAVE_PREFETCH_ARG
16628
        int did_prefetches = 0;
16629
#endif
16630
16631
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
16632
            ret = AesEncrypt_preFetchOpt(aes, in, out, &did_prefetches);
16633
            if (ret != 0)
16634
                break;
16635
            in += WC_AES_BLOCK_SIZE;
16636
            out += WC_AES_BLOCK_SIZE;
16637
        }
16638
#endif
16639
779
    }
16640
779
#endif
16641
16642
779
    VECTOR_REGISTERS_POP;
16643
16644
779
    return ret;
16645
779
}
16646
16647
#ifdef HAVE_AES_DECRYPT
16648
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
16649
    Aes* aes, byte* out, const byte* in, word32 sz)
16650
337
{
16651
337
    int ret = 0;
16652
16653
337
#ifdef WOLF_CRYPTO_CB
16654
337
    #ifndef WOLF_CRYPTO_CB_FIND
16655
337
    if (aes->devId != INVALID_DEVID)
16656
256
    #endif
16657
256
    {
16658
256
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
16659
256
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16660
0
            return ret;
16661
256
        ret = 0;
16662
        /* fall-through when unavailable */
16663
256
    }
16664
337
#endif
16665
#ifdef WOLF_CRYPTO_CB_ONLY_AES
16666
    return NO_VALID_DEVID;
16667
#endif
16668
#ifdef WOLFSSL_IMXRT_DCP
16669
    if (aes->keylen == 16)
16670
        return DCPAesEcbDecrypt(aes, out, in, sz);
16671
#endif
16672
16673
    /* Software key schedule required from here on. */
16674
337
    if (!WC_AES_KEY_IS_SET(aes)) {
16675
0
        WOLFSSL_MSG("AES key not set");
16676
0
        return MISSING_KEY;
16677
0
    }
16678
16679
337
    VECTOR_REGISTERS_PUSH;
16680
16681
#if defined(WOLFSSL_RISCV_ASM)
16682
    AES_decrypt_blocks_RISCV64(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16683
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16684
#ifdef WOLFSSL_ARM32_AES_DISPATCH
16685
    if (aes->use_aes_hw_crypto) {
16686
        AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key,
16687
            (int)aes->rounds);
16688
    }
16689
    else {
16690
        AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key,
16691
            aes->rounds);
16692
    }
16693
#elif !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16694
    AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16695
#else
16696
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
16697
#endif
16698
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16699
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16700
    if (aes->use_aes_hw_crypto) {
16701
        AES_decrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
16702
            (int)aes->rounds);
16703
    }
16704
    else
16705
#endif
16706
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
16707
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16708
    if (sz >= 64)
16709
#endif
16710
    {
16711
        AES_ECB_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
16712
            aes->rounds);
16713
    }
16714
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16715
    else
16716
#endif
16717
#endif
16718
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16719
    {
16720
        AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key,
16721
            aes->rounds);
16722
    }
16723
#endif
16724
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
16725
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
16726
    ret = 0;
16727
#else
16728
#ifdef WOLFSSL_AESNI
16729
    if (aes->use_aesni) {
16730
    #ifdef WOLFSSL_X86_64_BUILD
16731
        AesEcbDecryptBlocks(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16732
    #else
16733
        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16734
    #endif
16735
    }
16736
    else
16737
#endif
16738
337
    {
16739
337
#if defined(NEED_AES_TABLES)
16740
337
        AesDecryptBlocks_C(aes, in, out, sz);
16741
#else
16742
        word32 i;
16743
16744
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
16745
            ret = wc_AesDecryptDirect(aes, out, in);
16746
            if (ret != 0)
16747
                break;
16748
            in += WC_AES_BLOCK_SIZE;
16749
            out += WC_AES_BLOCK_SIZE;
16750
        }
16751
#endif
16752
337
    }
16753
337
#endif
16754
16755
337
    VECTOR_REGISTERS_POP;
16756
16757
337
    return ret;
16758
337
}
16759
#endif
16760
16761
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16762
653
{
16763
653
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16764
0
      return BAD_FUNC_ARG;
16765
653
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
16766
0
        return BAD_LENGTH_E;
16767
0
    }
16768
16769
653
    return _AesEcbEncrypt(aes, out, in, sz);
16770
653
}
16771
16772
#ifdef HAVE_AES_DECRYPT
16773
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16774
81
{
16775
81
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16776
0
      return BAD_FUNC_ARG;
16777
81
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
16778
0
        return BAD_LENGTH_E;
16779
0
    }
16780
16781
81
    return _AesEcbDecrypt(aes, out, in, sz);
16782
81
}
16783
#endif /* HAVE_AES_DECRYPT */
16784
#endif
16785
#endif /* HAVE_AES_ECB */
16786
16787
#if defined(WOLFSSL_AES_CFB)
16788
16789
#if defined(WOLFSSL_NXP_HASHCRYPT_AES)
16790
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
16791
16792
#elif defined(WOLFSSL_PSOC6_CRYPTO)
16793
16794
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16795
{
16796
    if (aes == NULL)
16797
        return BAD_FUNC_ARG;
16798
    if (!WC_AES_KEY_IS_SET(aes)) {
16799
        WOLFSSL_MSG("AES key not set");
16800
        return MISSING_KEY;
16801
    }
16802
    return wc_Psoc6_Aes_CfbEncrypt(aes, out, in, sz);
16803
}
16804
16805
#ifdef HAVE_AES_DECRYPT
16806
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16807
{
16808
    if (aes == NULL)
16809
        return BAD_FUNC_ARG;
16810
    if (!WC_AES_KEY_IS_SET(aes)) {
16811
        WOLFSSL_MSG("AES key not set");
16812
        return MISSING_KEY;
16813
    }
16814
    return wc_Psoc6_Aes_CfbDecrypt(aes, out, in, sz);
16815
}
16816
#endif /* HAVE_AES_DECRYPT */
16817
16818
#else
16819
/* Feedback AES mode
16820
 *
16821
 * aes structure holding key to use for encryption
16822
 * out buffer to hold result of encryption (must be at least as large as input
16823
 *     buffer)
16824
 * in  buffer to encrypt
16825
 * sz  size of input buffer
16826
 * mode flag to specify AES mode
16827
 *
16828
 * returns 0 on success and negative error values on failure
16829
 */
16830
/* Software AES - CFB Encrypt */
16831
static WARN_UNUSED_RESULT int AesCfbEncrypt_C(Aes* aes, byte* out,
16832
    const byte* in, word32 sz)
16833
0
{
16834
0
    int ret = 0;
16835
0
    word32 processed;
16836
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
16837
0
    int did_prefetches = 0;
16838
0
#endif
16839
16840
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16841
0
        return BAD_FUNC_ARG;
16842
0
    }
16843
0
    if (!WC_AES_KEY_IS_SET(aes)) {
16844
0
        WOLFSSL_MSG("AES key not set");
16845
0
        return MISSING_KEY;
16846
0
    }
16847
0
    if (sz == 0) {
16848
0
        return 0;
16849
0
    }
16850
16851
0
    if (aes->left > 0) {
16852
        /* consume any unused bytes left in aes->tmp */
16853
0
        processed = min(aes->left, sz);
16854
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16855
0
            processed);
16856
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out,
16857
0
            processed);
16858
0
        aes->left -= processed;
16859
0
        out += processed;
16860
0
        in += processed;
16861
0
        sz -= processed;
16862
0
    }
16863
16864
0
    VECTOR_REGISTERS_PUSH;
16865
16866
0
    while (sz >= WC_AES_BLOCK_SIZE) {
16867
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
16868
0
                                        &did_prefetches);
16869
0
        if (ret != 0) {
16870
0
            break;
16871
0
        }
16872
0
        xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
16873
0
        XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
16874
0
        out += WC_AES_BLOCK_SIZE;
16875
0
        in  += WC_AES_BLOCK_SIZE;
16876
0
        sz  -= WC_AES_BLOCK_SIZE;
16877
0
    }
16878
16879
    /* encrypt left over data */
16880
0
    if ((ret == 0) && sz) {
16881
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16882
0
                                     &did_prefetches);
16883
0
        if (ret == 0) {
16884
0
            xorbufout(out, in, aes->tmp, sz);
16885
0
            XMEMCPY(aes->reg, out, sz);
16886
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
16887
0
        }
16888
0
    }
16889
16890
0
    VECTOR_REGISTERS_POP;
16891
16892
0
    return ret;
16893
0
}
16894
16895
16896
#if defined(HAVE_AES_DECRYPT)
16897
/* CFB 128
16898
 *
16899
 * aes structure holding key to use for decryption
16900
 * out buffer to hold result of decryption (must be at least as large as input
16901
 *     buffer)
16902
 * in  buffer to decrypt
16903
 * sz  size of input buffer
16904
 *
16905
 * returns 0 on success and negative error values on failure
16906
 */
16907
/* Software AES - CFB Decrypt */
16908
static WARN_UNUSED_RESULT int AesCfbDecrypt_C(Aes* aes, byte* out,
16909
    const byte* in, word32 sz, byte mode)
16910
0
{
16911
0
    int ret = 0;
16912
0
    word32 processed;
16913
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
16914
0
    int did_prefetches = 0;
16915
0
#endif
16916
0
#ifndef WC_AES_CFB_DEC_BUF_BLOCKS
16917
0
    #define WC_AES_CFB_DEC_BUF_BLOCKS 32
16918
#elif WC_AES_CFB_DEC_BUF_BLOCKS < 2
16919
    #error Invalid WC_AES_CFB_DEC_BUF_BLOCKS
16920
#endif
16921
0
#ifdef WOLFSSL_SMALL_STACK
16922
0
    byte *tmp = NULL;
16923
0
#endif
16924
16925
0
    (void)mode;
16926
16927
0
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16928
0
        return BAD_FUNC_ARG;
16929
0
    }
16930
0
    if (!WC_AES_KEY_IS_SET(aes)) {
16931
0
        WOLFSSL_MSG("AES key not set");
16932
0
        return MISSING_KEY;
16933
0
    }
16934
0
    if (sz == 0) {
16935
0
        return 0;
16936
0
    }
16937
16938
0
    if (aes->left > 0) {
16939
        /* consume any unused bytes left in aes->tmp */
16940
0
        processed = min(aes->left, sz);
16941
        /* copy input over to aes->reg */
16942
0
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, processed);
16943
0
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16944
0
            processed);
16945
0
        aes->left -= processed;
16946
0
        out += processed;
16947
0
        in += processed;
16948
0
        sz -= processed;
16949
0
    }
16950
16951
#if defined(WOLFSSL_SMALL_STACK) && defined(HAVE_AES_ECB) &&    \
16952
    !defined(WOLFSSL_PIC32MZ_CRYPT) &&                          \
16953
    (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
16954
    /* Only suffer the heap overhead if sz is enough to warrant it.
16955
     *
16956
     * Allocate the working buffer before suspending interrupts, so that we can
16957
     * allocate with regular GFP_KERNEL.
16958
     */
16959
    if (sz >= WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE)
16960
        tmp = (byte *)XMALLOC(WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_AES);
16961
16962
    VECTOR_REGISTERS_PUSH2(XFREE(tmp, NULL, DYNAMIC_TYPE_AES););
16963
#else
16964
0
    VECTOR_REGISTERS_PUSH;
16965
0
#endif
16966
16967
    #if defined(HAVE_AES_ECB) && \
16968
        !defined(WOLFSSL_PIC32MZ_CRYPT) && \
16969
        (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
16970
#ifdef WOLFSSL_SMALL_STACK
16971
    if (tmp != NULL)
16972
#endif
16973
    {
16974
#ifndef WOLFSSL_SMALL_STACK
16975
        ALIGN16 byte tmp[WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE];
16976
#endif
16977
        if (sz >= 2 * WC_AES_BLOCK_SIZE) {
16978
            /* CFB-decrypt keystream block i is E(C_{i-1}): block 0 uses the
16979
             * feedback register, block i>=1 uses the previous cipher block.  So
16980
             * ECB the ciphertext straight out of 'in' (no shift-copy) to get
16981
             * E(C_0..C_{n-1}), XOR block i with the (i-1)th ECB output, and
16982
             * carry E(C_{n-1}) as the next chunk's block-0 keystream - E(reg)
16983
             * is computed only once here. */
16984
            ALIGN16 byte ks[WC_AES_BLOCK_SIZE];
16985
            ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, ks,
16986
                                         &did_prefetches);
16987
            while ((ret == 0) && (sz >= 2 * WC_AES_BLOCK_SIZE)) {
16988
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
16989
                word32 nbytes;
16990
                if (blocks > WC_AES_CFB_DEC_BUF_BLOCKS)
16991
                    blocks = WC_AES_CFB_DEC_BUF_BLOCKS;
16992
                nbytes = blocks * WC_AES_BLOCK_SIZE;
16993
                /* tmp[i] = E(C_i), read directly from the input. Already inside
16994
                 * VECTOR_REGISTERS_PUSH, so use the inner ECB (no nested
16995
                 * save/restore or re-dispatch) where available. */
16996
            #if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
16997
                if (aes->use_aesni) {
16998
                    AesEcbEncryptBlocks(in, tmp, nbytes, (byte*)aes->key,
16999
                                        (int)aes->rounds);
17000
                }
17001
                else
17002
            #endif
17003
                {
17004
                    ret = wc_AesEcbEncrypt(aes, tmp, in, nbytes);
17005
                    if (ret != 0)
17006
                        break;
17007
                }
17008
                /* Feedback for the tail = last cipher block; save it before the
17009
                 * XOR can overwrite 'in' (in == out case). */
17010
                XMEMCPY((byte*)aes->reg, in + nbytes - WC_AES_BLOCK_SIZE,
17011
                        WC_AES_BLOCK_SIZE);
17012
                /* P_0 = C_0 ^ E(feedback); P_i = C_i ^ E(C_{i-1}) =
17013
                 *       C_i ^ tmp[i-1]. */
17014
                xorbufout(out, in, ks, WC_AES_BLOCK_SIZE);
17015
                xorbufout(out + WC_AES_BLOCK_SIZE, in + WC_AES_BLOCK_SIZE, tmp,
17016
                          nbytes - WC_AES_BLOCK_SIZE);
17017
                /* Carry E(last cipher block) as the next chunk's block-0 KS. */
17018
                XMEMCPY(ks, tmp + nbytes - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
17019
                out += nbytes;
17020
                in  += nbytes;
17021
                sz  -= nbytes;
17022
            }
17023
        }
17024
    }
17025
    #endif
17026
0
    while (sz >= WC_AES_BLOCK_SIZE) {
17027
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17028
0
                                        &did_prefetches);
17029
0
        if (ret != 0) {
17030
0
            break;
17031
0
        }
17032
0
        XMEMCPY((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
17033
0
        xorbufout(out, in, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
17034
0
        out += WC_AES_BLOCK_SIZE;
17035
0
        in  += WC_AES_BLOCK_SIZE;
17036
0
        sz  -= WC_AES_BLOCK_SIZE;
17037
0
    }
17038
17039
    /* decrypt left over data */
17040
0
    if ((ret == 0) && sz) {
17041
0
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17042
0
                                        &did_prefetches);
17043
0
        if (ret == 0) {
17044
0
            XMEMCPY(aes->reg, in, sz);
17045
0
            xorbufout(out, in, aes->tmp, sz);
17046
0
            aes->left = WC_AES_BLOCK_SIZE - sz;
17047
0
        }
17048
0
    }
17049
17050
0
    VECTOR_REGISTERS_POP;
17051
17052
0
#ifdef WOLFSSL_SMALL_STACK
17053
    /* Free tmp after restoring interrupts, so that GFP_KERNEL is usable. */
17054
0
    XFREE(tmp, NULL, DYNAMIC_TYPE_AES);
17055
0
#endif
17056
17057
0
    return ret;
17058
0
}
17059
#endif /* HAVE_AES_DECRYPT */
17060
17061
/* CFB 128
17062
 *
17063
 * aes structure holding key to use for encryption
17064
 * out buffer to hold result of encryption (must be at least as large as input
17065
 *     buffer)
17066
 * in  buffer to encrypt
17067
 * sz  size of input buffer
17068
 *
17069
 * returns 0 on success and negative error values on failure
17070
 */
17071
/* Software AES - CFB Encrypt */
17072
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17073
0
{
17074
0
#ifdef WOLF_CRYPTO_CB
17075
0
    if (aes == NULL)
17076
0
        return BAD_FUNC_ARG;
17077
0
    #ifndef WOLF_CRYPTO_CB_FIND
17078
0
    if (aes->devId != INVALID_DEVID)
17079
0
    #endif
17080
0
    {
17081
0
        int crypto_cb_ret = wc_CryptoCb_AesCfbEncrypt(aes, out, in, sz);
17082
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17083
0
            return crypto_cb_ret;
17084
        /* fall-through when unavailable */
17085
0
    }
17086
0
#endif
17087
0
    return AesCfbEncrypt_C(aes, out, in, sz);
17088
0
}
17089
17090
17091
#ifdef HAVE_AES_DECRYPT
17092
/* CFB 128
17093
 *
17094
 * aes structure holding key to use for decryption
17095
 * out buffer to hold result of decryption (must be at least as large as input
17096
 *     buffer)
17097
 * in  buffer to decrypt
17098
 * sz  size of input buffer
17099
 *
17100
 * returns 0 on success and negative error values on failure
17101
 */
17102
/* Software AES - CFB Decrypt */
17103
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17104
0
{
17105
0
#ifdef WOLF_CRYPTO_CB
17106
0
    if (aes == NULL)
17107
0
        return BAD_FUNC_ARG;
17108
0
    #ifndef WOLF_CRYPTO_CB_FIND
17109
0
    if (aes->devId != INVALID_DEVID)
17110
0
    #endif
17111
0
    {
17112
0
        int crypto_cb_ret = wc_CryptoCb_AesCfbDecrypt(aes, out, in, sz);
17113
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17114
0
            return crypto_cb_ret;
17115
        /* fall-through when unavailable */
17116
0
    }
17117
0
#endif
17118
0
    return AesCfbDecrypt_C(aes, out, in, sz, AES_CFB_MODE);
17119
0
}
17120
#endif /* HAVE_AES_DECRYPT */
17121
#endif /* WOLFSSL_PSOC6_CRYPTO */
17122
17123
#ifndef WOLFSSL_NO_AES_CFB_1_8
17124
/* shift the whole WC_AES_BLOCK_SIZE array left by 8 or 1 bits */
17125
static void shiftLeftArray(byte* ary, byte shift)
17126
62.8k
{
17127
62.8k
    int i;
17128
17129
62.8k
    if (shift == WOLFSSL_BIT_SIZE) {
17130
        /* shifting over by 8 bits */
17131
144k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
17132
135k
            ary[i] = ary[i+1];
17133
135k
        }
17134
9.00k
        ary[i] = 0;
17135
9.00k
    }
17136
53.8k
    else {
17137
        /* shifting over by 7 or less bits.  WC_OCTET on the stores: a (byte)
17138
         * cast does not drop bits shifted past bit 7 where CHAR_BIT != 8, so
17139
         * cells would exceed 0xFF and corrupt the feedback register. */
17140
862k
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
17141
808k
            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
17142
808k
            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
17143
808k
            ary[i] = WC_OCTET((ary[i] << shift) + carry);
17144
808k
        }
17145
53.8k
        ary[i] = WC_OCTET(ary[i] << shift);
17146
53.8k
    }
17147
62.8k
}
17148
17149
17150
/* returns 0 on success and negative values on failure */
17151
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
17152
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
17153
206
{
17154
206
    byte *pt;
17155
206
    int ret = 0;
17156
206
#ifdef WC_AES_HAVE_PREFETCH_ARG
17157
206
    int did_prefetches = 0;
17158
206
#endif
17159
17160
206
    if (aes == NULL || out == NULL || in == NULL) {
17161
0
        return BAD_FUNC_ARG;
17162
0
    }
17163
17164
206
    if (!WC_AES_KEY_IS_SET(aes)) {
17165
0
        WOLFSSL_MSG("AES key not set");
17166
0
        return MISSING_KEY;
17167
0
    }
17168
206
    if (sz == 0) {
17169
0
        return 0;
17170
0
    }
17171
17172
206
    VECTOR_REGISTERS_PUSH;
17173
17174
9.20k
    while (sz > 0) {
17175
9.00k
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17176
9.00k
                                        &did_prefetches);
17177
9.00k
        if (ret != 0)
17178
0
            break;
17179
9.00k
        if (dir == AES_DECRYPTION) {
17180
4.54k
            pt = (byte*)aes->reg;
17181
17182
            /* LSB + CAT */
17183
4.54k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
17184
4.54k
            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
17185
4.54k
        }
17186
17187
        /* MSB + XOR */
17188
    #ifdef BIG_ENDIAN_ORDER
17189
        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
17190
    #endif
17191
9.00k
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
17192
9.00k
        if (dir == AES_ENCRYPTION) {
17193
4.46k
            pt = (byte*)aes->reg;
17194
17195
            /* LSB + CAT */
17196
4.46k
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
17197
4.46k
            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
17198
4.46k
        }
17199
17200
9.00k
        out += 1;
17201
9.00k
        in  += 1;
17202
9.00k
        sz  -= 1;
17203
9.00k
    }
17204
17205
206
    VECTOR_REGISTERS_POP;
17206
17207
206
    return ret;
17208
206
}
17209
17210
17211
/* returns 0 on success and negative values on failure */
17212
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
17213
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
17214
171
{
17215
171
    byte tmp;
17216
171
    byte cur = 0; /* hold current work in order to handle inline in=out */
17217
171
    byte* pt;
17218
171
    int bit = 7;
17219
171
    int ret = 0;
17220
171
#ifdef WC_AES_HAVE_PREFETCH_ARG
17221
171
    int did_prefetches = 0;
17222
171
#endif
17223
17224
171
    if (aes == NULL || out == NULL || in == NULL) {
17225
0
        return BAD_FUNC_ARG;
17226
0
    }
17227
17228
171
    if (!WC_AES_KEY_IS_SET(aes)) {
17229
0
        WOLFSSL_MSG("AES key not set");
17230
0
        return MISSING_KEY;
17231
0
    }
17232
171
    if (sz == 0) {
17233
0
        return 0;
17234
0
    }
17235
17236
171
    VECTOR_REGISTERS_PUSH;
17237
17238
54.0k
    while (sz > 0) {
17239
53.8k
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17240
53.8k
                                        &did_prefetches);
17241
53.8k
        if (ret != 0)
17242
0
            break;
17243
53.8k
        if (dir == AES_DECRYPTION) {
17244
17.0k
            pt = (byte*)aes->reg;
17245
17246
            /* LSB + CAT */
17247
17.0k
            tmp = (byte)((0X01U << bit) & in[0]);
17248
17.0k
            tmp = (byte)(tmp >> bit);
17249
17.0k
            tmp &= 0x01;
17250
17.0k
            shiftLeftArray((byte*)aes->reg, 1);
17251
17.0k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
17252
17.0k
        }
17253
17254
        /* MSB  + XOR */
17255
53.8k
        tmp = (byte)((0X01U << bit) & in[0]);
17256
53.8k
        pt = (byte*)aes->tmp;
17257
53.8k
        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
17258
53.8k
        tmp &= 0x01;
17259
53.8k
        cur = (byte)(cur | (tmp << bit));
17260
17261
17262
53.8k
        if (dir == AES_ENCRYPTION) {
17263
36.8k
            pt = (byte*)aes->reg;
17264
17265
            /* LSB + CAT */
17266
36.8k
            shiftLeftArray((byte*)aes->reg, 1);
17267
36.8k
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
17268
36.8k
        }
17269
17270
53.8k
        bit--;
17271
53.8k
        if (bit < 0) {
17272
6.73k
            out[0] = cur;
17273
6.73k
            out += 1;
17274
6.73k
            in  += 1;
17275
6.73k
            sz  -= 1;
17276
6.73k
            bit = 7U;
17277
6.73k
            cur = 0;
17278
6.73k
        }
17279
47.1k
        else {
17280
47.1k
            sz -= 1;
17281
47.1k
        }
17282
53.8k
    }
17283
17284
171
    if (ret == 0) {
17285
171
        if (bit < 7) {
17286
0
            out[0] = cur;
17287
0
        }
17288
171
    }
17289
17290
171
    VECTOR_REGISTERS_POP;
17291
17292
171
    return ret;
17293
171
}
17294
17295
17296
/* CFB 1
17297
 *
17298
 * aes structure holding key to use for encryption
17299
 * out buffer to hold result of encryption (must be at least as large as input
17300
 *     buffer)
17301
 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
17302
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
17303
 *
17304
 * returns 0 on success and negative values on failure
17305
 */
17306
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17307
123
{
17308
123
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
17309
123
}
17310
17311
17312
/* CFB 8
17313
 *
17314
 * aes structure holding key to use for encryption
17315
 * out buffer to hold result of encryption (must be at least as large as input
17316
 *     buffer)
17317
 * in  buffer to encrypt
17318
 * sz  size of input buffer
17319
 *
17320
 * returns 0 on success and negative values on failure
17321
 */
17322
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17323
155
{
17324
155
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
17325
155
}
17326
#ifdef HAVE_AES_DECRYPT
17327
17328
/* CFB 1
17329
 *
17330
 * aes structure holding key to use for encryption
17331
 * out buffer to hold result of encryption (must be at least as large as input
17332
 *     buffer)
17333
 * in  buffer to encrypt
17334
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
17335
 *
17336
 * returns 0 on success and negative values on failure
17337
 */
17338
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17339
48
{
17340
48
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
17341
48
}
17342
17343
17344
/* CFB 8
17345
 *
17346
 * aes structure holding key to use for encryption
17347
 * out buffer to hold result of encryption (must be at least as large as input
17348
 *     buffer)
17349
 * in  buffer to encrypt
17350
 * sz  size of input buffer
17351
 *
17352
 * returns 0 on success and negative values on failure
17353
 */
17354
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17355
51
{
17356
51
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
17357
51
}
17358
#endif /* HAVE_AES_DECRYPT */
17359
#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
17360
#endif /* WOLFSSL_AES_CFB */
17361
17362
#ifdef WOLFSSL_AES_OFB
17363
#ifdef WOLFSSL_NXP_HASHCRYPT_AES
17364
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
17365
17366
#else /* software */
17367
/* OFB AES mode
17368
 *
17369
 * aes structure holding key to use for encryption
17370
 * out buffer to hold result of encryption (must be at least as large as input
17371
 *     buffer)
17372
 * in  buffer to encrypt
17373
 * sz  size of input buffer
17374
 *
17375
 * returns 0 on success and negative error values on failure
17376
 */
17377
/* Software AES - OFB Encrypt/Decrypt */
17378
static WARN_UNUSED_RESULT int AesOfbCrypt_C(Aes* aes, byte* out, const byte* in,
17379
    word32 sz)
17380
525
{
17381
525
    int ret = 0;
17382
525
    word32 processed;
17383
525
#ifdef WC_AES_HAVE_PREFETCH_ARG
17384
525
    int did_prefetches = 0;
17385
525
#endif
17386
17387
525
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
17388
0
        return BAD_FUNC_ARG;
17389
0
    }
17390
525
    if (!WC_AES_KEY_IS_SET(aes)) {
17391
0
        WOLFSSL_MSG("AES key not set");
17392
0
        return MISSING_KEY;
17393
0
    }
17394
525
    if (sz == 0) {
17395
0
        return 0;
17396
0
    }
17397
17398
525
    if (aes->left > 0) {
17399
        /* consume any unused bytes left in aes->tmp */
17400
310
        processed = min(aes->left, sz);
17401
310
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
17402
310
            processed);
17403
310
        aes->left -= processed;
17404
310
        out += processed;
17405
310
        in += processed;
17406
310
        sz -= processed;
17407
310
    }
17408
17409
525
    VECTOR_REGISTERS_PUSH;
17410
17411
1.86k
    while (sz >= WC_AES_BLOCK_SIZE) {
17412
1.34k
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
17413
1.34k
                                        &did_prefetches);
17414
1.34k
        if (ret != 0) {
17415
0
            break;
17416
0
        }
17417
1.34k
        xorbufout(out, in, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
17418
1.34k
        out += WC_AES_BLOCK_SIZE;
17419
1.34k
        in  += WC_AES_BLOCK_SIZE;
17420
1.34k
        sz  -= WC_AES_BLOCK_SIZE;
17421
1.34k
    }
17422
17423
    /* encrypt left over data */
17424
525
    if ((ret == 0) && sz) {
17425
198
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17426
198
                                        &did_prefetches);
17427
198
        if (ret == 0) {
17428
198
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
17429
198
            xorbufout(out, in, aes->tmp, sz);
17430
198
            aes->left = WC_AES_BLOCK_SIZE - sz;
17431
198
        }
17432
198
    }
17433
17434
525
    VECTOR_REGISTERS_POP;
17435
17436
525
    return ret;
17437
525
}
17438
17439
/* OFB
17440
 *
17441
 * aes structure holding key to use for encryption
17442
 * out buffer to hold result of encryption (must be at least as large as input
17443
 *     buffer)
17444
 * in  buffer to encrypt
17445
 * sz  size of input buffer
17446
 *
17447
 * returns 0 on success and negative error values on failure
17448
 */
17449
/* Software AES - OFB Encrypt */
17450
int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17451
424
{
17452
424
#ifdef WOLF_CRYPTO_CB
17453
424
    if (aes == NULL)
17454
0
        return BAD_FUNC_ARG;
17455
424
    #ifndef WOLF_CRYPTO_CB_FIND
17456
424
    if (aes->devId != INVALID_DEVID)
17457
0
    #endif
17458
0
    {
17459
0
        int crypto_cb_ret = wc_CryptoCb_AesOfbEncrypt(aes, out, in, sz);
17460
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17461
0
            return crypto_cb_ret;
17462
        /* fall-through when unavailable */
17463
0
    }
17464
424
#endif
17465
424
    return AesOfbCrypt_C(aes, out, in, sz);
17466
424
}
17467
17468
17469
#ifdef HAVE_AES_DECRYPT
17470
/* OFB
17471
 *
17472
 * aes structure holding key to use for decryption
17473
 * out buffer to hold result of decryption (must be at least as large as input
17474
 *     buffer)
17475
 * in  buffer to decrypt
17476
 * sz  size of input buffer
17477
 *
17478
 * returns 0 on success and negative error values on failure
17479
 */
17480
/* Software AES - OFB Decrypt */
17481
int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17482
101
{
17483
101
#ifdef WOLF_CRYPTO_CB
17484
101
    if (aes == NULL)
17485
0
        return BAD_FUNC_ARG;
17486
101
    #ifndef WOLF_CRYPTO_CB_FIND
17487
101
    if (aes->devId != INVALID_DEVID)
17488
0
    #endif
17489
0
    {
17490
0
        int crypto_cb_ret = wc_CryptoCb_AesOfbDecrypt(aes, out, in, sz);
17491
0
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17492
0
            return crypto_cb_ret;
17493
        /* fall-through when unavailable */
17494
0
    }
17495
101
#endif
17496
101
    return AesOfbCrypt_C(aes, out, in, sz);
17497
101
}
17498
#endif /* HAVE_AES_DECRYPT */
17499
#endif /* software */
17500
#endif /* WOLFSSL_AES_OFB */
17501
17502
17503
#ifdef HAVE_AES_KEYWRAP
17504
17505
/* Initialize key wrap counter with value */
17506
static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
17507
0
{
17508
0
    word32 i;
17509
0
    word32 bytes;
17510
17511
0
    bytes = sizeof(word32);
17512
0
    for (i = 0; i < sizeof(word32); i++) {
17513
0
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
17514
0
        bytes--;
17515
0
    }
17516
0
}
17517
17518
/* Increment key wrap counter */
17519
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
17520
0
{
17521
0
    int i;
17522
17523
    /* in network byte order so start at end and work back */
17524
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
17525
        /* See IncrementAesCounter() on why this masks to an octet. */
17526
0
        inOutCtr[i] = WC_OCTET(inOutCtr[i] + 1);
17527
0
        if (inOutCtr[i] != 0)  /* we're done unless we overflow */
17528
0
            return;
17529
0
    }
17530
0
}
17531
17532
/* Decrement key wrap counter */
17533
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
17534
0
{
17535
0
    int i;
17536
17537
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
17538
        /* Where CHAR_BIT != 8 a bare --byte underflows 0x00 to 0xFFFF, not
17539
         * 0xFF, so the borrow is lost. */
17540
0
        inOutCtr[i] = WC_OCTET(inOutCtr[i] - 1);
17541
0
        if (inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
17542
0
            return;
17543
0
    }
17544
0
}
17545
17546
/* Core RFC 3394 wrapping loop: plaintext at out+8, initial A in aiv; writes
17547
 * C[0]=A and wrapped R[i] in place.  Caller owns output-buffer sizing. */
17548
static int AesKeyWrapRaw(Aes* aes, word32 inSz, byte* out, const byte* aiv)
17549
0
{
17550
0
    word32 i;
17551
0
    byte* r;
17552
0
    int j;
17553
0
    int ret = 0;
17554
17555
0
    byte t[KEYWRAP_BLOCK_SIZE];
17556
0
    byte tmp[WC_AES_BLOCK_SIZE];
17557
17558
    /* at least two 64-bit blocks, on a 64-bit boundary */
17559
0
    if (aes == NULL || out == NULL || aiv == NULL ||
17560
0
        inSz < 2 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0) {
17561
0
        return BAD_FUNC_ARG;
17562
0
    }
17563
17564
#ifndef HAVE_AES_ECB
17565
    /* The block loop below uses the wc_AesEncryptDirect macro, which bypasses
17566
     * the public function's guard. With HAVE_AES_ECB the loop calls
17567
     * wc_AesEcbEncrypt instead, whose own guard sits after the crypto
17568
     * callback dispatch, so a device-held key still reaches the device. */
17569
    if (!WC_AES_KEY_IS_SET(aes)) {
17570
        WOLFSSL_MSG("AES key not set");
17571
        return MISSING_KEY;
17572
    }
17573
#endif
17574
17575
0
    r = out + KEYWRAP_BLOCK_SIZE;
17576
0
    XMEMSET(t, 0, sizeof(t));
17577
17578
    /* A = initial value */
17579
0
    XMEMCPY(tmp, aiv, KEYWRAP_BLOCK_SIZE);
17580
17581
#ifndef HAVE_AES_ECB
17582
    /* Direct block access must save vector registers across the loop; with
17583
     * HAVE_AES_ECB wc_AesEcbEncrypt saves them and can route to an ECB cb. */
17584
    VECTOR_REGISTERS_PUSH;
17585
#endif
17586
17587
0
    for (j = 0; j <= 5; j++) {
17588
0
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
17589
            /* load R[i] */
17590
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
17591
17592
0
#ifdef HAVE_AES_ECB
17593
0
            ret = wc_AesEcbEncrypt(aes, tmp, tmp, WC_AES_BLOCK_SIZE);
17594
#else
17595
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
17596
#endif
17597
0
            if (ret != 0)
17598
0
                break;
17599
17600
            /* calculate new A */
17601
0
            IncrementKeyWrapCounter(t);
17602
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
17603
17604
            /* save R[i] */
17605
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
17606
0
            r += KEYWRAP_BLOCK_SIZE;
17607
0
        }
17608
0
        if (ret != 0)
17609
0
            break;
17610
0
        r = out + KEYWRAP_BLOCK_SIZE;
17611
0
    }
17612
17613
#ifndef HAVE_AES_ECB
17614
    VECTOR_REGISTERS_POP;
17615
#endif
17616
17617
0
    if (ret != 0)
17618
0
        return ret;
17619
17620
    /* C[0] = A */
17621
0
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
17622
17623
0
    return 0;
17624
0
}
17625
17626
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
17627
        word32 outSz, const byte* iv)
17628
0
{
17629
0
    int ret;
17630
0
    byte aiv[KEYWRAP_BLOCK_SIZE];
17631
17632
    /* >= two 64-bit blocks on a 64-bit boundary, output fits outSz; inSz
17633
     * capped at INT_MAX-8 so the returned inSz+8 stays a non-negative int. */
17634
0
    if (aes == NULL || in == NULL || out == NULL ||
17635
0
        inSz < 2 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0 ||
17636
0
        inSz > 0x7FFFFFFFU - KEYWRAP_BLOCK_SIZE ||
17637
0
        outSz < inSz + KEYWRAP_BLOCK_SIZE)
17638
0
        return BAD_FUNC_ARG;
17639
17640
0
#ifdef WOLF_CRYPTO_CB
17641
0
    #ifndef WOLF_CRYPTO_CB_FIND
17642
0
    if (aes->devId != INVALID_DEVID)
17643
0
    #endif
17644
0
    {
17645
0
        ret = wc_CryptoCb_AesKeyWrap(aes, in, inSz, out, outSz, iv, 0);
17646
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
17647
0
            return ret;
17648
0
        }
17649
        /* fall through to software when unavailable */
17650
0
    }
17651
0
#endif
17652
17653
    /* user IV is optional */
17654
0
    if (iv == NULL) {
17655
0
        XMEMSET(aiv, 0xA6, KEYWRAP_BLOCK_SIZE);
17656
0
    }
17657
0
    else {
17658
0
        XMEMCPY(aiv, iv, KEYWRAP_BLOCK_SIZE);
17659
0
    }
17660
17661
    /* stage plaintext at out+8; XMEMMOVE so in-place wrap (in == out) is safe */
17662
0
    XMEMMOVE(out + KEYWRAP_BLOCK_SIZE, in, inSz);
17663
17664
0
    ret = AesKeyWrapRaw(aes, inSz, out, aiv);
17665
0
    if (ret != 0) {
17666
        /* wipe the plaintext staged at out+8 (and any partial cipher state
17667
         * left there) so it is not leaked to the caller on failure */
17668
0
        ForceZero(out + KEYWRAP_BLOCK_SIZE, inSz);
17669
0
        return ret;
17670
0
    }
17671
17672
0
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
17673
0
}
17674
17675
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
17676
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
17677
                  byte* out, word32 outSz, const byte* iv)
17678
0
{
17679
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
17680
0
    int ret;
17681
17682
0
    if (key == NULL)
17683
0
        return BAD_FUNC_ARG;
17684
17685
0
#ifdef WOLFSSL_SMALL_STACK
17686
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
17687
0
                              DYNAMIC_TYPE_AES)) == NULL)
17688
0
        return MEMORY_E;
17689
0
#endif
17690
17691
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17692
0
    if (ret != 0)
17693
0
        goto out;
17694
17695
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
17696
0
    if (ret != 0) {
17697
0
        wc_AesFree(aes);
17698
0
        goto out;
17699
0
    }
17700
17701
0
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
17702
17703
0
    wc_AesFree(aes);
17704
17705
0
  out:
17706
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
17707
17708
0
    return ret;
17709
0
}
17710
17711
/* Core RFC 3394 unwrapping loop: decrypts (n+1) blocks in `in` to n blocks in
17712
 * out and recovered A in aOut.  No integrity check; caller verifies A. */
17713
static int AesKeyUnWrapRaw(Aes* aes, const byte* in, word32 inSz, byte* out,
17714
        byte* aOut)
17715
0
{
17716
0
    byte* r;
17717
0
    word32 i, n;
17718
0
    int j;
17719
0
    int ret = 0;
17720
17721
0
    byte t[KEYWRAP_BLOCK_SIZE];
17722
0
    byte tmp[WC_AES_BLOCK_SIZE];
17723
17724
    /* (n+1) blocks in, n >= 2 recovered blocks out, on a 64-bit boundary */
17725
0
    if (aes == NULL || in == NULL || out == NULL || aOut == NULL ||
17726
0
        inSz < 3 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0) {
17727
0
        return BAD_FUNC_ARG;
17728
0
    }
17729
17730
#ifndef HAVE_AES_ECB
17731
    /* The block loop below uses the wc_AesDecryptDirect macro, which bypasses
17732
     * the public function's guard. With HAVE_AES_ECB the loop calls
17733
     * wc_AesEcbDecrypt instead, whose own guard sits after the crypto
17734
     * callback dispatch, so a device-held key still reaches the device. */
17735
    if (!WC_AES_KEY_IS_SET(aes)) {
17736
        WOLFSSL_MSG("AES key not set");
17737
        return MISSING_KEY;
17738
    }
17739
#endif
17740
17741
    /* A = C[0], R[i] = C[i]; XMEMMOVE so in-place unwrap (in == out) is safe */
17742
0
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
17743
0
    XMEMMOVE(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
17744
0
    XMEMSET(t, 0, sizeof(t));
17745
17746
#ifndef HAVE_AES_ECB
17747
    /* Like AesKeyWrapRaw: HAVE_AES_ECB routes each block through wc_AesEcbDecrypt
17748
     * (saves registers + ECB cb); otherwise save vector registers here. */
17749
    VECTOR_REGISTERS_PUSH;
17750
#endif
17751
17752
    /* initialize counter to 6n */
17753
0
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
17754
0
    InitKeyWrapCounter(t, 6 * n);
17755
17756
0
    for (j = 5; j >= 0; j--) {
17757
0
        for (i = n; i >= 1; i--) {
17758
17759
            /* calculate A */
17760
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
17761
0
            DecrementKeyWrapCounter(t);
17762
17763
            /* load R[i], starting at end of R */
17764
0
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
17765
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
17766
0
#ifdef HAVE_AES_ECB
17767
0
            ret = wc_AesEcbDecrypt(aes, tmp, tmp, WC_AES_BLOCK_SIZE);
17768
#else
17769
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
17770
#endif
17771
0
            if (ret != 0)
17772
0
                break;
17773
17774
            /* save R[i] */
17775
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
17776
0
        }
17777
0
        if (ret != 0)
17778
0
            break;
17779
0
    }
17780
17781
#ifndef HAVE_AES_ECB
17782
    VECTOR_REGISTERS_POP;
17783
#endif
17784
17785
0
    if (ret != 0)
17786
0
        return ret;
17787
17788
    /* return recovered A */
17789
0
    XMEMCPY(aOut, tmp, KEYWRAP_BLOCK_SIZE);
17790
17791
0
    return 0;
17792
0
}
17793
17794
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
17795
        word32 outSz, const byte* iv)
17796
0
{
17797
0
    int ret;
17798
0
    byte a[KEYWRAP_BLOCK_SIZE];
17799
17800
0
    const byte* expIv;
17801
0
    const byte defaultIV[] = {
17802
0
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
17803
0
    };
17804
17805
    /* (n+1) >= 3 blocks on a 64-bit boundary, n blocks fit outSz; inSz capped
17806
     * at INT_MAX so the returned inSz-8 stays a non-negative int. */
17807
0
    if (aes == NULL || in == NULL || out == NULL ||
17808
0
        inSz < 3 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0 ||
17809
0
        inSz > 0x7FFFFFFFU || outSz < inSz - KEYWRAP_BLOCK_SIZE)
17810
0
        return BAD_FUNC_ARG;
17811
17812
0
#ifdef WOLF_CRYPTO_CB
17813
0
    #ifndef WOLF_CRYPTO_CB_FIND
17814
0
    if (aes->devId != INVALID_DEVID)
17815
0
    #endif
17816
0
    {
17817
0
        ret = wc_CryptoCb_AesKeyUnWrap(aes, in, inSz, out, outSz, iv, 0);
17818
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
17819
0
            return ret;
17820
0
        }
17821
        /* fall through to software when unavailable */
17822
0
    }
17823
0
#endif
17824
17825
    /* user IV optional */
17826
0
    if (iv != NULL) {
17827
0
        expIv = iv;
17828
0
    }
17829
0
    else {
17830
0
        expIv = defaultIV;
17831
0
    }
17832
17833
0
    ret = AesKeyUnWrapRaw(aes, in, inSz, out, a);
17834
0
    if (ret != 0) {
17835
0
        return ret;
17836
0
    }
17837
17838
    /* verify IV */
17839
0
    if (ConstantCompare(a, expIv, KEYWRAP_BLOCK_SIZE) != 0) {
17840
        /* IV check failed: wipe the recovered plaintext key material left in
17841
         * out before returning so it is not leaked to the caller */
17842
0
        ForceZero(out, inSz - KEYWRAP_BLOCK_SIZE);
17843
0
        return BAD_KEYWRAP_IV_E;
17844
0
    }
17845
17846
0
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
17847
0
}
17848
17849
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
17850
                    byte* out, word32 outSz, const byte* iv)
17851
0
{
17852
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
17853
0
    int ret;
17854
17855
0
    (void)iv;
17856
17857
0
    if (key == NULL)
17858
0
        return BAD_FUNC_ARG;
17859
17860
0
#ifdef WOLFSSL_SMALL_STACK
17861
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
17862
0
                              DYNAMIC_TYPE_AES)) == NULL)
17863
0
        return MEMORY_E;
17864
0
#endif
17865
17866
17867
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17868
0
    if (ret != 0)
17869
0
        goto out;
17870
17871
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
17872
0
    if (ret != 0) {
17873
0
        wc_AesFree(aes);
17874
0
        goto out;
17875
0
    }
17876
17877
0
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
17878
17879
0
    wc_AesFree(aes);
17880
17881
0
  out:
17882
0
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
17883
17884
0
    return ret;
17885
0
}
17886
17887
#ifdef WOLFSSL_AES_KEYWRAP_PADDING
17888
17889
/* RFC 5649 AIV high-half constant; the low half carries the 32-bit MLI. */
17890
static const byte kwpAivConst[] = { 0xA6, 0x59, 0x59, 0xA6 };
17891
17892
/* Build the RFC 5649 AIV: 4-byte constant (iv override or default) | 4-byte
17893
 * big-endian MLI m. */
17894
static void BuildKwpAiv(byte* aiv, const byte* iv, word32 m)
17895
{
17896
    if (iv == NULL) {
17897
        XMEMCPY(aiv, kwpAivConst, sizeof(kwpAivConst));
17898
    }
17899
    else {
17900
        XMEMCPY(aiv, iv, sizeof(kwpAivConst));
17901
    }
17902
17903
    aiv[4] = (byte)(m >> 24);
17904
    aiv[5] = (byte)(m >> 16);
17905
    aiv[6] = (byte)(m >>  8);
17906
    aiv[7] = (byte)(m);
17907
}
17908
17909
int wc_AesKeyWrap_Pad_ex(Aes* aes, const byte* in, word32 inSz, byte* out,
17910
        word32 outSz, const byte* iv)
17911
{
17912
    int ret;
17913
    word32 n;
17914
    word32 padSz;
17915
    byte aiv[KEYWRAP_BLOCK_SIZE];
17916
17917
    /* inSz capped at INT_MAX-(2*8-1) so rounding up to whole blocks plus the
17918
     * AIV block can't overflow padSz+8; too-small output -> BAD_FUNC_ARG. */
17919
    if (aes == NULL || in == NULL || inSz == 0 || out == NULL ||
17920
        inSz > 0x7FFFFFFFU - (2 * KEYWRAP_BLOCK_SIZE - 1))
17921
        return BAD_FUNC_ARG;
17922
17923
    /* n = ceil(m/8) padded blocks; output is (n+1) blocks */
17924
    n = (inSz + KEYWRAP_BLOCK_SIZE - 1) / KEYWRAP_BLOCK_SIZE;
17925
    padSz = n * KEYWRAP_BLOCK_SIZE;
17926
    if (outSz < padSz + KEYWRAP_BLOCK_SIZE)
17927
        return BAD_FUNC_ARG;
17928
17929
#ifdef WOLF_CRYPTO_CB
17930
    #ifndef WOLF_CRYPTO_CB_FIND
17931
    if (aes->devId != INVALID_DEVID)
17932
    #endif
17933
    {
17934
        ret = wc_CryptoCb_AesKeyWrap(aes, in, inSz, out, outSz, iv, 1);
17935
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
17936
            return ret;
17937
        }
17938
        /* fall through to software when unavailable */
17939
    }
17940
#endif
17941
17942
    /* AIV = const | MLI(inSz) */
17943
    BuildKwpAiv(aiv, iv, inSz);
17944
17945
    /* stage plaintext at out+8 (XMEMMOVE for in-place), zeroing the pad octets */
17946
    XMEMMOVE(out + KEYWRAP_BLOCK_SIZE, in, inSz);
17947
    if (padSz > inSz) {
17948
        XMEMSET(out + KEYWRAP_BLOCK_SIZE + inSz, 0, padSz - inSz);
17949
    }
17950
17951
    if (n == 1) {
17952
        /* single block: C[0]|C[1] = ENC(K, AIV | P[1]) */
17953
        byte tmp[WC_AES_BLOCK_SIZE];
17954
        XMEMCPY(tmp, aiv, KEYWRAP_BLOCK_SIZE);
17955
        XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, out + KEYWRAP_BLOCK_SIZE,
17956
                KEYWRAP_BLOCK_SIZE);
17957
#ifdef HAVE_AES_ECB
17958
        /* Route through wc_AesEcbEncrypt so an ECB crypto callback can service
17959
         * the block; it saves its own registers. */
17960
        ret = wc_AesEcbEncrypt(aes, out, tmp, WC_AES_BLOCK_SIZE);
17961
#else
17962
        VECTOR_REGISTERS_PUSH;
17963
        ret = wc_AesEncryptDirect(aes, out, tmp);
17964
        VECTOR_REGISTERS_POP;
17965
#endif
17966
        /* tmp held AIV | plaintext key material */
17967
        ForceZero(tmp, sizeof(tmp));
17968
    }
17969
    else {
17970
        /* run the RFC 3394 loop with the AIV as the initial value */
17971
        ret = AesKeyWrapRaw(aes, padSz, out, aiv);
17972
    }
17973
    if (ret != 0) {
17974
        /* wipe the plaintext staged at out+8 (and any partial cipher state)
17975
         * so it is not leaked to the caller on failure */
17976
        ForceZero(out + KEYWRAP_BLOCK_SIZE, padSz);
17977
        return ret;
17978
    }
17979
17980
    return (int)(padSz + KEYWRAP_BLOCK_SIZE);
17981
}
17982
17983
int wc_AesKeyWrap_Pad(const byte* key, word32 keySz, const byte* in,
17984
        word32 inSz, byte* out, word32 outSz, const byte* iv)
17985
{
17986
    WC_DECLARE_VAR(aes, Aes, 1, NULL);
17987
    int ret;
17988
17989
    if (key == NULL) {
17990
        return BAD_FUNC_ARG;
17991
    }
17992
17993
    WC_ALLOC_VAR_EX(aes, Aes, 1, NULL, DYNAMIC_TYPE_AES, return MEMORY_E);
17994
17995
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17996
    if (ret != 0) {
17997
        goto out;
17998
    }
17999
18000
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
18001
    if (ret != 0) {
18002
        wc_AesFree(aes);
18003
        goto out;
18004
    }
18005
18006
    ret = wc_AesKeyWrap_Pad_ex(aes, in, inSz, out, outSz, iv);
18007
18008
    wc_AesFree(aes);
18009
18010
  out:
18011
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
18012
18013
    return ret;
18014
}
18015
18016
int wc_AesKeyUnWrap_Pad_ex(Aes* aes, const byte* in, word32 inSz, byte* out,
18017
        word32 outSz, const byte* iv)
18018
{
18019
    int ret;
18020
    word32 n;
18021
    word32 mli;
18022
    byte a[KEYWRAP_BLOCK_SIZE];
18023
    byte expConst[sizeof(kwpAivConst)];
18024
18025
    /* (n+1) >= 2 blocks on a 64-bit boundary; inSz capped at INT_MAX so the
18026
     * returned MLI stays a non-negative int; too-small output -> BAD_FUNC_ARG. */
18027
    if (aes == NULL || in == NULL || out == NULL ||
18028
        inSz < 2 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0 ||
18029
        inSz > 0x7FFFFFFFU || outSz < inSz - KEYWRAP_BLOCK_SIZE)
18030
        return BAD_FUNC_ARG;
18031
18032
#ifdef WOLF_CRYPTO_CB
18033
    #ifndef WOLF_CRYPTO_CB_FIND
18034
    if (aes->devId != INVALID_DEVID)
18035
    #endif
18036
    {
18037
        ret = wc_CryptoCb_AesKeyUnWrap(aes, in, inSz, out, outSz, iv, 1);
18038
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
18039
            return ret;
18040
        }
18041
        /* fall through to software when unavailable */
18042
    }
18043
#endif
18044
18045
    /* number of padded 64-bit plaintext blocks */
18046
    n = (inSz / KEYWRAP_BLOCK_SIZE) - 1;
18047
18048
    if (n == 1) {
18049
        /* single block: AIV|P[1] = DEC(K, C[0]|C[1]) */
18050
        byte tmp[WC_AES_BLOCK_SIZE];
18051
#ifdef HAVE_AES_ECB
18052
        /* Route through wc_AesEcbDecrypt so an ECB crypto callback can service
18053
         * the block; it saves its own registers. */
18054
        ret = wc_AesEcbDecrypt(aes, tmp, in, WC_AES_BLOCK_SIZE);
18055
#else
18056
        VECTOR_REGISTERS_PUSH;
18057
        ret = wc_AesDecryptDirect(aes, tmp, in);
18058
        VECTOR_REGISTERS_POP;
18059
#endif
18060
        if (ret == 0) {
18061
            XMEMCPY(a, tmp, KEYWRAP_BLOCK_SIZE);
18062
            XMEMCPY(out, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
18063
        }
18064
        /* tmp held AIV | plaintext key material */
18065
        ForceZero(tmp, sizeof(tmp));
18066
    }
18067
    else {
18068
        /* recover A and padded plaintext via the RFC 3394 loop (no check) */
18069
        ret = AesKeyUnWrapRaw(aes, in, inSz, out, a);
18070
    }
18071
    if (ret != 0) {
18072
        return ret;
18073
    }
18074
18075
    /* expected high-half constant (iv override or default) */
18076
    if (iv == NULL) {
18077
        XMEMCPY(expConst, kwpAivConst, sizeof(kwpAivConst));
18078
    }
18079
    else {
18080
        XMEMCPY(expConst, iv, sizeof(kwpAivConst));
18081
    }
18082
18083
    /* MLI = LSB(32,A) in network order */
18084
    mli = ((word32)a[4] << 24) | ((word32)a[5] << 16) |
18085
          ((word32)a[6] <<  8) |  (word32)a[7];
18086
18087
    /* Validate the three RFC 5649 checks in constant time: fold failures into
18088
     * one mask and branch once, so timing does not reveal which check failed. */
18089
    {
18090
        word32 dataSz  = inSz - KEYWRAP_BLOCK_SIZE;   /* 8*n plaintext octets */
18091
        word32 lastBlk = dataSz - KEYWRAP_BLOCK_SIZE; /* offset 8*(n-1)       */
18092
        word32 fail;
18093
        word32 j;
18094
#ifndef WORD64_AVAILABLE
18095
        byte   lowMask = (byte)~(byte)(0u - ((mli >> 31) & 1u));
18096
        int    mliInt  = (int)(mli & 0x7FFFFFFFu);
18097
#endif
18098
18099
        /* check 1: MSB(32,A) == constant */
18100
        fail = (word32)ctMaskNotEq(ConstantCompare(a, expConst,
18101
                                           (int)sizeof(kwpAivConst)), 0);
18102
18103
#ifdef WORD64_AVAILABLE
18104
        /* check 2: 8*(n-1) < MLI <= 8*n */
18105
        fail |= ~(ctMaskWord32GTE(mli, lastBlk + 1)    /* MLI >= 8*(n-1)+1 */
18106
                & ctMaskWord32GTE(dataSz, mli));       /* 8*n >= MLI       */
18107
18108
        /* check 3: octets in [MLI, 8*n) are zero.  A valid MLI is in the final
18109
         * block, so scan it at fixed offsets, requiring zero where off >= MLI. */
18110
        for (j = 0; j < KEYWRAP_BLOCK_SIZE; j++) {
18111
            word32 off = lastBlk + j;
18112
            fail |= ctMaskWord32GTE(off, mli)          /* off >= MLI */
18113
                    & (word32)ctMaskNotEq((int)out[off], 0);
18114
        }
18115
#else
18116
        /* No word64: compare in int range.  MLI with its high bit set (>= 2^31
18117
         * > 8*n) is forced to fail so the int compares see valid values. */
18118
18119
        /* check 2: 8*(n-1) < MLI <= 8*n */
18120
        fail |= (word32)(byte)~(byte)(ctMaskGT(mliInt, (int)lastBlk)
18121
                                    & ctMaskLTE(mliInt, (int)dataSz)
18122
                                    & lowMask);
18123
18124
        /* check 3: octets in [MLI, 8*n) are zero (see note above). */
18125
        for (j = 0; j < KEYWRAP_BLOCK_SIZE; j++) {
18126
            int  off   = (int)(lastBlk + j);
18127
            byte isPad = (byte)(ctMaskGTE(off, mliInt) & lowMask);
18128
            fail |= (word32)(byte)(isPad &
18129
                                   ctMaskNotEq((int)out[lastBlk + j], 0));
18130
        }
18131
#endif
18132
18133
        if (fail != 0) {
18134
            goto badIv;
18135
        }
18136
    }
18137
18138
    return (int)mli;
18139
18140
badIv:
18141
    /* integrity check failed: wipe the recovered plaintext in out so it is
18142
     * not leaked to the caller */
18143
    ForceZero(out, inSz - KEYWRAP_BLOCK_SIZE);
18144
    return BAD_KEYWRAP_IV_E;
18145
}
18146
18147
int wc_AesKeyUnWrap_Pad(const byte* key, word32 keySz, const byte* in,
18148
        word32 inSz, byte* out, word32 outSz, const byte* iv)
18149
{
18150
    WC_DECLARE_VAR(aes, Aes, 1, NULL);
18151
    int ret;
18152
18153
    if (key == NULL) {
18154
        return BAD_FUNC_ARG;
18155
    }
18156
18157
    WC_ALLOC_VAR_EX(aes, Aes, 1, NULL, DYNAMIC_TYPE_AES, return MEMORY_E);
18158
18159
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
18160
    if (ret != 0) {
18161
        goto out;
18162
    }
18163
18164
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
18165
    if (ret != 0) {
18166
        wc_AesFree(aes);
18167
        goto out;
18168
    }
18169
18170
    ret = wc_AesKeyUnWrap_Pad_ex(aes, in, inSz, out, outSz, iv);
18171
18172
    wc_AesFree(aes);
18173
18174
  out:
18175
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
18176
18177
    return ret;
18178
}
18179
18180
#endif /* WOLFSSL_AES_KEYWRAP_PADDING */
18181
18182
#endif /* HAVE_AES_KEYWRAP */
18183
18184
#ifdef WOLFSSL_AES_XTS
18185
18186
/* Galois Field to use */
18187
902
#define GF_XTS 0x87
18188
18189
/* Set up keys for encryption and/or decryption.
18190
 *
18191
 * aes   buffer holding aes subkeys
18192
 * heap  heap hint to use for memory. Can be NULL
18193
 * devId id to use with async crypto. Can be 0
18194
 *
18195
 * return 0 on success
18196
 */
18197
int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
18198
513
{
18199
513
    int    ret = 0;
18200
18201
513
    if (aes == NULL) {
18202
0
        return BAD_FUNC_ARG;
18203
0
    }
18204
18205
513
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
18206
0
        return ret;
18207
0
    }
18208
513
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
18209
0
        (void)wc_AesFree(&aes->tweak);
18210
0
        return ret;
18211
0
    }
18212
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18213
    if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) {
18214
        (void)wc_AesFree(&aes->tweak);
18215
        (void)wc_AesFree(&aes->aes);
18216
        return ret;
18217
    }
18218
#endif
18219
18220
513
    return 0;
18221
513
}
18222
18223
/* Set up keys for encryption and/or decryption.
18224
 *
18225
 * aes   buffer holding aes subkeys
18226
 * key   AES key for encrypt/decrypt and tweak process (concatenated)
18227
 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
18228
 *       32 for a 16 byte key.
18229
 * dir   direction: AES_ENCRYPTION, AES_DECRYPTION, or
18230
 *       AES_ENCRYPTION_AND_DECRYPTION
18231
 *
18232
 * return 0 on success
18233
 */
18234
int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
18235
512
{
18236
512
    word32 keySz;
18237
512
    int    ret = 0;
18238
18239
512
    if (aes == NULL || key == NULL) {
18240
0
        return BAD_FUNC_ARG;
18241
0
    }
18242
18243
512
    if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION)
18244
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18245
        && (dir != AES_ENCRYPTION_AND_DECRYPTION)
18246
#endif
18247
512
        )
18248
0
    {
18249
0
        return BAD_FUNC_ARG;
18250
0
    }
18251
18252
512
    if ((len != (AES_128_KEY_SIZE*2)) &&
18253
110
#ifndef HAVE_FIPS
18254
        /* XTS-384 not allowed by FIPS and can not be treated like
18255
         * RSA-4096 bit keys back in the day, can not vendor affirm
18256
         * the use of 2 concatenated 192-bit keys (XTS-384) */
18257
110
        (len != (AES_192_KEY_SIZE*2)) &&
18258
110
#endif
18259
110
        (len != (AES_256_KEY_SIZE*2)))
18260
0
    {
18261
0
        WOLFSSL_MSG("Unsupported key size");
18262
0
        return WC_KEY_SIZE_E;
18263
0
    }
18264
18265
512
    keySz = len/2;
18266
18267
512
#if defined(HAVE_FIPS) || !defined(WC_AES_XTS_ALLOW_DUPLICATE_KEYS)
18268
512
    if (XMEMCMP(key, key + keySz, keySz) == 0) {
18269
44
        WOLFSSL_MSG("AES-XTS main and tweak keys must differ");
18270
44
        return BAD_FUNC_ARG;
18271
44
    }
18272
468
#endif
18273
18274
468
    if (dir == AES_ENCRYPTION
18275
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18276
        || dir == AES_ENCRYPTION_AND_DECRYPTION
18277
#endif
18278
468
        )
18279
210
    {
18280
210
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
18281
210
    }
18282
18283
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18284
    if ((ret == 0) && ((dir == AES_DECRYPTION)
18285
                       || (dir == AES_ENCRYPTION_AND_DECRYPTION)))
18286
        ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION);
18287
#else
18288
468
    if (dir == AES_DECRYPTION)
18289
258
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
18290
468
#endif
18291
18292
468
    if (ret == 0)
18293
468
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
18294
468
                AES_ENCRYPTION);
18295
18296
#ifdef WOLFSSL_AESNI
18297
    if (ret == 0) {
18298
        /* With WC_C_DYNAMIC_FALLBACK, the main and tweak keys could have
18299
         * conflicting _aesni status, but the AES-XTS asm implementations need
18300
         * them to all be AESNI.  If any aren't, disable AESNI on all.
18301
         */
18302
    #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18303
        if ((((dir == AES_ENCRYPTION) ||
18304
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
18305
             && (aes->aes.use_aesni != aes->tweak.use_aesni))
18306
            ||
18307
            (((dir == AES_DECRYPTION) ||
18308
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
18309
             && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)))
18310
        {
18311
        #ifdef WC_C_DYNAMIC_FALLBACK
18312
            aes->aes.use_aesni = 0;
18313
            aes->aes_decrypt.use_aesni = 0;
18314
            aes->tweak.use_aesni = 0;
18315
        #else
18316
            ret = SYSLIB_FAILED_E;
18317
        #endif
18318
        }
18319
    #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
18320
        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
18321
        #ifdef WC_C_DYNAMIC_FALLBACK
18322
            aes->aes.use_aesni = 0;
18323
            aes->tweak.use_aesni = 0;
18324
        #else
18325
            ret = SYSLIB_FAILED_E;
18326
        #endif
18327
        }
18328
    #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
18329
    }
18330
#endif /* WOLFSSL_AESNI */
18331
18332
468
    return ret;
18333
512
}
18334
18335
/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
18336
 *
18337
 * Note: is up to user to call wc_AesXtsFree when done.
18338
 *
18339
 * return 0 on success
18340
 */
18341
int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
18342
        void* heap, int devId)
18343
0
{
18344
0
    int    ret = 0;
18345
18346
0
    if (aes == NULL || key == NULL) {
18347
0
        return BAD_FUNC_ARG;
18348
0
    }
18349
18350
0
    ret = wc_AesXtsInit(aes, heap, devId);
18351
0
    if (ret != 0)
18352
0
        return ret;
18353
18354
0
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
18355
18356
0
    if (ret != 0)
18357
0
        wc_AesXtsFree(aes);
18358
18359
0
    return ret;
18360
0
}
18361
18362
18363
/* This is used to free up resources used by Aes structs
18364
 *
18365
 * aes AES keys to free
18366
 *
18367
 * return 0 on success
18368
 */
18369
int wc_AesXtsFree(XtsAes* aes)
18370
513
{
18371
513
    if (aes != NULL) {
18372
513
        wc_AesFree(&aes->aes);
18373
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18374
        wc_AesFree(&aes->aes_decrypt);
18375
#endif
18376
513
        wc_AesFree(&aes->tweak);
18377
513
    }
18378
18379
513
    return 0;
18380
513
}
18381
18382
18383
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
18384
 * instead of a byte array. This just converts the word64 to a byte array and
18385
 * calls wc_AesXtsEncrypt.
18386
 *
18387
 * aes    AES keys to use for block encrypt/decrypt
18388
 * out    output buffer to hold cipher text
18389
 * in     input plain text buffer to encrypt
18390
 * sz     size of both out and in buffers
18391
 * sector value to use for tweak
18392
 *
18393
 * returns 0 on success
18394
 */
18395
int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
18396
        word32 sz, word64 sector)
18397
0
{
18398
0
    byte* pt;
18399
0
    byte  i[WC_AES_BLOCK_SIZE];
18400
18401
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
18402
#ifdef BIG_ENDIAN_ORDER
18403
    sector = ByteReverseWord64(sector);
18404
#endif
18405
0
    pt = (byte*)&sector;
18406
0
    XMEMCPY(i, pt, sizeof(word64));
18407
18408
0
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
18409
0
}
18410
18411
#ifdef HAVE_AES_DECRYPT
18412
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
18413
 * instead of a byte array. This just converts the word64 to a byte array.
18414
 *
18415
 * aes    AES keys to use for block encrypt/decrypt
18416
 * out    output buffer to hold plain text
18417
 * in     input cipher text buffer to encrypt
18418
 * sz     size of both out and in buffers
18419
 * sector value to use for tweak
18420
 *
18421
 * returns 0 on success
18422
 */
18423
int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
18424
        word64 sector)
18425
0
{
18426
0
    byte* pt;
18427
0
    byte  i[WC_AES_BLOCK_SIZE];
18428
18429
0
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
18430
#ifdef BIG_ENDIAN_ORDER
18431
    sector = ByteReverseWord64(sector);
18432
#endif
18433
0
    pt = (byte*)&sector;
18434
0
    XMEMCPY(i, pt, sizeof(word64));
18435
18436
0
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
18437
0
}
18438
#endif
18439
18440
#if defined(WOLFSSL_AESNI)
18441
18442
#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
18443
    #define USE_INTEL_SPEEDUP
18444
#endif
18445
18446
#if defined(USE_INTEL_SPEEDUP)
18447
    #define HAVE_INTEL_AVX1
18448
    #define HAVE_INTEL_AVX2
18449
#endif
18450
18451
/* aes_xts_x86_asm.S provides the AES-NI routines for 32-bit x86 but has no
18452
 * AVX1 variants, so the wider path must not be used there - AES_XTS_*_avx1
18453
 * would be undefined at link time.  Leaving HAVE_INTEL_AVX1 undefined is not
18454
 * an option: it is already defined above for the AES-GCM code, whose AVX1
18455
 * paths do exist for 32-bit x86 in aes_gcm_x86_asm.S.  VAES and AVX512 need
18456
 * no equivalent - both are already gated on WOLFSSL_X86_64_BUILD. */
18457
#if defined(HAVE_INTEL_AVX1) && !defined(WOLFSSL_X86_BUILD)
18458
    #define WC_AES_XTS_HAVE_AVX1
18459
#endif
18460
18461
void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
18462
                     const unsigned char* i, const unsigned char* key,
18463
                     const unsigned char* key2, int nr)
18464
                     XASM_LINK("AES_XTS_encrypt_aesni");
18465
#ifdef WOLFSSL_AESXTS_STREAM
18466
void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
18467
                     int tweak_nr)
18468
                     XASM_LINK("AES_XTS_init_aesni");
18469
void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
18470
                     const unsigned char* key, unsigned char *i, int nr)
18471
                     XASM_LINK("AES_XTS_encrypt_update_aesni");
18472
#endif
18473
#ifdef WC_AES_XTS_HAVE_AVX1
18474
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
18475
                     word32 sz, const unsigned char* i,
18476
                     const unsigned char* key, const unsigned char* key2,
18477
                     int nr)
18478
                     XASM_LINK("AES_XTS_encrypt_avx1");
18479
#ifdef WOLFSSL_AESXTS_STREAM
18480
void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
18481
                     int tweak_nr)
18482
                     XASM_LINK("AES_XTS_init_avx1");
18483
void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
18484
                     const unsigned char* key, unsigned char *i, int nr)
18485
                     XASM_LINK("AES_XTS_encrypt_update_avx1");
18486
#endif
18487
#endif /* WC_AES_XTS_HAVE_AVX1 */
18488
#ifdef HAVE_INTEL_VAES
18489
void AES_XTS_encrypt_vaes(const unsigned char *in, unsigned char *out,
18490
                     word32 sz, const unsigned char* i,
18491
                     const unsigned char* key, const unsigned char* key2,
18492
                     int nr)
18493
                     XASM_LINK("AES_XTS_encrypt_vaes");
18494
#ifdef WOLFSSL_AESXTS_STREAM
18495
void AES_XTS_init_vaes(unsigned char* i, const unsigned char* tweak_key,
18496
                     int tweak_nr)
18497
                     XASM_LINK("AES_XTS_init_vaes");
18498
void AES_XTS_encrypt_update_vaes(const unsigned char *in, unsigned char *out, word32 sz,
18499
                     const unsigned char* key, unsigned char *i, int nr)
18500
                     XASM_LINK("AES_XTS_encrypt_update_vaes");
18501
#endif
18502
#endif /* HAVE_INTEL_VAES */
18503
#ifdef HAVE_INTEL_AVX512
18504
void AES_XTS_encrypt_avx512(const unsigned char *in, unsigned char *out,
18505
                     word32 sz, const unsigned char* i,
18506
                     const unsigned char* key, const unsigned char* key2,
18507
                     int nr)
18508
                     XASM_LINK("AES_XTS_encrypt_avx512");
18509
#ifdef WOLFSSL_AESXTS_STREAM
18510
void AES_XTS_init_avx512(unsigned char* i, const unsigned char* tweak_key,
18511
                     int tweak_nr)
18512
                     XASM_LINK("AES_XTS_init_avx512");
18513
void AES_XTS_encrypt_update_avx512(const unsigned char *in, unsigned char *out, word32 sz,
18514
                     const unsigned char* key, unsigned char *i, int nr)
18515
                     XASM_LINK("AES_XTS_encrypt_update_avx512");
18516
#endif
18517
#endif /* HAVE_INTEL_AVX512 */
18518
18519
18520
#ifdef HAVE_AES_DECRYPT
18521
void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
18522
                     const unsigned char* i, const unsigned char* key,
18523
                     const unsigned char* key2, int nr)
18524
                     XASM_LINK("AES_XTS_decrypt_aesni");
18525
#ifdef WOLFSSL_AESXTS_STREAM
18526
void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
18527
                     const unsigned char* key, unsigned char *i, int nr)
18528
                     XASM_LINK("AES_XTS_decrypt_update_aesni");
18529
#endif
18530
#ifdef WC_AES_XTS_HAVE_AVX1
18531
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
18532
                     word32 sz, const unsigned char* i,
18533
                     const unsigned char* key, const unsigned char* key2,
18534
                     int nr)
18535
                     XASM_LINK("AES_XTS_decrypt_avx1");
18536
#ifdef WOLFSSL_AESXTS_STREAM
18537
void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
18538
                     const unsigned char* key, unsigned char *i, int nr)
18539
                     XASM_LINK("AES_XTS_decrypt_update_avx1");
18540
#endif
18541
#endif /* WC_AES_XTS_HAVE_AVX1 */
18542
#ifdef HAVE_INTEL_VAES
18543
void AES_XTS_decrypt_vaes(const unsigned char *in, unsigned char *out,
18544
                     word32 sz, const unsigned char* i,
18545
                     const unsigned char* key, const unsigned char* key2,
18546
                     int nr)
18547
                     XASM_LINK("AES_XTS_decrypt_vaes");
18548
#ifdef WOLFSSL_AESXTS_STREAM
18549
void AES_XTS_decrypt_update_vaes(const unsigned char *in, unsigned char *out, word32 sz,
18550
                     const unsigned char* key, unsigned char *i, int nr)
18551
                     XASM_LINK("AES_XTS_decrypt_update_vaes");
18552
#endif
18553
#endif /* HAVE_INTEL_VAES */
18554
#ifdef HAVE_INTEL_AVX512
18555
void AES_XTS_decrypt_avx512(const unsigned char *in, unsigned char *out,
18556
                     word32 sz, const unsigned char* i,
18557
                     const unsigned char* key, const unsigned char* key2,
18558
                     int nr)
18559
                     XASM_LINK("AES_XTS_decrypt_avx512");
18560
#ifdef WOLFSSL_AESXTS_STREAM
18561
void AES_XTS_decrypt_update_avx512(const unsigned char *in, unsigned char *out, word32 sz,
18562
                     const unsigned char* key, unsigned char *i, int nr)
18563
                     XASM_LINK("AES_XTS_decrypt_update_avx512");
18564
#endif
18565
#endif /* HAVE_INTEL_AVX512 */
18566
#endif /* HAVE_AES_DECRYPT */
18567
18568
#endif /* WOLFSSL_AESNI */
18569
18570
#ifdef HAVE_AES_ECB
18571
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
18572
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
18573
    defined(WOLFSSL_ARM32_AES_DISPATCH)) || defined(WOLFSSL_AESXTS_STREAM)
18574
/* helper function for encrypting / decrypting full buffer at once */
18575
static WARN_UNUSED_RESULT int _AesXtsHelper(
18576
    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
18577
382
{
18578
382
    word32 outSz   = sz;
18579
382
    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
18580
382
    byte*  pt      = out;
18581
18582
382
    outSz -= WC_AES_BLOCK_SIZE;
18583
18584
990
    while (outSz > 0) {
18585
608
        word32 j;
18586
608
        byte carry = 0;
18587
18588
        /* multiply by shift left and propagate carry */
18589
9.89k
        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
18590
9.28k
            byte tmpC;
18591
18592
9.28k
            tmpC   = (pt[j] >> 7) & 0x01;
18593
9.28k
            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
18594
9.28k
            carry  = tmpC;
18595
9.28k
        }
18596
608
        if (carry) {
18597
318
            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
18598
318
        }
18599
18600
608
        pt += WC_AES_BLOCK_SIZE;
18601
608
    }
18602
18603
382
    xorbuf(out, in, totalSz);
18604
382
#ifndef WOLFSSL_RISCV_ASM
18605
382
    if (dir == AES_ENCRYPTION) {
18606
126
        return _AesEcbEncrypt(aes, out, out, totalSz);
18607
126
    }
18608
256
    else {
18609
256
        return _AesEcbDecrypt(aes, out, out, totalSz);
18610
256
    }
18611
#else
18612
    if (dir == AES_ENCRYPTION) {
18613
        return wc_AesEcbEncrypt(aes, out, out, totalSz);
18614
    }
18615
    else {
18616
        return wc_AesEcbDecrypt(aes, out, out, totalSz);
18617
    }
18618
#endif
18619
382
}
18620
#endif
18621
#endif /* HAVE_AES_ECB */
18622
18623
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
18624
 *
18625
 * xaes  AES keys to use for block encrypt/decrypt
18626
 * out   output buffer to hold cipher text
18627
 * in    input plain text buffer to encrypt
18628
 * sz    size of both out and in buffers
18629
 * i     value to use for tweak
18630
 *
18631
 * returns 0 on success
18632
 */
18633
/* Software AES - XTS Encrypt  */
18634
18635
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
18636
     defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
18637
     defined(WOLFSSL_ARM32_AES_DISPATCH)) && !defined(WOLFSSL_PPC64_ASM)
18638
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
18639
                                  word32 sz,
18640
                                  byte *i);
18641
#if !defined(WOLFSSL_RISCV_ASM)
18642
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
18643
        const byte* i)
18644
177
{
18645
177
    int ret;
18646
177
    byte tweak_block[WC_AES_BLOCK_SIZE];
18647
18648
177
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
18649
177
    if (ret != 0)
18650
0
        return ret;
18651
18652
177
    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
18653
177
}
18654
#endif /* !WOLFSSL_RISCV_ASM */
18655
#endif
18656
18657
#ifdef WOLFSSL_AESXTS_STREAM
18658
18659
/* Block-streaming AES-XTS tweak setup.
18660
 *
18661
 * xaes  AES keys to use for block encrypt/decrypt
18662
 * i     readwrite value to use for tweak
18663
 *
18664
 * returns 0 on success
18665
 */
18666
static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
18667
    return wc_AesEncryptDirect(&xaes->tweak, i, i);
18668
}
18669
18670
#endif /* WOLFSSL_AESXTS_STREAM */
18671
18672
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
18673
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
18674
    defined(WOLFSSL_ARM32_AES_DISPATCH) || defined(WOLFSSL_AESXTS_STREAM)
18675
/* Block-streaming AES-XTS.
18676
 *
18677
 * Supply block-aligned input data with successive calls.  Final call need not
18678
 * be block aligned.
18679
 *
18680
 * xaes  AES keys to use for block encrypt/decrypt
18681
 * out   output buffer to hold cipher text
18682
 * in    input plain text buffer to encrypt
18683
 * sz    size of both out and in buffers
18684
 *
18685
 * returns 0 on success
18686
 */
18687
/* Software AES - XTS Encrypt  */
18688
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
18689
                                  word32 sz,
18690
                                  byte *i)
18691
177
{
18692
177
    int ret = 0;
18693
177
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
18694
177
    Aes *aes = &xaes->aes;
18695
18696
177
#ifdef HAVE_AES_ECB
18697
    /* encrypt all of buffer at once when possible */
18698
177
    if (in != out) { /* can not handle inline */
18699
126
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
18700
126
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
18701
0
            return ret;
18702
126
    }
18703
177
#endif
18704
18705
655
    while (blocks > 0) {
18706
478
        word32 j;
18707
478
        byte carry = 0;
18708
18709
478
#ifdef HAVE_AES_ECB
18710
478
        if (in == out)
18711
155
#endif
18712
155
        { /* check for if inline */
18713
155
            byte buf[WC_AES_BLOCK_SIZE];
18714
18715
155
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
18716
155
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
18717
155
            ret = wc_AesEncryptDirect(aes, out, buf);
18718
155
            if (ret != 0)
18719
0
                return ret;
18720
155
        }
18721
478
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
18722
18723
        /* multiply by shift left and propagate carry */
18724
8.12k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
18725
7.64k
            byte tmpC;
18726
18727
7.64k
            tmpC   = (i[j] >> 7) & 0x01;
18728
7.64k
            i[j] = (byte)(((i[j] << 1) + carry) & 0xFF);
18729
7.64k
            carry  = tmpC;
18730
7.64k
        }
18731
478
        if (carry) {
18732
274
            i[0] ^= GF_XTS;
18733
274
        }
18734
18735
478
        in  += WC_AES_BLOCK_SIZE;
18736
478
        out += WC_AES_BLOCK_SIZE;
18737
478
        sz  -= WC_AES_BLOCK_SIZE;
18738
478
        blocks--;
18739
478
    }
18740
18741
    /* stealing operation of XTS to handle left overs */
18742
177
    if (sz > 0) {
18743
21
        byte buf[WC_AES_BLOCK_SIZE];
18744
18745
21
        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
18746
21
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
18747
0
            return BUFFER_E;
18748
0
        }
18749
21
        if (in != out) {
18750
10
            XMEMCPY(out, buf, sz);
18751
10
            XMEMCPY(buf, in, sz);
18752
10
        }
18753
11
        else {
18754
11
            byte buf2[WC_AES_BLOCK_SIZE];
18755
18756
11
            XMEMCPY(buf2, buf, sz);
18757
11
            XMEMCPY(buf, in, sz);
18758
11
            XMEMCPY(out, buf2, sz);
18759
11
        }
18760
18761
21
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
18762
21
        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
18763
21
        if (ret == 0)
18764
21
            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
18765
21
    }
18766
18767
177
    return ret;
18768
177
}
18769
#endif
18770
18771
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
18772
 *
18773
 * xaes  AES keys to use for block encrypt/decrypt
18774
 * out   output buffer to hold cipher text
18775
 * in    input plain text buffer to encrypt
18776
 * sz    size of both out and in buffers
18777
 * i     value to use for tweak
18778
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
18779
 *       adds a sanity check on how the user calls the function.
18780
 *
18781
 * returns 0 on success
18782
 */
18783
int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
18784
        const byte* i, word32 iSz)
18785
192
{
18786
192
    int ret;
18787
18788
192
    Aes *aes;
18789
18790
192
    if (xaes == NULL || out == NULL || in == NULL) {
18791
0
        return BAD_FUNC_ARG;
18792
0
    }
18793
18794
#if FIPS_VERSION3_GE(6,0,0)
18795
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
18796
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
18797
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
18798
     */
18799
    if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
18800
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
18801
        return BAD_FUNC_ARG;
18802
    }
18803
#endif
18804
18805
192
    aes = &xaes->aes;
18806
18807
    /* rounds == 0 means no software key schedule: XTS has no crypto
18808
     * callback dispatch, so a device-owned key is unusable here. */
18809
192
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
18810
0
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
18811
0
        return BAD_FUNC_ARG;
18812
0
    }
18813
18814
192
    if (iSz < WC_AES_BLOCK_SIZE) {
18815
0
        return BAD_FUNC_ARG;
18816
0
    }
18817
18818
192
    if (sz < WC_AES_BLOCK_SIZE) {
18819
15
        WOLFSSL_MSG("Plain text input too small for encryption");
18820
15
        return BAD_FUNC_ARG;
18821
15
    }
18822
18823
#if defined(WOLFSSL_RISCV_ASM)
18824
    AES_XTS_encrypt_RISCV64(in, out, sz, i, (byte*)xaes->aes.key,
18825
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, (int)xaes->aes.rounds);
18826
    ret = 0;
18827
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
18828
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
18829
    /* The base 32-bit AES assembly has no XTS variant, so the run-time
18830
     * fallback is the software XTS (which dispatches per-block via
18831
     * wc_AesEncrypt). */
18832
#ifdef WOLFSSL_ARM32_AES_DISPATCH
18833
    if (xaes->aes.use_aes_hw_crypto) {
18834
        AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
18835
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18836
        ret = 0;
18837
    }
18838
    else {
18839
        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
18840
    }
18841
#else
18842
    AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
18843
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18844
    ret = 0;
18845
#endif
18846
#elif defined(WOLFSSL_AESNI)
18847
    if (aes->use_aesni) {
18848
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
18849
#if defined(HAVE_INTEL_AVX512)
18850
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18851
            AES_XTS_encrypt_avx512(in, out, sz, i,
18852
                                   (const byte*)aes->key,
18853
                                   (const byte*)xaes->tweak.key,
18854
                                   (int)aes->rounds);
18855
            ret = 0;
18856
        }
18857
        else
18858
#endif
18859
#if defined(HAVE_INTEL_VAES)
18860
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18861
            AES_XTS_encrypt_vaes(in, out, sz, i,
18862
                                 (const byte*)aes->key,
18863
                                 (const byte*)xaes->tweak.key,
18864
                                 (int)aes->rounds);
18865
            ret = 0;
18866
        }
18867
        else
18868
#endif
18869
#if defined(WC_AES_XTS_HAVE_AVX1)
18870
        if (IS_INTEL_AVX1(intel_flags)) {
18871
            AES_XTS_encrypt_avx1(in, out, sz, i,
18872
                                 (const byte*)aes->key,
18873
                                 (const byte*)xaes->tweak.key,
18874
                                 (int)aes->rounds);
18875
            ret = 0;
18876
        }
18877
        else
18878
#endif
18879
        {
18880
            AES_XTS_encrypt_aesni(in, out, sz, i,
18881
                                  (const byte*)aes->key,
18882
                                  (const byte*)xaes->tweak.key,
18883
                                  (int)aes->rounds);
18884
            ret = 0;
18885
        }
18886
        RESTORE_VECTOR_REGISTERS();
18887
    }
18888
    else {
18889
        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
18890
    }
18891
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
18892
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
18893
    if (aes->use_aes_hw_crypto) {
18894
        AES_XTS_encrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
18895
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18896
        ret = 0;
18897
    }
18898
    else
18899
#endif
18900
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
18901
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18902
    if (sz >= 32)
18903
#endif
18904
    {
18905
        AES_XTS_encrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
18906
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18907
        ret = 0;
18908
    }
18909
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18910
    else
18911
#endif
18912
#endif
18913
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18914
    {
18915
        AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
18916
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18917
        ret = 0;
18918
    }
18919
#endif
18920
#elif defined(WOLFSSL_PPC64_ASM)
18921
    AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
18922
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18923
    ret = 0;
18924
#else
18925
177
    ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
18926
177
#endif
18927
18928
177
    return ret;
18929
192
}
18930
18931
#ifdef WOLFSSL_AESXTS_STREAM
18932
18933
/* Block-streaming AES-XTS.
18934
 *
18935
 * xaes  AES keys to use for block encrypt/decrypt
18936
 * i     readwrite value to use for tweak
18937
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
18938
 *       adds a sanity check on how the user calls the function.
18939
 *
18940
 * returns 0 on success
18941
 */
18942
int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
18943
                         struct XtsAesStreamData *stream)
18944
{
18945
    int ret;
18946
18947
    Aes *aes;
18948
18949
    if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
18950
        return BAD_FUNC_ARG;
18951
    }
18952
18953
    if (iSz < WC_AES_BLOCK_SIZE) {
18954
        return BAD_FUNC_ARG;
18955
    }
18956
18957
    aes = &xaes->aes;
18958
18959
    /* rounds == 0 means no software key schedule: XTS has no crypto
18960
     * callback dispatch, so a device-owned key is unusable here. */
18961
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
18962
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
18963
        return BAD_FUNC_ARG;
18964
    }
18965
18966
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
18967
    stream->bytes_crypted_with_this_tweak = 0;
18968
18969
    {
18970
#if defined(WOLFSSL_AESNI)
18971
        if (aes->use_aesni) {
18972
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
18973
#if defined(HAVE_INTEL_AVX512)
18974
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18975
                AES_XTS_init_avx512(stream->tweak_block,
18976
                                    (const byte*)xaes->tweak.key,
18977
                                    (int)xaes->tweak.rounds);
18978
                ret = 0;
18979
            }
18980
            else
18981
#endif
18982
#if defined(HAVE_INTEL_VAES)
18983
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18984
                AES_XTS_init_vaes(stream->tweak_block,
18985
                                  (const byte*)xaes->tweak.key,
18986
                                  (int)xaes->tweak.rounds);
18987
                ret = 0;
18988
            }
18989
            else
18990
#endif
18991
#if defined(WC_AES_XTS_HAVE_AVX1)
18992
            if (IS_INTEL_AVX1(intel_flags)) {
18993
                AES_XTS_init_avx1(stream->tweak_block,
18994
                                  (const byte*)xaes->tweak.key,
18995
                                  (int)xaes->tweak.rounds);
18996
                ret = 0;
18997
            }
18998
            else
18999
#endif
19000
            {
19001
                AES_XTS_init_aesni(stream->tweak_block,
19002
                                   (const byte*)xaes->tweak.key,
19003
                                   (int)xaes->tweak.rounds);
19004
                ret = 0;
19005
            }
19006
            RESTORE_VECTOR_REGISTERS();
19007
        }
19008
        else
19009
#endif /* WOLFSSL_AESNI */
19010
        {
19011
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
19012
        }
19013
    }
19014
19015
    return ret;
19016
}
19017
19018
/* Block-streaming AES-XTS
19019
 *
19020
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
19021
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsEncryptUpdate().
19022
 * wc_AesXtsEncryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
19023
 *
19024
 * xaes  AES keys to use for block encrypt/decrypt
19025
 * out   output buffer to hold cipher text
19026
 * in    input plain text buffer to encrypt
19027
 * sz    size of both out and in buffers -- must be >= WC_AES_BLOCK_SIZE.
19028
 * i     value to use for tweak
19029
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
19030
 *       adds a sanity check on how the user calls the function.
19031
 *
19032
 * returns 0 on success
19033
 */
19034
static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19035
                           struct XtsAesStreamData *stream)
19036
{
19037
    int ret;
19038
19039
#if defined(WOLFSSL_AESNI)
19040
    Aes *aes;
19041
#endif
19042
19043
    if (xaes == NULL || out == NULL || in == NULL) {
19044
        return BAD_FUNC_ARG;
19045
    }
19046
19047
#if defined(WOLFSSL_AESNI)
19048
    aes = &xaes->aes;
19049
#endif
19050
19051
    if (sz < WC_AES_BLOCK_SIZE) {
19052
        WOLFSSL_MSG("Plain text input too small for encryption");
19053
        return BAD_FUNC_ARG;
19054
    }
19055
19056
    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
19057
    {
19058
        WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
19059
        return BAD_FUNC_ARG;
19060
    }
19061
19062
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
19063
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
19064
                             stream->bytes_crypted_with_this_tweak))
19065
    {
19066
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
19067
                    "in AesXtsEncryptUpdate().");
19068
    }
19069
#endif
19070
#if FIPS_VERSION3_GE(6,0,0)
19071
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
19072
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
19073
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
19074
     */
19075
    if (stream->bytes_crypted_with_this_tweak >
19076
        FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
19077
    {
19078
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
19079
        return BAD_FUNC_ARG;
19080
    }
19081
#endif
19082
    {
19083
#if defined(WOLFSSL_AESNI)
19084
        if (aes->use_aesni) {
19085
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
19086
#if defined(HAVE_INTEL_AVX512)
19087
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19088
                AES_XTS_encrypt_update_avx512(in, out, sz,
19089
                                              (const byte*)aes->key,
19090
                                              stream->tweak_block,
19091
                                              (int)aes->rounds);
19092
                ret = 0;
19093
            }
19094
            else
19095
#endif
19096
#if defined(HAVE_INTEL_VAES)
19097
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19098
                AES_XTS_encrypt_update_vaes(in, out, sz,
19099
                                            (const byte*)aes->key,
19100
                                            stream->tweak_block,
19101
                                            (int)aes->rounds);
19102
                ret = 0;
19103
            }
19104
            else
19105
#endif
19106
#if defined(WC_AES_XTS_HAVE_AVX1)
19107
            if (IS_INTEL_AVX1(intel_flags)) {
19108
                AES_XTS_encrypt_update_avx1(in, out, sz,
19109
                                            (const byte*)aes->key,
19110
                                            stream->tweak_block,
19111
                                            (int)aes->rounds);
19112
                ret = 0;
19113
            }
19114
            else
19115
#endif
19116
            {
19117
                AES_XTS_encrypt_update_aesni(in, out, sz,
19118
                                            (const byte*)aes->key,
19119
                                            stream->tweak_block,
19120
                                            (int)aes->rounds);
19121
                ret = 0;
19122
            }
19123
            RESTORE_VECTOR_REGISTERS();
19124
        }
19125
        else
19126
#endif /* WOLFSSL_AESNI */
19127
        {
19128
            ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
19129
        }
19130
    }
19131
19132
    return ret;
19133
}
19134
19135
int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19136
                           struct XtsAesStreamData *stream)
19137
{
19138
    if (stream == NULL)
19139
        return BAD_FUNC_ARG;
19140
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
19141
        return BAD_FUNC_ARG;
19142
    return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
19143
}
19144
19145
int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19146
                           struct XtsAesStreamData *stream)
19147
{
19148
    int ret;
19149
    if (stream == NULL)
19150
        return BAD_FUNC_ARG;
19151
    if (sz > 0)
19152
        ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
19153
    else
19154
        ret = 0;
19155
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
19156
     * after finalization.
19157
     */
19158
    stream->bytes_crypted_with_this_tweak |= 1U;
19159
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
19160
#ifdef WOLFSSL_CHECK_MEM_ZERO
19161
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
19162
#endif
19163
    return ret;
19164
}
19165
19166
#endif /* WOLFSSL_AESXTS_STREAM */
19167
19168
#ifdef HAVE_AES_DECRYPT
19169
19170
/* Same process as encryption but use aes_decrypt key.
19171
 *
19172
 * xaes  AES keys to use for block encrypt/decrypt
19173
 * out   output buffer to hold plain text
19174
 * in    input cipher text buffer to decrypt
19175
 * sz    size of both out and in buffers
19176
 * i     value to use for tweak
19177
 *
19178
 * returns 0 on success
19179
 */
19180
/* Software AES - XTS Decrypt */
19181
19182
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
19183
     defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
19184
     defined(WOLFSSL_ARM32_AES_DISPATCH)) && !defined(WOLFSSL_PPC64_ASM)
19185
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
19186
                                  word32 sz, byte *i);
19187
19188
#if !defined(WOLFSSL_RISCV_ASM)
19189
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19190
        const byte* i)
19191
256
{
19192
256
    int ret;
19193
256
    byte tweak_block[WC_AES_BLOCK_SIZE];
19194
19195
256
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
19196
256
    if (ret != 0)
19197
0
        return ret;
19198
19199
256
    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
19200
256
}
19201
#endif /* !WOLFSSL_RISCV_ASM */
19202
#endif
19203
19204
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
19205
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
19206
    defined(WOLFSSL_ARM32_AES_DISPATCH)) || defined(WOLFSSL_AESXTS_STREAM)
19207
/* Block-streaming AES-XTS.
19208
 *
19209
 * Same process as encryption but use decrypt key.
19210
 *
19211
 * Supply block-aligned input data with successive calls.  Final call need not
19212
 * be block aligned.
19213
 *
19214
 * xaes  AES keys to use for block encrypt/decrypt
19215
 * out   output buffer to hold plain text
19216
 * in    input cipher text buffer to decrypt
19217
 * sz    size of both out and in buffers
19218
 * i     value to use for tweak
19219
 *
19220
 * returns 0 on success
19221
 */
19222
/* Software AES - XTS Decrypt */
19223
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
19224
                                  word32 sz, byte *i)
19225
256
{
19226
256
    int ret = 0;
19227
256
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
19228
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
19229
    Aes *aes = &xaes->aes_decrypt;
19230
#else
19231
256
    Aes *aes = &xaes->aes;
19232
256
#endif
19233
256
    word32 j;
19234
256
    byte carry = 0;
19235
256
    byte stl = (sz % WC_AES_BLOCK_SIZE);
19236
19237
    /* if Stealing then break out of loop one block early to handle special
19238
     * case */
19239
256
    if (stl > 0) {
19240
100
        blocks--;
19241
100
    }
19242
19243
256
#ifdef HAVE_AES_ECB
19244
    /* decrypt all of buffer at once when possible */
19245
256
    if (in != out) { /* can not handle inline */
19246
256
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
19247
256
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
19248
0
            return ret;
19249
256
    }
19250
256
#endif
19251
19252
713
    while (blocks > 0) {
19253
457
#ifdef HAVE_AES_ECB
19254
457
        if (in == out)
19255
0
#endif
19256
0
        { /* check for if inline */
19257
0
            byte buf[WC_AES_BLOCK_SIZE];
19258
19259
0
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
19260
0
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
19261
0
            ret = wc_AesDecryptDirect(aes, out, buf);
19262
0
            if (ret != 0)
19263
0
                return ret;
19264
0
        }
19265
457
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
19266
19267
        /* multiply by shift left and propagate carry */
19268
7.76k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
19269
7.31k
            byte tmpC;
19270
19271
7.31k
            tmpC   = (i[j] >> 7) & 0x01;
19272
7.31k
            i[j] = (byte)(((i[j] << 1) + carry) & 0xFF);
19273
7.31k
            carry  = tmpC;
19274
7.31k
        }
19275
457
        if (carry) {
19276
259
            i[0] ^= GF_XTS;
19277
259
        }
19278
457
        carry = 0;
19279
19280
457
        in  += WC_AES_BLOCK_SIZE;
19281
457
        out += WC_AES_BLOCK_SIZE;
19282
457
        sz  -= WC_AES_BLOCK_SIZE;
19283
457
        blocks--;
19284
457
    }
19285
19286
    /* stealing operation of XTS to handle left overs */
19287
256
    if (sz >= WC_AES_BLOCK_SIZE) {
19288
100
        byte buf[WC_AES_BLOCK_SIZE];
19289
100
        byte tmp2[WC_AES_BLOCK_SIZE];
19290
19291
        /* multiply by shift left and propagate carry */
19292
1.70k
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
19293
1.60k
            byte tmpC;
19294
19295
1.60k
            tmpC   = (i[j] >> 7) & 0x01;
19296
1.60k
            tmp2[j] = (byte)((i[j] << 1) + carry);
19297
1.60k
            carry  = tmpC;
19298
1.60k
        }
19299
100
        if (carry) {
19300
51
            tmp2[0] ^= GF_XTS;
19301
51
        }
19302
19303
100
        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
19304
100
        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
19305
100
        ret = wc_AesDecryptDirect(aes, out, buf);
19306
100
        if (ret != 0)
19307
0
            return ret;
19308
100
        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
19309
19310
        /* tmp2 holds partial | last */
19311
100
        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
19312
100
        in  += WC_AES_BLOCK_SIZE;
19313
100
        out += WC_AES_BLOCK_SIZE;
19314
100
        sz  -= WC_AES_BLOCK_SIZE;
19315
19316
        /* Make buffer with end of cipher text | last */
19317
100
        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
19318
100
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
19319
0
            return BUFFER_E;
19320
0
        }
19321
100
        XMEMCPY(buf, in,   sz);
19322
100
        XMEMCPY(out, tmp2, sz);
19323
19324
100
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
19325
100
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
19326
100
        if (ret != 0)
19327
0
            return ret;
19328
100
        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
19329
100
        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
19330
100
    }
19331
19332
256
    return ret;
19333
256
}
19334
#endif
19335
19336
/* Same process as encryption but Aes key is AES_DECRYPTION type.
19337
 *
19338
 * xaes  AES keys to use for block encrypt/decrypt
19339
 * out   output buffer to hold plain text
19340
 * in    input cipher text buffer to decrypt
19341
 * sz    size of both out and in buffers
19342
 * i     value to use for tweak
19343
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
19344
 *       adds a sanity check on how the user calls the function.
19345
 *
19346
 * returns 0 on success
19347
 */
19348
int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19349
        const byte* i, word32 iSz)
19350
258
{
19351
258
    int ret;
19352
258
    Aes *aes;
19353
19354
258
    if (xaes == NULL || out == NULL || in == NULL) {
19355
0
        return BAD_FUNC_ARG;
19356
0
    }
19357
19358
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
19359
    aes = &xaes->aes_decrypt;
19360
#else
19361
258
    aes = &xaes->aes;
19362
258
#endif
19363
19364
/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
19365
 * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
19366
 * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes or
19367
 * 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
19368
 * return whenever sz / WC_AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
19369
 * not a sequence of complete blocks.
19370
 */
19371
19372
    /* rounds == 0 means no software key schedule: XTS has no crypto
19373
     * callback dispatch, so a device-owned key is unusable here. */
19374
258
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
19375
0
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
19376
0
        return BAD_FUNC_ARG;
19377
0
    }
19378
19379
258
    if (iSz < WC_AES_BLOCK_SIZE) {
19380
0
        return BAD_FUNC_ARG;
19381
0
    }
19382
19383
258
    if (sz < WC_AES_BLOCK_SIZE) {
19384
2
        WOLFSSL_MSG("Cipher text input too small for decryption");
19385
2
        return BAD_FUNC_ARG;
19386
2
    }
19387
19388
#if defined(WOLFSSL_RISCV_ASM)
19389
    /* Use the selected decrypt schedule (aes), not xaes->aes - under
19390
     * WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS xaes->aes holds the
19391
     * ENCRYPT schedule; matches the AESNI branch below. */
19392
    AES_XTS_decrypt_RISCV64(in, out, sz, i, (byte*)aes->key,
19393
        (byte*)xaes->tweak.key, (byte*)aes->tmp, (int)aes->rounds);
19394
    ret = 0;
19395
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
19396
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
19397
    /* The base 32-bit AES assembly has no XTS variant, so the run-time
19398
     * fallback is the software XTS (which dispatches per-block via
19399
     * wc_AesDecrypt). */
19400
#ifdef WOLFSSL_ARM32_AES_DISPATCH
19401
    if (aes->use_aes_hw_crypto) {
19402
        AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)aes->key,
19403
            (byte*)xaes->tweak.key, (byte*)aes->tmp, aes->rounds);
19404
        ret = 0;
19405
    }
19406
    else {
19407
        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
19408
    }
19409
#else
19410
    AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)aes->key,
19411
        (byte*)xaes->tweak.key, (byte*)aes->tmp, aes->rounds);
19412
    ret = 0;
19413
#endif
19414
#elif defined(WOLFSSL_AESNI)
19415
    if (aes->use_aesni) {
19416
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
19417
#if defined(HAVE_INTEL_AVX512)
19418
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19419
            AES_XTS_decrypt_avx512(in, out, sz, i,
19420
                                   (const byte*)aes->key,
19421
                                   (const byte*)xaes->tweak.key,
19422
                                   (int)aes->rounds);
19423
            ret = 0;
19424
        }
19425
        else
19426
#endif
19427
#if defined(HAVE_INTEL_VAES)
19428
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19429
            AES_XTS_decrypt_vaes(in, out, sz, i,
19430
                                 (const byte*)aes->key,
19431
                                 (const byte*)xaes->tweak.key,
19432
                                 (int)aes->rounds);
19433
            ret = 0;
19434
        }
19435
        else
19436
#endif
19437
#if defined(WC_AES_XTS_HAVE_AVX1)
19438
        if (IS_INTEL_AVX1(intel_flags)) {
19439
            AES_XTS_decrypt_avx1(in, out, sz, i,
19440
                                 (const byte*)aes->key,
19441
                                 (const byte*)xaes->tweak.key,
19442
                                 (int)aes->rounds);
19443
            ret = 0;
19444
        }
19445
        else
19446
#endif
19447
        {
19448
            AES_XTS_decrypt_aesni(in, out, sz, i,
19449
                                  (const byte*)aes->key,
19450
                                  (const byte*)xaes->tweak.key,
19451
                                  (int)aes->rounds);
19452
            ret = 0;
19453
        }
19454
        RESTORE_VECTOR_REGISTERS();
19455
    }
19456
    else {
19457
        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
19458
    }
19459
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
19460
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
19461
    if (aes->use_aes_hw_crypto) {
19462
        AES_XTS_decrypt_AARCH64(in, out, sz, i, (byte*)aes->key,
19463
            (byte*)xaes->tweak.key, (byte*)aes->tmp, aes->rounds);
19464
        ret = 0;
19465
    }
19466
    else
19467
#endif
19468
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
19469
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
19470
    if (sz >= 64)
19471
#endif
19472
    {
19473
        AES_XTS_decrypt_NEON(in, out, sz, i, (byte*)aes->key,
19474
            (byte*)xaes->tweak.key, (byte*)aes->tmp, aes->rounds);
19475
        ret = 0;
19476
    }
19477
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
19478
    else
19479
#endif
19480
#endif
19481
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
19482
    {
19483
        AES_XTS_decrypt(in, out, sz, i, (byte*)aes->key,
19484
            (byte*)xaes->tweak.key, (byte*)aes->tmp, aes->rounds);
19485
        ret = 0;
19486
    }
19487
#endif
19488
#elif defined(WOLFSSL_PPC64_ASM)
19489
    AES_XTS_decrypt(in, out, sz, i, (byte*)aes->key,
19490
        (byte*)xaes->tweak.key, (byte*)aes->tmp, aes->rounds);
19491
    ret = 0;
19492
#else
19493
256
    ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
19494
256
#endif
19495
19496
256
    return ret;
19497
258
}
19498
19499
#ifdef WOLFSSL_AESXTS_STREAM
19500
19501
/* Same process as encryption but Aes key is AES_DECRYPTION type.
19502
 *
19503
 * xaes  AES keys to use for block encrypt/decrypt
19504
 * i     readwrite value to use for tweak
19505
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
19506
 *       adds a sanity check on how the user calls the function.
19507
 *
19508
 * returns 0 on success
19509
 */
19510
int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
19511
                         struct XtsAesStreamData *stream)
19512
{
19513
    int ret;
19514
    Aes *aes;
19515
19516
    if (xaes == NULL) {
19517
        return BAD_FUNC_ARG;
19518
    }
19519
19520
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
19521
    aes = &xaes->aes_decrypt;
19522
#else
19523
    aes = &xaes->aes;
19524
#endif
19525
19526
    /* rounds == 0 means no software key schedule: XTS has no crypto
19527
     * callback dispatch, so a device-owned key is unusable here. */
19528
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
19529
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
19530
        return BAD_FUNC_ARG;
19531
    }
19532
19533
    if (iSz < WC_AES_BLOCK_SIZE) {
19534
        return BAD_FUNC_ARG;
19535
    }
19536
19537
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
19538
    stream->bytes_crypted_with_this_tweak = 0;
19539
19540
    {
19541
#if defined(WOLFSSL_AESNI)
19542
        if (aes->use_aesni) {
19543
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
19544
#if defined(HAVE_INTEL_AVX512)
19545
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19546
                AES_XTS_init_avx512(stream->tweak_block,
19547
                                    (const byte*)xaes->tweak.key,
19548
                                    (int)xaes->tweak.rounds);
19549
                ret = 0;
19550
            }
19551
            else
19552
#endif
19553
#if defined(HAVE_INTEL_VAES)
19554
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19555
                AES_XTS_init_vaes(stream->tweak_block,
19556
                                  (const byte*)xaes->tweak.key,
19557
                                  (int)xaes->tweak.rounds);
19558
                ret = 0;
19559
            }
19560
            else
19561
#endif
19562
#if defined(WC_AES_XTS_HAVE_AVX1)
19563
            if (IS_INTEL_AVX1(intel_flags)) {
19564
                AES_XTS_init_avx1(stream->tweak_block,
19565
                                  (const byte*)xaes->tweak.key,
19566
                                  (int)xaes->tweak.rounds);
19567
                ret = 0;
19568
            }
19569
            else
19570
#endif
19571
            {
19572
                AES_XTS_init_aesni(stream->tweak_block,
19573
                                   (const byte*)xaes->tweak.key,
19574
                                   (int)xaes->tweak.rounds);
19575
                ret = 0;
19576
            }
19577
            RESTORE_VECTOR_REGISTERS();
19578
        }
19579
        else
19580
#endif /* WOLFSSL_AESNI */
19581
        {
19582
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
19583
        }
19584
19585
    }
19586
19587
    return ret;
19588
}
19589
19590
/* Block-streaming AES-XTS
19591
 *
19592
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
19593
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsDecryptUpdate().
19594
 * wc_AesXtsDecryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
19595
 *
19596
 * xaes  AES keys to use for block encrypt/decrypt
19597
 * out   output buffer to hold plain text
19598
 * in    input cipher text buffer to decrypt
19599
 * sz    size of both out and in buffers
19600
 * i     tweak buffer of size WC_AES_BLOCK_SIZE.
19601
 *
19602
 * returns 0 on success
19603
 */
19604
static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19605
                           struct XtsAesStreamData *stream)
19606
{
19607
    int ret;
19608
#if defined(WOLFSSL_AESNI)
19609
    Aes *aes;
19610
#endif
19611
19612
    if (xaes == NULL || out == NULL || in == NULL) {
19613
        return BAD_FUNC_ARG;
19614
    }
19615
19616
#if defined(WOLFSSL_AESNI)
19617
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
19618
    aes = &xaes->aes_decrypt;
19619
#else
19620
    aes = &xaes->aes;
19621
#endif
19622
#endif
19623
19624
    if (sz < WC_AES_BLOCK_SIZE) {
19625
        WOLFSSL_MSG("Cipher text input too small for decryption");
19626
        return BAD_FUNC_ARG;
19627
    }
19628
19629
    if (stream->bytes_crypted_with_this_tweak &
19630
        ((word32)WC_AES_BLOCK_SIZE - 1U))
19631
    {
19632
        WOLFSSL_MSG("AesXtsDecryptUpdate after previous finalizing call");
19633
        return BAD_FUNC_ARG;
19634
    }
19635
19636
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
19637
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
19638
                             stream->bytes_crypted_with_this_tweak))
19639
    {
19640
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
19641
                    "in AesXtsDecryptUpdate().");
19642
    }
19643
#endif
19644
19645
    {
19646
#if defined(WOLFSSL_AESNI)
19647
        if (aes->use_aesni) {
19648
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
19649
#if defined(HAVE_INTEL_AVX512)
19650
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19651
                AES_XTS_decrypt_update_avx512(in, out, sz,
19652
                                              (const byte*)aes->key,
19653
                                              stream->tweak_block,
19654
                                              (int)aes->rounds);
19655
                ret = 0;
19656
            }
19657
            else
19658
#endif
19659
#if defined(HAVE_INTEL_VAES)
19660
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19661
                AES_XTS_decrypt_update_vaes(in, out, sz,
19662
                                            (const byte*)aes->key,
19663
                                            stream->tweak_block,
19664
                                            (int)aes->rounds);
19665
                ret = 0;
19666
            }
19667
            else
19668
#endif
19669
#if defined(WC_AES_XTS_HAVE_AVX1)
19670
            if (IS_INTEL_AVX1(intel_flags)) {
19671
                AES_XTS_decrypt_update_avx1(in, out, sz,
19672
                                            (const byte*)aes->key,
19673
                                            stream->tweak_block,
19674
                                            (int)aes->rounds);
19675
                ret = 0;
19676
            }
19677
            else
19678
#endif
19679
            {
19680
                AES_XTS_decrypt_update_aesni(in, out, sz,
19681
                                             (const byte*)aes->key,
19682
                                             stream->tweak_block,
19683
                                             (int)aes->rounds);
19684
                ret = 0;
19685
            }
19686
            RESTORE_VECTOR_REGISTERS();
19687
        }
19688
        else
19689
#endif /* WOLFSSL_AESNI */
19690
        {
19691
            ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
19692
                                         stream->tweak_block);
19693
        }
19694
    }
19695
19696
    return ret;
19697
}
19698
19699
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19700
                           struct XtsAesStreamData *stream)
19701
{
19702
    if (stream == NULL)
19703
        return BAD_FUNC_ARG;
19704
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
19705
        return BAD_FUNC_ARG;
19706
    return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
19707
}
19708
19709
int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19710
                           struct XtsAesStreamData *stream)
19711
{
19712
    int ret;
19713
    if (stream == NULL)
19714
        return BAD_FUNC_ARG;
19715
    if (sz > 0)
19716
        ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
19717
    else
19718
        ret = 0;
19719
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
19720
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
19721
     * after finalization.
19722
     */
19723
    stream->bytes_crypted_with_this_tweak |= 1U;
19724
#ifdef WOLFSSL_CHECK_MEM_ZERO
19725
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
19726
#endif
19727
    return ret;
19728
}
19729
19730
#endif /* WOLFSSL_AESXTS_STREAM */
19731
#endif /* HAVE_AES_DECRYPT */
19732
19733
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
19734
 * sectorSz bytes
19735
 *
19736
 * xaes     AES keys to use for block encrypt
19737
 * out      output buffer to hold cipher text
19738
 * in       input plain text buffer to encrypt
19739
 * sz       size of both out and in buffers
19740
 * sector   value to use for tweak
19741
 * sectorSz size of the sector
19742
 *
19743
 * returns 0 on success
19744
 */
19745
int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
19746
        word32 sz, word64 sector, word32 sectorSz)
19747
0
{
19748
0
    int ret  = 0;
19749
0
    word32 iter = 0;
19750
0
    word32 sectorCount;
19751
0
    word32 remainder;
19752
19753
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
19754
0
        return BAD_FUNC_ARG;
19755
0
    }
19756
19757
0
    if (sz < WC_AES_BLOCK_SIZE) {
19758
0
        WOLFSSL_MSG("Cipher text input too small for encryption");
19759
0
        return BAD_FUNC_ARG;
19760
0
    }
19761
19762
0
    sectorCount  = sz / sectorSz;
19763
0
    remainder = sz % sectorSz;
19764
19765
0
    while (sectorCount) {
19766
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
19767
0
                in + (iter * sectorSz), sectorSz, sector);
19768
0
        if (ret != 0)
19769
0
            break;
19770
19771
0
        sectorCount--;
19772
0
        iter++;
19773
0
        sector++;
19774
0
    }
19775
19776
0
    if (remainder && ret == 0)
19777
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
19778
0
                in + (iter * sectorSz), remainder, sector);
19779
19780
0
    return ret;
19781
0
}
19782
19783
#ifdef HAVE_AES_DECRYPT
19784
19785
/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
19786
 *
19787
 * xaes     AES keys to use for block decrypt
19788
 * out      output buffer to hold cipher text
19789
 * in       input plain text buffer to encrypt
19790
 * sz       size of both out and in buffers
19791
 * sector   value to use for tweak
19792
 * sectorSz size of the sector
19793
 *
19794
 * returns 0 on success
19795
 */
19796
int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
19797
        word32 sz, word64 sector, word32 sectorSz)
19798
0
{
19799
0
    int ret  = 0;
19800
0
    word32 iter = 0;
19801
0
    word32 sectorCount;
19802
0
    word32 remainder;
19803
19804
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
19805
0
        return BAD_FUNC_ARG;
19806
0
    }
19807
19808
0
    if (sz < WC_AES_BLOCK_SIZE) {
19809
0
        WOLFSSL_MSG("Cipher text input too small for decryption");
19810
0
        return BAD_FUNC_ARG;
19811
0
    }
19812
19813
0
    sectorCount  = sz / sectorSz;
19814
0
    remainder = sz % sectorSz;
19815
19816
0
    while (sectorCount) {
19817
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
19818
0
                in + (iter * sectorSz), sectorSz, sector);
19819
0
        if (ret != 0)
19820
0
            break;
19821
19822
0
        sectorCount--;
19823
0
        iter++;
19824
0
        sector++;
19825
0
    }
19826
19827
0
    if (remainder && ret == 0)
19828
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
19829
0
                in + (iter * sectorSz), remainder, sector);
19830
19831
0
    return ret;
19832
0
}
19833
#endif /* HAVE_AES_DECRYPT */
19834
#endif /* WOLFSSL_AES_XTS */
19835
19836
#ifdef WOLFSSL_CMAC
19837
19838
1.65k
int wc_local_CmacUpdateAes(struct Cmac *cmac, const byte* in, word32 inSz) {
19839
1.65k
    int ret = 0;
19840
1.65k
    Aes *aes = &cmac->aes;
19841
1.65k
#ifdef WC_AES_HAVE_PREFETCH_ARG
19842
1.65k
    int did_prefetches = 0;
19843
1.65k
#endif
19844
19845
1.65k
    VECTOR_REGISTERS_PUSH;
19846
19847
8.27k
    while ((ret == 0) && (inSz != 0)) {
19848
6.61k
        word32 add = min(inSz, WC_AES_BLOCK_SIZE - cmac->bufferSz);
19849
6.61k
        XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
19850
19851
6.61k
        cmac->bufferSz += add;
19852
6.61k
        inSz -= add;
19853
6.61k
        in += add;
19854
19855
6.61k
        if (cmac->bufferSz == WC_AES_BLOCK_SIZE && inSz != 0) {
19856
6.27k
            xorbuf(cmac->buffer, cmac->digest, WC_AES_BLOCK_SIZE);
19857
6.27k
            ret = AesEncrypt_preFetchOpt(aes, cmac->buffer,
19858
6.27k
                                            cmac->digest, &did_prefetches);
19859
6.27k
            if (ret == 0) {
19860
6.27k
                cmac->totalSz += WC_AES_BLOCK_SIZE;
19861
6.27k
                cmac->bufferSz = 0;
19862
6.27k
            }
19863
6.27k
        }
19864
6.61k
    }
19865
19866
1.65k
    VECTOR_REGISTERS_POP;
19867
19868
1.65k
    return ret;
19869
1.65k
}
19870
19871
#endif /* WOLFSSL_CMAC */
19872
19873
#ifdef WOLFSSL_AES_SIV
19874
19875
/*
19876
 * See RFC 5297 Section 2.4.
19877
 */
19878
static WARN_UNUSED_RESULT int S2V(
19879
    const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc,
19880
    const byte* nonce, word32 nonceSz, const byte* data,
19881
    word32 dataSz, byte* out)
19882
0
{
19883
0
#ifdef WOLFSSL_SMALL_STACK
19884
0
    byte* tmp[3] = {NULL, NULL, NULL};
19885
0
    int i;
19886
0
    Cmac* cmac;
19887
#else
19888
    byte tmp[3][WC_AES_BLOCK_SIZE];
19889
    Cmac cmac[1];
19890
#endif
19891
0
    word32 macSz = WC_AES_BLOCK_SIZE;
19892
0
    int ret = 0;
19893
0
    byte tmpi = 0;
19894
0
    word32 ai;
19895
0
    word32 zeroBytes;
19896
19897
0
#ifdef WOLFSSL_SMALL_STACK
19898
0
    for (i = 0; i < 3; ++i) {
19899
0
        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19900
0
        if (tmp[i] == NULL) {
19901
0
            ret = MEMORY_E;
19902
0
            break;
19903
0
        }
19904
0
    }
19905
0
    if (ret == 0)
19906
0
#endif
19907
19908
0
    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
19909
        /* See RFC 5297 Section 7. */
19910
0
        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
19911
0
                    " 126.");
19912
0
        ret = BAD_FUNC_ARG;
19913
0
    }
19914
19915
0
    if (ret == 0) {
19916
0
        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
19917
0
        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
19918
19919
0
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
19920
0
                                 key, keySz);
19921
0
    }
19922
19923
0
    if (ret == 0) {
19924
        /* Loop over authenticated associated data AD1..ADn */
19925
0
        for (ai = 0; ai < numAssoc; ++ai) {
19926
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
19927
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
19928
0
                                     assoc[ai].assocSz, key, keySz);
19929
0
            if (ret != 0)
19930
0
                break;
19931
0
            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
19932
0
            tmpi = (byte)(1 - tmpi);
19933
0
        }
19934
19935
        /* Add nonce as final AD. See RFC 5297 Section 3. */
19936
0
        if ((ret == 0) && (nonceSz > 0)) {
19937
0
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
19938
0
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
19939
0
                                     nonceSz, key, keySz);
19940
0
            if (ret == 0) {
19941
0
                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
19942
0
            }
19943
0
            tmpi = (byte)(1U - tmpi);
19944
0
        }
19945
19946
        /* For simplicity of the remaining code, make sure the "final" result
19947
           is always in tmp[0]. */
19948
0
        if (tmpi == 1) {
19949
0
            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
19950
0
        }
19951
0
    }
19952
19953
0
    if (ret == 0) {
19954
0
        if (dataSz >= WC_AES_BLOCK_SIZE) {
19955
19956
0
            WC_ALLOC_VAR_EX(cmac, Cmac, 1, NULL, DYNAMIC_TYPE_CMAC,
19957
0
                ret=MEMORY_E);
19958
0
            if (WC_VAR_OK(cmac))
19959
0
            {
19960
            #ifdef WOLFSSL_CHECK_MEM_ZERO
19961
                /* Aes part is checked by wc_AesFree. */
19962
                wc_MemZero_Add("wc_AesCmacGenerate cmac",
19963
                    ((unsigned char *)cmac) + sizeof(Aes),
19964
                    sizeof(Cmac) - sizeof(Aes));
19965
            #endif
19966
0
                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
19967
0
                       WC_AES_BLOCK_SIZE);
19968
0
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
19969
0
                if (ret == 0) {
19970
0
                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
19971
0
                }
19972
0
                if (ret == 0) {
19973
0
                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
19974
0
                }
19975
0
                if (ret == 0) {
19976
0
                    ret = wc_CmacFinal(cmac, out, &macSz);
19977
0
                }
19978
0
            }
19979
0
        #ifdef WOLFSSL_SMALL_STACK
19980
0
            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
19981
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
19982
            wc_MemZero_Check(cmac, sizeof(Cmac));
19983
        #endif
19984
0
        }
19985
0
        else {
19986
0
            XMEMCPY(tmp[2], data, dataSz);
19987
0
            tmp[2][dataSz] |= 0x80;
19988
0
            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
19989
0
            if (zeroBytes != 0) {
19990
0
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
19991
0
            }
19992
0
            ShiftAndXorRb(tmp[1], tmp[0]);
19993
0
            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
19994
0
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
19995
0
                                     keySz);
19996
0
        }
19997
0
    }
19998
19999
0
#ifdef WOLFSSL_SMALL_STACK
20000
0
    for (i = 0; i < 3; ++i) {
20001
0
        if (tmp[i] != NULL) {
20002
0
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
20003
0
        }
20004
0
    }
20005
0
#endif
20006
20007
0
    return ret;
20008
0
}
20009
20010
static WARN_UNUSED_RESULT int AesSivCipher(
20011
    const byte* key, word32 keySz, const AesSivAssoc* assoc,
20012
    word32 numAssoc, const byte* nonce, word32 nonceSz,
20013
    const byte* data, word32 dataSz, byte* siv, byte* out,
20014
    int enc)
20015
0
{
20016
0
    int ret = 0;
20017
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
20018
0
    byte sivTmp[WC_AES_BLOCK_SIZE];
20019
20020
#ifdef WOLFSSL_CHECK_MEM_ZERO
20021
    /* Poison before the (conditional) fill so error paths that never write
20022
     * sivTmp still leave it defined; the used paths overwrite it. Register
20023
     * here (the highest point from which every exit funnels to the single
20024
     * ForceZero+Check below). */
20025
    XMEMSET(sivTmp, 0xff, sizeof(sivTmp));
20026
    wc_MemZero_Add("AesSivCipher sivTmp", sivTmp, sizeof(sivTmp));
20027
#endif
20028
20029
0
    if (key == NULL || siv == NULL || out == NULL) {
20030
0
        WOLFSSL_MSG("Bad parameter");
20031
0
        ret = BAD_FUNC_ARG;
20032
0
    }
20033
20034
0
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
20035
0
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
20036
0
        ret = BAD_FUNC_ARG;
20037
0
    }
20038
20039
0
    if (ret == 0) {
20040
0
        if (enc == 1) {
20041
0
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
20042
0
                      dataSz, sivTmp);
20043
0
            if (ret != 0) {
20044
0
                WOLFSSL_MSG("S2V failed.");
20045
0
            }
20046
0
            else {
20047
0
                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
20048
0
            }
20049
0
        }
20050
0
        else {
20051
0
            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
20052
0
        }
20053
0
    }
20054
20055
0
    if (ret == 0) {
20056
0
#ifdef WOLFSSL_SMALL_STACK
20057
0
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
20058
#else
20059
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
20060
#endif
20061
0
        if (ret != 0) {
20062
0
            WOLFSSL_MSG("Failed to initialized AES object.");
20063
0
        }
20064
0
    }
20065
20066
0
    if (ret == 0) {
20067
0
        if (dataSz > 0) {
20068
0
            sivTmp[12] &= 0x7f;
20069
0
            sivTmp[8] &= 0x7f;
20070
0
            ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
20071
0
                               AES_ENCRYPTION);
20072
0
            if (ret != 0) {
20073
0
                WOLFSSL_MSG("Failed to set key for AES-CTR.");
20074
0
            }
20075
0
            else {
20076
0
                ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
20077
0
                if (ret != 0) {
20078
0
                    WOLFSSL_MSG("AES-CTR encryption failed.");
20079
0
                }
20080
0
            }
20081
0
        }
20082
20083
0
        if (ret == 0 && enc == 0) {
20084
0
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out,
20085
0
                      dataSz, sivTmp);
20086
0
            if (ret != 0) {
20087
0
                WOLFSSL_MSG("S2V failed.");
20088
0
            }
20089
20090
0
            if (ret == 0 && ConstantCompare(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
20091
0
                WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
20092
0
                ret = AES_SIV_AUTH_E;
20093
0
            }
20094
0
        }
20095
20096
0
        if (ret != 0) {
20097
0
            ForceZero(out, dataSz);
20098
0
        }
20099
20100
0
    #ifdef WOLFSSL_SMALL_STACK
20101
0
        wc_AesDelete(aes, NULL);
20102
    #else
20103
        wc_AesFree(aes);
20104
    #endif
20105
0
    }
20106
20107
0
    ForceZero(sivTmp, sizeof(sivTmp));
20108
#ifdef WOLFSSL_CHECK_MEM_ZERO
20109
    wc_MemZero_Check(sivTmp, sizeof(sivTmp));
20110
#endif
20111
20112
0
    return ret;
20113
0
}
20114
20115
/*
20116
 * See RFC 5297 Section 2.6.
20117
 */
20118
int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
20119
                     word32 assocSz, const byte* nonce, word32 nonceSz,
20120
                     const byte* in, word32 inSz, byte* siv, byte* out)
20121
0
{
20122
0
    AesSivAssoc ad;
20123
0
    ad.assoc = assoc;
20124
0
    ad.assocSz = assocSz;
20125
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
20126
0
                        siv, out, 1);
20127
0
}
20128
20129
/*
20130
 * See RFC 5297 Section 2.7.
20131
 */
20132
int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
20133
                     word32 assocSz, const byte* nonce, word32 nonceSz,
20134
                     const byte* in, word32 inSz, byte* siv, byte* out)
20135
0
{
20136
0
    AesSivAssoc ad;
20137
0
    ad.assoc = assoc;
20138
0
    ad.assocSz = assocSz;
20139
0
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
20140
0
                        siv, out, 0);
20141
0
}
20142
20143
/*
20144
 * See RFC 5297 Section 2.6.
20145
 */
20146
int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
20147
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
20148
                        const byte* in, word32 inSz, byte* siv, byte* out)
20149
0
{
20150
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
20151
0
                        siv, out, 1);
20152
0
}
20153
20154
/*
20155
 * See RFC 5297 Section 2.7.
20156
 */
20157
int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
20158
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
20159
                        const byte* in, word32 inSz, byte* siv, byte* out)
20160
0
{
20161
0
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
20162
0
                        siv, out, 0);
20163
0
}
20164
20165
#endif /* WOLFSSL_AES_SIV */
20166
20167
#ifdef WOLFSSL_AESGCM_SIV
20168
20169
/* AES-GCM-SIV - a nonce misuse-resistant AEAD. See RFC 8452.
20170
 *
20171
 * The implementation here is portable C.  AES block operations reuse the
20172
 * internal wc_AesEncrypt(), so HAVE_AESGCM is required for that to be built.
20173
 */
20174
#ifndef HAVE_AESGCM
20175
    #error "WOLFSSL_AESGCM_SIV requires HAVE_AESGCM"
20176
#endif
20177
20178
#define AES_GCM_SIV_NONCE_SZ  12
20179
#define AES_GCM_SIV_TAG_SZ    WC_AES_BLOCK_SIZE
20180
20181
#ifndef GCM_SMALL
20182
/* GF(2^128) reduction table used by the table-based software multiplies; not
20183
 * needed by the table-free GCM_SMALL variant. R[a] is the contribution, to the
20184
 * top two bytes, of reducing a nibble 'a' shifted out past x^127 (the GHASH
20185
 * polynomial x^128+x^7+x^2+x+1). Same table wolfSSL uses for table GHASH. */
20186
static const byte AES_GCM_SIV_R[16][2] = {
20187
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
20188
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
20189
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
20190
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
20191
};
20192
#endif
20193
20194
/* Reverse the order of the 16 bytes of a block. in and out must not alias. */
20195
static WC_INLINE void AesGcmSivByteReverse(byte* out, const byte* in)
20196
{
20197
#if !defined(WOLFSSL_USE_ALIGN) && defined(WORD64_AVAILABLE)
20198
    /* Unaligned word access is permitted: reverse eight bytes at a time with a
20199
     * hardware byte-swap rather than one byte at a time. Endian independent -
20200
     * load native, reverse the value's bytes, store native: that reverses the
20201
     * bytes in memory on both little- and big-endian. */
20202
    word64 lo, hi;
20203
    XMEMCPY(&lo, in,     sizeof(lo));
20204
    XMEMCPY(&hi, in + 8, sizeof(hi));
20205
    lo = ByteReverseWord64(lo);
20206
    hi = ByteReverseWord64(hi);
20207
    XMEMCPY(out,     &hi, sizeof(hi));
20208
    XMEMCPY(out + 8, &lo, sizeof(lo));
20209
#else
20210
    int i;
20211
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
20212
        out[i] = in[WC_AES_BLOCK_SIZE - 1 - i];
20213
    }
20214
#endif
20215
}
20216
20217
/* POLYVAL state (RFC 8452 Section 3). POLYVAL is GHASH on byte-reversed inputs,
20218
 * so the field is the GHASH field with the most-significant bit of byte 0 the
20219
 * x^0 coefficient (see RFC 8452 Appendix A). The key is one of:
20220
 *  - GCM_SMALL: the 16-byte key (table-free, smallest footprint).
20221
 *  - word64:    a Shoup 4-bit table (256 bytes), word64 multiply - used when a
20222
 *               64-bit type is available and GCM_WORD32 is not requested.
20223
 *  - word32:    the same 4-bit table, word32 multiply - used for GCM_WORD32 or
20224
 *               when no 64-bit type is available.
20225
 *
20226
 * Every variant reads the message, key and running sum a byte at a time and
20227
 * (the word64/word32 variants) load/store their words with explicit shifts or
20228
 * a byte-swap rather than casting buffers, so all are independent of platform
20229
 * endianness; the word loads also respect WOLFSSL_USE_ALIGN, so input, key and
20230
 * output buffers may be little- or big-endian and aligned or unaligned.
20231
 */
20232
/* When the generated x86_64 AES-NI/PCLMUL POLYVAL multiply is available
20233
 * (aes_gcm_asm.S), the per-block multiply can be offloaded to it at runtime.
20234
 * This is the generated external assembly - no assembly lives in this file. */
20235
#if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
20236
    #define WC_POLYVAL_ASM
20237
#ifdef __cplusplus
20238
    extern "C" {
20239
#endif
20240
    /* s += POLYVAL of 'blocks' 16-byte blocks of data, hash key h prepared as
20241
     * the byte-reversed mulX_GHASH(ByteReverse(authKey)); s is POLYVAL byte
20242
     * order. */
20243
    void AES_GCMSIV_polyval_aesni(unsigned char* s, const unsigned char* h,
20244
        const unsigned char* data, word32 blocks)
20245
        XASM_LINK("AES_GCMSIV_polyval_aesni");
20246
#ifdef HAVE_INTEL_AVX1
20247
    void AES_GCMSIV_polyval_avx1(unsigned char* s, const unsigned char* h,
20248
        const unsigned char* data, word32 blocks)
20249
        XASM_LINK("AES_GCMSIV_polyval_avx1");
20250
#endif
20251
#ifdef HAVE_INTEL_VAES
20252
    /* Aggregated 2-blocks-per-ymm POLYVAL (VPCLMULQDQ). */
20253
    void AES_GCMSIV_polyval_vaes(unsigned char* s, const unsigned char* h,
20254
        const unsigned char* data, word32 blocks)
20255
        XASM_LINK("AES_GCMSIV_polyval_vaes");
20256
#endif
20257
#ifdef HAVE_INTEL_AVX512
20258
    /* Aggregated 4-blocks-per-zmm POLYVAL (VPCLMULQDQ). */
20259
    void AES_GCMSIV_polyval_avx512(unsigned char* s, const unsigned char* h,
20260
        const unsigned char* data, word32 blocks)
20261
        XASM_LINK("AES_GCMSIV_polyval_avx512");
20262
#endif
20263
    /* AES-GCM-SIV CTR keystream (RFC 8452): a 32-bit little-endian counter in
20264
     * the first 4 bytes of the block (mod 2^32, no carry), block used directly
20265
     * as the AES input. Encrypts the full-16-byte-block portion of 'length'
20266
     * bytes (pipelined), advancing and writing 'ctr' back. */
20267
    #define WC_GCMSIV_CTR_ASM
20268
    void AES_GCMSIV_ctr_aesni(const unsigned char* in, unsigned char* out,
20269
        unsigned long length, const unsigned char* KS, int nr,
20270
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_aesni");
20271
#ifdef HAVE_INTEL_AVX1
20272
    void AES_GCMSIV_ctr_avx1(const unsigned char* in, unsigned char* out,
20273
        unsigned long length, const unsigned char* KS, int nr,
20274
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_avx1");
20275
#endif
20276
#ifdef HAVE_INTEL_VAES
20277
    void AES_GCMSIV_ctr_vaes(const unsigned char* in, unsigned char* out,
20278
        unsigned long length, const unsigned char* KS, int nr,
20279
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_vaes");
20280
#endif
20281
#ifdef HAVE_INTEL_AVX512
20282
    void AES_GCMSIV_ctr_avx512(const unsigned char* in, unsigned char* out,
20283
        unsigned long length, const unsigned char* KS, int nr,
20284
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_avx512");
20285
#endif
20286
#ifdef __cplusplus
20287
    }
20288
#endif
20289
#elif defined(WOLFSSL_ARMASM) && defined(__aarch64__)
20290
    /* The generated AArch64 POLYVAL multiplies (armv8-aes-asm.S) offload the
20291
     * per-block multiply: PMULL when the CPU has the crypto extension, else the
20292
     * 8-bit-pmul NEON variant, else the scalar (base) variant. This is the
20293
     * generated external assembly - no assembly lives here. */
20294
    #define WC_POLYVAL_ASM
20295
    #define WC_POLYVAL_ASM_AARCH64
20296
    /* The base (scalar) variant multiplies through the word64 software table
20297
     * poly->m, so it is only available when that table is built. */
20298
    #if defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) && \
20299
        !defined(GCM_SMALL) && !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
20300
        #define WC_POLYVAL_ASM_AARCH64_BASE
20301
    #endif
20302
#ifdef __cplusplus
20303
    extern "C" {
20304
#endif
20305
    /* s += POLYVAL of 'blocks' 16-byte blocks of data. For the PMULL and NEON
20306
     * variants h is the prepared key (byte-reversed mulX_GHASH(ByteReverse(
20307
     * authKey))); for the base variant h is the word64 table poly->m. s is in
20308
     * POLYVAL byte order in every case. */
20309
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20310
    void AES_GCMSIV_polyval_pmull(unsigned char* s, const unsigned char* h,
20311
        const unsigned char* data, word32 blocks)
20312
        XASM_LINK("AES_GCMSIV_polyval_pmull");
20313
#endif
20314
#ifndef WOLFSSL_ARMASM_NO_NEON
20315
    void AES_GCMSIV_polyval_neon(unsigned char* s, const unsigned char* h,
20316
        const unsigned char* data, word32 blocks)
20317
        XASM_LINK("AES_GCMSIV_polyval_neon");
20318
#endif
20319
#ifdef WC_POLYVAL_ASM_AARCH64_BASE
20320
    void AES_GCMSIV_polyval_base(unsigned char* s, const unsigned char* h,
20321
        const unsigned char* data, word32 blocks)
20322
        XASM_LINK("AES_GCMSIV_polyval_base");
20323
#endif
20324
    /* AES-GCM-SIV CTR keystream (RFC 8452): 32-bit little-endian counter in the
20325
     * first 4 bytes of the block, mod 2^32, block used directly. Full-block
20326
     * portion only (the C tail finishes any partial block). The crypto variant
20327
     * pipelines aese; the NEON/base variants pipeline software table AES. KS is
20328
     * the AES key schedule in every case. */
20329
    #define WC_GCMSIV_CTR_ASM
20330
    #define WC_GCMSIV_CTR_ASM_AARCH64
20331
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20332
    void AES_GCMSIV_ctr_aarch64(const unsigned char* in, unsigned char* out,
20333
        unsigned long length, const unsigned char* KS, int nr,
20334
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_aarch64");
20335
#endif
20336
#ifndef WOLFSSL_ARMASM_NO_NEON
20337
    void AES_GCMSIV_ctr_neon(const unsigned char* in, unsigned char* out,
20338
        unsigned long length, const unsigned char* KS, int nr,
20339
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_neon");
20340
#endif
20341
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
20342
    void AES_GCMSIV_ctr_base(const unsigned char* in, unsigned char* out,
20343
        unsigned long length, const unsigned char* KS, int nr,
20344
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_base");
20345
#endif
20346
#ifdef __cplusplus
20347
    }
20348
#endif
20349
#elif defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
20350
      !defined(WOLFSSL_ARMASM_THUMB2)
20351
    /* AArch32 (32-bit ARM). The generated armv8-32-aes-asm.S provides POLYVAL
20352
     * and CTR for the crypto (vmull.p64 / aese) and base (table) variants. In a
20353
     * run-time dispatch build both are compiled in and the selectors below pick
20354
     * one per CPU (WOLFSSL_ARM32_AES_DISPATCH); otherwise the choice is fixed
20355
     * at compile time by WOLFSSL_ARMASM_NO_HW_CRYPTO - matching the rest of the
20356
     * AArch32 AES. */
20357
    #define WC_POLYVAL_ASM
20358
    #define WC_POLYVAL_ASM_AARCH32
20359
    #define WC_GCMSIV_CTR_ASM
20360
    #define WC_GCMSIV_CTR_ASM_AARCH32
20361
    /* The base POLYVAL multiplies through the word64 software table poly->m,
20362
     * compiled when the crypto extension can be absent at run time (no-crypto
20363
     * build or the run-time dispatch build) and the table is available. */
20364
    #if (defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
20365
         defined(WOLFSSL_ARM32_AES_DISPATCH)) && defined(WORD64_AVAILABLE) && \
20366
        !defined(GCM_WORD32) && !defined(GCM_SMALL)
20367
        #define WC_POLYVAL_ASM_AARCH32_BASE
20368
    #endif
20369
#ifdef __cplusplus
20370
    extern "C" {
20371
#endif
20372
    /* Crypto and base variants both exist in a dispatch build; the selectors
20373
     * below pick one per CPU at run time. */
20374
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20375
    void AES_GCMSIV_polyval_crypto(unsigned char* s, const unsigned char* h,
20376
        const unsigned char* data, word32 blocks)
20377
        XASM_LINK("AES_GCMSIV_polyval_crypto");
20378
    void AES_GCMSIV_ctr_crypto(const unsigned char* in, unsigned char* out,
20379
        unsigned long length, const unsigned char* KS, int nr,
20380
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_crypto");
20381
#endif
20382
#if defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || defined(WOLFSSL_ARM32_AES_DISPATCH)
20383
#ifdef WC_POLYVAL_ASM_AARCH32_BASE
20384
    void AES_GCMSIV_polyval_base(unsigned char* s, const unsigned char* h,
20385
        const unsigned char* data, word32 blocks)
20386
        XASM_LINK("AES_GCMSIV_polyval_base");
20387
#endif
20388
    void AES_GCMSIV_ctr_base(const unsigned char* in, unsigned char* out,
20389
        unsigned long length, const unsigned char* KS, int nr,
20390
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_base");
20391
#endif
20392
#ifdef __cplusplus
20393
    }
20394
#endif
20395
#elif defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_THUMB2)
20396
    /* Thumb-2 (32-bit ARM, Thumb-2 encoding). A single table-based variant
20397
     * (ported from the AArch32 base): POLYVAL multiplies through the word64
20398
     * software table poly->m; CTR is the table AES with the SIV counter. */
20399
    #define WC_GCMSIV_CTR_ASM
20400
    #define WC_GCMSIV_CTR_ASM_THUMB2
20401
    #if defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) && !defined(GCM_SMALL)
20402
        #define WC_POLYVAL_ASM
20403
        #define WC_POLYVAL_ASM_THUMB2
20404
    #endif
20405
#ifdef __cplusplus
20406
    extern "C" {
20407
#endif
20408
#ifdef WC_POLYVAL_ASM_THUMB2
20409
    void AES_GCMSIV_polyval_thumb2(unsigned char* s, const unsigned char* h,
20410
        const unsigned char* data, word32 blocks)
20411
        XASM_LINK("AES_GCMSIV_polyval_thumb2");
20412
#endif
20413
    void AES_GCMSIV_ctr_thumb2(const unsigned char* in, unsigned char* out,
20414
        unsigned long length, const unsigned char* KS, int nr,
20415
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_thumb2");
20416
#ifdef __cplusplus
20417
    }
20418
#endif
20419
#endif
20420
20421
#ifdef WC_POLYVAL_ASM
20422
    typedef void (*AesGcmSivPolyvalFn)(unsigned char* s, const unsigned char* h,
20423
        const unsigned char* data, word32 blocks);
20424
#endif
20425
#ifdef WC_GCMSIV_CTR_ASM
20426
    typedef void (*AesGcmSivCtrFn)(const unsigned char* in, unsigned char* out,
20427
        unsigned long length, const unsigned char* KS, int nr,
20428
        unsigned char* ctr);
20429
#endif
20430
20431
typedef struct AesGcmSivPolyval {
20432
#ifdef WC_POLYVAL_ASM
20433
    byte hHw[WC_AES_BLOCK_SIZE]; /* prepared key for the asm multiply */
20434
    const byte* asmKey;          /* key passed to fn: hHw, or the table below */
20435
    AesGcmSivPolyvalFn fn;       /* asm multiply, or NULL for software */
20436
#endif
20437
#if defined(GCM_SMALL)
20438
    byte   h[WC_AES_BLOCK_SIZE]; /* hash key = mulX_GHASH(ByteReverse(H)) */
20439
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
20440
    word64 m[16][2];             /* m[i] = i * mulX_GHASH(ByteReverse(H)) */
20441
#else
20442
    word32 m[16][4];             /* m[i] = i * mulX_GHASH(ByteReverse(H)) */
20443
#endif
20444
    byte s[WC_AES_BLOCK_SIZE];   /* running sum, GHASH representation */
20445
} AesGcmSivPolyval;
20446
20447
/* Multiply a GF(2^128) element (GHASH bit order: the most-significant bit of
20448
 * byte 0 is the x^0 coefficient) by x: shift the 128-bit value right by one
20449
 * and reduce with the GHASH polynomial. Branch free, so constant time. Used by
20450
 * the GCM_SMALL multiply and to derive the carry-less-multiply asm hash key
20451
 * (mulX_GHASH); the word64/word32 table variants use AesGcmSivMulX64/32, so this
20452
 * is only compiled when one of those two callers is. Placed after the
20453
 * WC_POLYVAL_ASM #defines above so that guard is resolved here. */
20454
#if defined(GCM_SMALL) || defined(WC_POLYVAL_ASM)
20455
static WC_INLINE void AesGcmSivMulX(byte* x)
20456
{
20457
    int i;
20458
    byte carryIn = 0;
20459
    byte borrow = (byte)((0x00U - (x[WC_AES_BLOCK_SIZE - 1] & 0x01U)) & 0xE1U);
20460
20461
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
20462
        byte carryOut = (byte)((x[i] & 0x01) << 7);
20463
        x[i] = (byte)((x[i] >> 1) | carryIn);
20464
        carryIn = carryOut;
20465
    }
20466
    x[0] ^= borrow;
20467
}
20468
#endif /* GCM_SMALL || WC_POLYVAL_ASM */
20469
20470
#if defined(GCM_SMALL)
20471
20472
/* s = s * h with no precomputed table: decompose h bit-by-bit and accumulate
20473
 * shifted copies of s. Mirrors wolfSSL's GCM_SMALL GMULT. */
20474
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
20475
{
20476
    byte Z[WC_AES_BLOCK_SIZE];
20477
    byte V[WC_AES_BLOCK_SIZE];
20478
    int i, j;
20479
20480
    XMEMSET(Z, 0, sizeof(Z));
20481
    XMEMCPY(V, poly->s, WC_AES_BLOCK_SIZE);
20482
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
20483
        byte y = poly->h[i];
20484
        for (j = 0; j < 8; j++) {
20485
            if (y & 0x80) {
20486
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
20487
            }
20488
            AesGcmSivMulX(V);
20489
            y = (byte)(y << 1);
20490
        }
20491
    }
20492
    XMEMCPY(poly->s, Z, WC_AES_BLOCK_SIZE);
20493
}
20494
20495
/* Store the hash key mulX_GHASH(ByteReverse(h)); no table to build. */
20496
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
20497
{
20498
    AesGcmSivByteReverse(poly->h, h);
20499
    AesGcmSivMulX(poly->h);
20500
    XMEMSET(poly->s, 0, sizeof(poly->s));
20501
}
20502
20503
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
20504
20505
/* Load/store a big-endian word64 - the high word is bytes 0..7 of the block,
20506
 * so byte 0 (the x^0..x^7 coefficients) is the most-significant byte.
20507
 *
20508
 * Where unaligned word access is permitted (!WOLFSSL_USE_ALIGN) this is a
20509
 * single word64 load/store plus a hardware byte-swap on little-endian; where
20510
 * alignment is required it is assembled a byte at a time. Both forms are
20511
 * endian independent. */
20512
#ifndef WOLFSSL_USE_ALIGN
20513
static WC_INLINE word64 AesGcmSivLoad64(const byte* b)
20514
{
20515
    word64 v;
20516
    XMEMCPY(&v, b, sizeof(v));
20517
#ifdef LITTLE_ENDIAN_ORDER
20518
    v = ByteReverseWord64(v);
20519
#endif
20520
    return v;
20521
}
20522
static WC_INLINE void AesGcmSivStore64(byte* b, word64 v)
20523
{
20524
#ifdef LITTLE_ENDIAN_ORDER
20525
    v = ByteReverseWord64(v);
20526
#endif
20527
    XMEMCPY(b, &v, sizeof(v));
20528
}
20529
#else
20530
static WC_INLINE word64 AesGcmSivLoad64(const byte* b)
20531
{
20532
    return ((word64)b[0] << 56) | ((word64)b[1] << 48) |
20533
           ((word64)b[2] << 40) | ((word64)b[3] << 32) |
20534
           ((word64)b[4] << 24) | ((word64)b[5] << 16) |
20535
           ((word64)b[6] <<  8) | ((word64)b[7]);
20536
}
20537
static WC_INLINE void AesGcmSivStore64(byte* b, word64 v)
20538
{
20539
    b[0] = (byte)(v >> 56); b[1] = (byte)(v >> 48);
20540
    b[2] = (byte)(v >> 40); b[3] = (byte)(v >> 32);
20541
    b[4] = (byte)(v >> 24); b[5] = (byte)(v >> 16);
20542
    b[6] = (byte)(v >>  8); b[7] = (byte)(v);
20543
}
20544
#endif
20545
20546
/* Multiply the 128-bit value (hi,lo) by x and reduce: a right shift by one of
20547
 * the whole value, XOR-ing the reduction polynomial (0xe1 into byte 0) when a
20548
 * one is shifted out past x^127 (the low bit of lo). */
20549
static WC_INLINE void AesGcmSivMulX64(word64* hi, word64* lo)
20550
{
20551
    word64 carry = *lo & 1;
20552
    *lo = (*lo >> 1) | (*hi << 63);
20553
    *hi = (*hi >> 1) ^ (W64LIT(0xe100000000000000) & (word64)(0 - carry));
20554
}
20555
20556
/* s = s * H. The accumulator is shifted right a nibble at a time; the nibble
20557
 * that falls off is reduced through AES_GCM_SIV_R into the top two bytes. */
20558
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
20559
{
20560
    byte* x = poly->s;
20561
    word64 (*m)[2] = poly->m;
20562
    word64 zHi = 0, zLo = 0;
20563
    int i;
20564
20565
    for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
20566
        byte xi = x[i];
20567
        byte a;
20568
20569
        /* low nibble */
20570
        zHi ^= m[xi & 0xf][0];
20571
        zLo ^= m[xi & 0xf][1];
20572
        a = (byte)(zLo & 0xf);
20573
        zLo = (zLo >> 4) | (zHi << 60);
20574
        zHi = zHi >> 4;
20575
        zHi ^= ((word64)AES_GCM_SIV_R[a][0] << 56) |
20576
               ((word64)AES_GCM_SIV_R[a][1] << 48);
20577
20578
        /* high nibble */
20579
        zHi ^= m[xi >> 4][0];
20580
        zLo ^= m[xi >> 4][1];
20581
        if (i == 0) {
20582
            break;
20583
        }
20584
        a = (byte)(zLo & 0xf);
20585
        zLo = (zLo >> 4) | (zHi << 60);
20586
        zHi = zHi >> 4;
20587
        zHi ^= ((word64)AES_GCM_SIV_R[a][0] << 56) |
20588
               ((word64)AES_GCM_SIV_R[a][1] << 48);
20589
    }
20590
20591
    AesGcmSivStore64(x,     zHi);
20592
    AesGcmSivStore64(x + 8, zLo);
20593
}
20594
20595
/* Build the 4-bit table for mulX_GHASH(ByteReverse(h)). */
20596
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
20597
{
20598
    byte hrev[WC_AES_BLOCK_SIZE];
20599
    word64 (*m)[2] = poly->m;
20600
    int i;
20601
20602
#ifdef WOLFSSL_CHECK_MEM_ZERO
20603
    /* hrev will hold ByteReverse(H), the per-message hash key; register from
20604
     * the top (baseline keeps it defined) so every exit reaches the
20605
     * ForceZero+Check below. */
20606
    XMEMSET(hrev, 0, sizeof(hrev));
20607
    wc_MemZero_Add("AesGcmSivPolyvalInitSw hrev", hrev, sizeof(hrev));
20608
#endif
20609
20610
    /* m[8] = 1 * H = mulX_GHASH(ByteReverse(h)); successive halvings give the
20611
     * power-of-two nibble entries. */
20612
    AesGcmSivByteReverse(hrev, h);
20613
    m[0x8][0] = AesGcmSivLoad64(hrev);
20614
    m[0x8][1] = AesGcmSivLoad64(hrev + 8);
20615
    AesGcmSivMulX64(&m[0x8][0], &m[0x8][1]);
20616
    m[0x4][0] = m[0x8][0]; m[0x4][1] = m[0x8][1]; AesGcmSivMulX64(&m[0x4][0], &m[0x4][1]);
20617
    m[0x2][0] = m[0x4][0]; m[0x2][1] = m[0x4][1]; AesGcmSivMulX64(&m[0x2][0], &m[0x2][1]);
20618
    m[0x1][0] = m[0x2][0]; m[0x1][1] = m[0x2][1]; AesGcmSivMulX64(&m[0x1][0], &m[0x1][1]);
20619
20620
    /* The rest are sums of those basis entries (i = high bit + remainder). */
20621
    m[0x0][0] = 0; m[0x0][1] = 0;
20622
    for (i = 0; i < 16; i++) {
20623
        static const byte hibit[16] =
20624
            { 0, 0, 0, 2, 0, 4, 4, 4, 0, 8, 8, 8, 8, 8, 8, 8 };
20625
        int top = hibit[i];
20626
        if (top != 0) {
20627
            m[i][0] = m[top][0] ^ m[i - top][0];
20628
            m[i][1] = m[top][1] ^ m[i - top][1];
20629
        }
20630
    }
20631
20632
    XMEMSET(poly->s, 0, sizeof(poly->s));
20633
    /* hrev held ByteReverse(H), the per-message hash key; wipe it. */
20634
    ForceZero(hrev, sizeof(hrev));
20635
#ifdef WOLFSSL_CHECK_MEM_ZERO
20636
    wc_MemZero_Check(hrev, sizeof(hrev));
20637
#endif
20638
}
20639
20640
#else /* word32: GCM_WORD32 or no 64-bit type */
20641
20642
/* Load/store a big-endian word32 - byte 0 is the most-significant byte. Same
20643
 * aligned/unaligned split as AesGcmSivLoad64/Store64; both forms are endian
20644
 * independent. */
20645
#ifndef WOLFSSL_USE_ALIGN
20646
static WC_INLINE word32 AesGcmSivLoad32(const byte* b)
20647
{
20648
    word32 v;
20649
    XMEMCPY(&v, b, sizeof(v));
20650
#ifdef LITTLE_ENDIAN_ORDER
20651
    v = ByteReverseWord32(v);
20652
#endif
20653
    return v;
20654
}
20655
static WC_INLINE void AesGcmSivStore32(byte* b, word32 v)
20656
{
20657
#ifdef LITTLE_ENDIAN_ORDER
20658
    v = ByteReverseWord32(v);
20659
#endif
20660
    XMEMCPY(b, &v, sizeof(v));
20661
}
20662
#else
20663
static WC_INLINE word32 AesGcmSivLoad32(const byte* b)
20664
{
20665
    return ((word32)b[0] << 24) | ((word32)b[1] << 16) |
20666
           ((word32)b[2] <<  8) | ((word32)b[3]);
20667
}
20668
static WC_INLINE void AesGcmSivStore32(byte* b, word32 v)
20669
{
20670
    b[0] = (byte)(v >> 24); b[1] = (byte)(v >> 16);
20671
    b[2] = (byte)(v >>  8); b[3] = (byte)(v);
20672
}
20673
#endif
20674
20675
/* Multiply the 128-bit value (z[0] most significant) by x and reduce: shift
20676
 * the whole value right by one, XOR-ing 0xe1 into byte 0 when a one is shifted
20677
 * out past x^127 (the low bit of z[3]). */
20678
static WC_INLINE void AesGcmSivMulX32(word32* z)
20679
{
20680
    word32 carry = z[3] & 1;
20681
    z[3] = (z[3] >> 1) | (z[2] << 31);
20682
    z[2] = (z[2] >> 1) | (z[1] << 31);
20683
    z[1] = (z[1] >> 1) | (z[0] << 31);
20684
    z[0] = (z[0] >> 1) ^ (0xe1000000U & (word32)(0 - carry));
20685
}
20686
20687
/* s = s * H. The accumulator is shifted right a nibble at a time; the nibble
20688
 * that falls off is reduced through AES_GCM_SIV_R into the top two bytes. */
20689
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
20690
{
20691
    byte* x = poly->s;
20692
    word32 (*m)[4] = poly->m;
20693
    word32 z0 = 0, z1 = 0, z2 = 0, z3 = 0;
20694
    int i;
20695
20696
    for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
20697
        word32* mr;
20698
        byte xi = x[i];
20699
        byte a;
20700
20701
        /* low nibble */
20702
        mr = m[xi & 0xf];
20703
        z0 ^= mr[0]; z1 ^= mr[1]; z2 ^= mr[2]; z3 ^= mr[3];
20704
        a = (byte)(z3 & 0xf);
20705
        z3 = (z3 >> 4) | (z2 << 28);
20706
        z2 = (z2 >> 4) | (z1 << 28);
20707
        z1 = (z1 >> 4) | (z0 << 28);
20708
        z0 = z0 >> 4;
20709
        z0 ^= ((word32)AES_GCM_SIV_R[a][0] << 24) |
20710
              ((word32)AES_GCM_SIV_R[a][1] << 16);
20711
20712
        /* high nibble */
20713
        mr = m[xi >> 4];
20714
        z0 ^= mr[0]; z1 ^= mr[1]; z2 ^= mr[2]; z3 ^= mr[3];
20715
        if (i == 0) {
20716
            break;
20717
        }
20718
        a = (byte)(z3 & 0xf);
20719
        z3 = (z3 >> 4) | (z2 << 28);
20720
        z2 = (z2 >> 4) | (z1 << 28);
20721
        z1 = (z1 >> 4) | (z0 << 28);
20722
        z0 = z0 >> 4;
20723
        z0 ^= ((word32)AES_GCM_SIV_R[a][0] << 24) |
20724
              ((word32)AES_GCM_SIV_R[a][1] << 16);
20725
    }
20726
20727
    AesGcmSivStore32(x,      z0);
20728
    AesGcmSivStore32(x + 4,  z1);
20729
    AesGcmSivStore32(x + 8,  z2);
20730
    AesGcmSivStore32(x + 12, z3);
20731
}
20732
20733
/* Build the 4-bit table for mulX_GHASH(ByteReverse(h)). */
20734
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
20735
{
20736
    byte hrev[WC_AES_BLOCK_SIZE];
20737
    word32 (*m)[4] = poly->m;
20738
    int i;
20739
20740
#ifdef WOLFSSL_CHECK_MEM_ZERO
20741
    /* hrev will hold ByteReverse(H), the per-message hash key; register from
20742
     * the top (baseline keeps it defined) so every exit reaches the
20743
     * ForceZero+Check below. */
20744
    XMEMSET(hrev, 0, sizeof(hrev));
20745
    wc_MemZero_Add("AesGcmSivPolyvalInitSw hrev", hrev, sizeof(hrev));
20746
#endif
20747
20748
    /* m[8] = 1 * H = mulX_GHASH(ByteReverse(h)); successive halvings give the
20749
     * power-of-two nibble entries. */
20750
    AesGcmSivByteReverse(hrev, h);
20751
    m[0x8][0] = AesGcmSivLoad32(hrev);
20752
    m[0x8][1] = AesGcmSivLoad32(hrev + 4);
20753
    m[0x8][2] = AesGcmSivLoad32(hrev + 8);
20754
    m[0x8][3] = AesGcmSivLoad32(hrev + 12);
20755
    AesGcmSivMulX32(m[0x8]);
20756
    XMEMCPY(m[0x4], m[0x8], sizeof(m[0x4])); AesGcmSivMulX32(m[0x4]);
20757
    XMEMCPY(m[0x2], m[0x4], sizeof(m[0x2])); AesGcmSivMulX32(m[0x2]);
20758
    XMEMCPY(m[0x1], m[0x2], sizeof(m[0x1])); AesGcmSivMulX32(m[0x1]);
20759
20760
    /* The rest are sums of those basis entries (i = high bit + remainder). */
20761
    m[0x0][0] = 0; m[0x0][1] = 0; m[0x0][2] = 0; m[0x0][3] = 0;
20762
    for (i = 0; i < 16; i++) {
20763
        static const byte hibit[16] =
20764
            { 0, 0, 0, 2, 0, 4, 4, 4, 0, 8, 8, 8, 8, 8, 8, 8 };
20765
        int top = hibit[i];
20766
        if (top != 0) {
20767
            m[i][0] = m[top][0] ^ m[i - top][0];
20768
            m[i][1] = m[top][1] ^ m[i - top][1];
20769
            m[i][2] = m[top][2] ^ m[i - top][2];
20770
            m[i][3] = m[top][3] ^ m[i - top][3];
20771
        }
20772
    }
20773
20774
    XMEMSET(poly->s, 0, sizeof(poly->s));
20775
    /* hrev held ByteReverse(H), the per-message hash key; wipe it. */
20776
    ForceZero(hrev, sizeof(hrev));
20777
#ifdef WOLFSSL_CHECK_MEM_ZERO
20778
    wc_MemZero_Check(hrev, sizeof(hrev));
20779
#endif
20780
}
20781
20782
#endif /* POLYVAL multiply variant */
20783
20784
#ifdef WC_POLYVAL_ASM_THUMB2
20785
/* Thumb-2: the single table POLYVAL variant. */
20786
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
20787
{
20788
    return &AES_GCMSIV_polyval_thumb2;
20789
}
20790
#elif defined(WC_POLYVAL_ASM_AARCH32)
20791
/* AArch32: crypto (vmull.p64) POLYVAL when the CPU implements PMULL, else the
20792
 * base (table) variant.  In a run-time dispatch build the choice is made per
20793
 * CPU - matching the flags Check_CPU_support_HwCrypto set on the Aes object,
20794
 * which AES-GCM-SIV keys through wc_AesSetKey; otherwise it is fixed at compile
20795
 * time. */
20796
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
20797
{
20798
#ifdef WOLFSSL_ARM32_AES_DISPATCH
20799
    cpuid_get_flags_ex(&cpuid_flags);
20800
    if (IS_ARM32_PMULL(cpuid_flags)) {
20801
        return &AES_GCMSIV_polyval_crypto;
20802
    }
20803
    /* The base multiply needs the word64 table (poly->m), which is not built
20804
     * for GCM_SMALL / GCM_WORD32; fall back to the C multiply there. */
20805
#ifdef WC_POLYVAL_ASM_AARCH32_BASE
20806
    return &AES_GCMSIV_polyval_base;
20807
#else
20808
    return NULL;
20809
#endif
20810
#elif !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
20811
    return &AES_GCMSIV_polyval_crypto;
20812
#elif defined(WC_POLYVAL_ASM_AARCH32_BASE)
20813
    return &AES_GCMSIV_polyval_base;
20814
#else
20815
    return NULL;
20816
#endif
20817
}
20818
#elif defined(WC_POLYVAL_ASM_AARCH64)
20819
/* Select the best available generated POLYVAL multiply: PMULL when the CPU has
20820
 * the crypto extension, else the 8-bit-pmul NEON variant, else the scalar base
20821
 * variant, else NULL to fall back to software. */
20822
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
20823
{
20824
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20825
    cpuid_get_flags_ex(&cpuid_flags);
20826
    if (IS_AARCH64_PMULL(cpuid_flags)) {
20827
        return &AES_GCMSIV_polyval_pmull;
20828
    }
20829
#endif
20830
#ifndef WOLFSSL_ARMASM_NO_NEON
20831
    return &AES_GCMSIV_polyval_neon;
20832
#elif defined(WC_POLYVAL_ASM_AARCH64_BASE)
20833
    return &AES_GCMSIV_polyval_base;
20834
#else
20835
    return NULL;
20836
#endif
20837
}
20838
#elif defined(WC_POLYVAL_ASM)
20839
/* Select the best available generated POLYVAL multiply for this CPU, or NULL
20840
 * to fall back to software. PCLMUL is present on every AES-NI capable CPU, so
20841
 * AES-NI gates the base path (matching wolfSSL's AES-GCM). */
20842
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
20843
{
20844
    cpuid_get_flags_ex(&intel_flags);
20845
    if (!IS_INTEL_AESNI(intel_flags)) {
20846
        return NULL;
20847
    }
20848
#ifdef HAVE_INTEL_AVX512
20849
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
20850
        return &AES_GCMSIV_polyval_avx512;
20851
    }
20852
#endif
20853
#ifdef HAVE_INTEL_VAES
20854
    if (IS_INTEL_VAES(intel_flags) && IS_INTEL_AVX2(intel_flags)) {
20855
        return &AES_GCMSIV_polyval_vaes;
20856
    }
20857
#endif
20858
#ifdef HAVE_INTEL_AVX1
20859
    if (IS_INTEL_AVX1(intel_flags)) {
20860
        return &AES_GCMSIV_polyval_avx1;
20861
    }
20862
#endif
20863
    return &AES_GCMSIV_polyval_aesni;
20864
}
20865
#endif
20866
20867
#ifdef WC_GCMSIV_CTR_ASM_THUMB2
20868
/* Thumb-2: the single table CTR variant. */
20869
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
20870
{
20871
    return &AES_GCMSIV_ctr_thumb2;
20872
}
20873
#elif defined(WC_GCMSIV_CTR_ASM_AARCH32)
20874
/* AArch32: crypto (aese) CTR when the CPU implements AES, else the base (table)
20875
 * variant.  The CTR keystream runs through the AES key schedule, so the variant
20876
 * must match how the key was expanded (Check_CPU_support_HwCrypto): the crypto
20877
 * schedule is taken only when both AES and PMULL are present. */
20878
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
20879
{
20880
#ifdef WOLFSSL_ARM32_AES_DISPATCH
20881
    cpuid_get_flags_ex(&cpuid_flags);
20882
    if (IS_ARM32_AES(cpuid_flags) && IS_ARM32_PMULL(cpuid_flags)) {
20883
        return &AES_GCMSIV_ctr_crypto;
20884
    }
20885
    return &AES_GCMSIV_ctr_base;
20886
#elif !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
20887
    return &AES_GCMSIV_ctr_crypto;
20888
#else
20889
    return &AES_GCMSIV_ctr_base;
20890
#endif
20891
}
20892
#elif defined(WC_GCMSIV_CTR_ASM_AARCH64)
20893
/* Select the best generated CTR keystream: pipelined aese when the CPU has the
20894
 * AES extension, else the NEON or base software-table variant, else NULL. */
20895
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
20896
{
20897
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20898
    cpuid_get_flags_ex(&cpuid_flags);
20899
    if (IS_AARCH64_AES(cpuid_flags)) {
20900
        return &AES_GCMSIV_ctr_aarch64;
20901
    }
20902
#endif
20903
#ifndef WOLFSSL_ARMASM_NO_NEON
20904
    return &AES_GCMSIV_ctr_neon;
20905
#elif !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
20906
    return &AES_GCMSIV_ctr_base;
20907
#else
20908
    return NULL;
20909
#endif
20910
}
20911
#elif defined(WC_GCMSIV_CTR_ASM)
20912
/* Select the best generated AES-GCM-SIV CTR keystream for this CPU. AES-NI is
20913
 * the base; AVX1/VAES/AVX512 are progressively wider pipelines. */
20914
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
20915
{
20916
    cpuid_get_flags_ex(&intel_flags);
20917
    if (!IS_INTEL_AESNI(intel_flags)) {
20918
        return NULL;
20919
    }
20920
#ifdef HAVE_INTEL_AVX512
20921
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
20922
        return &AES_GCMSIV_ctr_avx512;
20923
    }
20924
#endif
20925
#ifdef HAVE_INTEL_VAES
20926
    if (IS_INTEL_VAES(intel_flags) && IS_INTEL_AVX2(intel_flags)) {
20927
        return &AES_GCMSIV_ctr_vaes;
20928
    }
20929
#endif
20930
#ifdef HAVE_INTEL_AVX1
20931
    if (IS_INTEL_AVX1(intel_flags)) {
20932
        return &AES_GCMSIV_ctr_avx1;
20933
    }
20934
#endif
20935
    return &AES_GCMSIV_ctr_aesni;
20936
}
20937
#endif
20938
20939
/* Initialize POLYVAL with the 16-byte hash key h, using the generated assembly
20940
 * multiply when the CPU supports it and a software variant otherwise. */
20941
static void AesGcmSivPolyvalInit(AesGcmSivPolyval* poly, const byte* h)
20942
{
20943
#ifdef WC_POLYVAL_ASM
20944
    AesGcmSivPolyvalFn fn = AesGcmSivPolyvalAsm();
20945
    if (fn != NULL) {
20946
#if defined(WC_POLYVAL_ASM_AARCH64_BASE) || defined(WC_POLYVAL_ASM_AARCH32_BASE)
20947
        if (fn == &AES_GCMSIV_polyval_base) {
20948
            /* The scalar variant multiplies through the word64 software table,
20949
             * so build it and point the asm at it. */
20950
            AesGcmSivPolyvalInitSw(poly, h);
20951
            poly->asmKey = (const byte*)poly->m;
20952
            poly->fn = fn;
20953
            return;
20954
        }
20955
#endif
20956
#ifdef WC_POLYVAL_ASM_THUMB2
20957
        if (fn == &AES_GCMSIV_polyval_thumb2) {
20958
            /* Table variant: build the word64 software table and point at it. */
20959
            AesGcmSivPolyvalInitSw(poly, h);
20960
            poly->asmKey = (const byte*)poly->m;
20961
            poly->fn = fn;
20962
            return;
20963
        }
20964
#endif
20965
        {
20966
            byte t[WC_AES_BLOCK_SIZE];
20967
        #ifdef WOLFSSL_CHECK_MEM_ZERO
20968
            /* t will hold the prepared hash key; register from the top
20969
             * (baseline keeps it defined) so every exit of this block reaches
20970
             * the ForceZero+Check below. */
20971
            XMEMSET(t, 0, sizeof(t));
20972
            wc_MemZero_Add("AesGcmSivPolyvalInit t", t, sizeof(t));
20973
        #endif
20974
            /* Prepare the hash key for the asm: byte-reversed
20975
             * mulX_GHASH(ByteReverse(h)). */
20976
            AesGcmSivByteReverse(t, h);
20977
            AesGcmSivMulX(t);
20978
            AesGcmSivByteReverse(poly->hHw, t);
20979
            XMEMSET(poly->s, 0, sizeof(poly->s));
20980
            poly->asmKey = poly->hHw;
20981
            poly->fn = fn;
20982
            /* t held the prepared hash key; wipe the stack copy. */
20983
            ForceZero(t, sizeof(t));
20984
        #ifdef WOLFSSL_CHECK_MEM_ZERO
20985
            wc_MemZero_Check(t, sizeof(t));
20986
        #endif
20987
        }
20988
        return;
20989
    }
20990
    poly->fn = NULL;
20991
#endif
20992
    AesGcmSivPolyvalInitSw(poly, h);
20993
}
20994
20995
/* Add data to the POLYVAL sum. A trailing partial block is zero-padded to a
20996
 * full block, which is exactly the padding RFC 8452 applies to the AAD and
20997
 * the plaintext independently. */
20998
static void AesGcmSivPolyvalUpdate(AesGcmSivPolyval* poly, const byte* data,
20999
    word32 sz)
21000
{
21001
    byte block[WC_AES_BLOCK_SIZE];
21002
    byte rev[WC_AES_BLOCK_SIZE];
21003
    int k;
21004
21005
#ifdef WOLFSSL_CHECK_MEM_ZERO
21006
    /* block holds a padded AAD/plaintext block/tail in both the asm and the
21007
     * scalar path; register from the top (baseline keeps it defined) so every
21008
     * exit reaches a ForceZero+Check. */
21009
    XMEMSET(block, 0, sizeof(block));
21010
    wc_MemZero_Add("AesGcmSivPolyvalUpdate block", block, sizeof(block));
21011
#endif
21012
21013
#ifdef WC_POLYVAL_ASM
21014
    if (poly->fn != NULL) {
21015
        word32 blocks = sz / WC_AES_BLOCK_SIZE;
21016
        word32 partial = sz % WC_AES_BLOCK_SIZE;
21017
        if (blocks > 0) {
21018
            poly->fn(poly->s, poly->asmKey, data, blocks);
21019
            data += blocks * WC_AES_BLOCK_SIZE;
21020
        }
21021
        if (partial > 0) {
21022
            XMEMSET(block, 0, sizeof(block));
21023
            XMEMCPY(block, data, partial);
21024
            poly->fn(poly->s, poly->asmKey, block, 1);
21025
        }
21026
        /* block may have held a padded AAD/plaintext tail; wipe it. */
21027
        ForceZero(block, sizeof(block));
21028
    #ifdef WOLFSSL_CHECK_MEM_ZERO
21029
        wc_MemZero_Check(block, sizeof(block));
21030
    #endif
21031
        return;
21032
    }
21033
#endif
21034
#ifdef WOLFSSL_CHECK_MEM_ZERO
21035
    /* rev holds a byte-reversed AAD/plaintext block; only the scalar path uses
21036
     * it, so register it here (baseline covers the sz == 0 case). */
21037
    XMEMSET(rev, 0, sizeof(rev));
21038
    wc_MemZero_Add("AesGcmSivPolyvalUpdate rev", rev, sizeof(rev));
21039
#endif
21040
    while (sz >= WC_AES_BLOCK_SIZE) {
21041
        AesGcmSivByteReverse(rev, data);
21042
        for (k = 0; k < WC_AES_BLOCK_SIZE; k++) {
21043
            poly->s[k] ^= rev[k];
21044
        }
21045
        AesGcmSivGMult(poly);
21046
        data += WC_AES_BLOCK_SIZE;
21047
        sz   -= WC_AES_BLOCK_SIZE;
21048
    }
21049
    if (sz > 0) {
21050
        XMEMSET(block, 0, sizeof(block));
21051
        XMEMCPY(block, data, sz);
21052
        AesGcmSivByteReverse(rev, block);
21053
        for (k = 0; k < WC_AES_BLOCK_SIZE; k++) {
21054
            poly->s[k] ^= rev[k];
21055
        }
21056
        AesGcmSivGMult(poly);
21057
    }
21058
    /* block/rev held byte-reversed AAD/plaintext blocks; wipe them. */
21059
    ForceZero(block, sizeof(block));
21060
    ForceZero(rev, sizeof(rev));
21061
#ifdef WOLFSSL_CHECK_MEM_ZERO
21062
    wc_MemZero_Check(block, sizeof(block));
21063
    wc_MemZero_Check(rev, sizeof(rev));
21064
#endif
21065
}
21066
21067
/* Output the 16-byte POLYVAL result and wipe the key material and state. */
21068
static void AesGcmSivPolyvalFinal(AesGcmSivPolyval* poly, byte* out)
21069
{
21070
    AesGcmSivByteReverse(out, poly->s);
21071
    ForceZero(poly, sizeof(*poly));
21072
}
21073
21074
/* Derive the message-authentication-key and message-encryption-key from the
21075
 * key-generating-key (loaded into kgk) and the nonce. See RFC 8452 Section 4.
21076
 *
21077
 * authKey is 16 bytes; encKey is keySz bytes (16 or 32). */
21078
static WARN_UNUSED_RESULT int AesGcmSivDeriveKeys(Aes* kgk, const byte* nonce,
21079
    word32 keySz, byte* authKey, byte* encKey)
21080
{
21081
    byte block[WC_AES_BLOCK_SIZE];
21082
    byte out[WC_AES_BLOCK_SIZE];
21083
    word32 ctr;
21084
    word32 encBlocks = keySz / 8; /* 2 for AES-128, 4 for AES-256 */
21085
    int ret = 0;
21086
21087
    /* Each derivation block is: LE32(counter) || nonce(12 bytes). The low 8
21088
     * bytes of each AES output are concatenated to form the derived keys. */
21089
    XMEMCPY(block + 4, nonce, AES_GCM_SIV_NONCE_SZ);
21090
21091
#ifdef WOLFSSL_CHECK_MEM_ZERO
21092
    /* out receives the derived auth/enc key bytes from each AES block. */
21093
    XMEMSET(out, 0xff, sizeof(out));
21094
    wc_MemZero_Add("AesGcmSivDeriveKeys out", out, sizeof(out));
21095
#endif
21096
21097
    for (ctr = 0; ctr < 2; ctr++) {
21098
        block[0] = (byte)ctr;
21099
        block[1] = 0; block[2] = 0; block[3] = 0;
21100
        ret = wc_AesEncrypt(kgk, block, out);
21101
        if (ret != 0)
21102
            break;
21103
        XMEMCPY(authKey + ctr * 8, out, 8);
21104
    }
21105
21106
    for (ctr = 0; (ret == 0) && (ctr < encBlocks); ctr++) {
21107
        block[0] = (byte)(ctr + 2);
21108
        block[1] = 0; block[2] = 0; block[3] = 0;
21109
        ret = wc_AesEncrypt(kgk, block, out);
21110
        if (ret != 0)
21111
            break;
21112
        XMEMCPY(encKey + ctr * 8, out, 8);
21113
    }
21114
21115
    ForceZero(block, sizeof(block));
21116
    ForceZero(out, sizeof(out));
21117
#ifdef WOLFSSL_CHECK_MEM_ZERO
21118
    wc_MemZero_Check(out, sizeof(out));
21119
#endif
21120
21121
    return ret;
21122
}
21123
21124
/* Compute the AES-GCM-SIV tag over the AAD and plaintext. enc holds the
21125
 * message-encryption-key. See RFC 8452 Section 4. */
21126
static WARN_UNUSED_RESULT int AesGcmSivCalcTag(Aes* enc, const byte* authKey,
21127
    const byte* nonce, const byte* aad, word32 aadSz, const byte* plain,
21128
    word32 plainSz, byte* tag)
21129
{
21130
    AesGcmSivPolyval poly;
21131
    byte lenBlock[WC_AES_BLOCK_SIZE];
21132
    byte s[WC_AES_BLOCK_SIZE];
21133
    /* Bit lengths (sz * 8) as 64-bit values, computed without needing a
21134
     * 64-bit type: low 32 bits and the 3 bits that carry into the next word. */
21135
    word32 aadLo = aadSz << 3, aadHi = aadSz >> 29;
21136
    word32 ptLo  = plainSz << 3, ptHi = plainSz >> 29;
21137
    int i;
21138
    int ret;
21139
21140
#ifdef WOLFSSL_CHECK_MEM_ZERO
21141
    /* s holds the POLYVAL result then the pre-encryption tag input. Register
21142
     * from the top (single exit funnels to the ForceZero+Check below);
21143
     * baseline keeps it defined for the checker. */
21144
    XMEMSET(s, 0, sizeof(s));
21145
    wc_MemZero_Add("AesGcmSivCalcTag s", s, sizeof(s));
21146
#endif
21147
21148
    AesGcmSivPolyvalInit(&poly, authKey);
21149
    AesGcmSivPolyvalUpdate(&poly, aad, aadSz);
21150
    AesGcmSivPolyvalUpdate(&poly, plain, plainSz);
21151
21152
    /* Length block: LE64(aad_bits) || LE64(plaintext_bits). */
21153
    lenBlock[0]  = (byte)aadLo; lenBlock[1] = (byte)(aadLo >> 8);
21154
    lenBlock[2]  = (byte)(aadLo >> 16); lenBlock[3] = (byte)(aadLo >> 24);
21155
    lenBlock[4]  = (byte)aadHi; lenBlock[5] = (byte)(aadHi >> 8);
21156
    lenBlock[6]  = (byte)(aadHi >> 16); lenBlock[7] = (byte)(aadHi >> 24);
21157
    lenBlock[8]  = (byte)ptLo; lenBlock[9] = (byte)(ptLo >> 8);
21158
    lenBlock[10] = (byte)(ptLo >> 16); lenBlock[11] = (byte)(ptLo >> 24);
21159
    lenBlock[12] = (byte)ptHi; lenBlock[13] = (byte)(ptHi >> 8);
21160
    lenBlock[14] = (byte)(ptHi >> 16); lenBlock[15] = (byte)(ptHi >> 24);
21161
    AesGcmSivPolyvalUpdate(&poly, lenBlock, WC_AES_BLOCK_SIZE);
21162
21163
    AesGcmSivPolyvalFinal(&poly, s);
21164
21165
    /* XOR the nonce into the first 12 bytes and clear the top bit of the
21166
     * last byte, then encrypt to produce the tag. */
21167
    for (i = 0; i < AES_GCM_SIV_NONCE_SZ; i++) {
21168
        s[i] ^= nonce[i];
21169
    }
21170
    s[WC_AES_BLOCK_SIZE - 1] &= 0x7f;
21171
21172
    ret = wc_AesEncrypt(enc, s, tag);
21173
21174
    ForceZero(s, sizeof(s));
21175
#ifdef WOLFSSL_CHECK_MEM_ZERO
21176
    wc_MemZero_Check(s, sizeof(s));
21177
#endif
21178
    return ret;
21179
}
21180
21181
/* Apply AES-GCM-SIV's counter mode to in, producing out. enc holds the
21182
 * message-encryption-key, tag is the 16-byte authentication tag. The counter
21183
 * is the tag with the top bit of the last byte set; only the first 4 bytes
21184
 * are incremented, as a little-endian 32-bit value, wrapping modulo 2^32.
21185
 * See RFC 8452 Section 4. */
21186
static WARN_UNUSED_RESULT int AesGcmSivCtr(Aes* enc, const byte* tag,
21187
    const byte* in, word32 sz, byte* out)
21188
{
21189
    byte ctrBlock[WC_AES_BLOCK_SIZE];
21190
    byte ks[WC_AES_BLOCK_SIZE];
21191
    word32 c;
21192
    int ret = 0;
21193
21194
#ifdef WOLFSSL_CHECK_MEM_ZERO
21195
    /* ks holds the AES-CTR keystream block; register from the top (single
21196
     * exit funnels to the ForceZero+Check below). */
21197
    XMEMSET(ks, 0, sizeof(ks));
21198
    wc_MemZero_Add("AesGcmSivCtr ks", ks, sizeof(ks));
21199
#endif
21200
21201
    XMEMCPY(ctrBlock, tag, WC_AES_BLOCK_SIZE);
21202
    ctrBlock[WC_AES_BLOCK_SIZE - 1] |= 0x80;
21203
21204
#ifdef WC_GCMSIV_CTR_ASM
21205
    /* Offload the full-block keystream to the pipelined assembly; it advances
21206
     * and writes ctrBlock back. The final partial block (if any) is finished by
21207
     * the scalar loop below. */
21208
    {
21209
        AesGcmSivCtrFn fn = AesGcmSivCtrAsm();
21210
        if (fn != NULL) {
21211
            word32 full = sz & ~(word32)(WC_AES_BLOCK_SIZE - 1);
21212
            if (full > 0) {
21213
                fn(in, out, (unsigned long)full, (const byte*)enc->key,
21214
                    (int)enc->rounds, ctrBlock);
21215
                in  += full;
21216
                out += full;
21217
                sz  -= full;
21218
            }
21219
        }
21220
    }
21221
#endif
21222
21223
    c = (word32)ctrBlock[0]        | ((word32)ctrBlock[1] << 8) |
21224
        ((word32)ctrBlock[2] << 16) | ((word32)ctrBlock[3] << 24);
21225
21226
    while (sz > 0) {
21227
        word32 n = (sz < WC_AES_BLOCK_SIZE) ? sz : (word32)WC_AES_BLOCK_SIZE;
21228
        word32 i;
21229
21230
        ret = wc_AesEncrypt(enc, ctrBlock, ks);
21231
        if (ret != 0)
21232
            break;
21233
        for (i = 0; i < n; i++) {
21234
            out[i] = (byte)(in[i] ^ ks[i]);
21235
        }
21236
21237
        in  += n;
21238
        out += n;
21239
        sz  -= n;
21240
21241
        c++;
21242
        ctrBlock[0] = (byte)c;         ctrBlock[1] = (byte)(c >> 8);
21243
        ctrBlock[2] = (byte)(c >> 16); ctrBlock[3] = (byte)(c >> 24);
21244
    }
21245
21246
    ForceZero(ks, sizeof(ks));
21247
    ForceZero(ctrBlock, sizeof(ctrBlock));
21248
#ifdef WOLFSSL_CHECK_MEM_ZERO
21249
    wc_MemZero_Check(ks, sizeof(ks));
21250
#endif
21251
    return ret;
21252
}
21253
21254
/* Common validation for the encrypt/decrypt entry points. */
21255
static WARN_UNUSED_RESULT int AesGcmSivCheckArgs(const byte* key, word32 keySz,
21256
    const byte* nonce, word32 nonceSz, const byte* aad, word32 aadSz,
21257
    const byte* in, word32 inSz, const byte* out, const byte* tag,
21258
    word32 tagSz)
21259
{
21260
    if (key == NULL || nonce == NULL || tag == NULL) {
21261
        return BAD_FUNC_ARG;
21262
    }
21263
    if ((inSz != 0) && ((in == NULL) || (out == NULL))) {
21264
        return BAD_FUNC_ARG;
21265
    }
21266
    if ((aadSz != 0) && (aad == NULL)) {
21267
        return BAD_FUNC_ARG;
21268
    }
21269
    if ((keySz != 16) && (keySz != 32)) {
21270
        return BAD_FUNC_ARG;
21271
    }
21272
    if (nonceSz != AES_GCM_SIV_NONCE_SZ) {
21273
        return BAD_FUNC_ARG;
21274
    }
21275
    if (tagSz != AES_GCM_SIV_TAG_SZ) {
21276
        return BAD_FUNC_ARG;
21277
    }
21278
    return 0;
21279
}
21280
21281
/*
21282
 * Encrypt with AES-GCM-SIV. See RFC 8452 Section 4.
21283
 *
21284
 * out receives inSz bytes of ciphertext; tag receives the 16-byte tag.
21285
 */
21286
int wc_AesGcmSivEncrypt(const byte* key, word32 keySz, const byte* nonce,
21287
    word32 nonceSz, const byte* aad, word32 aadSz, const byte* in,
21288
    word32 inSz, byte* out, byte* tag, word32 tagSz)
21289
{
21290
    WC_DECLARE_VAR(aes, Aes, 1, 0);
21291
    byte authKey[WC_AES_BLOCK_SIZE];
21292
    byte encKey[32];
21293
    byte tagTmp[AES_GCM_SIV_TAG_SZ];
21294
    int ret;
21295
21296
#ifdef WOLFSSL_CHECK_MEM_ZERO
21297
    /* Derived per-message MAC key, encryption key, and tag. Register from the
21298
     * top; every exit funnels to the shared ForceZero+Check block below. */
21299
    XMEMSET(authKey, 0, sizeof(authKey));
21300
    XMEMSET(encKey, 0, sizeof(encKey));
21301
    XMEMSET(tagTmp, 0, sizeof(tagTmp));
21302
    wc_MemZero_Add("wc_AesGcmSivEncrypt authKey", authKey, sizeof(authKey));
21303
    wc_MemZero_Add("wc_AesGcmSivEncrypt encKey", encKey, sizeof(encKey));
21304
    wc_MemZero_Add("wc_AesGcmSivEncrypt tagTmp", tagTmp, sizeof(tagTmp));
21305
#endif
21306
21307
    ret = AesGcmSivCheckArgs(key, keySz, nonce, nonceSz, aad, aadSz, in, inSz,
21308
                             out, tag, tagSz);
21309
21310
    if (ret == 0) {
21311
    #ifdef WOLFSSL_SMALL_STACK
21312
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
21313
    #else
21314
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
21315
    #endif
21316
    }
21317
21318
    if (ret == 0) {
21319
        /* Load the key-generating-key and derive the per-message keys. */
21320
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
21321
        if (ret == 0) {
21322
            ret = AesGcmSivDeriveKeys(aes, nonce, keySz, authKey, encKey);
21323
        }
21324
        /* Switch the AES object to the message-encryption-key. */
21325
        if (ret == 0) {
21326
            ret = wc_AesSetKey(aes, encKey, keySz, NULL, AES_ENCRYPTION);
21327
        }
21328
        /* Tag is computed over the plaintext, then the plaintext is
21329
         * encrypted with the tag-derived counter. */
21330
        if (ret == 0) {
21331
            ret = AesGcmSivCalcTag(aes, authKey, nonce, aad, aadSz, in, inSz,
21332
                                   tagTmp);
21333
        }
21334
        if (ret == 0) {
21335
            ret = AesGcmSivCtr(aes, tagTmp, in, inSz, out);
21336
        }
21337
        if (ret == 0) {
21338
            XMEMCPY(tag, tagTmp, AES_GCM_SIV_TAG_SZ);
21339
        }
21340
21341
    #ifdef WOLFSSL_SMALL_STACK
21342
        wc_AesDelete(aes, NULL);
21343
    #else
21344
        wc_AesFree(aes);
21345
    #endif
21346
    }
21347
21348
    ForceZero(authKey, sizeof(authKey));
21349
    ForceZero(encKey, sizeof(encKey));
21350
    ForceZero(tagTmp, sizeof(tagTmp));
21351
#ifdef WOLFSSL_CHECK_MEM_ZERO
21352
    wc_MemZero_Check(authKey, sizeof(authKey));
21353
    wc_MemZero_Check(encKey, sizeof(encKey));
21354
    wc_MemZero_Check(tagTmp, sizeof(tagTmp));
21355
#endif
21356
21357
    return ret;
21358
}
21359
21360
/*
21361
 * Decrypt with AES-GCM-SIV. See RFC 8452 Section 4.
21362
 *
21363
 * in is inSz bytes of ciphertext, tag is the received 16-byte tag. On a
21364
 * successful authentication out receives inSz bytes of plaintext; on failure
21365
 * out is zeroed and AES_GCM_AUTH_E is returned.
21366
 */
21367
int wc_AesGcmSivDecrypt(const byte* key, word32 keySz, const byte* nonce,
21368
    word32 nonceSz, const byte* aad, word32 aadSz, const byte* in,
21369
    word32 inSz, byte* out, const byte* tag, word32 tagSz)
21370
{
21371
    WC_DECLARE_VAR(aes, Aes, 1, 0);
21372
    byte authKey[WC_AES_BLOCK_SIZE];
21373
    byte encKey[32];
21374
    byte expTag[AES_GCM_SIV_TAG_SZ];
21375
    int ret;
21376
21377
#ifdef WOLFSSL_CHECK_MEM_ZERO
21378
    /* Derived per-message MAC key, encryption key, and recomputed tag.
21379
     * Register from the top; every exit funnels to the shared ForceZero+Check
21380
     * block below. */
21381
    XMEMSET(authKey, 0, sizeof(authKey));
21382
    XMEMSET(encKey, 0, sizeof(encKey));
21383
    XMEMSET(expTag, 0, sizeof(expTag));
21384
    wc_MemZero_Add("wc_AesGcmSivDecrypt authKey", authKey, sizeof(authKey));
21385
    wc_MemZero_Add("wc_AesGcmSivDecrypt encKey", encKey, sizeof(encKey));
21386
    wc_MemZero_Add("wc_AesGcmSivDecrypt expTag", expTag, sizeof(expTag));
21387
#endif
21388
21389
    ret = AesGcmSivCheckArgs(key, keySz, nonce, nonceSz, aad, aadSz, in, inSz,
21390
                             out, tag, tagSz);
21391
21392
    if (ret == 0) {
21393
    #ifdef WOLFSSL_SMALL_STACK
21394
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
21395
    #else
21396
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
21397
    #endif
21398
    }
21399
21400
    if (ret == 0) {
21401
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
21402
        if (ret == 0) {
21403
            ret = AesGcmSivDeriveKeys(aes, nonce, keySz, authKey, encKey);
21404
        }
21405
        if (ret == 0) {
21406
            ret = wc_AesSetKey(aes, encKey, keySz, NULL, AES_ENCRYPTION);
21407
        }
21408
        /* Recover the plaintext, then recompute and verify the tag over it. */
21409
        if (ret == 0) {
21410
            ret = AesGcmSivCtr(aes, tag, in, inSz, out);
21411
        }
21412
        if (ret == 0) {
21413
            ret = AesGcmSivCalcTag(aes, authKey, nonce, aad, aadSz, out, inSz,
21414
                                   expTag);
21415
        }
21416
        if (ret == 0) {
21417
            if (ConstantCompare(expTag, tag, AES_GCM_SIV_TAG_SZ) != 0) {
21418
                ret = AES_GCM_AUTH_E;
21419
            }
21420
        }
21421
        if (ret != 0) {
21422
            ForceZero(out, inSz);
21423
        }
21424
21425
    #ifdef WOLFSSL_SMALL_STACK
21426
        wc_AesDelete(aes, NULL);
21427
    #else
21428
        wc_AesFree(aes);
21429
    #endif
21430
    }
21431
21432
    ForceZero(authKey, sizeof(authKey));
21433
    ForceZero(encKey, sizeof(encKey));
21434
    ForceZero(expTag, sizeof(expTag));
21435
#ifdef WOLFSSL_CHECK_MEM_ZERO
21436
    wc_MemZero_Check(authKey, sizeof(authKey));
21437
    wc_MemZero_Check(encKey, sizeof(encKey));
21438
    wc_MemZero_Check(expTag, sizeof(expTag));
21439
#endif
21440
21441
    return ret;
21442
}
21443
21444
#endif /* WOLFSSL_AESGCM_SIV */
21445
21446
#if defined(WOLFSSL_AES_EAX)
21447
21448
/*
21449
 * AES EAX one-shot API
21450
 * Encrypts input data and computes an auth tag over the input
21451
 * auth data and ciphertext
21452
 *
21453
 * Returns 0 on success
21454
 * Returns error code on failure
21455
 */
21456
int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
21457
                          const byte* in, word32 inSz,
21458
                          const byte* nonce, word32 nonceSz,
21459
                          /* output computed auth tag */
21460
                          byte* authTag, word32 authTagSz,
21461
                          /* input data to authenticate */
21462
                          const byte* authIn, word32 authInSz)
21463
{
21464
#if defined(WOLFSSL_SMALL_STACK)
21465
    AesEax *eax;
21466
#else
21467
    AesEax eax_mem;
21468
    AesEax *eax = &eax_mem;
21469
#endif
21470
    int ret;
21471
    int eaxInited = 0;
21472
21473
    if (key == NULL || nonce == NULL || authTag == NULL
21474
            || (inSz > 0 && (out == NULL || in == NULL))
21475
            || (authInSz > 0 && authIn == NULL)) {
21476
        return BAD_FUNC_ARG;
21477
    }
21478
21479
#if defined(WOLFSSL_SMALL_STACK)
21480
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
21481
                                 NULL,
21482
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
21483
        return MEMORY_E;
21484
    }
21485
#endif
21486
21487
    if ((ret = wc_AesEaxInit(eax,
21488
                             key, keySz,
21489
                             nonce, nonceSz,
21490
                             authIn, authInSz)) != 0) {
21491
        goto cleanup;
21492
    }
21493
    eaxInited = 1;
21494
21495
    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
21496
        goto cleanup;
21497
    }
21498
21499
    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
21500
        goto cleanup;
21501
    }
21502
21503
cleanup:
21504
    if (eaxInited)
21505
        wc_AesEaxFree(eax);
21506
#if defined(WOLFSSL_SMALL_STACK)
21507
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
21508
#endif
21509
    return ret;
21510
}
21511
21512
21513
/*
21514
 * AES EAX one-shot API
21515
 * Decrypts and authenticates data against a supplied auth tag
21516
 *
21517
 * Returns 0 on success
21518
 * Returns error code on failure
21519
 */
21520
int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
21521
                          const byte* in, word32 inSz,
21522
                          const byte* nonce, word32 nonceSz,
21523
                          /* auth tag to verify against */
21524
                          const byte* authTag, word32 authTagSz,
21525
                          /* input data to authenticate */
21526
                          const byte* authIn, word32 authInSz)
21527
{
21528
#if defined(WOLFSSL_SMALL_STACK)
21529
    AesEax *eax;
21530
#else
21531
    AesEax eax_mem;
21532
    AesEax *eax = &eax_mem;
21533
#endif
21534
    int ret;
21535
    int eaxInited = 0;
21536
21537
    if (key == NULL || nonce == NULL || authTag == NULL
21538
            || (inSz > 0 && (out == NULL || in == NULL))
21539
            || (authInSz > 0 && authIn == NULL)) {
21540
        return BAD_FUNC_ARG;
21541
    }
21542
21543
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ
21544
            || authTagSz > WC_AES_BLOCK_SIZE) {
21545
        return BAD_FUNC_ARG;
21546
    }
21547
21548
#if defined(WOLFSSL_SMALL_STACK)
21549
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
21550
                                 NULL,
21551
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
21552
        return MEMORY_E;
21553
    }
21554
#endif
21555
21556
    if ((ret = wc_AesEaxInit(eax,
21557
                             key, keySz,
21558
                             nonce, nonceSz,
21559
                             authIn, authInSz)) != 0) {
21560
21561
        goto cleanup;
21562
    }
21563
    eaxInited = 1;
21564
21565
    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
21566
        goto cleanup;
21567
    }
21568
21569
    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
21570
        goto cleanup;
21571
    }
21572
21573
cleanup:
21574
    if (eaxInited)
21575
        wc_AesEaxFree(eax);
21576
#if defined(WOLFSSL_SMALL_STACK)
21577
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
21578
#endif
21579
    return ret;
21580
}
21581
21582
21583
/*
21584
 * AES EAX Incremental API:
21585
 * Initializes an AES EAX encryption or decryption operation. This must be
21586
 * called before any other EAX APIs are used on the AesEax struct
21587
 *
21588
 * Returns 0 on success
21589
 * Returns error code on failure
21590
 */
21591
int  wc_AesEaxInit(AesEax* eax,
21592
                   const byte* key, word32 keySz,
21593
                   const byte* nonce, word32 nonceSz,
21594
                   const byte* authIn, word32 authInSz)
21595
{
21596
    int ret = 0;
21597
    word32 cmacSize;
21598
    int aesInited = 0;
21599
    int nonceCmacInited = 0;
21600
    int aadCmacInited = 0;
21601
21602
    if (eax == NULL || key == NULL ||  nonce == NULL) {
21603
        return BAD_FUNC_ARG;
21604
    }
21605
21606
    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
21607
21608
    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
21609
        goto out;
21610
    }
21611
    aesInited = 1;
21612
21613
    if ((ret = wc_AesSetKey(&eax->aes,
21614
                            key,
21615
                            keySz,
21616
                            NULL,
21617
                            AES_ENCRYPTION)) != 0) {
21618
        goto out;
21619
    }
21620
21621
    /*
21622
    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
21623
    *   N' = OMAC^0_K(N)
21624
    */
21625
    if ((ret = wc_InitCmac(&eax->nonceCmac,
21626
                           key,
21627
                           keySz,
21628
                           WC_CMAC_AES,
21629
                           NULL)) != 0) {
21630
        return ret;
21631
    }
21632
    nonceCmacInited = 1;
21633
21634
    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
21635
                             eax->prefixBuf,
21636
                             sizeof(eax->prefixBuf))) != 0) {
21637
        goto out;
21638
    }
21639
21640
    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
21641
        goto out;
21642
    }
21643
21644
    cmacSize = WC_AES_BLOCK_SIZE;
21645
    if ((ret = wc_CmacFinal(&eax->nonceCmac,
21646
                            eax->nonceCmacFinal,
21647
                            &cmacSize)) != 0) {
21648
        goto out;
21649
    }
21650
21651
    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
21652
        goto out;
21653
    }
21654
21655
    /*
21656
     * start the OMAC used to build the auth tag chunk for the AD .
21657
     * This CMAC is continued in subsequent update calls when more auth data is
21658
     * provided
21659
     *   H' = OMAC^1_K(H)
21660
     */
21661
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 1;
21662
    if ((ret = wc_InitCmac(&eax->aadCmac,
21663
                           key,
21664
                           keySz,
21665
                           WC_CMAC_AES,
21666
                           NULL)) != 0) {
21667
        goto out;
21668
    }
21669
    aadCmacInited = 1;
21670
21671
    if ((ret = wc_CmacUpdate(&eax->aadCmac,
21672
                             eax->prefixBuf,
21673
                             sizeof(eax->prefixBuf))) != 0) {
21674
        goto out;
21675
    }
21676
21677
    if (authIn != NULL) {
21678
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
21679
            goto out;
21680
        }
21681
    }
21682
21683
    /*
21684
     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
21685
     * updated in subsequent calls to encrypt/decrypt
21686
     *  C' = OMAC^2_K(C)
21687
     */
21688
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 2;
21689
    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
21690
                           key,
21691
                           keySz,
21692
                           WC_CMAC_AES,
21693
                           NULL)) != 0) {
21694
        goto out;
21695
    }
21696
21697
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
21698
                             eax->prefixBuf,
21699
                             sizeof(eax->prefixBuf))) != 0) {
21700
        goto out;
21701
    }
21702
21703
out:
21704
21705
    if (ret != 0) {
21706
        if (aesInited)
21707
            wc_AesFree(&eax->aes);
21708
        if (nonceCmacInited)
21709
            wc_CmacFree(&eax->nonceCmac);
21710
        if (aadCmacInited)
21711
            wc_CmacFree(&eax->aadCmac);
21712
    }
21713
21714
    return ret;
21715
}
21716
21717
21718
/*
21719
 * AES EAX Incremental API:
21720
 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
21721
 * the authentication stream
21722
 *
21723
 * Returns 0 on success
21724
 * Returns error code on failure
21725
 */
21726
int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
21727
                            const byte* in, word32 inSz,
21728
                            const byte* authIn, word32 authInSz)
21729
{
21730
    int ret;
21731
21732
    if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))
21733
            || (authInSz > 0 && authIn == NULL)) {
21734
        return BAD_FUNC_ARG;
21735
    }
21736
21737
    if (inSz > 0) {
21738
        /*
21739
         * Encrypt the plaintext using AES CTR
21740
         *  C = CTR(M)
21741
         */
21742
        if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
21743
            return ret;
21744
        }
21745
21746
        /*
21747
         * update OMAC with new ciphertext
21748
         *  C' = OMAC^2_K(C)
21749
         */
21750
        if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
21751
            return ret;
21752
        }
21753
    }
21754
21755
    /* If there exists new auth data, update the OMAC for that as well */
21756
    if (authIn != NULL) {
21757
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
21758
            return ret;
21759
        }
21760
    }
21761
21762
    return 0;
21763
}
21764
21765
21766
/*
21767
 * AES EAX Incremental API:
21768
 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
21769
 * the authentication stream
21770
 *
21771
 * Returns 0 on success
21772
 * Returns error code on failure
21773
 */
21774
int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
21775
                            const byte* in, word32 inSz,
21776
                            const byte* authIn, word32 authInSz)
21777
{
21778
    int ret;
21779
21780
    if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))
21781
            || (authInSz > 0 && authIn == NULL)) {
21782
        return BAD_FUNC_ARG;
21783
    }
21784
21785
    if (inSz > 0) {
21786
        /*
21787
         * Decrypt the plaintext using AES CTR
21788
         *  C = CTR(M)
21789
         */
21790
        if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
21791
            return ret;
21792
        }
21793
21794
        /*
21795
         * update OMAC with new ciphertext
21796
         *  C' = OMAC^2_K(C)
21797
         */
21798
        if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
21799
            return ret;
21800
        }
21801
    }
21802
21803
    /* If there exists new auth data, update the OMAC for that as well */
21804
    if (authIn != NULL) {
21805
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
21806
            return ret;
21807
        }
21808
    }
21809
21810
    return 0;
21811
}
21812
21813
21814
/*
21815
 * AES EAX Incremental API:
21816
 * Provides additional auth data information to the authentication
21817
 * stream for an authenticated encryption or decryption operation
21818
 *
21819
 * Returns 0 on success
21820
 * Returns error code on failure
21821
 */
21822
int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
21823
{
21824
    if (eax == NULL) {
21825
        return BAD_FUNC_ARG;
21826
    }
21827
    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
21828
}
21829
21830
21831
/*
21832
 * AES EAX Incremental API:
21833
 * Finalizes the authenticated encryption operation, computing the auth tag
21834
 * over previously supplied auth data and computed ciphertext
21835
 *
21836
 * Returns 0 on success
21837
 * Returns error code on failure
21838
 */
21839
int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
21840
{
21841
    word32 cmacSize;
21842
    int ret;
21843
    word32 i;
21844
21845
    if (eax == NULL || authTag == NULL || authTagSz == 0 ||
21846
            authTagSz > WC_AES_BLOCK_SIZE || authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
21847
        return BAD_FUNC_ARG;
21848
    }
21849
21850
    /* Complete the OMAC for the ciphertext */
21851
    cmacSize = WC_AES_BLOCK_SIZE;
21852
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
21853
                                  eax->ciphertextCmacFinal,
21854
                                  &cmacSize)) != 0) {
21855
        return ret;
21856
    }
21857
21858
    /* Complete the OMAC for auth data */
21859
    cmacSize = WC_AES_BLOCK_SIZE;
21860
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
21861
                                  eax->aadCmacFinal,
21862
                                  &cmacSize)) != 0) {
21863
        return ret;
21864
    }
21865
21866
    /*
21867
     * Concatenate all three auth tag chunks into the final tag, truncating
21868
     * at the specified tag length
21869
     *   T = Tag [first authTagSz bytes]
21870
     */
21871
    for (i = 0; i < authTagSz; i++) {
21872
        authTag[i] = eax->nonceCmacFinal[i]
21873
                    ^ eax->aadCmacFinal[i]
21874
                    ^ eax->ciphertextCmacFinal[i];
21875
    }
21876
21877
    return 0;
21878
}
21879
21880
21881
/*
21882
 * AES EAX Incremental API:
21883
 * Finalizes the authenticated decryption operation, computing the auth tag
21884
 * for the previously supplied auth data and cipher text and validating it
21885
 * against a provided auth tag
21886
 *
21887
 * Returns 0 on success
21888
 * Return error code for failure
21889
 */
21890
int wc_AesEaxDecryptFinal(AesEax* eax,
21891
                          const byte* authIn, word32 authInSz)
21892
{
21893
    int ret;
21894
    word32 i;
21895
    word32 cmacSize;
21896
21897
#if defined(WOLFSSL_SMALL_STACK)
21898
    byte *authTag;
21899
#else
21900
    byte authTag[WC_AES_BLOCK_SIZE];
21901
#endif
21902
21903
    if (eax == NULL || authIn == NULL || authInSz > WC_AES_BLOCK_SIZE
21904
            || authInSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
21905
        return BAD_FUNC_ARG;
21906
    }
21907
21908
    /* Complete the OMAC for the ciphertext */
21909
    cmacSize = WC_AES_BLOCK_SIZE;
21910
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
21911
                                  eax->ciphertextCmacFinal,
21912
                                  &cmacSize)) != 0) {
21913
        return ret;
21914
    }
21915
21916
    /* Complete the OMAC for auth data */
21917
    cmacSize = WC_AES_BLOCK_SIZE;
21918
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
21919
                                  eax->aadCmacFinal,
21920
                                  &cmacSize)) != 0) {
21921
        return ret;
21922
    }
21923
21924
#if defined(WOLFSSL_SMALL_STACK)
21925
    authTag = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21926
    if (authTag == NULL) {
21927
        return MEMORY_E;
21928
    }
21929
#endif
21930
21931
    /*
21932
     * Concatenate all three auth tag chunks into the final tag, truncating
21933
     * at the specified tag length
21934
     *   T = Tag [first authInSz bytes]
21935
     */
21936
    for (i = 0; i < authInSz; i++) {
21937
        authTag[i] = eax->nonceCmacFinal[i]
21938
                    ^ eax->aadCmacFinal[i]
21939
                    ^ eax->ciphertextCmacFinal[i];
21940
    }
21941
21942
    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
21943
        ret = AES_EAX_AUTH_E;
21944
    }
21945
    else {
21946
        ret = 0;
21947
    }
21948
21949
#if defined(WOLFSSL_SMALL_STACK)
21950
    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21951
#endif
21952
21953
    return ret;
21954
}
21955
21956
/*
21957
 * Frees the underlying CMAC and AES contexts. Must be called when done using
21958
 * the AES EAX context structure.
21959
 *
21960
 * Returns 0 on success
21961
 * Returns error code on failure
21962
 */
21963
int wc_AesEaxFree(AesEax* eax)
21964
{
21965
    if (eax == NULL) {
21966
        return BAD_FUNC_ARG;
21967
    }
21968
21969
    (void)wc_CmacFree(&eax->ciphertextCmac);
21970
    (void)wc_CmacFree(&eax->aadCmac);
21971
    wc_AesFree(&eax->aes);
21972
21973
    return 0;
21974
}
21975
21976
#endif /* WOLFSSL_AES_EAX */
21977
21978
#ifdef WOLFSSL_AES_CTS
21979
21980
21981
/* One-shot API */
21982
int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out,
21983
                     const byte* in, word32 inSz,
21984
                     const byte* iv)
21985
{
21986
    WC_DECLARE_VAR(aes, Aes, 1, 0);
21987
    int ret = 0;
21988
    word32 outSz = inSz;
21989
21990
    if (key == NULL || out == NULL || in == NULL || iv == NULL)
21991
        return BAD_FUNC_ARG;
21992
21993
#ifdef WOLFSSL_SMALL_STACK
21994
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
21995
#else
21996
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
21997
#endif
21998
    if (ret == 0)
21999
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
22000
    if (ret == 0)
22001
        ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz);
22002
    if (ret == 0) {
22003
        out += outSz;
22004
        outSz = inSz - outSz;
22005
        ret = wc_AesCtsEncryptFinal(aes, out, &outSz);
22006
    }
22007
22008
#ifdef WOLFSSL_SMALL_STACK
22009
    wc_AesDelete(aes, NULL);
22010
#else
22011
    wc_AesFree(aes);
22012
#endif
22013
    return ret;
22014
}
22015
22016
int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out,
22017
                     const byte* in, word32 inSz,
22018
                     const byte* iv)
22019
{
22020
    WC_DECLARE_VAR(aes, Aes, 1, 0);
22021
    int ret = 0;
22022
    word32 outSz = inSz;
22023
22024
    if (key == NULL || out == NULL || in == NULL || iv == NULL) {
22025
        return BAD_FUNC_ARG;
22026
    }
22027
22028
#ifdef WOLFSSL_SMALL_STACK
22029
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
22030
#else
22031
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
22032
#endif
22033
    if (ret == 0)
22034
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
22035
    if (ret == 0)
22036
        ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz);
22037
    if (ret == 0) {
22038
        out += outSz;
22039
        outSz = inSz - outSz;
22040
        ret = wc_AesCtsDecryptFinal(aes, out, &outSz);
22041
    }
22042
22043
#ifdef WOLFSSL_SMALL_STACK
22044
    wc_AesDelete(aes, NULL);
22045
#else
22046
    wc_AesFree(aes);
22047
#endif
22048
    return ret;
22049
}
22050
22051
static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz,
22052
                        const byte* in, word32 inSz, int enc)
22053
{
22054
    word32 blocks = 0;
22055
    int ret = 0;
22056
    word32 writtenSz = 0;
22057
    word32 tmpOutSz;
22058
22059
    if (aes == NULL || out == NULL || in == NULL || outSz == NULL)
22060
        return BAD_FUNC_ARG;
22061
22062
    /* Error out early for easy sanity check */
22063
    if (*outSz < inSz)
22064
        return BUFFER_E;
22065
    tmpOutSz = *outSz;
22066
22067
    /* We need to store last two blocks of plaintext */
22068
    if (aes->left > 0) {
22069
        word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left);
22070
        XMEMCPY(aes->ctsBlock + aes->left, in, copySz);
22071
        aes->left += copySz;
22072
        in += copySz;
22073
        inSz -= copySz;
22074
22075
        if (aes->left == WC_AES_BLOCK_SIZE * 2) {
22076
            if (inSz > WC_AES_BLOCK_SIZE) {
22077
                if (tmpOutSz < WC_AES_BLOCK_SIZE * 2)
22078
                    return BUFFER_E;
22079
                if (enc) {
22080
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
22081
                                           WC_AES_BLOCK_SIZE * 2);
22082
                }
22083
                else {
22084
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
22085
                                           WC_AES_BLOCK_SIZE * 2);
22086
                }
22087
                if (ret != 0)
22088
                    return ret;
22089
                out += WC_AES_BLOCK_SIZE * 2;
22090
                writtenSz += WC_AES_BLOCK_SIZE * 2;
22091
                tmpOutSz -= WC_AES_BLOCK_SIZE * 2;
22092
                aes->left = 0;
22093
            }
22094
            else if (inSz > 0) {
22095
                if (tmpOutSz < WC_AES_BLOCK_SIZE)
22096
                    return BUFFER_E;
22097
                if (enc) {
22098
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
22099
                                           WC_AES_BLOCK_SIZE);
22100
                }
22101
                else {
22102
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
22103
                                           WC_AES_BLOCK_SIZE);
22104
                }
22105
                if (ret != 0)
22106
                    return ret;
22107
                out += WC_AES_BLOCK_SIZE;
22108
                writtenSz += WC_AES_BLOCK_SIZE;
22109
                tmpOutSz -= WC_AES_BLOCK_SIZE;
22110
                /* Move the last block in ctsBlock to the beginning for
22111
                 * next operation */
22112
                XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE,
22113
                        WC_AES_BLOCK_SIZE);
22114
                XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz);
22115
                aes->left = WC_AES_BLOCK_SIZE + inSz;
22116
                *outSz = writtenSz;
22117
                return ret; /* Return the result of encryption */
22118
            }
22119
            else {
22120
                /* Can't output data as we need > 1 block for Final call */
22121
                *outSz = writtenSz;
22122
                return 0;
22123
            }
22124
        }
22125
        else {
22126
            /* All input has been absorbed into aes->ctsBlock */
22127
            *outSz = 0;
22128
            return 0;
22129
        }
22130
    }
22131
    if (inSz > WC_AES_BLOCK_SIZE) {
22132
        /* We need to store the last two full or partial blocks */
22133
        blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE;
22134
        blocks -= 2;
22135
    }
22136
    if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE)
22137
        return BUFFER_E;
22138
    if (enc)
22139
        ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
22140
    else
22141
        ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
22142
    in += blocks * WC_AES_BLOCK_SIZE;
22143
    inSz -= blocks * WC_AES_BLOCK_SIZE;
22144
    XMEMCPY(aes->ctsBlock, in, inSz);
22145
    aes->left = inSz;
22146
    writtenSz += blocks * WC_AES_BLOCK_SIZE;
22147
    *outSz = writtenSz;
22148
    return ret;
22149
}
22150
22151
/* Incremental API */
22152
int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz,
22153
                           const byte* in, word32 inSz)
22154
{
22155
    return AesCtsUpdate(aes, out, outSz, in, inSz, 1);
22156
}
22157
22158
int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz)
22159
{
22160
    int ret = 0;
22161
22162
    if (aes == NULL || out == NULL || outSz == NULL)
22163
        return BAD_FUNC_ARG;
22164
    if (*outSz < aes->left)
22165
        return BUFFER_E;
22166
22167
    /* Input must be at least two complete or partial blocks */
22168
    if (aes->left <= WC_AES_BLOCK_SIZE)
22169
        return BAD_FUNC_ARG;
22170
22171
    /* Zero padding */
22172
    XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left);
22173
22174
    ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock,
22175
                           WC_AES_BLOCK_SIZE * 2);
22176
    if (ret != 0)
22177
        return ret;
22178
22179
    XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
22180
    XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock,
22181
            aes->left - WC_AES_BLOCK_SIZE);
22182
    *outSz = aes->left;
22183
    return ret;
22184
}
22185
22186
int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz,
22187
                           const byte* in, word32 inSz)
22188
{
22189
    return AesCtsUpdate(aes, out, outSz, in, inSz, 0);
22190
}
22191
22192
int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz)
22193
{
22194
    int ret = 0;
22195
    byte iv[WC_AES_BLOCK_SIZE];
22196
    byte tmp[WC_AES_BLOCK_SIZE];
22197
    word32 partialSz;
22198
    word32 padSz;
22199
22200
    if (aes == NULL || out == NULL || outSz == NULL)
22201
        return BAD_FUNC_ARG;
22202
    if (*outSz < aes->left)
22203
        return BUFFER_E;
22204
22205
    /* Input must be at least two complete or partial blocks */
22206
    if (aes->left <= WC_AES_BLOCK_SIZE)
22207
        return BAD_FUNC_ARG;
22208
22209
    partialSz = aes->left - WC_AES_BLOCK_SIZE;
22210
    padSz = 2 * WC_AES_BLOCK_SIZE - aes->left;
22211
    /* Zero pad */
22212
    XMEMSET(aes->ctsBlock + aes->left, 0, padSz);
22213
22214
    /* Store IV */
22215
    XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE);
22216
    /* Load IV */
22217
    XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
22218
22219
    ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE);
22220
    if (ret != 0)
22221
        return ret;
22222
22223
    /* Write out partial block */
22224
    XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz);
22225
    /* Retrieve the padding */
22226
    XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz);
22227
    /* Restore IV */
22228
    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
22229
22230
    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE,
22231
                           WC_AES_BLOCK_SIZE);
22232
    if (ret != 0)
22233
        return ret;
22234
22235
    *outSz = aes->left;
22236
    return ret;
22237
}
22238
22239
#endif /* WOLFSSL_AES_CTS */
22240
22241
#endif /* !NO_AES */