Coverage Report

Created: 2026-09-27 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/wolfcrypt/src/aes.c
Line
Count
Source
1
/* aes.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
/*
23
24
DESCRIPTION
25
This library provides the interfaces to the Advanced Encryption Standard (AES)
26
for encrypting and decrypting data. AES is the standard known for a symmetric
27
block cipher mechanism that uses n-bit binary string parameter key with 128-bits,
28
192-bits, and 256-bits of key sizes.
29
30
*/
31
32
/*
33
 * AES Build Options:
34
 *
35
 * Core:
36
 * NO_AES:                  Disable AES support entirely          default: off
37
 * WOLFSSL_AES_128:         Enable AES-128 key size               default: on
38
 * WOLFSSL_AES_192:         Enable AES-192 key size               default: on
39
 * WOLFSSL_AES_256:         Enable AES-256 key size               default: on
40
 * AES_MAX_KEY_SIZE:        Maximum AES key size in bits           default: 256
41
 *
42
 * Cipher Modes:
43
 * HAVE_AES_CBC:            Enable AES-CBC mode                   default: on
44
 * HAVE_AES_ECB:            Enable AES-ECB mode                   default: off
45
 * HAVE_AES_DECRYPT:        Enable AES decryption                 default: on
46
 * WOLFSSL_AES_COUNTER:     Enable AES-CTR mode                   default: off
47
 * WOLFSSL_AES_CFB:         Enable AES-CFB mode                   default: off
48
 * WOLFSSL_NO_AES_CFB_1_8:  Disable AES-CFB-1 and AES-CFB-8      default: off
49
 * WOLFSSL_AES_OFB:         Enable AES-OFB mode                   default: off
50
 * WOLFSSL_AES_DIRECT:      Enable direct AES encrypt/decrypt API default: off
51
 * WOLFSSL_AES_XTS:         Enable AES-XTS mode                   default: off
52
 * WOLFSSL_AES_CTS:         Enable AES-CTS (ciphertext stealing)  default: off
53
 * WOLFSSL_AES_SIV:         Enable AES-SIV (synthetic IV) mode    default: off
54
 * WOLFSSL_AESGCM_SIV:      Enable AES-GCM-SIV (RFC 8452) mode    default: off
55
 * WOLFSSL_AES_EAX:         Enable AES-EAX AEAD mode              default: off
56
 * WOLFSSL_CMAC:            Enable AES-CMAC (RFC 4493)            default: off
57
 * HAVE_AESCCM:             Enable AES-CCM mode                   default: off
58
 * HAVE_AES_KEYWRAP:        Enable AES key wrap (RFC 3394)        default: off
59
 * WOLFSSL_AES_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
0
        #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
0
{
2393
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2394
0
    volatile word32 x = 0;
2395
0
    int i;
2396
0
    int j;
2397
2398
0
    for (i = 0; i < 4; i++) {
2399
        /* 256 elements, each one is 4 bytes */
2400
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
2401
0
            x &= Te[i][j];
2402
0
        }
2403
0
    }
2404
2405
0
    return x;
2406
#else
2407
    return 0;
2408
#endif
2409
0
}
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
0
#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
0
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
2645
0
     ((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
0
{
2663
0
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
2664
0
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
2665
0
    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
0
    rk = aes->key;
2674
0
#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
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
2687
0
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
2688
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
2689
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
2690
2691
0
#ifdef LITTLE_ENDIAN_ORDER
2692
0
    s0 = ByteReverseWord32(s0);
2693
0
    s1 = ByteReverseWord32(s1);
2694
0
    s2 = ByteReverseWord32(s2);
2695
0
    s3 = ByteReverseWord32(s3);
2696
0
#endif
2697
0
#endif /* WOLFSSL_WIDE_BYTE */
2698
2699
    /* AddRoundKey */
2700
0
    s0 ^= rk[0];
2701
0
    s1 ^= rk[1];
2702
0
    s2 ^= rk[2];
2703
0
    s3 ^= rk[3];
2704
2705
0
#ifndef WOLFSSL_AES_SMALL_TABLES
2706
2707
0
#ifndef WC_NO_CACHE_RESISTANT
2708
0
    if (*prefetch_ptr == 0) {
2709
0
        s0 |= PreFetchTe();
2710
0
        if (prefetch_ptr != &always_prefetch)
2711
0
            *prefetch_ptr = 1;
2712
0
    }
2713
#else
2714
    (void)prefetch_ptr;
2715
#endif
2716
2717
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2718
0
#define ENC_ROUND_T_S(o)                                                       \
2719
0
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
2720
0
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
2721
0
         rk[(o)+4];                                                            \
2722
0
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
2723
0
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
2724
0
         rk[(o)+5];                                                            \
2725
0
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
2726
0
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
2727
0
         rk[(o)+6];                                                            \
2728
0
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
2729
0
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
2730
0
         rk[(o)+7]
2731
0
#define ENC_ROUND_S_T(o)                                                       \
2732
0
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
2733
0
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
2734
0
         rk[(o)+0];                                                            \
2735
0
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
2736
0
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
2737
0
         rk[(o)+1];                                                            \
2738
0
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
2739
0
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
2740
0
         rk[(o)+2];                                                            \
2741
0
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
2742
0
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
2743
0
         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
0
#ifndef WOLFSSL_AES_NO_UNROLL
2769
/* Unroll the loop. */
2770
0
                       ENC_ROUND_T_S( 0);
2771
0
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2772
0
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2773
0
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2774
0
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2775
0
    if (r > 5) {
2776
0
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2777
0
        if (r > 6) {
2778
0
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2779
0
        }
2780
0
    }
2781
0
    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
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2805
0
    s0 =
2806
0
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2807
0
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2808
0
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2809
0
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2810
0
        rk[0];
2811
0
    s1 =
2812
0
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2813
0
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2814
0
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2815
0
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2816
0
        rk[1];
2817
0
    s2 =
2818
0
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2819
0
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2820
0
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2821
0
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2822
0
        rk[2];
2823
0
    s3 =
2824
0
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2825
0
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2826
0
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2827
0
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2828
0
        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
0
#ifdef LITTLE_ENDIAN_ORDER
2951
0
    s0 = ByteReverseWord32(s0);
2952
0
    s1 = ByteReverseWord32(s1);
2953
0
    s2 = ByteReverseWord32(s2);
2954
0
    s3 = ByteReverseWord32(s3);
2955
0
#endif
2956
2957
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2958
0
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2959
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2960
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2961
0
#endif /* WOLFSSL_WIDE_BYTE */
2962
0
}
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
{
2977
    word32 i;
2978
    int did_prefetches = 0;
2979
2980
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
2981
        AesEncrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
2982
        in += WC_AES_BLOCK_SIZE;
2983
        out += WC_AES_BLOCK_SIZE;
2984
    }
2985
}
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
0
    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
0
{
3555
#if defined(MAX3266X_AES)
3556
    word32 keySize;
3557
#endif
3558
#if defined(MAX3266X_CB)
3559
    int ret_cb;
3560
#endif
3561
0
    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
0
    r = aes->rounds >> 1;
3572
3573
0
    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
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
3715
0
    AesEncrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
3716
#else
3717
    AesEncrypt_C(aes, inBlock, outBlock, r);
3718
#endif
3719
3720
0
    return 0;
3721
0
} /* 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
0
{
3736
0
    volatile word32 x = 0;
3737
0
    int i;
3738
0
    int j;
3739
3740
0
    for (i = 0; i < 4; i++) {
3741
        /* 256 elements, each one is 4 bytes */
3742
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
3743
0
            x &= Td[i][j];
3744
0
        }
3745
0
    }
3746
3747
0
    return x;
3748
0
}
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
0
{
3754
0
#ifndef WOLFSSL_AES_TOUCH_LINES
3755
0
    volatile word32 x = 0;
3756
0
    int i;
3757
3758
0
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
3759
0
        x &= (word32)Td4[i];
3760
0
    }
3761
3762
0
    return x;
3763
#else
3764
    return 0;
3765
#endif
3766
0
}
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
0
{
3785
0
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
3786
0
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
3787
0
    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
0
    rk = aes->key;
3796
0
#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
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
3809
0
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
3810
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
3811
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
3812
3813
0
#ifdef LITTLE_ENDIAN_ORDER
3814
0
    s0 = ByteReverseWord32(s0);
3815
0
    s1 = ByteReverseWord32(s1);
3816
0
    s2 = ByteReverseWord32(s2);
3817
0
    s3 = ByteReverseWord32(s3);
3818
0
#endif
3819
0
#endif /* WOLFSSL_WIDE_BYTE */
3820
3821
0
    s0 ^= rk[0];
3822
0
    s1 ^= rk[1];
3823
0
    s2 ^= rk[2];
3824
0
    s3 ^= rk[3];
3825
3826
0
#ifndef WOLFSSL_AES_SMALL_TABLES
3827
3828
0
#ifndef WC_NO_CACHE_RESISTANT
3829
0
    if (*prefetch_ptr == 0) {
3830
0
        s0 |= PreFetchTd();
3831
        /* don't set the prefetched flag here -- PreFetchTd4() is called
3832
         * below.
3833
         */
3834
0
    }
3835
#else
3836
    (void)prefetch_ptr;
3837
#endif
3838
3839
0
#ifndef WOLFSSL_AES_TOUCH_LINES
3840
/* Unroll the loop. */
3841
0
#define DEC_ROUND_T_S(o)                                            \
3842
0
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
3843
0
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
3844
0
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
3845
0
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
3846
0
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
3847
0
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
3848
0
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
3849
0
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
3850
0
#define DEC_ROUND_S_T(o)                                            \
3851
0
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
3852
0
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
3853
0
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
3854
0
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
3855
0
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
3856
0
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
3857
0
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
3858
0
         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
0
#ifndef WOLFSSL_AES_NO_UNROLL
3884
0
                       DEC_ROUND_T_S( 0);
3885
0
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3886
0
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3887
0
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3888
0
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3889
0
    if (r > 5) {
3890
0
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3891
0
        if (r > 6) {
3892
0
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3893
0
        }
3894
0
    }
3895
0
    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
0
#ifndef WC_NO_CACHE_RESISTANT
3919
0
    if (*prefetch_ptr == 0) {
3920
0
        t0 |= PreFetchTd4();
3921
0
        if (prefetch_ptr != &always_prefetch)
3922
0
            *prefetch_ptr = 1;
3923
0
    }
3924
#else
3925
    (void)prefetch_ptr;
3926
#endif
3927
3928
0
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3929
0
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3930
0
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3931
0
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3932
0
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3933
0
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3934
0
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3935
0
                          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
0
#ifdef LITTLE_ENDIAN_ORDER
4031
0
    s0 = ByteReverseWord32(s0);
4032
0
    s1 = ByteReverseWord32(s1);
4033
0
    s2 = ByteReverseWord32(s2);
4034
0
    s3 = ByteReverseWord32(s3);
4035
0
#endif
4036
4037
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
4038
0
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
4039
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
4040
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
4041
0
#endif /* WOLFSSL_WIDE_BYTE */
4042
4043
0
}
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
{
4058
    word32 i;
4059
    int did_prefetches = 0;
4060
4061
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
4062
        AesDecrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
4063
        in += WC_AES_BLOCK_SIZE;
4064
        out += WC_AES_BLOCK_SIZE;
4065
    }
4066
}
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
    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
0
{
4431
#if defined(MAX3266X_AES)
4432
    word32 keySize;
4433
#endif
4434
#if defined(MAX3266X_CB)
4435
    int ret_cb;
4436
#endif
4437
0
    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
0
    r = aes->rounds >> 1;
4448
4449
0
    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
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
4565
0
    AesDecrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
4566
#else
4567
    AesDecrypt_C(aes, inBlock, outBlock, r);
4568
#endif
4569
4570
0
    return 0;
4571
0
} /* 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
0
{
5387
#ifdef WC_C_DYNAMIC_FALLBACK
5388
    word32* rk = aes->key_C_fallback;
5389
#else
5390
0
    word32* rk = aes->key;
5391
0
#endif
5392
0
    word32 temp;
5393
0
    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
0
    XMEMCPY(rk, key, keySz);
5401
0
#endif
5402
0
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_WIDE_BYTE) && \
5403
0
    !defined(WOLFSSL_PIC32MZ_CRYPT) && \
5404
0
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
5405
0
    !defined(MAX3266X_AES)
5406
    /* Always reverse words when using only SW */
5407
0
    {
5408
0
        ByteReverseWords(rk, rk, keySz);
5409
0
    }
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
0
    switch (keySz) {
5431
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
5432
0
        defined(WOLFSSL_AES_128)
5433
0
    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
0
        while (1)
5439
0
        {
5440
0
            temp  = rk[3];
5441
0
            rk[4] = rk[0] ^
5442
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5443
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5444
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5445
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5446
0
                (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
0
                rcon[i];
5454
0
            rk[5] = rk[1] ^ rk[4];
5455
0
            rk[6] = rk[2] ^ rk[5];
5456
0
            rk[7] = rk[3] ^ rk[6];
5457
0
            if (++i == 10)
5458
0
                break;
5459
0
            rk += 4;
5460
0
        }
5461
0
        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
0
    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
0
        while (1)
5473
0
        {
5474
0
            temp = rk[ 5];
5475
0
            rk[ 6] = rk[ 0] ^
5476
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5477
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5478
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5479
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5480
0
                (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
0
                rcon[i];
5488
0
            rk[ 7] = rk[ 1] ^ rk[ 6];
5489
0
            rk[ 8] = rk[ 2] ^ rk[ 7];
5490
0
            rk[ 9] = rk[ 3] ^ rk[ 8];
5491
0
            if (++i == 8)
5492
0
                break;
5493
0
            rk[10] = rk[ 4] ^ rk[ 9];
5494
0
            rk[11] = rk[ 5] ^ rk[10];
5495
0
            rk += 6;
5496
0
        }
5497
0
        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
0
    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
0
        while (1)
5508
0
        {
5509
0
            temp = rk[ 7];
5510
0
            rk[ 8] = rk[ 0] ^
5511
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5512
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5513
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5514
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5515
0
                (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
0
                rcon[i];
5523
0
            rk[ 9] = rk[ 1] ^ rk[ 8];
5524
0
            rk[10] = rk[ 2] ^ rk[ 9];
5525
0
            rk[11] = rk[ 3] ^ rk[10];
5526
0
            if (++i == 7)
5527
0
                break;
5528
0
            temp = rk[11];
5529
0
            rk[12] = rk[ 4] ^
5530
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5531
0
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
5532
0
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
5533
0
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
5534
0
                (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
0
            rk[13] = rk[ 5] ^ rk[12];
5542
0
            rk[14] = rk[ 6] ^ rk[13];
5543
0
            rk[15] = rk[ 7] ^ rk[14];
5544
5545
0
            rk += 8;
5546
0
        }
5547
0
        break;
5548
0
#endif /* 256 */
5549
0
    } /* switch */
5550
0
    ForceZero(&temp, sizeof(temp));
5551
5552
0
#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
5553
0
    if (dir == AES_DECRYPTION) {
5554
0
        unsigned int j;
5555
5556
#ifdef WC_C_DYNAMIC_FALLBACK
5557
        rk = aes->key_C_fallback;
5558
#else
5559
0
        rk = aes->key;
5560
0
#endif
5561
5562
        /* invert the order of the round keys: */
5563
0
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
5564
0
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
5565
0
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
5566
0
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
5567
0
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
5568
0
        }
5569
0
        ForceZero(&temp, sizeof(temp));
5570
0
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
5571
        /* apply the inverse MixColumn transform to all round keys but the
5572
           first and the last: */
5573
0
        for (i = 1; i < aes->rounds; i++) {
5574
0
            rk += 4;
5575
0
            rk[0] =
5576
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
5577
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
5578
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
5579
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
5580
0
            rk[1] =
5581
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
5582
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
5583
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
5584
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
5585
0
            rk[2] =
5586
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
5587
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
5588
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
5589
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
5590
0
            rk[3] =
5591
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
5592
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
5593
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
5594
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
5595
0
        }
5596
0
    #endif
5597
0
    }
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
0
    (void)temp;
5606
0
#endif
5607
0
}
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
0
    {
5643
0
        int ret;
5644
5645
0
        if (aes == NULL)
5646
0
            return BAD_FUNC_ARG;
5647
5648
0
        aes->keyInstalled = 0;
5649
0
        ret = AesSetKeyLocal_body(aes, userKey, keylen, iv, dir, checkKeyLen);
5650
0
        aes->keyInstalled = (ret == 0) ? 1 : 0;
5651
5652
0
        return ret;
5653
0
    }
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
0
    {
5659
0
        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
0
        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
0
        switch (keylen) {
5677
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5678
0
        defined(WOLFSSL_AES_128)
5679
0
        case 16:
5680
0
    #endif
5681
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5682
0
        defined(WOLFSSL_AES_192)
5683
0
        case 24:
5684
0
    #endif
5685
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5686
0
        defined(WOLFSSL_AES_256)
5687
0
        case 32:
5688
0
    #endif
5689
0
            break;
5690
0
        default:
5691
0
            return BAD_FUNC_ARG;
5692
0
        }
5693
5694
    #ifdef WOLF_CRYPTO_CB
5695
        #ifndef WOLF_CRYPTO_CB_FIND
5696
        if (aes->devId != INVALID_DEVID)
5697
        #endif
5698
        {
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
            if (keylen > sizeof(aes->devKey)) {
5734
                return BAD_FUNC_ARG;
5735
            }
5736
            XMEMCPY(aes->devKey, userKey, keylen);
5737
        }
5738
    #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
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
5804
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
5805
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) || \
5806
        defined(WOLFSSL_NXP_HASHCRYPT_AES)
5807
        #ifdef WOLF_CRYPTO_CB
5808
        #ifndef WOLF_CRYPTO_CB_FIND
5809
        if (aes->devId != INVALID_DEVID)
5810
        #endif
5811
        #endif
5812
        {
5813
            if (keylen > sizeof(aes->devKey)) {
5814
                return BAD_FUNC_ARG;
5815
            }
5816
            XMEMCPY(aes->devKey, userKey, keylen);
5817
        }
5818
    #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
0
        (void) checkKeyLen;
5846
0
    #endif
5847
5848
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5849
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5850
        defined(WOLFSSL_AES_CTS)
5851
        aes->left = 0;
5852
    #endif
5853
5854
0
        aes->keylen = (int)keylen;
5855
0
        aes->rounds = (keylen/4) + 6;
5856
0
        ret = wc_AesSetIV(aes, iv);
5857
0
        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
0
#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
0
        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
0
        XMEMCPY(aes->key, userKey, keylen);
6058
6059
0
#ifndef WC_AES_BITSLICED
6060
0
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
6061
0
        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
6062
0
        && !defined(MAX3266X_AES)
6063
6064
        /* software */
6065
0
        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
0
#endif /* !WC_AES_BITSLICED */
6097
6098
0
#ifdef NEED_AES_TABLES
6099
0
        AesSetKey_C(aes, userKey, keylen, dir);
6100
0
#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
0
        return ret;
6129
0
#endif
6130
6131
0
#endif /* !WC_C_DYNAMIC_FALLBACK */
6132
6133
0
    } /* wc_AesSetKeyLocal */
6134
6135
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
6136
            const byte* iv, int dir)
6137
0
    {
6138
0
        if (aes == NULL) {
6139
0
            return BAD_FUNC_ARG;
6140
0
        }
6141
0
        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
0
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
6166
6167
0
    } /* 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
    {
6175
        if (aes == NULL) {
6176
            return BAD_FUNC_ARG;
6177
        }
6178
        if (keylen > sizeof(aes->key)) {
6179
            return BAD_FUNC_ARG;
6180
        }
6181
6182
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
6183
    }
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
0
{
6191
0
    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
0
    if (iv)
6203
0
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
6204
0
    else
6205
0
        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
6206
6207
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
6208
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
6209
    defined(WOLFSSL_AES_CTS)
6210
    /* Clear any unused bytes from last cipher op. */
6211
    aes->left = 0;
6212
#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
0
    return 0;
6236
0
}
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
0
#define VECTOR_REGISTERS_PUSH WC_DO_NOTHING
6304
#define VECTOR_REGISTERS_PUSH2(fail_clause) WC_DO_NOTHING
6305
0
#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
        {
6331
            int ret;
6332
6333
            if (aes == NULL || out == NULL || in == NULL)
6334
                return BAD_FUNC_ARG;
6335
            if (!WC_AES_KEY_IS_SET(aes)) {
6336
                WOLFSSL_MSG("AES key not set");
6337
                return MISSING_KEY;
6338
            }
6339
            VECTOR_REGISTERS_PUSH;
6340
            ret = wc_AesEncrypt(aes, in, out);
6341
            VECTOR_REGISTERS_POP;
6342
            return ret;
6343
        }
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
        #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
        {
6356
            int ret;
6357
6358
            if (aes == NULL)
6359
                return BAD_FUNC_ARG;
6360
            if (!WC_AES_KEY_IS_SET(aes)) {
6361
                WOLFSSL_MSG("AES key not set");
6362
                return MISSING_KEY;
6363
            }
6364
            VECTOR_REGISTERS_PUSH;
6365
            ret = wc_AesDecrypt(aes, in, out);
6366
            VECTOR_REGISTERS_POP;
6367
            return ret;
6368
        }
6369
6370
        #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
0
    {
7258
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7259
0
        word32 blocks;
7260
0
        int ret;
7261
0
#endif
7262
7263
0
        if (aes == NULL || out == NULL || in == NULL) {
7264
0
            return BAD_FUNC_ARG;
7265
0
        }
7266
7267
0
        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
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7274
0
        blocks = sz / WC_AES_BLOCK_SIZE;
7275
0
#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
    #ifdef WOLF_CRYPTO_CB
7290
        #ifndef WOLF_CRYPTO_CB_FIND
7291
        if (aes->devId != INVALID_DEVID)
7292
        #endif
7293
        {
7294
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
7295
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7296
                return crypto_cb_ret;
7297
            /* fall-through when unavailable */
7298
        }
7299
    #endif
7300
7301
        /* Single key guard after all offload dispatches. */
7302
0
        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
0
        {
7458
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
7459
0
            int did_prefetches = 0;
7460
0
#endif
7461
0
            ret = 0;
7462
0
            while (blocks--) {
7463
0
                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
7464
0
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7465
0
                                                (byte*)aes->reg,
7466
0
                                                &did_prefetches);
7467
0
                if (ret != 0)
7468
0
                    break;
7469
0
                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
7470
7471
0
                out += WC_AES_BLOCK_SIZE;
7472
0
                in  += WC_AES_BLOCK_SIZE;
7473
0
            }
7474
0
        }
7475
7476
    #ifdef WOLFSSL_AESNI
7477
        VECTOR_REGISTERS_POP;
7478
    #endif
7479
7480
0
        return ret;
7481
0
#endif
7482
0
    } /* 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
0
    {
7488
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7489
0
        word32 blocks;
7490
0
        int ret;
7491
0
#endif
7492
7493
0
        if (aes == NULL || out == NULL || in == NULL) {
7494
0
            return BAD_FUNC_ARG;
7495
0
        }
7496
7497
0
        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
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7519
0
        blocks = sz / WC_AES_BLOCK_SIZE;
7520
0
#endif
7521
0
        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
    #ifdef WOLF_CRYPTO_CB
7536
        #ifndef WOLF_CRYPTO_CB_FIND
7537
        if (aes->devId != INVALID_DEVID)
7538
        #endif
7539
        {
7540
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
7541
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7542
                return crypto_cb_ret;
7543
            /* fall-through when unavailable */
7544
        }
7545
    #endif
7546
7547
        /* Single key guard after all offload dispatches. */
7548
0
        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
0
        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
0
        {
7681
0
            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
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
7744
0
            {
7745
0
            int did_prefetches = 0;
7746
0
#endif
7747
0
            while (blocks--) {
7748
0
                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
7749
0
                ret = AesDecrypt_preFetchOpt(aes, in, out, &did_prefetches);
7750
0
                if (ret != 0)
7751
0
                    return ret;
7752
0
                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7753
                /* store iv for next call */
7754
0
                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7755
7756
0
                out += WC_AES_BLOCK_SIZE;
7757
0
                in  += WC_AES_BLOCK_SIZE;
7758
0
            }
7759
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
7760
0
            }
7761
0
#endif
7762
0
#endif
7763
0
        }
7764
7765
0
        VECTOR_REGISTERS_POP;
7766
7767
0
        return ret;
7768
0
#endif
7769
0
    }
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
        {
8004
            /* in network byte order so start at end and work back */
8005
            int i;
8006
            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
                inOutCtr[i] = WC_OCTET(inOutCtr[i] + 1);
8010
                if (inOutCtr[i] != 0)  /* we're done unless we overflow */
8011
                    return;
8012
            }
8013
        }
8014
        #endif
8015
8016
        /* Software AES - CTR Encrypt */
8017
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
8018
        {
8019
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
8020
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8021
            byte scratch[WC_AES_BLOCK_SIZE];
8022
    #endif
8023
    #if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
8024
            int ret = 0;
8025
    #endif
8026
            word32 processed;
8027
#ifdef WC_AES_HAVE_PREFETCH_ARG
8028
            int did_prefetches = 0;
8029
#endif
8030
8031
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
8032
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8033
            XMEMSET(scratch, 0, sizeof(scratch));
8034
    #endif
8035
8036
            if (aes == NULL || out == NULL || in == NULL) {
8037
                return BAD_FUNC_ARG;
8038
            }
8039
8040
            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
                return 0;
8044
            }
8045
8046
        #ifdef WOLF_CRYPTO_CB
8047
            #ifndef WOLF_CRYPTO_CB_FIND
8048
            if (aes->devId != INVALID_DEVID)
8049
            #endif
8050
            {
8051
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
8052
                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
8053
                    return crypto_cb_ret;
8054
                /* fall-through when unavailable */
8055
            }
8056
        #endif
8057
8058
            /* Software/HW key schedule required from here on. */
8059
            if (!WC_AES_KEY_IS_SET(aes)) {
8060
                WOLFSSL_MSG("AES key not set");
8061
                return MISSING_KEY;
8062
            }
8063
8064
            /* consume any unused bytes left in aes->tmp */
8065
            processed = min(aes->left, sz);
8066
            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
8067
                      processed);
8068
            out += processed;
8069
            in += processed;
8070
            aes->left -= processed;
8071
            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
            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
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
8240
            !defined(XTRANSFORM_AESCTRBLOCK)
8241
            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
8242
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
8243
                byte* counter = (byte*)aes->reg;
8244
                byte* c = out;
8245
                while (blocks--) {
8246
                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
8247
                    c += WC_AES_BLOCK_SIZE;
8248
                    IncrementAesCounter(counter);
8249
                }
8250
8251
                /* reset number of blocks and then do encryption */
8252
                blocks = sz / WC_AES_BLOCK_SIZE;
8253
                ret = wc_AesEcbEncrypt(aes, out, out,
8254
                                       WC_AES_BLOCK_SIZE * blocks);
8255
                if (ret == 0) {
8256
                    xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
8257
                    in += WC_AES_BLOCK_SIZE * blocks;
8258
                    out += WC_AES_BLOCK_SIZE * blocks;
8259
                    sz -= blocks * WC_AES_BLOCK_SIZE;
8260
                }
8261
                else {
8262
                    ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
8263
                }
8264
            }
8265
            else
8266
        #endif
8267
            {
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
                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
                    ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
8280
                                                    scratch,
8281
                                                    &did_prefetches);
8282
                    if (ret != 0)
8283
                        break;
8284
                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
8285
                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
8286
                #endif
8287
                    IncrementAesCounter((byte*)aes->reg);
8288
8289
                    out += WC_AES_BLOCK_SIZE;
8290
                    in  += WC_AES_BLOCK_SIZE;
8291
                    sz  -= WC_AES_BLOCK_SIZE;
8292
                    aes->left = 0;
8293
                }
8294
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
8295
            }
8296
8297
            /* handle non block size remaining and store unused byte count in left */
8298
            if ((ret == 0) && sz) {
8299
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
8300
                                                (byte*)aes->tmp,
8301
                                                &did_prefetches);
8302
                if (ret == 0) {
8303
                    IncrementAesCounter((byte*)aes->reg);
8304
                    aes->left = WC_AES_BLOCK_SIZE - sz;
8305
                    xorbufout(out, in, aes->tmp, sz);
8306
                }
8307
            }
8308
8309
            if (ret < 0)
8310
                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
            VECTOR_REGISTERS_POP;
8317
8318
            return ret;
8319
    #endif
8320
        }
8321
8322
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
8323
                                        const byte* iv, int dir)
8324
        {
8325
            if (aes == NULL) {
8326
                return BAD_FUNC_ARG;
8327
            }
8328
            if (len > sizeof(aes->key)) {
8329
                return BAD_FUNC_ARG;
8330
            }
8331
8332
            return wc_AesSetKey(aes, key, len, iv, dir);
8333
        }
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
0
{
8365
0
    int i;
8366
0
    for (i = (int)ctrSz - 1; i >= 0; i--) {
8367
        /* See IncrementAesCounter() on why this masks to an octet. */
8368
0
        ctr[i] = WC_OCTET(ctr[i] + 1);
8369
0
        if (ctr[i] != 0)
8370
0
            break;
8371
0
    }
8372
0
}
8373
#endif /* HAVE_AESGCM || HAVE_AESCCM */
8374
8375
8376
#ifdef HAVE_AESGCM
8377
8378
#ifdef WOLFSSL_AESGCM_STREAM
8379
    /* Access initialization counter data. */
8380
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
8381
    /* Access counter data. */
8382
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
8383
    /* Access tag data. */
8384
    #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
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
8389
8390
    #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
0
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
0
    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
0
    case 16:
8446
0
#endif
8447
0
        return 0;
8448
0
    default:
8449
0
        WOLFSSL_MSG("AES-GCM unsupported authTagSz");
8450
0
        return BAD_FUNC_ARG;
8451
0
    }
8452
0
#endif
8453
0
}
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
0
{
8471
0
    int i;
8472
8473
    /* in network byte order so start at end and work back */
8474
0
    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
0
        inOutCtr[i] = WC_OCTET(inOutCtr[i] + 1);
8477
0
        if (inOutCtr[i] != 0)  /* we're done unless we overflow */
8478
0
            return;
8479
0
    }
8480
0
}
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
0
    #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
0
{
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
0
    word32 szHi = (sz >> (CHAR_BIT * sizeof(sz) - 3));
8504
0
    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
0
    buf[0] = WC_OCTET(szHi >> 24);
8509
0
    buf[1] = WC_OCTET(szHi >> 16);
8510
0
    buf[2] = WC_OCTET(szHi >>  8);
8511
0
    buf[3] = WC_OCTET(szHi);
8512
0
    buf[4] = WC_OCTET(sz >> 24);
8513
0
    buf[5] = WC_OCTET(sz >> 16);
8514
0
    buf[6] = WC_OCTET(sz >>  8);
8515
0
    buf[7] = WC_OCTET(sz);
8516
0
}
8517
8518
8519
static WC_INLINE void RIGHTSHIFTX(byte* x)
8520
0
{
8521
0
    int i;
8522
0
    int carryIn = 0;
8523
0
    volatile byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
8524
8525
0
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
8526
0
        int carryOut = (x[i] & 0x01) << 7;
8527
0
        x[i] = (byte) ((x[i] >> 1) | carryIn);
8528
0
        carryIn = carryOut;
8529
0
    }
8530
0
    x[0] ^= borrow;
8531
0
}
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
0
{
8572
0
    int i;
8573
0
    for (i = 15; i > 0; i--)
8574
0
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
8575
0
    r8[0] = (byte)(z8[0] >> 4);
8576
0
}
8577
#endif
8578
8579
void GenerateM0(Gcm* gcm)
8580
0
{
8581
0
#if !defined(WC_16BIT_CPU)
8582
0
    int i;
8583
0
#endif
8584
0
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
8585
8586
    /* 0 times -> 0x0 */
8587
0
    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
8588
    /* 1 times -> 0x8 */
8589
0
    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
8590
    /* 2 times -> 0x4 */
8591
0
    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
8592
0
    RIGHTSHIFTX(m[0x4]);
8593
    /* 4 times -> 0x2 */
8594
0
    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
8595
0
    RIGHTSHIFTX(m[0x2]);
8596
    /* 8 times -> 0x1 */
8597
0
    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
8598
0
    RIGHTSHIFTX(m[0x1]);
8599
8600
    /* 0x3 */
8601
0
    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
8602
0
    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
8603
8604
    /* 0x5 -> 0x7 */
8605
0
    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
8606
0
    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
8607
0
    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
8608
0
    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
8609
0
    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
8610
0
    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
8611
8612
    /* 0x9 -> 0xf */
8613
0
    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
8614
0
    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
8615
0
    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
8616
0
    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
8617
0
    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
8618
0
    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
8619
0
    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
8620
0
    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
8621
0
    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
8622
0
    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
8623
0
    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
8624
0
    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
8625
0
    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
8626
0
    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
8627
8628
0
#if !defined(WC_16BIT_CPU)
8629
0
    for (i = 0; i < 16; i++) {
8630
0
        Shift4_M0(m[16+i], m[i]);
8631
0
    }
8632
0
#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
0
}
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
0
{
8719
0
    int  ret;
8720
0
    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
0
    if (!((len == 16) || (len == 24) || (len == 32)))
8740
0
        return BAD_FUNC_ARG;
8741
8742
0
    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
0
    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
8759
0
    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
#ifdef WOLFSSL_AESGCM_STREAM
8772
    aes->gcmKeySet = 1;
8773
#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
0
#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
0
    if (ret == 0) {
8854
0
        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
0
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
8866
8867
0
        if (ret == 0) {
8868
0
#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
0
            {
8895
0
                GenerateM0(&aes->gcm);
8896
0
            }
8897
0
#endif /* GCM_TABLE || GCM_TABLE_4BIT */
8898
0
        }
8899
0
#endif /* WOLFSSL_RISCV_SCALAR_CRYPTO_ASM */
8900
8901
0
        VECTOR_REGISTERS_POP;
8902
0
    }
8903
0
#endif /* !FREESCALE_LTC_AES_GCM && !WOLFSSL_PSOC6_CRYPTO */
8904
0
#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
#ifdef WOLF_CRYPTO_CB
8911
    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
        {
8919
            XMEMCPY(aes->devKey, key, len);
8920
        }
8921
    }
8922
#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
0
    return ret;
8934
0
}
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
0
{
9929
0
    int i;
9930
0
    word64 z8[2] = {0, 0};
9931
0
    byte a;
9932
0
    word64* x8 = (word64*)x;
9933
0
    word64* m8;
9934
0
    word64 n0, n1, n2, n3;
9935
0
    byte xi;
9936
9937
0
    for (i = 15; i > 0; i--) {
9938
0
        xi = x[i];
9939
9940
        /* XOR in (msn * H) */
9941
0
        m8 = (word64*)m[xi & 0xf];
9942
0
        z8[0] ^= m8[0];
9943
0
        z8[1] ^= m8[1];
9944
9945
        /* Cache top byte for remainder calculations - lost in rotate. */
9946
0
        a = (byte)(z8[1] >> 56);
9947
9948
        /* Rotate Z by 8-bits */
9949
0
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
9950
0
        z8[0] <<= 8;
9951
9952
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9953
0
        m8 = (word64*)m[16 + (xi >> 4)];
9954
0
        z8[0] ^= m8[0];
9955
0
        z8[1] ^= m8[1];
9956
9957
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9958
0
        z8[0] ^= (word64)R[16 + (a & 0xf)];
9959
        /* XOR in next significant nibble (XORed with H) * remainder */
9960
0
        m8 = (word64*)m[xi >> 4];
9961
0
        a ^= (byte)(m8[1] >> 52);
9962
0
        z8[0] ^= (word64)R[a >> 4];
9963
0
    }
9964
9965
0
    xi = x[0];
9966
9967
    /* XOR in most significant nibble * H */
9968
0
    m8 = (word64*)m[xi & 0xf];
9969
0
    z8[0] ^= m8[0];
9970
0
    z8[1] ^= m8[1];
9971
9972
    /* Cache top byte for remainder calculations - lost in rotate. */
9973
0
    a = (z8[1] >> 56) & 0xf;
9974
9975
    /* Rotate z by 4-bits */
9976
0
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
9977
0
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
9978
0
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
9979
0
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
9980
0
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
9981
0
    z8[0] = (n1 >> 4) | (n0 << 12);
9982
9983
    /* XOR in next significant nibble * H */
9984
0
    m8 = (word64*)m[xi >> 4];
9985
0
    z8[0] ^= m8[0];
9986
0
    z8[1] ^= m8[1];
9987
    /* XOR in most significant nibble * remainder */
9988
0
    z8[0] ^= (word64)R[a];
9989
9990
    /* Write back result. */
9991
0
    x8[0] = z8[0];
9992
0
    x8[1] = z8[1];
9993
0
}
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
0
{
10000
0
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
10001
0
    byte scratch[WC_AES_BLOCK_SIZE];
10002
0
    word32 blocks, partial;
10003
10004
0
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
10005
10006
    /* Hash in A, the Additional Authentication Data */
10007
0
    if (aSz != 0 && a != NULL) {
10008
0
        blocks = aSz / WC_AES_BLOCK_SIZE;
10009
0
        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
0
        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
0
        if (partial != 0) {
10027
0
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10028
0
            XMEMCPY(scratch, a, partial);
10029
0
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
10030
0
            GMULT(x, gcm->M0);
10031
0
        }
10032
0
    #endif
10033
0
    }
10034
10035
    /* Hash in C, the Ciphertext */
10036
0
    if (cSz != 0 && c != NULL) {
10037
0
        blocks = cSz / WC_AES_BLOCK_SIZE;
10038
0
        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
0
        while (blocks--) {
10051
0
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
10052
0
            GMULT(x, gcm->M0);
10053
0
            c += WC_AES_BLOCK_SIZE;
10054
0
        }
10055
0
        if (partial != 0) {
10056
0
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10057
0
            XMEMCPY(scratch, c, partial);
10058
0
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
10059
0
            GMULT(x, gcm->M0);
10060
0
        }
10061
0
    #endif
10062
0
    }
10063
10064
    /* Hash in the lengths of A and C in bits */
10065
0
    FlattenSzInBits(&scratch[0], aSz);
10066
0
    FlattenSzInBits(&scratch[8], cSz);
10067
#ifdef GCM_GMULT_LEN
10068
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
10069
#else
10070
0
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
10071
0
    GMULT(x, gcm->M0);
10072
0
#endif
10073
10074
    /* Copy the result into s. */
10075
0
    XMEMCPY(s, x, sSz);
10076
0
}
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
#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
    do {                                                \
10106
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
10107
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
10108
    }                                                   \
10109
    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
    do {                                          \
10680
        byte scratch[WC_AES_BLOCK_SIZE];          \
10681
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
10682
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
10683
        GHASH_ONE_BLOCK(aes, scratch);            \
10684
    }                                             \
10685
    while (0)
10686
#endif
10687
10688
/* Initialize a GHASH for streaming operations.
10689
 *
10690
 * @param [in, out] aes  AES GCM object.
10691
 */
10692
static void GHASH_INIT(Aes* aes) {
10693
    /* Set tag to all zeros as initial value. */
10694
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
10695
    /* Reset counts of AAD and cipher text. */
10696
    aes->aOver = 0;
10697
    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
    {
10706
        /* Extra initialization based on implementation. */
10707
        GHASH_INIT_EXTRA(aes);
10708
    }
10709
}
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
{
10722
    word32 blocks;
10723
    word32 partial;
10724
10725
    /* Hash in A, the Additional Authentication Data */
10726
    if (aSz != 0 && a != NULL) {
10727
        /* Update count of AAD we have hashed. */
10728
        aes->aSz += aSz;
10729
        /* Check if we have unprocessed data. */
10730
        if (aes->aOver > 0) {
10731
            /* Calculate amount we can use - fill up the block. */
10732
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10733
            if (sz > aSz) {
10734
                sz = (byte)aSz;
10735
            }
10736
            /* Copy extra into last GHASH block array and update count. */
10737
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
10738
            aes->aOver = (byte)(aes->aOver + sz);
10739
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
10740
                /* We have filled up the block and can process. */
10741
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10742
                /* Reset count. */
10743
                aes->aOver = 0;
10744
            }
10745
            /* Used up some data. */
10746
            aSz -= sz;
10747
            a += sz;
10748
        }
10749
10750
        /* Calculate number of blocks of AAD and the leftover. */
10751
        blocks = aSz / WC_AES_BLOCK_SIZE;
10752
        partial = aSz % WC_AES_BLOCK_SIZE;
10753
        /* GHASH full blocks now. */
10754
        while (blocks--) {
10755
            GHASH_ONE_BLOCK(aes, a);
10756
            a += WC_AES_BLOCK_SIZE;
10757
        }
10758
        if (partial != 0) {
10759
            /* Cache the partial block. */
10760
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
10761
            aes->aOver = (byte)partial;
10762
        }
10763
    }
10764
    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
        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10768
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
10769
        /* GHASH last AAD block. */
10770
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10771
        /* Clear partial count for next time through. */
10772
        aes->aOver = 0;
10773
    }
10774
10775
    /* Hash in C, the Ciphertext */
10776
    if (cSz != 0 && c != NULL) {
10777
        /* Update count of cipher text we have hashed. */
10778
        aes->cSz += cSz;
10779
        if (aes->cOver > 0) {
10780
            /* Calculate amount we can use - fill up the block. */
10781
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
10782
            if (sz > cSz) {
10783
                sz = (byte)cSz;
10784
            }
10785
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
10786
            /* Update count of unused encrypted counter. */
10787
            aes->cOver = (byte)(aes->cOver + sz);
10788
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
10789
                /* We have filled up the block and can process. */
10790
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10791
                /* Reset count. */
10792
                aes->cOver = 0;
10793
            }
10794
            /* Used up some data. */
10795
            cSz -= sz;
10796
            c += sz;
10797
        }
10798
10799
        /* Calculate number of blocks of cipher text and the leftover. */
10800
        blocks = cSz / WC_AES_BLOCK_SIZE;
10801
        partial = cSz % WC_AES_BLOCK_SIZE;
10802
        /* GHASH full blocks now. */
10803
        while (blocks--) {
10804
            GHASH_ONE_BLOCK(aes, c);
10805
            c += WC_AES_BLOCK_SIZE;
10806
        }
10807
        if (partial != 0) {
10808
            /* Cache the partial block. */
10809
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
10810
            aes->cOver = (byte)partial;
10811
        }
10812
    }
10813
}
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
{
10825
    /* AAD block incomplete when > 0 */
10826
    byte over = aes->aOver;
10827
10828
    if (aes->cOver > 0) {
10829
        /* Cipher text block incomplete. */
10830
        over = aes->cOver;
10831
    }
10832
    if (over > 0) {
10833
        /* Zeroize the unused part of the block. */
10834
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
10835
            (size_t)WC_AES_BLOCK_SIZE - over);
10836
        /* Hash the last block of cipher text. */
10837
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10838
    }
10839
    /* Hash in the lengths of AAD and cipher text in bits */
10840
    GHASH_LEN_BLOCK(aes);
10841
    /* Copy the result into s. */
10842
    XMEMCPY(s, AES_TAG(aes), sSz);
10843
    /* reset aes->gcm.H in case of reuse */
10844
    GHASH_INIT_EXTRA(aes);
10845
}
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
0
{
11216
0
    int ret = 0;
11217
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
11218
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
11219
0
    const byte* p = in;
11220
0
    byte* c = out;
11221
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
11222
0
    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
11223
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
11224
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
11225
0
    int did_prefetches = 0;
11226
0
#endif
11227
11228
0
    if (ivSz == GCM_NONCE_MID_SZ) {
11229
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
11230
0
        XMEMCPY(counter, iv, ivSz);
11231
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
11232
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
11233
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
11234
0
    }
11235
0
    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
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
11242
#ifdef OPENSSL_EXTRA
11243
        aes->gcm.aadLen = aadTemp;
11244
#endif
11245
0
    }
11246
0
    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
0
    {
11286
0
        while (blocks--) {
11287
0
            IncrementGcmCounter(counter);
11288
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
11289
0
            ret = AesEncrypt_preFetchOpt(aes, counter, scratch,
11290
0
                                            &did_prefetches);
11291
0
            if (ret != 0)
11292
0
                return ret;
11293
0
            xorbufout(c, scratch, p, WC_AES_BLOCK_SIZE);
11294
0
        #endif
11295
0
            p += WC_AES_BLOCK_SIZE;
11296
0
            c += WC_AES_BLOCK_SIZE;
11297
0
        }
11298
0
    }
11299
11300
0
    if (partial != 0) {
11301
0
        IncrementGcmCounter(counter);
11302
0
        ret = AesEncrypt_preFetchOpt(aes, counter, scratch, &did_prefetches);
11303
0
        if (ret != 0)
11304
0
            return ret;
11305
0
        xorbufout(c, scratch, p, partial);
11306
0
    }
11307
0
    if (authTag) {
11308
0
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
11309
0
        ret = AesEncrypt_preFetchOpt(aes, initialCounter, scratch,
11310
0
                                        &did_prefetches);
11311
0
        if (ret != 0)
11312
0
            return ret;
11313
0
        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
0
    }
11320
11321
0
    return ret;
11322
0
}
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
0
{
11464
0
    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
0
    if (aes == NULL || iv == NULL || ivSz == 0 ||
11470
0
        (sz != 0 && (in == NULL || out == NULL)) ||
11471
0
        authTag == NULL ||
11472
0
        ((authInSz > 0) && (authIn == NULL)))
11473
0
    {
11474
0
        return BAD_FUNC_ARG;
11475
0
    }
11476
11477
0
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
11478
0
    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
#ifdef WOLF_CRYPTO_CB
11487
    #ifndef WOLF_CRYPTO_CB_FIND
11488
    if (aes->devId != INVALID_DEVID)
11489
    #endif
11490
    {
11491
        int crypto_cb_ret =
11492
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
11493
                                      authTagSz, authIn, authInSz);
11494
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11495
            return crypto_cb_ret;
11496
        /* fall-through when unavailable */
11497
    }
11498
#endif
11499
11500
    /* Software/HW key schedule (and hash subkey H) required from here on. */
11501
0
    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
0
    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
0
    {
11717
0
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11718
0
                                authIn, authInSz);
11719
0
    }
11720
0
#endif
11721
11722
0
    VECTOR_REGISTERS_POP;
11723
11724
0
    return ret;
11725
0
}
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
#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
    if (c != p && blocks > 0) { /* can not handle inline decryption */
12135
        while (blocks--) {
12136
            IncrementGcmCounter(counter);
12137
            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
12138
            p += WC_AES_BLOCK_SIZE;
12139
        }
12140
12141
        /* reset number of blocks and then do encryption */
12142
        blocks = sz / WC_AES_BLOCK_SIZE;
12143
12144
        ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
12145
        if (ret != 0) {
12146
            ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
12147
            return ret;
12148
        }
12149
        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
12150
        c += WC_AES_BLOCK_SIZE * blocks;
12151
    }
12152
    else
12153
#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
0
{
12324
0
    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
0
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
12333
0
        authTag == NULL || ivSz == 0)
12334
0
    {
12335
0
        return BAD_FUNC_ARG;
12336
0
    }
12337
12338
0
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
12339
0
    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
#ifdef WOLF_CRYPTO_CB
12348
    #ifndef WOLF_CRYPTO_CB_FIND
12349
    if (aes->devId != INVALID_DEVID)
12350
    #endif
12351
    {
12352
        int crypto_cb_ret =
12353
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
12354
                                      authTag, authTagSz, authIn, authInSz);
12355
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
12356
            return crypto_cb_ret;
12357
        /* fall-through when unavailable */
12358
    }
12359
#endif
12360
12361
    /* Software/HW key schedule (and hash subkey H) required from here on. */
12362
0
    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
0
    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
0
    {
12592
0
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
12593
0
                                                             authIn, authInSz);
12594
0
    }
12595
0
#endif
12596
12597
0
    VECTOR_REGISTERS_POP;
12598
12599
0
    return ret;
12600
0
}
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
{
12614
    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
12615
    int ret;
12616
12617
    if (ivSz == GCM_NONCE_MID_SZ) {
12618
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
12619
        XMEMCPY(counter, iv, ivSz);
12620
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
12621
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
12622
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
12623
    }
12624
    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
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
12631
    #ifdef OPENSSL_EXTRA
12632
        aes->gcm.aadLen = aadTemp;
12633
    #endif
12634
    }
12635
12636
    /* Copy in the counter for use with cipher. */
12637
    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
12638
    /* Encrypt initial counter into a buffer for GCM. */
12639
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
12640
    if (ret != 0)
12641
        return ret;
12642
    /* Reset state fields. */
12643
    aes->over = 0;
12644
    aes->aSz = 0;
12645
    aes->cSz = 0;
12646
    /* Initialization for GHASH. */
12647
    GHASH_INIT(aes);
12648
12649
    return 0;
12650
}
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
{
12664
    word32 blocks;
12665
    word32 partial;
12666
    int ret;
12667
12668
    /* Check if previous encrypted block was not used up. */
12669
    if (aes->over > 0) {
12670
        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
12671
        if (pSz > sz) pSz = (byte)sz;
12672
12673
        /* Use some/all of last encrypted block. */
12674
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
12675
        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
12676
12677
        /* Some data used. */
12678
        sz  -= pSz;
12679
        in  += pSz;
12680
        out += pSz;
12681
    }
12682
12683
    /* Calculate the number of blocks needing to be encrypted and any leftover.
12684
     */
12685
    blocks  = sz / WC_AES_BLOCK_SIZE;
12686
    partial = sz & (WC_AES_BLOCK_SIZE - 1);
12687
12688
#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
    if ((out != in) && blocks > 0) {
12694
        word32 b;
12695
        /* Place incrementing counter blocks into cipher text. */
12696
        for (b = 0; b < blocks; b++) {
12697
            IncrementGcmCounter(AES_COUNTER(aes));
12698
            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
12699
        }
12700
12701
        /* Encrypt counter blocks. */
12702
        ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
12703
        if (ret != 0) {
12704
            ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
12705
            return ret;
12706
        }
12707
        /* XOR in plaintext. */
12708
        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
12709
        /* Skip over processed data. */
12710
        in += WC_AES_BLOCK_SIZE * blocks;
12711
        out += WC_AES_BLOCK_SIZE * blocks;
12712
    }
12713
    else
12714
#endif /* HAVE_AES_ECB */
12715
    {
12716
        /* Encrypt block by block. */
12717
        while (blocks--) {
12718
            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
12719
            IncrementGcmCounter(AES_COUNTER(aes));
12720
            /* Encrypt counter into a buffer. */
12721
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
12722
            if (ret != 0)
12723
                return ret;
12724
            /* XOR plain text into encrypted counter into cipher text buffer. */
12725
            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
12726
            /* Data complete. */
12727
            in  += WC_AES_BLOCK_SIZE;
12728
            out += WC_AES_BLOCK_SIZE;
12729
        }
12730
    }
12731
12732
    if (partial != 0) {
12733
        /* Generate an extra block and use up as much as needed. */
12734
        IncrementGcmCounter(AES_COUNTER(aes));
12735
        /* Encrypt counter into cache. */
12736
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
12737
        if (ret != 0)
12738
            return ret;
12739
        /* XOR plain text into encrypted counter into cipher text buffer. */
12740
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
12741
        /* Keep amount of encrypted block used. */
12742
        aes->over = (byte)partial;
12743
    }
12744
12745
    return 0;
12746
}
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
{
12757
    /* Calculate authentication tag. */
12758
    GHASH_FINAL(aes, authTag, authTagSz);
12759
    /* XOR in as much of encrypted counter as is required. */
12760
    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
    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
12767
12768
    return 0;
12769
}
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
{
14573
    int ret = 0;
14574
14575
    /* Check validity of parameters. */
14576
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
14577
            ((ivSz == 0) && (iv != NULL)) ||
14578
            ((ivSz > 0) && (iv == NULL))) {
14579
        ret = BAD_FUNC_ARG;
14580
    }
14581
14582
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
14583
    if ((ret == 0) && (aes->streamData == NULL)) {
14584
        /* Allocate buffers for streaming. */
14585
        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
14586
        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
14587
                                                              DYNAMIC_TYPE_AES);
14588
        if (aes->streamData == NULL) {
14589
            ret = MEMORY_E;
14590
        }
14591
    }
14592
#endif
14593
14594
    /* Set the key if passed in. */
14595
    if ((ret == 0) && (key != NULL)) {
14596
        ret = wc_AesGcmSetKey(aes, key, len);
14597
    }
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
    if (ret == 0) {
14624
        if (iv != NULL) {
14625
            if (ivSz <= WC_AES_BLOCK_SIZE) {
14626
                /* Set the IV passed in if it is smaller than a block. */
14627
                XMEMMOVE((byte*)aes->reg, iv, ivSz);
14628
                aes->nonceSz = ivSz;
14629
            }
14630
            else {
14631
                /* FIPS short-nonce detection depends on aes->nonceSz == 0
14632
                 * signifying that supplied ivSz > WC_AES_BLOCK_SIZE.
14633
                 */
14634
                aes->nonceSz = 0;
14635
            }
14636
        }
14637
        else {
14638
            /* No IV passed in, check for cached IV. */
14639
            if (aes->nonceSz != 0) {
14640
                /* Use the cached copy. */
14641
                iv = (byte*)aes->reg;
14642
                ivSz = aes->nonceSz;
14643
            }
14644
        }
14645
14646
        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
            {
14677
                ret = AesGcmInit_C(aes, iv, ivSz);
14678
            }
14679
14680
            if (ret == 0)
14681
                aes->nonceSet = 1;
14682
        }
14683
    }
14684
14685
    return ret;
14686
}
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
{
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
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
14713
}
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
{
14736
    int ret;
14737
14738
    /* Check validity of parameters. */
14739
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
14740
        ret = BAD_FUNC_ARG;
14741
    }
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
    else {
14748
        /* Copy out the IV including generated part for decryption. */
14749
        XMEMCPY(ivOut, aes->reg, ivOutSz);
14750
        /* Initialize AES GCM cipher with key and cached Iv. */
14751
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
14752
    }
14753
14754
    return ret;
14755
}
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
{
14761
    int ret = 0;
14762
14763
    /* Check validity of parameters. */
14764
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
14765
            ((out == NULL) || (in == NULL)))) {
14766
        ret = BAD_FUNC_ARG;
14767
    }
14768
14769
    /* Check key has been set. */
14770
    if ((ret == 0) && (!aes->gcmKeySet)) {
14771
        ret = MISSING_KEY;
14772
    }
14773
    /* Check IV has been set. */
14774
    if ((ret == 0) && (!aes->nonceSet)) {
14775
        ret = MISSING_IV;
14776
    }
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
    if ((ret == 0) &&
14789
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
14790
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
14791
    {
14792
        ret = AES_GCM_OVERFLOW_E;
14793
    }
14794
14795
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
14796
        aes->invokeCtr[0]++;
14797
        if (aes->invokeCtr[0] == 0) {
14798
            aes->invokeCtr[1]++;
14799
            if (aes->invokeCtr[1] == 0)
14800
                ret = AES_GCM_OVERFLOW_E;
14801
        }
14802
    }
14803
14804
    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
        {
14826
            /* Encrypt the plaintext. */
14827
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
14828
            if (ret == 0) {
14829
                /* Update the authentication tag with any authentication data and the
14830
                 * new cipher text. */
14831
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
14832
            }
14833
        }
14834
    }
14835
14836
    return ret;
14837
}
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
{
14851
    int ret = 0;
14852
14853
    /* Check validity of parameters. */
14854
    if ((aes == NULL) || (authTag == NULL)) {
14855
        ret = BAD_FUNC_ARG;
14856
    }
14857
14858
    if (ret == 0)
14859
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
14860
14861
    /* Check key has been set. */
14862
    if ((ret == 0) && (!aes->gcmKeySet)) {
14863
        ret = MISSING_KEY;
14864
    }
14865
    /* Check IV has been set. */
14866
    if ((ret == 0) && (!aes->nonceSet)) {
14867
        ret = MISSING_IV;
14868
    }
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
    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
        {
14895
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
14896
        }
14897
    }
14898
14899
    if ((ret == 0) && aes->ctrSet) {
14900
        IncCtr((byte*)aes->reg, aes->nonceSz);
14901
    }
14902
14903
    return ret;
14904
}
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
{
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
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
14932
}
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
{
14938
    int ret = 0;
14939
14940
    /* Check validity of parameters. */
14941
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
14942
            ((out == NULL) || (in == NULL)))) {
14943
        ret = BAD_FUNC_ARG;
14944
    }
14945
14946
    /* Check key has been set. */
14947
    if ((ret == 0) && (!aes->gcmKeySet)) {
14948
        ret = MISSING_KEY;
14949
    }
14950
    /* Check IV has been set. */
14951
    if ((ret == 0) && (!aes->nonceSet)) {
14952
        ret = MISSING_IV;
14953
    }
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
    if ((ret == 0) &&
14961
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
14962
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
14963
    {
14964
        ret = AES_GCM_OVERFLOW_E;
14965
    }
14966
14967
    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
        {
14988
            /* Update the authentication tag with any authentication data and
14989
             * cipher text. */
14990
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
14991
            /* Decrypt the cipher text. */
14992
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
14993
        }
14994
    }
14995
14996
    return ret;
14997
}
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
{
15011
    int ret = 0;
15012
15013
    /* Check validity of parameters. */
15014
    if ((aes == NULL) || (authTag == NULL)) {
15015
        ret = BAD_FUNC_ARG;
15016
    }
15017
15018
    if (ret == 0)
15019
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
15020
15021
    /* Check key has been set. */
15022
    if ((ret == 0) && (!aes->gcmKeySet)) {
15023
        ret = MISSING_KEY;
15024
    }
15025
    /* Check IV has been set. */
15026
    if ((ret == 0) && (!aes->nonceSet)) {
15027
        ret = MISSING_IV;
15028
    }
15029
15030
    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
        {
15050
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
15051
            /* Calculate authentication tag. */
15052
            ret = AesGcmFinal_C(aes, calcTag, WC_AES_BLOCK_SIZE);
15053
            if (ret == 0) {
15054
                /* Check calculated tag matches the one passed in. */
15055
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
15056
                    ret = AES_GCM_AUTH_E;
15057
                }
15058
            }
15059
        }
15060
    }
15061
15062
    return ret;
15063
}
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
0
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
15075
0
    return (ivSz == GCM_NONCE_MIN_SZ ||
15076
0
            ivSz == GCM_NONCE_MID_SZ ||
15077
0
            ivSz == GCM_NONCE_MAX_SZ);
15078
0
}
15079
15080
15081
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
15082
0
{
15083
0
    int ret = 0;
15084
15085
0
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
15086
0
        ret = BAD_FUNC_ARG;
15087
0
    }
15088
15089
0
    if (ret == 0) {
15090
0
        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
0
        aes->invokeCtr[0] = 0;
15096
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
15097
    #ifdef WOLFSSL_AESGCM_STREAM
15098
        aes->ctrSet = 1;
15099
    #endif
15100
0
        aes->nonceSz = ivSz;
15101
0
    }
15102
15103
0
    return ret;
15104
0
}
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
    #ifdef WOLFSSL_AESGCM_STREAM
15136
        aes->ctrSet = 1;
15137
    #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
0
{
15150
0
    int ret = 0;
15151
15152
0
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
15153
0
        ivOut == NULL || ivOutSz != aes->nonceSz ||
15154
0
        (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
0
    if (ret == 0) {
15165
0
        aes->invokeCtr[0]++;
15166
0
        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
0
    }
15172
15173
0
    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
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
15179
0
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
15180
0
                               ivOut, ivOutSz,
15181
0
                               authTag, authTagSz,
15182
0
                               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
0
        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
0
        if (ret == 0 || ret == WC_NO_ERR_TRACE(WC_PENDING_E))
15191
0
            IncCtr((byte*)aes->reg, ivOutSz);
15192
0
    }
15193
15194
0
    return ret;
15195
0
}
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
#ifdef WOLFSSL_SMALL_STACK
15211
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
15212
#else
15213
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15214
0
#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
#ifdef WOLFSSL_SMALL_STACK
15226
    wc_AesDelete(aes, NULL);
15227
#else
15228
0
    wc_AesFree(aes);
15229
0
#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
#ifdef WOLFSSL_SMALL_STACK
15250
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
15251
#else
15252
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15253
0
#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
#ifdef WOLFSSL_SMALL_STACK
15262
    wc_AesDelete(aes, NULL);
15263
#else
15264
0
    wc_AesFree(aes);
15265
0
#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
{
15313
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
15314
        return BAD_FUNC_ARG;
15315
15316
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
15317
}
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
{
15325
    /* values here are from RFC 3610 section 2 */
15326
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
15327
            && sz != 16) {
15328
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
15329
        return BAD_FUNC_ARG;
15330
    }
15331
    return 0;
15332
}
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
{
15480
    int ret;
15481
15482
    /* process the bulk of the data */
15483
    while (inSz >= WC_AES_BLOCK_SIZE) {
15484
        xorbuf(out, in, WC_AES_BLOCK_SIZE);
15485
        in += WC_AES_BLOCK_SIZE;
15486
        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
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
15493
        if (ret != 0)
15494
            return ret;
15495
    }
15496
15497
    /* process remainder of the data */
15498
    if (inSz > 0) {
15499
        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
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
15505
        if (ret != 0)
15506
            return ret;
15507
    }
15508
15509
    return 0;
15510
}
15511
15512
static WARN_UNUSED_RESULT int roll_auth(
15513
    Aes* aes, const byte* in, word32 inSz, byte* out)
15514
{
15515
    word32 authLenSz;
15516
    word32 remainder;
15517
    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
    if (inSz <= 0xFEFF) {
15523
        authLenSz = 2;
15524
        out[0] ^= WC_OCTET(inSz >> 8);
15525
        out[1] ^= WC_OCTET(inSz);
15526
    }
15527
    else {
15528
        authLenSz = 6;
15529
        out[0] ^= 0xFF;
15530
        out[1] ^= 0xFE;
15531
        out[2] ^= WC_OCTET(inSz >> 24);
15532
        out[3] ^= WC_OCTET(inSz >> 16);
15533
        out[4] ^= WC_OCTET(inSz >>  8);
15534
        out[5] ^= WC_OCTET(inSz);
15535
    }
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
    remainder = WC_AES_BLOCK_SIZE - authLenSz;
15543
    if (inSz >= remainder) {
15544
        /* plenty of bulk data to fill the remainder of this block */
15545
        xorbuf(out + authLenSz, in, remainder);
15546
        inSz -= remainder;
15547
        in += remainder;
15548
    }
15549
    else {
15550
        /* not enough bulk data, copy what is available, and pad zero */
15551
        xorbuf(out + authLenSz, in, inSz);
15552
        inSz = 0;
15553
    }
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
    ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
15559
15560
    if ((ret == 0) && (inSz > 0)) {
15561
        ret = roll_x(aes, in, inSz, out);
15562
    }
15563
15564
    return ret;
15565
}
15566
15567
15568
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
15569
{
15570
    word32 i;
15571
15572
    for (i = 0; i < lenSz; i++) {
15573
        /* See IncrementAesCounter(): a bare ++byte leaves 0x100 in the cell
15574
         * and never carries. */
15575
        B[WC_AES_BLOCK_SIZE - 1 - i] =
15576
            WC_OCTET(B[WC_AES_BLOCK_SIZE - 1 - i] + 1);
15577
        if (B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
15578
    }
15579
}
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
{
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
    byte A[WC_AES_BLOCK_SIZE];
15633
    byte B[WC_AES_BLOCK_SIZE];
15634
#endif
15635
    byte lenSz;
15636
    word32 i;
15637
    byte mask = 0xFF;
15638
    const word32 wordSz = (word32)sizeof(word32);
15639
    int ret;
15640
15641
    /* sanity check on arguments */
15642
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
15643
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
15644
            authTagSz > WC_AES_BLOCK_SIZE)
15645
        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
    if (authIn == NULL && authInSz > 0)
15650
        return BAD_FUNC_ARG;
15651
15652
    /* sanity check on tag size */
15653
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
15654
        return BAD_FUNC_ARG;
15655
    }
15656
15657
    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
    if ((lenSz < sizeof(inSz)) &&
15663
        (inSz >= ((word32)1 << (lenSz * 8))))
15664
    {
15665
        return AES_CCM_OVERFLOW_E;
15666
    }
15667
15668
#ifdef WOLF_CRYPTO_CB
15669
    #ifndef WOLF_CRYPTO_CB_FIND
15670
    if (aes->devId != INVALID_DEVID)
15671
    #endif
15672
    {
15673
        int crypto_cb_ret =
15674
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
15675
                                      authTag, authTagSz, authIn, authInSz);
15676
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15677
            return crypto_cb_ret;
15678
        /* fall-through when unavailable */
15679
    }
15680
#endif
15681
15682
    /* Software/HW key schedule required from here on. */
15683
    if (!WC_AES_KEY_IS_SET(aes)) {
15684
        WOLFSSL_MSG("AES key not set");
15685
        return MISSING_KEY;
15686
    }
15687
15688
    XMEMSET(A, 0, sizeof(A));
15689
    XMEMCPY(B+1, nonce, nonceSz);
15690
15691
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
15692
                  + (8 * (((byte)authTagSz - 2) / 2))
15693
                  + (lenSz - 1));
15694
    for (i = 0; i < lenSz; i++) {
15695
        if (mask && i >= wordSz)
15696
            mask = 0x00;
15697
        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
15698
    }
15699
15700
#ifdef WOLFSSL_CHECK_MEM_ZERO
15701
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
15702
#endif
15703
15704
    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
    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
    if ((ret == 0) && (authInSz > 0))
15715
        ret = roll_auth(aes, authIn, authInSz, A);
15716
15717
    if ((ret == 0) && (inSz > 0))
15718
        ret = roll_x(aes, in, inSz, A);
15719
15720
    if (ret == 0) {
15721
        XMEMCPY(authTag, A, authTagSz);
15722
15723
        B[0] = (byte)(lenSz - 1U);
15724
        for (i = 0; i < lenSz; i++)
15725
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15726
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15727
    }
15728
15729
    if (ret == 0) {
15730
        xorbuf(authTag, A, authTagSz);
15731
        B[15] = 1;
15732
    }
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
    if (ret == 0) {
15753
        while (inSz >= WC_AES_BLOCK_SIZE) {
15754
            ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15755
            if (ret != 0)
15756
                break;
15757
            xorbuf(A, in, WC_AES_BLOCK_SIZE);
15758
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
15759
15760
            AesCcmCtrInc(B, lenSz);
15761
            inSz -= WC_AES_BLOCK_SIZE;
15762
            in += WC_AES_BLOCK_SIZE;
15763
            out += WC_AES_BLOCK_SIZE;
15764
        }
15765
    }
15766
    if ((ret == 0) && (inSz > 0)) {
15767
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15768
    }
15769
    if ((ret == 0) && (inSz > 0)) {
15770
        xorbuf(A, in, inSz);
15771
        XMEMCPY(out, A, inSz);
15772
    }
15773
15774
    ForceZero(A, sizeof(A));
15775
    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
    VECTOR_REGISTERS_POP;
15783
15784
    return ret;
15785
}
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
{
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
    byte A[WC_AES_BLOCK_SIZE];
15799
    byte B[WC_AES_BLOCK_SIZE];
15800
#endif
15801
    byte* o;
15802
    byte lenSz;
15803
    word32 i, oSz;
15804
    byte mask = 0xFF;
15805
    const word32 wordSz = (word32)sizeof(word32);
15806
    int ret = 0;
15807
#ifdef WC_AES_HAVE_PREFETCH_ARG
15808
    int did_prefetches = 0;
15809
#endif
15810
15811
    /* sanity check on arguments */
15812
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
15813
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
15814
        authTagSz > WC_AES_BLOCK_SIZE)
15815
        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
    if (authIn == NULL && authInSz > 0)
15820
        return BAD_FUNC_ARG;
15821
15822
    /* sanity check on tag size */
15823
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
15824
        return BAD_FUNC_ARG;
15825
    }
15826
15827
    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
    if ((lenSz < sizeof(inSz)) &&
15833
        (inSz >= ((word32)1 << (lenSz * 8))))
15834
    {
15835
        return AES_CCM_OVERFLOW_E;
15836
    }
15837
15838
#ifdef WOLF_CRYPTO_CB
15839
    #ifndef WOLF_CRYPTO_CB_FIND
15840
    if (aes->devId != INVALID_DEVID)
15841
    #endif
15842
    {
15843
        int crypto_cb_ret =
15844
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
15845
            authTag, authTagSz, authIn, authInSz);
15846
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15847
            return crypto_cb_ret;
15848
        /* fall-through when unavailable */
15849
    }
15850
#endif
15851
15852
    /* Software/HW key schedule required from here on. */
15853
    if (!WC_AES_KEY_IS_SET(aes)) {
15854
        WOLFSSL_MSG("AES key not set");
15855
        return MISSING_KEY;
15856
    }
15857
15858
    o = out;
15859
    oSz = inSz;
15860
    XMEMSET(A, 0, sizeof A);
15861
    XMEMCPY(B+1, nonce, nonceSz);
15862
15863
    B[0] = (byte)(lenSz - 1U);
15864
    for (i = 0; i < lenSz; i++)
15865
        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15866
    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
    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
    while (oSz >= WC_AES_BLOCK_SIZE) {
15896
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15897
        if (ret != 0)
15898
            break;
15899
        xorbuf(A, in, WC_AES_BLOCK_SIZE);
15900
        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
15901
        AesCcmCtrInc(B, lenSz);
15902
        oSz -= WC_AES_BLOCK_SIZE;
15903
        in += WC_AES_BLOCK_SIZE;
15904
        o += WC_AES_BLOCK_SIZE;
15905
    }
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
    if ((ret == 0) && (oSz > 0))
15910
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15911
15912
    if ((ret == 0) && (oSz > 0)) {
15913
        xorbuf(A, in, oSz);
15914
        XMEMCPY(o, A, oSz);
15915
    }
15916
15917
    if (ret == 0) {
15918
        o = out;
15919
        oSz = inSz;
15920
15921
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
15922
                      + (8 * (((byte)authTagSz - 2) / 2))
15923
                      + (lenSz - 1));
15924
        for (i = 0; i < lenSz; i++) {
15925
            if (mask && i >= wordSz)
15926
                mask = 0x00;
15927
            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
15928
        }
15929
15930
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15931
    }
15932
15933
    if (ret == 0) {
15934
        if (authInSz > 0)
15935
            ret = roll_auth(aes, authIn, authInSz, A);
15936
    }
15937
    if ((ret == 0) && (inSz > 0))
15938
        ret = roll_x(aes, o, oSz, A);
15939
15940
    if (ret == 0) {
15941
        B[0] = (byte)(lenSz - 1U);
15942
        for (i = 0; i < lenSz; i++)
15943
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15944
        ret = AesEncrypt_preFetchOpt(aes, B, B, &did_prefetches);
15945
    }
15946
15947
    if (ret == 0)
15948
        xorbuf(A, B, authTagSz);
15949
15950
    if (ret == 0) {
15951
        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
            if (inSz > 0)
15960
                XMEMSET(out, 0, inSz);
15961
            #endif
15962
            ret = AES_CCM_AUTH_E;
15963
        }
15964
    }
15965
15966
    ForceZero(A, sizeof(A));
15967
    ForceZero(B, sizeof(B));
15968
    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
    VECTOR_REGISTERS_POP;
15976
15977
    return ret;
15978
}
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
{
15988
    int ret = 0;
15989
15990
    if (aes == NULL || nonce == NULL ||
15991
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
15992
15993
        ret = BAD_FUNC_ARG;
15994
    }
15995
15996
    if (ret == 0) {
15997
        XMEMCPY(aes->reg, nonce, nonceSz);
15998
        aes->nonceSz = nonceSz;
15999
16000
        /* Invocation counter should be 2^61 */
16001
        aes->invokeCtr[0] = 0;
16002
        aes->invokeCtr[1] = 0xE0000000;
16003
    }
16004
16005
    return ret;
16006
}
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
{
16014
    int ret = 0;
16015
16016
    if (aes == NULL || out == NULL ||
16017
        (in == NULL && sz != 0) ||
16018
        ivOut == NULL ||
16019
        (authIn == NULL && authInSz != 0) ||
16020
        (ivOutSz != aes->nonceSz)) {
16021
16022
        ret = BAD_FUNC_ARG;
16023
    }
16024
16025
    if (ret == 0) {
16026
        aes->invokeCtr[0]++;
16027
        if (aes->invokeCtr[0] == 0) {
16028
            aes->invokeCtr[1]++;
16029
            if (aes->invokeCtr[1] == 0)
16030
                ret = AES_CCM_OVERFLOW_E;
16031
        }
16032
    }
16033
16034
    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
        XMEMCPY(ivOut, aes->reg, aes->nonceSz);
16038
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
16039
                               ivOut, aes->nonceSz,
16040
                               authTag, authTagSz,
16041
                               authIn, authInSz);
16042
        /* Put the nonce back unconditionally - see wc_AesGcmEncrypt_ex(). */
16043
        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
        if (ret == 0 || ret == WC_NO_ERR_TRACE(WC_PENDING_E))
16047
            IncCtr((byte*)aes->reg, aes->nonceSz);
16048
    }
16049
16050
    return ret;
16051
}
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
#define AES_NEW_INIT_ID     1
16062
#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
#ifdef WOLF_PRIVATE_KEY_ID
16077
        case AES_NEW_INIT_ID:
16078
            if (id == NULL || idLen == 0 || label != NULL) {
16079
                ret = BAD_FUNC_ARG;
16080
            }
16081
            else {
16082
                ret = wc_AesInit_Id(aes, id, idLen, heap, devId);
16083
            }
16084
            break;
16085
        case AES_NEW_INIT_LABEL:
16086
            if (label == NULL || id != NULL || idLen != 0) {
16087
                ret = BAD_FUNC_ARG;
16088
            }
16089
            else {
16090
                ret = wc_AesInit_Label(aes, label, heap, devId);
16091
            }
16092
            break;
16093
#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
{
16130
    return _AesNew_common(heap, devId, result_code,
16131
                          AES_NEW_INIT_ID, id, len, NULL);
16132
}
16133
16134
Aes* wc_AesNew_Label(const char* label, void* heap, int devId,
16135
                      int *result_code)
16136
{
16137
    return _AesNew_common(heap, devId, result_code,
16138
                          AES_NEW_INIT_LABEL, NULL, 0, label);
16139
}
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
0
{
16159
0
    int ret = 0;
16160
16161
0
    if (aes == NULL)
16162
0
        return BAD_FUNC_ARG;
16163
16164
0
    XMEMSET(aes, 0, sizeof(*aes));
16165
16166
0
    aes->heap = heap;
16167
16168
#if defined(WOLF_CRYPTO_CB)
16169
    aes->devId = devId;
16170
    aes->devCtx = NULL;
16171
#else
16172
0
    (void)devId;
16173
0
#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
0
    return ret;
16202
0
}
16203
16204
#ifdef WOLF_PRIVATE_KEY_ID
16205
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
16206
{
16207
    int ret = 0;
16208
16209
    if (aes == NULL || (id == NULL && len > 0))
16210
        ret = BAD_FUNC_ARG;
16211
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
16212
        ret = BUFFER_E;
16213
16214
    if (ret == 0)
16215
        ret = wc_AesInit(aes, heap, devId);
16216
    if (ret == 0 && id != NULL && len != 0) {
16217
        XMEMCPY(aes->id, id, (size_t)len);
16218
        aes->idLen = len;
16219
        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
    }
16223
16224
    return ret;
16225
}
16226
16227
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
16228
{
16229
    int ret = 0;
16230
    size_t labelLen = 0;
16231
16232
    if (aes == NULL || label == NULL)
16233
        ret = BAD_FUNC_ARG;
16234
    if (ret == 0) {
16235
        labelLen = XSTRLEN(label);
16236
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
16237
            ret = BUFFER_E;
16238
    }
16239
16240
    if (ret == 0)
16241
        ret = wc_AesInit(aes, heap, devId);
16242
    if (ret == 0) {
16243
        XMEMCPY(aes->label, label, labelLen);
16244
        aes->labelLen = (int)labelLen;
16245
        aes->idLen = 0;
16246
        /* keyInstalled stays 0: see wc_AesInit_Id() above. */
16247
    }
16248
16249
    return ret;
16250
}
16251
#endif
16252
16253
/* Free Aes resources */
16254
void wc_AesFree(Aes* aes)
16255
0
{
16256
0
    if (aes == NULL) {
16257
0
        return;
16258
0
    }
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
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
16315
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
16316
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
16317
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
16318
#endif
16319
#if defined(WOLFSSL_IMXRT_DCP)
16320
    DCPAesFree(aes);
16321
#endif
16322
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
16323
    !defined(WOLFSSL_AESNI)
16324
    if (aes->streamData != NULL) {
16325
        ForceZero(aes->streamData, aes->streamData_sz);
16326
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
16327
        aes->streamData = NULL;
16328
    }
16329
#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
0
    ForceZero(aes, sizeof(Aes));
16354
16355
#ifdef WOLFSSL_CHECK_MEM_ZERO
16356
    wc_MemZero_Check(aes, sizeof(Aes));
16357
#endif
16358
0
}
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
{
16533
    int ret = 0;
16534
16535
#ifdef WOLF_CRYPTO_CB
16536
    #ifndef WOLF_CRYPTO_CB_FIND
16537
    if (aes->devId != INVALID_DEVID)
16538
    #endif
16539
    {
16540
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
16541
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16542
            return ret;
16543
        ret = 0;
16544
        /* fall-through when unavailable */
16545
    }
16546
#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
    if (!WC_AES_KEY_IS_SET(aes)) {
16559
        WOLFSSL_MSG("AES key not set");
16560
        return MISSING_KEY;
16561
    }
16562
16563
    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
    {
16623
#if defined(NEED_AES_TABLES)
16624
        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
    }
16640
#endif
16641
16642
    VECTOR_REGISTERS_POP;
16643
16644
    return ret;
16645
}
16646
16647
#ifdef HAVE_AES_DECRYPT
16648
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
16649
    Aes* aes, byte* out, const byte* in, word32 sz)
16650
{
16651
    int ret = 0;
16652
16653
#ifdef WOLF_CRYPTO_CB
16654
    #ifndef WOLF_CRYPTO_CB_FIND
16655
    if (aes->devId != INVALID_DEVID)
16656
    #endif
16657
    {
16658
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
16659
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16660
            return ret;
16661
        ret = 0;
16662
        /* fall-through when unavailable */
16663
    }
16664
#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
    if (!WC_AES_KEY_IS_SET(aes)) {
16675
        WOLFSSL_MSG("AES key not set");
16676
        return MISSING_KEY;
16677
    }
16678
16679
    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
    {
16739
#if defined(NEED_AES_TABLES)
16740
        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
    }
16753
#endif
16754
16755
    VECTOR_REGISTERS_POP;
16756
16757
    return ret;
16758
}
16759
#endif
16760
16761
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16762
{
16763
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16764
      return BAD_FUNC_ARG;
16765
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
16766
        return BAD_LENGTH_E;
16767
    }
16768
16769
    return _AesEcbEncrypt(aes, out, in, sz);
16770
}
16771
16772
#ifdef HAVE_AES_DECRYPT
16773
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16774
{
16775
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16776
      return BAD_FUNC_ARG;
16777
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
16778
        return BAD_LENGTH_E;
16779
    }
16780
16781
    return _AesEcbDecrypt(aes, out, in, sz);
16782
}
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
{
16834
    int ret = 0;
16835
    word32 processed;
16836
#ifdef WC_AES_HAVE_PREFETCH_ARG
16837
    int did_prefetches = 0;
16838
#endif
16839
16840
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16841
        return BAD_FUNC_ARG;
16842
    }
16843
    if (!WC_AES_KEY_IS_SET(aes)) {
16844
        WOLFSSL_MSG("AES key not set");
16845
        return MISSING_KEY;
16846
    }
16847
    if (sz == 0) {
16848
        return 0;
16849
    }
16850
16851
    if (aes->left > 0) {
16852
        /* consume any unused bytes left in aes->tmp */
16853
        processed = min(aes->left, sz);
16854
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16855
            processed);
16856
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out,
16857
            processed);
16858
        aes->left -= processed;
16859
        out += processed;
16860
        in += processed;
16861
        sz -= processed;
16862
    }
16863
16864
    VECTOR_REGISTERS_PUSH;
16865
16866
    while (sz >= WC_AES_BLOCK_SIZE) {
16867
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
16868
                                        &did_prefetches);
16869
        if (ret != 0) {
16870
            break;
16871
        }
16872
        xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
16873
        XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
16874
        out += WC_AES_BLOCK_SIZE;
16875
        in  += WC_AES_BLOCK_SIZE;
16876
        sz  -= WC_AES_BLOCK_SIZE;
16877
    }
16878
16879
    /* encrypt left over data */
16880
    if ((ret == 0) && sz) {
16881
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16882
                                     &did_prefetches);
16883
        if (ret == 0) {
16884
            xorbufout(out, in, aes->tmp, sz);
16885
            XMEMCPY(aes->reg, out, sz);
16886
            aes->left = WC_AES_BLOCK_SIZE - sz;
16887
        }
16888
    }
16889
16890
    VECTOR_REGISTERS_POP;
16891
16892
    return ret;
16893
}
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
{
16911
    int ret = 0;
16912
    word32 processed;
16913
#ifdef WC_AES_HAVE_PREFETCH_ARG
16914
    int did_prefetches = 0;
16915
#endif
16916
#ifndef WC_AES_CFB_DEC_BUF_BLOCKS
16917
    #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
#ifdef WOLFSSL_SMALL_STACK
16922
    byte *tmp = NULL;
16923
#endif
16924
16925
    (void)mode;
16926
16927
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16928
        return BAD_FUNC_ARG;
16929
    }
16930
    if (!WC_AES_KEY_IS_SET(aes)) {
16931
        WOLFSSL_MSG("AES key not set");
16932
        return MISSING_KEY;
16933
    }
16934
    if (sz == 0) {
16935
        return 0;
16936
    }
16937
16938
    if (aes->left > 0) {
16939
        /* consume any unused bytes left in aes->tmp */
16940
        processed = min(aes->left, sz);
16941
        /* copy input over to aes->reg */
16942
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, processed);
16943
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16944
            processed);
16945
        aes->left -= processed;
16946
        out += processed;
16947
        in += processed;
16948
        sz -= processed;
16949
    }
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
    VECTOR_REGISTERS_PUSH;
16965
#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
    while (sz >= WC_AES_BLOCK_SIZE) {
17027
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17028
                                        &did_prefetches);
17029
        if (ret != 0) {
17030
            break;
17031
        }
17032
        XMEMCPY((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
17033
        xorbufout(out, in, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
17034
        out += WC_AES_BLOCK_SIZE;
17035
        in  += WC_AES_BLOCK_SIZE;
17036
        sz  -= WC_AES_BLOCK_SIZE;
17037
    }
17038
17039
    /* decrypt left over data */
17040
    if ((ret == 0) && sz) {
17041
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17042
                                        &did_prefetches);
17043
        if (ret == 0) {
17044
            XMEMCPY(aes->reg, in, sz);
17045
            xorbufout(out, in, aes->tmp, sz);
17046
            aes->left = WC_AES_BLOCK_SIZE - sz;
17047
        }
17048
    }
17049
17050
    VECTOR_REGISTERS_POP;
17051
17052
#ifdef WOLFSSL_SMALL_STACK
17053
    /* Free tmp after restoring interrupts, so that GFP_KERNEL is usable. */
17054
    XFREE(tmp, NULL, DYNAMIC_TYPE_AES);
17055
#endif
17056
17057
    return ret;
17058
}
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
{
17074
#ifdef WOLF_CRYPTO_CB
17075
    if (aes == NULL)
17076
        return BAD_FUNC_ARG;
17077
    #ifndef WOLF_CRYPTO_CB_FIND
17078
    if (aes->devId != INVALID_DEVID)
17079
    #endif
17080
    {
17081
        int crypto_cb_ret = wc_CryptoCb_AesCfbEncrypt(aes, out, in, sz);
17082
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17083
            return crypto_cb_ret;
17084
        /* fall-through when unavailable */
17085
    }
17086
#endif
17087
    return AesCfbEncrypt_C(aes, out, in, sz);
17088
}
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
{
17105
#ifdef WOLF_CRYPTO_CB
17106
    if (aes == NULL)
17107
        return BAD_FUNC_ARG;
17108
    #ifndef WOLF_CRYPTO_CB_FIND
17109
    if (aes->devId != INVALID_DEVID)
17110
    #endif
17111
    {
17112
        int crypto_cb_ret = wc_CryptoCb_AesCfbDecrypt(aes, out, in, sz);
17113
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17114
            return crypto_cb_ret;
17115
        /* fall-through when unavailable */
17116
    }
17117
#endif
17118
    return AesCfbDecrypt_C(aes, out, in, sz, AES_CFB_MODE);
17119
}
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
{
17127
    int i;
17128
17129
    if (shift == WOLFSSL_BIT_SIZE) {
17130
        /* shifting over by 8 bits */
17131
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
17132
            ary[i] = ary[i+1];
17133
        }
17134
        ary[i] = 0;
17135
    }
17136
    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
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
17141
            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
17142
            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
17143
            ary[i] = WC_OCTET((ary[i] << shift) + carry);
17144
        }
17145
        ary[i] = WC_OCTET(ary[i] << shift);
17146
    }
17147
}
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
{
17154
    byte *pt;
17155
    int ret = 0;
17156
#ifdef WC_AES_HAVE_PREFETCH_ARG
17157
    int did_prefetches = 0;
17158
#endif
17159
17160
    if (aes == NULL || out == NULL || in == NULL) {
17161
        return BAD_FUNC_ARG;
17162
    }
17163
17164
    if (!WC_AES_KEY_IS_SET(aes)) {
17165
        WOLFSSL_MSG("AES key not set");
17166
        return MISSING_KEY;
17167
    }
17168
    if (sz == 0) {
17169
        return 0;
17170
    }
17171
17172
    VECTOR_REGISTERS_PUSH;
17173
17174
    while (sz > 0) {
17175
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17176
                                        &did_prefetches);
17177
        if (ret != 0)
17178
            break;
17179
        if (dir == AES_DECRYPTION) {
17180
            pt = (byte*)aes->reg;
17181
17182
            /* LSB + CAT */
17183
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
17184
            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
17185
        }
17186
17187
        /* MSB + XOR */
17188
    #ifdef BIG_ENDIAN_ORDER
17189
        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
17190
    #endif
17191
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
17192
        if (dir == AES_ENCRYPTION) {
17193
            pt = (byte*)aes->reg;
17194
17195
            /* LSB + CAT */
17196
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
17197
            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
17198
        }
17199
17200
        out += 1;
17201
        in  += 1;
17202
        sz  -= 1;
17203
    }
17204
17205
    VECTOR_REGISTERS_POP;
17206
17207
    return ret;
17208
}
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
{
17215
    byte tmp;
17216
    byte cur = 0; /* hold current work in order to handle inline in=out */
17217
    byte* pt;
17218
    int bit = 7;
17219
    int ret = 0;
17220
#ifdef WC_AES_HAVE_PREFETCH_ARG
17221
    int did_prefetches = 0;
17222
#endif
17223
17224
    if (aes == NULL || out == NULL || in == NULL) {
17225
        return BAD_FUNC_ARG;
17226
    }
17227
17228
    if (!WC_AES_KEY_IS_SET(aes)) {
17229
        WOLFSSL_MSG("AES key not set");
17230
        return MISSING_KEY;
17231
    }
17232
    if (sz == 0) {
17233
        return 0;
17234
    }
17235
17236
    VECTOR_REGISTERS_PUSH;
17237
17238
    while (sz > 0) {
17239
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17240
                                        &did_prefetches);
17241
        if (ret != 0)
17242
            break;
17243
        if (dir == AES_DECRYPTION) {
17244
            pt = (byte*)aes->reg;
17245
17246
            /* LSB + CAT */
17247
            tmp = (byte)((0X01U << bit) & in[0]);
17248
            tmp = (byte)(tmp >> bit);
17249
            tmp &= 0x01;
17250
            shiftLeftArray((byte*)aes->reg, 1);
17251
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
17252
        }
17253
17254
        /* MSB  + XOR */
17255
        tmp = (byte)((0X01U << bit) & in[0]);
17256
        pt = (byte*)aes->tmp;
17257
        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
17258
        tmp &= 0x01;
17259
        cur = (byte)(cur | (tmp << bit));
17260
17261
17262
        if (dir == AES_ENCRYPTION) {
17263
            pt = (byte*)aes->reg;
17264
17265
            /* LSB + CAT */
17266
            shiftLeftArray((byte*)aes->reg, 1);
17267
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
17268
        }
17269
17270
        bit--;
17271
        if (bit < 0) {
17272
            out[0] = cur;
17273
            out += 1;
17274
            in  += 1;
17275
            sz  -= 1;
17276
            bit = 7U;
17277
            cur = 0;
17278
        }
17279
        else {
17280
            sz -= 1;
17281
        }
17282
    }
17283
17284
    if (ret == 0) {
17285
        if (bit < 7) {
17286
            out[0] = cur;
17287
        }
17288
    }
17289
17290
    VECTOR_REGISTERS_POP;
17291
17292
    return ret;
17293
}
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
{
17308
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
17309
}
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
{
17324
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
17325
}
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
{
17340
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
17341
}
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
{
17356
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
17357
}
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
{
17381
    int ret = 0;
17382
    word32 processed;
17383
#ifdef WC_AES_HAVE_PREFETCH_ARG
17384
    int did_prefetches = 0;
17385
#endif
17386
17387
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
17388
        return BAD_FUNC_ARG;
17389
    }
17390
    if (!WC_AES_KEY_IS_SET(aes)) {
17391
        WOLFSSL_MSG("AES key not set");
17392
        return MISSING_KEY;
17393
    }
17394
    if (sz == 0) {
17395
        return 0;
17396
    }
17397
17398
    if (aes->left > 0) {
17399
        /* consume any unused bytes left in aes->tmp */
17400
        processed = min(aes->left, sz);
17401
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
17402
            processed);
17403
        aes->left -= processed;
17404
        out += processed;
17405
        in += processed;
17406
        sz -= processed;
17407
    }
17408
17409
    VECTOR_REGISTERS_PUSH;
17410
17411
    while (sz >= WC_AES_BLOCK_SIZE) {
17412
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
17413
                                        &did_prefetches);
17414
        if (ret != 0) {
17415
            break;
17416
        }
17417
        xorbufout(out, in, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
17418
        out += WC_AES_BLOCK_SIZE;
17419
        in  += WC_AES_BLOCK_SIZE;
17420
        sz  -= WC_AES_BLOCK_SIZE;
17421
    }
17422
17423
    /* encrypt left over data */
17424
    if ((ret == 0) && sz) {
17425
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17426
                                        &did_prefetches);
17427
        if (ret == 0) {
17428
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
17429
            xorbufout(out, in, aes->tmp, sz);
17430
            aes->left = WC_AES_BLOCK_SIZE - sz;
17431
        }
17432
    }
17433
17434
    VECTOR_REGISTERS_POP;
17435
17436
    return ret;
17437
}
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
{
17452
#ifdef WOLF_CRYPTO_CB
17453
    if (aes == NULL)
17454
        return BAD_FUNC_ARG;
17455
    #ifndef WOLF_CRYPTO_CB_FIND
17456
    if (aes->devId != INVALID_DEVID)
17457
    #endif
17458
    {
17459
        int crypto_cb_ret = wc_CryptoCb_AesOfbEncrypt(aes, out, in, sz);
17460
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17461
            return crypto_cb_ret;
17462
        /* fall-through when unavailable */
17463
    }
17464
#endif
17465
    return AesOfbCrypt_C(aes, out, in, sz);
17466
}
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
{
17483
#ifdef WOLF_CRYPTO_CB
17484
    if (aes == NULL)
17485
        return BAD_FUNC_ARG;
17486
    #ifndef WOLF_CRYPTO_CB_FIND
17487
    if (aes->devId != INVALID_DEVID)
17488
    #endif
17489
    {
17490
        int crypto_cb_ret = wc_CryptoCb_AesOfbDecrypt(aes, out, in, sz);
17491
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17492
            return crypto_cb_ret;
17493
        /* fall-through when unavailable */
17494
    }
17495
#endif
17496
    return AesOfbCrypt_C(aes, out, in, sz);
17497
}
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
{
17508
    word32 i;
17509
    word32 bytes;
17510
17511
    bytes = sizeof(word32);
17512
    for (i = 0; i < sizeof(word32); i++) {
17513
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
17514
        bytes--;
17515
    }
17516
}
17517
17518
/* Increment key wrap counter */
17519
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
17520
{
17521
    int i;
17522
17523
    /* in network byte order so start at end and work back */
17524
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
17525
        /* See IncrementAesCounter() on why this masks to an octet. */
17526
        inOutCtr[i] = WC_OCTET(inOutCtr[i] + 1);
17527
        if (inOutCtr[i] != 0)  /* we're done unless we overflow */
17528
            return;
17529
    }
17530
}
17531
17532
/* Decrement key wrap counter */
17533
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
17534
{
17535
    int i;
17536
17537
    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
        inOutCtr[i] = WC_OCTET(inOutCtr[i] - 1);
17541
        if (inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
17542
            return;
17543
    }
17544
}
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
{
17550
    word32 i;
17551
    byte* r;
17552
    int j;
17553
    int ret = 0;
17554
17555
    byte t[KEYWRAP_BLOCK_SIZE];
17556
    byte tmp[WC_AES_BLOCK_SIZE];
17557
17558
    /* at least two 64-bit blocks, on a 64-bit boundary */
17559
    if (aes == NULL || out == NULL || aiv == NULL ||
17560
        inSz < 2 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0) {
17561
        return BAD_FUNC_ARG;
17562
    }
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
    r = out + KEYWRAP_BLOCK_SIZE;
17576
    XMEMSET(t, 0, sizeof(t));
17577
17578
    /* A = initial value */
17579
    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
    for (j = 0; j <= 5; j++) {
17588
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
17589
            /* load R[i] */
17590
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
17591
17592
#ifdef HAVE_AES_ECB
17593
            ret = wc_AesEcbEncrypt(aes, tmp, tmp, WC_AES_BLOCK_SIZE);
17594
#else
17595
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
17596
#endif
17597
            if (ret != 0)
17598
                break;
17599
17600
            /* calculate new A */
17601
            IncrementKeyWrapCounter(t);
17602
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
17603
17604
            /* save R[i] */
17605
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
17606
            r += KEYWRAP_BLOCK_SIZE;
17607
        }
17608
        if (ret != 0)
17609
            break;
17610
        r = out + KEYWRAP_BLOCK_SIZE;
17611
    }
17612
17613
#ifndef HAVE_AES_ECB
17614
    VECTOR_REGISTERS_POP;
17615
#endif
17616
17617
    if (ret != 0)
17618
        return ret;
17619
17620
    /* C[0] = A */
17621
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
17622
17623
    return 0;
17624
}
17625
17626
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
17627
        word32 outSz, const byte* iv)
17628
{
17629
    int ret;
17630
    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
    if (aes == NULL || in == NULL || out == NULL ||
17635
        inSz < 2 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0 ||
17636
        inSz > 0x7FFFFFFFU - KEYWRAP_BLOCK_SIZE ||
17637
        outSz < inSz + KEYWRAP_BLOCK_SIZE)
17638
        return BAD_FUNC_ARG;
17639
17640
#ifdef WOLF_CRYPTO_CB
17641
    #ifndef WOLF_CRYPTO_CB_FIND
17642
    if (aes->devId != INVALID_DEVID)
17643
    #endif
17644
    {
17645
        ret = wc_CryptoCb_AesKeyWrap(aes, in, inSz, out, outSz, iv, 0);
17646
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
17647
            return ret;
17648
        }
17649
        /* fall through to software when unavailable */
17650
    }
17651
#endif
17652
17653
    /* user IV is optional */
17654
    if (iv == NULL) {
17655
        XMEMSET(aiv, 0xA6, KEYWRAP_BLOCK_SIZE);
17656
    }
17657
    else {
17658
        XMEMCPY(aiv, iv, KEYWRAP_BLOCK_SIZE);
17659
    }
17660
17661
    /* stage plaintext at out+8; XMEMMOVE so in-place wrap (in == out) is safe */
17662
    XMEMMOVE(out + KEYWRAP_BLOCK_SIZE, in, inSz);
17663
17664
    ret = AesKeyWrapRaw(aes, inSz, out, aiv);
17665
    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
        ForceZero(out + KEYWRAP_BLOCK_SIZE, inSz);
17669
        return ret;
17670
    }
17671
17672
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
17673
}
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
{
17679
    WC_DECLARE_VAR(aes, Aes, 1, 0);
17680
    int ret;
17681
17682
    if (key == NULL)
17683
        return BAD_FUNC_ARG;
17684
17685
#ifdef WOLFSSL_SMALL_STACK
17686
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
17687
                              DYNAMIC_TYPE_AES)) == NULL)
17688
        return MEMORY_E;
17689
#endif
17690
17691
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17692
    if (ret != 0)
17693
        goto out;
17694
17695
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
17696
    if (ret != 0) {
17697
        wc_AesFree(aes);
17698
        goto out;
17699
    }
17700
17701
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
17702
17703
    wc_AesFree(aes);
17704
17705
  out:
17706
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
17707
17708
    return ret;
17709
}
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
{
17716
    byte* r;
17717
    word32 i, n;
17718
    int j;
17719
    int ret = 0;
17720
17721
    byte t[KEYWRAP_BLOCK_SIZE];
17722
    byte tmp[WC_AES_BLOCK_SIZE];
17723
17724
    /* (n+1) blocks in, n >= 2 recovered blocks out, on a 64-bit boundary */
17725
    if (aes == NULL || in == NULL || out == NULL || aOut == NULL ||
17726
        inSz < 3 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0) {
17727
        return BAD_FUNC_ARG;
17728
    }
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
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
17743
    XMEMMOVE(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
17744
    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
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
17754
    InitKeyWrapCounter(t, 6 * n);
17755
17756
    for (j = 5; j >= 0; j--) {
17757
        for (i = n; i >= 1; i--) {
17758
17759
            /* calculate A */
17760
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
17761
            DecrementKeyWrapCounter(t);
17762
17763
            /* load R[i], starting at end of R */
17764
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
17765
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
17766
#ifdef HAVE_AES_ECB
17767
            ret = wc_AesEcbDecrypt(aes, tmp, tmp, WC_AES_BLOCK_SIZE);
17768
#else
17769
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
17770
#endif
17771
            if (ret != 0)
17772
                break;
17773
17774
            /* save R[i] */
17775
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
17776
        }
17777
        if (ret != 0)
17778
            break;
17779
    }
17780
17781
#ifndef HAVE_AES_ECB
17782
    VECTOR_REGISTERS_POP;
17783
#endif
17784
17785
    if (ret != 0)
17786
        return ret;
17787
17788
    /* return recovered A */
17789
    XMEMCPY(aOut, tmp, KEYWRAP_BLOCK_SIZE);
17790
17791
    return 0;
17792
}
17793
17794
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
17795
        word32 outSz, const byte* iv)
17796
{
17797
    int ret;
17798
    byte a[KEYWRAP_BLOCK_SIZE];
17799
17800
    const byte* expIv;
17801
    const byte defaultIV[] = {
17802
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
17803
    };
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
    if (aes == NULL || in == NULL || out == NULL ||
17808
        inSz < 3 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0 ||
17809
        inSz > 0x7FFFFFFFU || outSz < inSz - KEYWRAP_BLOCK_SIZE)
17810
        return BAD_FUNC_ARG;
17811
17812
#ifdef WOLF_CRYPTO_CB
17813
    #ifndef WOLF_CRYPTO_CB_FIND
17814
    if (aes->devId != INVALID_DEVID)
17815
    #endif
17816
    {
17817
        ret = wc_CryptoCb_AesKeyUnWrap(aes, in, inSz, out, outSz, iv, 0);
17818
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
17819
            return ret;
17820
        }
17821
        /* fall through to software when unavailable */
17822
    }
17823
#endif
17824
17825
    /* user IV optional */
17826
    if (iv != NULL) {
17827
        expIv = iv;
17828
    }
17829
    else {
17830
        expIv = defaultIV;
17831
    }
17832
17833
    ret = AesKeyUnWrapRaw(aes, in, inSz, out, a);
17834
    if (ret != 0) {
17835
        return ret;
17836
    }
17837
17838
    /* verify IV */
17839
    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
        ForceZero(out, inSz - KEYWRAP_BLOCK_SIZE);
17843
        return BAD_KEYWRAP_IV_E;
17844
    }
17845
17846
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
17847
}
17848
17849
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
17850
                    byte* out, word32 outSz, const byte* iv)
17851
{
17852
    WC_DECLARE_VAR(aes, Aes, 1, 0);
17853
    int ret;
17854
17855
    (void)iv;
17856
17857
    if (key == NULL)
17858
        return BAD_FUNC_ARG;
17859
17860
#ifdef WOLFSSL_SMALL_STACK
17861
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
17862
                              DYNAMIC_TYPE_AES)) == NULL)
17863
        return MEMORY_E;
17864
#endif
17865
17866
17867
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17868
    if (ret != 0)
17869
        goto out;
17870
17871
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
17872
    if (ret != 0) {
17873
        wc_AesFree(aes);
17874
        goto out;
17875
    }
17876
17877
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
17878
17879
    wc_AesFree(aes);
17880
17881
  out:
17882
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
17883
17884
    return ret;
17885
}
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
#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
{
18199
    int    ret = 0;
18200
18201
    if (aes == NULL) {
18202
        return BAD_FUNC_ARG;
18203
    }
18204
18205
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
18206
        return ret;
18207
    }
18208
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
18209
        (void)wc_AesFree(&aes->tweak);
18210
        return ret;
18211
    }
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
    return 0;
18221
}
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
{
18236
    word32 keySz;
18237
    int    ret = 0;
18238
18239
    if (aes == NULL || key == NULL) {
18240
        return BAD_FUNC_ARG;
18241
    }
18242
18243
    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
        )
18248
    {
18249
        return BAD_FUNC_ARG;
18250
    }
18251
18252
    if ((len != (AES_128_KEY_SIZE*2)) &&
18253
#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
        (len != (AES_192_KEY_SIZE*2)) &&
18258
#endif
18259
        (len != (AES_256_KEY_SIZE*2)))
18260
    {
18261
        WOLFSSL_MSG("Unsupported key size");
18262
        return WC_KEY_SIZE_E;
18263
    }
18264
18265
    keySz = len/2;
18266
18267
#if defined(HAVE_FIPS) || !defined(WC_AES_XTS_ALLOW_DUPLICATE_KEYS)
18268
    if (XMEMCMP(key, key + keySz, keySz) == 0) {
18269
        WOLFSSL_MSG("AES-XTS main and tweak keys must differ");
18270
        return BAD_FUNC_ARG;
18271
    }
18272
#endif
18273
18274
    if (dir == AES_ENCRYPTION
18275
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18276
        || dir == AES_ENCRYPTION_AND_DECRYPTION
18277
#endif
18278
        )
18279
    {
18280
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
18281
    }
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
    if (dir == AES_DECRYPTION)
18289
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
18290
#endif
18291
18292
    if (ret == 0)
18293
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
18294
                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
    return ret;
18333
}
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
{
18344
    int    ret = 0;
18345
18346
    if (aes == NULL || key == NULL) {
18347
        return BAD_FUNC_ARG;
18348
    }
18349
18350
    ret = wc_AesXtsInit(aes, heap, devId);
18351
    if (ret != 0)
18352
        return ret;
18353
18354
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
18355
18356
    if (ret != 0)
18357
        wc_AesXtsFree(aes);
18358
18359
    return ret;
18360
}
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
{
18371
    if (aes != NULL) {
18372
        wc_AesFree(&aes->aes);
18373
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18374
        wc_AesFree(&aes->aes_decrypt);
18375
#endif
18376
        wc_AesFree(&aes->tweak);
18377
    }
18378
18379
    return 0;
18380
}
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
{
18398
    byte* pt;
18399
    byte  i[WC_AES_BLOCK_SIZE];
18400
18401
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
18402
#ifdef BIG_ENDIAN_ORDER
18403
    sector = ByteReverseWord64(sector);
18404
#endif
18405
    pt = (byte*)&sector;
18406
    XMEMCPY(i, pt, sizeof(word64));
18407
18408
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
18409
}
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
{
18426
    byte* pt;
18427
    byte  i[WC_AES_BLOCK_SIZE];
18428
18429
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
18430
#ifdef BIG_ENDIAN_ORDER
18431
    sector = ByteReverseWord64(sector);
18432
#endif
18433
    pt = (byte*)&sector;
18434
    XMEMCPY(i, pt, sizeof(word64));
18435
18436
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
18437
}
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
{
18578
    word32 outSz   = sz;
18579
    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
18580
    byte*  pt      = out;
18581
18582
    outSz -= WC_AES_BLOCK_SIZE;
18583
18584
    while (outSz > 0) {
18585
        word32 j;
18586
        byte carry = 0;
18587
18588
        /* multiply by shift left and propagate carry */
18589
        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
18590
            byte tmpC;
18591
18592
            tmpC   = (pt[j] >> 7) & 0x01;
18593
            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
18594
            carry  = tmpC;
18595
        }
18596
        if (carry) {
18597
            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
18598
        }
18599
18600
        pt += WC_AES_BLOCK_SIZE;
18601
    }
18602
18603
    xorbuf(out, in, totalSz);
18604
#ifndef WOLFSSL_RISCV_ASM
18605
    if (dir == AES_ENCRYPTION) {
18606
        return _AesEcbEncrypt(aes, out, out, totalSz);
18607
    }
18608
    else {
18609
        return _AesEcbDecrypt(aes, out, out, totalSz);
18610
    }
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
}
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
{
18645
    int ret;
18646
    byte tweak_block[WC_AES_BLOCK_SIZE];
18647
18648
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
18649
    if (ret != 0)
18650
        return ret;
18651
18652
    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
18653
}
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
{
18692
    int ret = 0;
18693
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
18694
    Aes *aes = &xaes->aes;
18695
18696
#ifdef HAVE_AES_ECB
18697
    /* encrypt all of buffer at once when possible */
18698
    if (in != out) { /* can not handle inline */
18699
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
18700
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
18701
            return ret;
18702
    }
18703
#endif
18704
18705
    while (blocks > 0) {
18706
        word32 j;
18707
        byte carry = 0;
18708
18709
#ifdef HAVE_AES_ECB
18710
        if (in == out)
18711
#endif
18712
        { /* check for if inline */
18713
            byte buf[WC_AES_BLOCK_SIZE];
18714
18715
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
18716
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
18717
            ret = wc_AesEncryptDirect(aes, out, buf);
18718
            if (ret != 0)
18719
                return ret;
18720
        }
18721
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
18722
18723
        /* multiply by shift left and propagate carry */
18724
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
18725
            byte tmpC;
18726
18727
            tmpC   = (i[j] >> 7) & 0x01;
18728
            i[j] = (byte)(((i[j] << 1) + carry) & 0xFF);
18729
            carry  = tmpC;
18730
        }
18731
        if (carry) {
18732
            i[0] ^= GF_XTS;
18733
        }
18734
18735
        in  += WC_AES_BLOCK_SIZE;
18736
        out += WC_AES_BLOCK_SIZE;
18737
        sz  -= WC_AES_BLOCK_SIZE;
18738
        blocks--;
18739
    }
18740
18741
    /* stealing operation of XTS to handle left overs */
18742
    if (sz > 0) {
18743
        byte buf[WC_AES_BLOCK_SIZE];
18744
18745
        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
18746
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
18747
            return BUFFER_E;
18748
        }
18749
        if (in != out) {
18750
            XMEMCPY(out, buf, sz);
18751
            XMEMCPY(buf, in, sz);
18752
        }
18753
        else {
18754
            byte buf2[WC_AES_BLOCK_SIZE];
18755
18756
            XMEMCPY(buf2, buf, sz);
18757
            XMEMCPY(buf, in, sz);
18758
            XMEMCPY(out, buf2, sz);
18759
        }
18760
18761
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
18762
        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
18763
        if (ret == 0)
18764
            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
18765
    }
18766
18767
    return ret;
18768
}
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
{
18786
    int ret;
18787
18788
    Aes *aes;
18789
18790
    if (xaes == NULL || out == NULL || in == NULL) {
18791
        return BAD_FUNC_ARG;
18792
    }
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
    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
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
18810
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
18811
        return BAD_FUNC_ARG;
18812
    }
18813
18814
    if (iSz < WC_AES_BLOCK_SIZE) {
18815
        return BAD_FUNC_ARG;
18816
    }
18817
18818
    if (sz < WC_AES_BLOCK_SIZE) {
18819
        WOLFSSL_MSG("Plain text input too small for encryption");
18820
        return BAD_FUNC_ARG;
18821
    }
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
    ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
18926
#endif
18927
18928
    return ret;
18929
}
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
{
19192
    int ret;
19193
    byte tweak_block[WC_AES_BLOCK_SIZE];
19194
19195
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
19196
    if (ret != 0)
19197
        return ret;
19198
19199
    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
19200
}
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
{
19226
    int ret = 0;
19227
    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
    Aes *aes = &xaes->aes;
19232
#endif
19233
    word32 j;
19234
    byte carry = 0;
19235
    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
    if (stl > 0) {
19240
        blocks--;
19241
    }
19242
19243
#ifdef HAVE_AES_ECB
19244
    /* decrypt all of buffer at once when possible */
19245
    if (in != out) { /* can not handle inline */
19246
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
19247
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
19248
            return ret;
19249
    }
19250
#endif
19251
19252
    while (blocks > 0) {
19253
#ifdef HAVE_AES_ECB
19254
        if (in == out)
19255
#endif
19256
        { /* check for if inline */
19257
            byte buf[WC_AES_BLOCK_SIZE];
19258
19259
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
19260
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
19261
            ret = wc_AesDecryptDirect(aes, out, buf);
19262
            if (ret != 0)
19263
                return ret;
19264
        }
19265
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
19266
19267
        /* multiply by shift left and propagate carry */
19268
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
19269
            byte tmpC;
19270
19271
            tmpC   = (i[j] >> 7) & 0x01;
19272
            i[j] = (byte)(((i[j] << 1) + carry) & 0xFF);
19273
            carry  = tmpC;
19274
        }
19275
        if (carry) {
19276
            i[0] ^= GF_XTS;
19277
        }
19278
        carry = 0;
19279
19280
        in  += WC_AES_BLOCK_SIZE;
19281
        out += WC_AES_BLOCK_SIZE;
19282
        sz  -= WC_AES_BLOCK_SIZE;
19283
        blocks--;
19284
    }
19285
19286
    /* stealing operation of XTS to handle left overs */
19287
    if (sz >= WC_AES_BLOCK_SIZE) {
19288
        byte buf[WC_AES_BLOCK_SIZE];
19289
        byte tmp2[WC_AES_BLOCK_SIZE];
19290
19291
        /* multiply by shift left and propagate carry */
19292
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
19293
            byte tmpC;
19294
19295
            tmpC   = (i[j] >> 7) & 0x01;
19296
            tmp2[j] = (byte)((i[j] << 1) + carry);
19297
            carry  = tmpC;
19298
        }
19299
        if (carry) {
19300
            tmp2[0] ^= GF_XTS;
19301
        }
19302
19303
        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
19304
        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
19305
        ret = wc_AesDecryptDirect(aes, out, buf);
19306
        if (ret != 0)
19307
            return ret;
19308
        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
19309
19310
        /* tmp2 holds partial | last */
19311
        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
19312
        in  += WC_AES_BLOCK_SIZE;
19313
        out += WC_AES_BLOCK_SIZE;
19314
        sz  -= WC_AES_BLOCK_SIZE;
19315
19316
        /* Make buffer with end of cipher text | last */
19317
        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
19318
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
19319
            return BUFFER_E;
19320
        }
19321
        XMEMCPY(buf, in,   sz);
19322
        XMEMCPY(out, tmp2, sz);
19323
19324
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
19325
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
19326
        if (ret != 0)
19327
            return ret;
19328
        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
19329
        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
19330
    }
19331
19332
    return ret;
19333
}
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
{
19351
    int ret;
19352
    Aes *aes;
19353
19354
    if (xaes == NULL || out == NULL || in == NULL) {
19355
        return BAD_FUNC_ARG;
19356
    }
19357
19358
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
19359
    aes = &xaes->aes_decrypt;
19360
#else
19361
    aes = &xaes->aes;
19362
#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
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
19375
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
19376
        return BAD_FUNC_ARG;
19377
    }
19378
19379
    if (iSz < WC_AES_BLOCK_SIZE) {
19380
        return BAD_FUNC_ARG;
19381
    }
19382
19383
    if (sz < WC_AES_BLOCK_SIZE) {
19384
        WOLFSSL_MSG("Cipher text input too small for decryption");
19385
        return BAD_FUNC_ARG;
19386
    }
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
    ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
19494
#endif
19495
19496
    return ret;
19497
}
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
{
19748
    int ret  = 0;
19749
    word32 iter = 0;
19750
    word32 sectorCount;
19751
    word32 remainder;
19752
19753
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
19754
        return BAD_FUNC_ARG;
19755
    }
19756
19757
    if (sz < WC_AES_BLOCK_SIZE) {
19758
        WOLFSSL_MSG("Cipher text input too small for encryption");
19759
        return BAD_FUNC_ARG;
19760
    }
19761
19762
    sectorCount  = sz / sectorSz;
19763
    remainder = sz % sectorSz;
19764
19765
    while (sectorCount) {
19766
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
19767
                in + (iter * sectorSz), sectorSz, sector);
19768
        if (ret != 0)
19769
            break;
19770
19771
        sectorCount--;
19772
        iter++;
19773
        sector++;
19774
    }
19775
19776
    if (remainder && ret == 0)
19777
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
19778
                in + (iter * sectorSz), remainder, sector);
19779
19780
    return ret;
19781
}
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
{
19799
    int ret  = 0;
19800
    word32 iter = 0;
19801
    word32 sectorCount;
19802
    word32 remainder;
19803
19804
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
19805
        return BAD_FUNC_ARG;
19806
    }
19807
19808
    if (sz < WC_AES_BLOCK_SIZE) {
19809
        WOLFSSL_MSG("Cipher text input too small for decryption");
19810
        return BAD_FUNC_ARG;
19811
    }
19812
19813
    sectorCount  = sz / sectorSz;
19814
    remainder = sz % sectorSz;
19815
19816
    while (sectorCount) {
19817
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
19818
                in + (iter * sectorSz), sectorSz, sector);
19819
        if (ret != 0)
19820
            break;
19821
19822
        sectorCount--;
19823
        iter++;
19824
        sector++;
19825
    }
19826
19827
    if (remainder && ret == 0)
19828
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
19829
                in + (iter * sectorSz), remainder, sector);
19830
19831
    return ret;
19832
}
19833
#endif /* HAVE_AES_DECRYPT */
19834
#endif /* WOLFSSL_AES_XTS */
19835
19836
#ifdef WOLFSSL_CMAC
19837
19838
int wc_local_CmacUpdateAes(struct Cmac *cmac, const byte* in, word32 inSz) {
19839
    int ret = 0;
19840
    Aes *aes = &cmac->aes;
19841
#ifdef WC_AES_HAVE_PREFETCH_ARG
19842
    int did_prefetches = 0;
19843
#endif
19844
19845
    VECTOR_REGISTERS_PUSH;
19846
19847
    while ((ret == 0) && (inSz != 0)) {
19848
        word32 add = min(inSz, WC_AES_BLOCK_SIZE - cmac->bufferSz);
19849
        XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
19850
19851
        cmac->bufferSz += add;
19852
        inSz -= add;
19853
        in += add;
19854
19855
        if (cmac->bufferSz == WC_AES_BLOCK_SIZE && inSz != 0) {
19856
            xorbuf(cmac->buffer, cmac->digest, WC_AES_BLOCK_SIZE);
19857
            ret = AesEncrypt_preFetchOpt(aes, cmac->buffer,
19858
                                            cmac->digest, &did_prefetches);
19859
            if (ret == 0) {
19860
                cmac->totalSz += WC_AES_BLOCK_SIZE;
19861
                cmac->bufferSz = 0;
19862
            }
19863
        }
19864
    }
19865
19866
    VECTOR_REGISTERS_POP;
19867
19868
    return ret;
19869
}
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
{
19883
#ifdef WOLFSSL_SMALL_STACK
19884
    byte* tmp[3] = {NULL, NULL, NULL};
19885
    int i;
19886
    Cmac* cmac;
19887
#else
19888
    byte tmp[3][WC_AES_BLOCK_SIZE];
19889
    Cmac cmac[1];
19890
#endif
19891
    word32 macSz = WC_AES_BLOCK_SIZE;
19892
    int ret = 0;
19893
    byte tmpi = 0;
19894
    word32 ai;
19895
    word32 zeroBytes;
19896
19897
#ifdef WOLFSSL_SMALL_STACK
19898
    for (i = 0; i < 3; ++i) {
19899
        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19900
        if (tmp[i] == NULL) {
19901
            ret = MEMORY_E;
19902
            break;
19903
        }
19904
    }
19905
    if (ret == 0)
19906
#endif
19907
19908
    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
19909
        /* See RFC 5297 Section 7. */
19910
        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
19911
                    " 126.");
19912
        ret = BAD_FUNC_ARG;
19913
    }
19914
19915
    if (ret == 0) {
19916
        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
19917
        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
19918
19919
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
19920
                                 key, keySz);
19921
    }
19922
19923
    if (ret == 0) {
19924
        /* Loop over authenticated associated data AD1..ADn */
19925
        for (ai = 0; ai < numAssoc; ++ai) {
19926
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
19927
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
19928
                                     assoc[ai].assocSz, key, keySz);
19929
            if (ret != 0)
19930
                break;
19931
            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
19932
            tmpi = (byte)(1 - tmpi);
19933
        }
19934
19935
        /* Add nonce as final AD. See RFC 5297 Section 3. */
19936
        if ((ret == 0) && (nonceSz > 0)) {
19937
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
19938
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
19939
                                     nonceSz, key, keySz);
19940
            if (ret == 0) {
19941
                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
19942
            }
19943
            tmpi = (byte)(1U - tmpi);
19944
        }
19945
19946
        /* For simplicity of the remaining code, make sure the "final" result
19947
           is always in tmp[0]. */
19948
        if (tmpi == 1) {
19949
            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
19950
        }
19951
    }
19952
19953
    if (ret == 0) {
19954
        if (dataSz >= WC_AES_BLOCK_SIZE) {
19955
19956
            WC_ALLOC_VAR_EX(cmac, Cmac, 1, NULL, DYNAMIC_TYPE_CMAC,
19957
                ret=MEMORY_E);
19958
            if (WC_VAR_OK(cmac))
19959
            {
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
                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
19967
                       WC_AES_BLOCK_SIZE);
19968
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
19969
                if (ret == 0) {
19970
                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
19971
                }
19972
                if (ret == 0) {
19973
                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
19974
                }
19975
                if (ret == 0) {
19976
                    ret = wc_CmacFinal(cmac, out, &macSz);
19977
                }
19978
            }
19979
        #ifdef WOLFSSL_SMALL_STACK
19980
            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
19981
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
19982
            wc_MemZero_Check(cmac, sizeof(Cmac));
19983
        #endif
19984
        }
19985
        else {
19986
            XMEMCPY(tmp[2], data, dataSz);
19987
            tmp[2][dataSz] |= 0x80;
19988
            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
19989
            if (zeroBytes != 0) {
19990
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
19991
            }
19992
            ShiftAndXorRb(tmp[1], tmp[0]);
19993
            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
19994
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
19995
                                     keySz);
19996
        }
19997
    }
19998
19999
#ifdef WOLFSSL_SMALL_STACK
20000
    for (i = 0; i < 3; ++i) {
20001
        if (tmp[i] != NULL) {
20002
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
20003
        }
20004
    }
20005
#endif
20006
20007
    return ret;
20008
}
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
{
20016
    int ret = 0;
20017
    WC_DECLARE_VAR(aes, Aes, 1, 0);
20018
    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
    if (key == NULL || siv == NULL || out == NULL) {
20030
        WOLFSSL_MSG("Bad parameter");
20031
        ret = BAD_FUNC_ARG;
20032
    }
20033
20034
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
20035
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
20036
        ret = BAD_FUNC_ARG;
20037
    }
20038
20039
    if (ret == 0) {
20040
        if (enc == 1) {
20041
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
20042
                      dataSz, sivTmp);
20043
            if (ret != 0) {
20044
                WOLFSSL_MSG("S2V failed.");
20045
            }
20046
            else {
20047
                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
20048
            }
20049
        }
20050
        else {
20051
            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
20052
        }
20053
    }
20054
20055
    if (ret == 0) {
20056
#ifdef WOLFSSL_SMALL_STACK
20057
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
20058
#else
20059
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
20060
#endif
20061
        if (ret != 0) {
20062
            WOLFSSL_MSG("Failed to initialized AES object.");
20063
        }
20064
    }
20065
20066
    if (ret == 0) {
20067
        if (dataSz > 0) {
20068
            sivTmp[12] &= 0x7f;
20069
            sivTmp[8] &= 0x7f;
20070
            ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
20071
                               AES_ENCRYPTION);
20072
            if (ret != 0) {
20073
                WOLFSSL_MSG("Failed to set key for AES-CTR.");
20074
            }
20075
            else {
20076
                ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
20077
                if (ret != 0) {
20078
                    WOLFSSL_MSG("AES-CTR encryption failed.");
20079
                }
20080
            }
20081
        }
20082
20083
        if (ret == 0 && enc == 0) {
20084
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out,
20085
                      dataSz, sivTmp);
20086
            if (ret != 0) {
20087
                WOLFSSL_MSG("S2V failed.");
20088
            }
20089
20090
            if (ret == 0 && ConstantCompare(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
20091
                WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
20092
                ret = AES_SIV_AUTH_E;
20093
            }
20094
        }
20095
20096
        if (ret != 0) {
20097
            ForceZero(out, dataSz);
20098
        }
20099
20100
    #ifdef WOLFSSL_SMALL_STACK
20101
        wc_AesDelete(aes, NULL);
20102
    #else
20103
        wc_AesFree(aes);
20104
    #endif
20105
    }
20106
20107
    ForceZero(sivTmp, sizeof(sivTmp));
20108
#ifdef WOLFSSL_CHECK_MEM_ZERO
20109
    wc_MemZero_Check(sivTmp, sizeof(sivTmp));
20110
#endif
20111
20112
    return ret;
20113
}
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
{
20122
    AesSivAssoc ad;
20123
    ad.assoc = assoc;
20124
    ad.assocSz = assocSz;
20125
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
20126
                        siv, out, 1);
20127
}
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
{
20136
    AesSivAssoc ad;
20137
    ad.assoc = assoc;
20138
    ad.assocSz = assocSz;
20139
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
20140
                        siv, out, 0);
20141
}
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
{
20150
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
20151
                        siv, out, 1);
20152
}
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
{
20161
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
20162
                        siv, out, 0);
20163
}
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 */