Coverage Report

Created: 2026-08-23 06:13

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
        if (wolfSSL_CryptHwMutexLock() == 0) {
1364
        #ifdef FREESCALE_MMCAU_CLASSIC
1365
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1366
                WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
1367
                return BAD_ALIGN_E;
1368
            }
1369
            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1370
        #else
1371
            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1372
                                 outBlock);
1373
        #endif
1374
            wolfSSL_CryptHwMutexUnLock();
1375
        }
1376
        return 0;
1377
    }
1378
    #ifdef HAVE_AES_DECRYPT
1379
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1380
        Aes* aes, const byte* inBlock, byte* outBlock)
1381
    {
1382
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1383
        {
1384
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1385
            if (ret < 0)
1386
                return ret;
1387
        }
1388
#endif
1389
        if (wolfSSL_CryptHwMutexLock() == 0) {
1390
        #ifdef FREESCALE_MMCAU_CLASSIC
1391
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
1392
                WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
1393
                return BAD_ALIGN_E;
1394
            }
1395
            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
1396
        #else
1397
            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
1398
                                 outBlock);
1399
        #endif
1400
            wolfSSL_CryptHwMutexUnLock();
1401
        }
1402
        return 0;
1403
    }
1404
    #endif /* HAVE_AES_DECRYPT */
1405
1406
#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
1407
        && !defined(WOLFSSL_QNX_CAAM)) || \
1408
      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
1409
        defined(HAVE_AESCCM))
1410
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1411
            Aes* aes, const byte* inBlock, byte* outBlock)
1412
        {
1413
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1414
            {
1415
                int ret =
1416
                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1417
                if (ret < 0)
1418
                    return ret;
1419
            }
1420
#endif
1421
            return wc_AesEncryptDirect(aes, outBlock, inBlock);
1422
        }
1423
1424
#elif defined(WOLFSSL_AFALG)
1425
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
1426
1427
#elif defined(WOLFSSL_DEVCRYPTO_AES)
1428
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
1429
1430
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
1431
    #include "hal_data.h"
1432
1433
    #ifndef WOLFSSL_SCE_AES256_HANDLE
1434
        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
1435
    #endif
1436
1437
    #ifndef WOLFSSL_SCE_AES192_HANDLE
1438
        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
1439
    #endif
1440
1441
    #ifndef WOLFSSL_SCE_AES128_HANDLE
1442
        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
1443
    #endif
1444
1445
    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
1446
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1447
    {
1448
        word32 ret = SSP_SUCCESS;
1449
        /* The SCE driver needs 32-bit words: stage the caller's byte
1450
         * buffers through aligned locals, leaving the input untouched. */
1451
        word32 in32[WC_AES_BLOCK_SIZE / sizeof(word32)];
1452
        word32 out32[WC_AES_BLOCK_SIZE / sizeof(word32)];
1453
        int bigEndian = (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1454
                CRYPTO_WORD_ENDIAN_BIG);
1455
        int i;
1456
1457
        if ((sz % WC_AES_BLOCK_SIZE) != 0) {
1458
            return BAD_FUNC_ARG;
1459
        }
1460
1461
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
1462
            XMEMCPY(in32, inBlock + i, WC_AES_BLOCK_SIZE);
1463
            if (bigEndian) {
1464
                ByteReverseWords(in32, in32, WC_AES_BLOCK_SIZE);
1465
            }
1466
1467
            switch (aes->keylen) {
1468
        #ifdef WOLFSSL_AES_128
1469
                case AES_128_KEY_SIZE:
1470
                    ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
1471
                            WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, NULL,
1472
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1473
                    break;
1474
        #endif
1475
        #ifdef WOLFSSL_AES_192
1476
                case AES_192_KEY_SIZE:
1477
                    ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
1478
                            WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, NULL,
1479
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1480
                    break;
1481
        #endif
1482
        #ifdef WOLFSSL_AES_256
1483
                case AES_256_KEY_SIZE:
1484
                    ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
1485
                            WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, NULL,
1486
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1487
                    break;
1488
        #endif
1489
                default:
1490
                    WOLFSSL_MSG("Unknown key size");
1491
                    return BAD_FUNC_ARG;
1492
            }
1493
1494
            if (ret != SSP_SUCCESS) {
1495
                return WC_HW_E;
1496
            }
1497
1498
            if (bigEndian) {
1499
                ByteReverseWords(out32, out32, WC_AES_BLOCK_SIZE);
1500
            }
1501
            XMEMCPY(outBlock + i, out32, WC_AES_BLOCK_SIZE);
1502
        }
1503
1504
        return 0;
1505
    }
1506
1507
    #if defined(HAVE_AES_DECRYPT)
1508
    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
1509
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
1510
    {
1511
        word32 ret = SSP_SUCCESS;
1512
        /* The SCE driver needs 32-bit words: stage the caller's byte
1513
         * buffers through aligned locals, leaving the input untouched. */
1514
        word32 in32[WC_AES_BLOCK_SIZE / sizeof(word32)];
1515
        word32 out32[WC_AES_BLOCK_SIZE / sizeof(word32)];
1516
        int bigEndian = (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1517
                CRYPTO_WORD_ENDIAN_BIG);
1518
        int i;
1519
1520
        if ((sz % WC_AES_BLOCK_SIZE) != 0) {
1521
            return BAD_FUNC_ARG;
1522
        }
1523
1524
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
1525
            XMEMCPY(in32, inBlock + i, WC_AES_BLOCK_SIZE);
1526
            if (bigEndian) {
1527
                ByteReverseWords(in32, in32, WC_AES_BLOCK_SIZE);
1528
            }
1529
1530
            switch (aes->keylen) {
1531
        #ifdef WOLFSSL_AES_128
1532
                case AES_128_KEY_SIZE:
1533
                    ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
1534
                            WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
1535
                            aes->reg,
1536
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1537
                    break;
1538
        #endif
1539
        #ifdef WOLFSSL_AES_192
1540
                case AES_192_KEY_SIZE:
1541
                    ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
1542
                            WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
1543
                            aes->reg,
1544
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1545
                    break;
1546
        #endif
1547
        #ifdef WOLFSSL_AES_256
1548
                case AES_256_KEY_SIZE:
1549
                    ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
1550
                            WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
1551
                            aes->reg,
1552
                            (WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
1553
                    break;
1554
        #endif
1555
                default:
1556
                    WOLFSSL_MSG("Unknown key size");
1557
                    return BAD_FUNC_ARG;
1558
            }
1559
1560
            if (ret != SSP_SUCCESS) {
1561
                return WC_HW_E;
1562
            }
1563
1564
            if (bigEndian) {
1565
                ByteReverseWords(out32, out32, WC_AES_BLOCK_SIZE);
1566
            }
1567
            XMEMCPY(outBlock + i, out32, WC_AES_BLOCK_SIZE);
1568
        }
1569
1570
        return 0;
1571
    }
1572
    #endif /* HAVE_AES_DECRYPT */
1573
1574
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
1575
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
1576
        Aes* aes, const byte* inBlock, byte* outBlock)
1577
    {
1578
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1579
        {
1580
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1581
            if (ret < 0)
1582
                return ret;
1583
        }
1584
#endif
1585
        return AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1586
    }
1587
    #endif
1588
1589
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1590
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
1591
        Aes* aes, const byte* inBlock, byte* outBlock)
1592
    {
1593
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
1594
        {
1595
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
1596
            if (ret < 0)
1597
                return ret;
1598
        }
1599
#endif
1600
        return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
1601
    }
1602
    #endif
1603
1604
#elif defined(WOLFSSL_KCAPI_AES)
1605
    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
1606
    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
1607
        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1608
        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
1609
        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
1610
        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
1611
1612
        #define NEED_AES_TABLES
1613
    #endif
1614
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
1615
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
1616
1617
#elif defined(WOLFSSL_RISCV_ASM)
1618
/* Block cipher implemented by the generated RISC-V assembly
1619
 * (riscv-64-aes-asm.S / _c.c). The key schedule is wired in wc_AesSetKeyLocal.
1620
 * Vector-crypto overrides the bulk modes (ECB/CBC/CTR/GCM/XTS) with asm; scalar
1621
 * and base run the common-C modes over these single-block primitives, so the
1622
 * block routine is needed whenever a common-C mode (or Direct/CCM/GCM-stream)
1623
 * is built. */
1624
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
1625
    defined(WOLFSSL_AESGCM_STREAM) || defined(HAVE_AESGCM) || \
1626
    defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) || \
1627
    defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_XTS) || \
1628
    defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
1629
    defined(WOLFSSL_AES_CFB)
1630
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
1631
    byte* outBlock)
1632
{
1633
    AES_encrypt_RISCV64(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1634
    return 0;
1635
}
1636
#endif
1637
1638
#if defined(HAVE_AES_DECRYPT) && (defined(WOLFSSL_AES_DIRECT) || \
1639
    defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
1640
    defined(WOLFSSL_AES_XTS) || defined(HAVE_AESCCM))
1641
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
1642
    byte* outBlock)
1643
{
1644
    AES_decrypt_RISCV64(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
1645
    return 0;
1646
}
1647
#endif
1648
1649
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1650
/* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
1651
1652
#elif defined(WOLFSSL_PSOC6_CRYPTO)
1653
1654
    #if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
1655
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
1656
            Aes* aes, const byte* inBlock, byte* outBlock)
1657
        {
1658
            return wc_Psoc6_Aes_Encrypt(aes, inBlock, outBlock);
1659
        }
1660
    #endif
1661
1662
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
1663
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
1664
            Aes* aes, const byte* inBlock, byte* outBlock)
1665
        {
1666
            return wc_Psoc6_Aes_Decrypt(aes, inBlock, outBlock);
1667
        }
1668
1669
    #endif
1670
#elif defined(WOLF_CRYPTO_CB_ONLY_AES)
1671
    /* No software implementation AES T-tables, S-box, Rcon and the C key
1672
     * schedule are stripped. */
1673
#else
1674
1675
    /* using wolfCrypt software implementation */
1676
    #define NEED_AES_TABLES
1677
#endif
1678
1679
1680
1681
#if defined(WC_AES_BITSLICED) && !defined(HAVE_AES_ECB)
1682
    #error "When WC_AES_BITSLICED is defined, HAVE_AES_ECB is needed."
1683
#endif
1684
1685
#ifdef NEED_AES_TABLES
1686
1687
#ifndef WC_AES_BITSLICED
1688
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1689
#if !defined(WOLFSSL_ESP32_CRYPT) || \
1690
    (defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
1691
     defined(NEED_AES_HW_FALLBACK))
1692
#ifndef WOLFSSL_PPC64_ASM
1693
static const FLASH_QUALIFIER word32 rcon[] = {
1694
    0x01000000, 0x02000000, 0x04000000, 0x08000000,
1695
    0x10000000, 0x20000000, 0x40000000, 0x80000000,
1696
    0x1B000000, 0x36000000,
1697
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1698
};
1699
#endif
1700
#endif /* ESP32 */
1701
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
1702
1703
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
1704
      defined(HAVE_AESCCM)
1705
#ifndef WOLFSSL_AES_SMALL_TABLES
1706
static const FLASH_QUALIFIER word32 Te[4][256] = {
1707
{
1708
    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1709
    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1710
    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1711
    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1712
    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1713
    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1714
    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1715
    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1716
    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1717
    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1718
    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1719
    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1720
    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1721
    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1722
    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1723
    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1724
    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1725
    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1726
    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1727
    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1728
    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1729
    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1730
    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1731
    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1732
    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1733
    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1734
    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1735
    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1736
    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1737
    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1738
    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1739
    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1740
    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1741
    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1742
    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1743
    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1744
    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1745
    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1746
    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1747
    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1748
    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1749
    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1750
    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1751
    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1752
    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1753
    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1754
    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1755
    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1756
    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1757
    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1758
    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1759
    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1760
    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1761
    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1762
    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1763
    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1764
    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1765
    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1766
    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1767
    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1768
    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1769
    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1770
    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1771
    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1772
},
1773
{
1774
    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1775
    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1776
    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1777
    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1778
    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1779
    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1780
    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1781
    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1782
    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1783
    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1784
    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1785
    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1786
    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1787
    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1788
    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1789
    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1790
    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1791
    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1792
    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1793
    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1794
    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1795
    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1796
    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1797
    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1798
    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1799
    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1800
    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1801
    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1802
    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1803
    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1804
    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1805
    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1806
    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1807
    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1808
    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1809
    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1810
    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1811
    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1812
    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1813
    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1814
    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1815
    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1816
    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1817
    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1818
    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1819
    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1820
    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1821
    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1822
    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1823
    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1824
    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1825
    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1826
    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1827
    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1828
    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1829
    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1830
    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1831
    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1832
    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1833
    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1834
    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1835
    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1836
    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1837
    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1838
},
1839
{
1840
    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1841
    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1842
    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1843
    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1844
    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1845
    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1846
    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1847
    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1848
    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1849
    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1850
    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1851
    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1852
    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1853
    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1854
    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1855
    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1856
    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1857
    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1858
    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1859
    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1860
    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1861
    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1862
    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1863
    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1864
    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1865
    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1866
    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1867
    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1868
    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1869
    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1870
    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1871
    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1872
    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1873
    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1874
    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1875
    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1876
    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1877
    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1878
    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1879
    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1880
    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1881
    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1882
    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1883
    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1884
    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1885
    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1886
    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1887
    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1888
    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1889
    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1890
    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1891
    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1892
    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1893
    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1894
    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1895
    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1896
    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1897
    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1898
    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1899
    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1900
    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1901
    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1902
    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1903
    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1904
},
1905
{
1906
    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1907
    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1908
    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1909
    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1910
    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1911
    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1912
    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1913
    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1914
    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1915
    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1916
    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1917
    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1918
    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1919
    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1920
    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1921
    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1922
    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1923
    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1924
    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1925
    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1926
    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1927
    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1928
    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1929
    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1930
    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1931
    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1932
    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1933
    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1934
    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1935
    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1936
    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1937
    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1938
    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1939
    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1940
    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1941
    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1942
    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1943
    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1944
    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1945
    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1946
    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1947
    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1948
    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1949
    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1950
    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1951
    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1952
    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1953
    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1954
    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1955
    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1956
    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1957
    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1958
    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1959
    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1960
    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1961
    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1962
    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1963
    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1964
    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1965
    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1966
    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1967
    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1968
    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1969
    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1970
}
1971
};
1972
1973
#ifdef HAVE_AES_DECRYPT
1974
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
1975
static const FLASH_QUALIFIER word32 Td[4][256] = {
1976
{
1977
    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1978
    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1979
    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1980
    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1981
    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1982
    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1983
    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1984
    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1985
    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1986
    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1987
    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1988
    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1989
    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1990
    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1991
    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1992
    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1993
    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1994
    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1995
    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1996
    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1997
    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1998
    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1999
    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
2000
    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
2001
    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
2002
    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
2003
    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
2004
    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
2005
    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
2006
    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
2007
    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
2008
    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
2009
    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
2010
    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
2011
    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
2012
    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
2013
    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
2014
    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
2015
    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
2016
    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
2017
    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
2018
    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
2019
    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
2020
    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
2021
    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
2022
    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
2023
    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
2024
    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
2025
    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
2026
    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
2027
    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
2028
    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
2029
    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
2030
    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
2031
    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
2032
    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
2033
    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
2034
    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
2035
    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
2036
    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
2037
    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
2038
    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
2039
    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
2040
    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
2041
},
2042
{
2043
    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
2044
    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
2045
    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
2046
    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
2047
    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
2048
    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
2049
    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
2050
    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
2051
    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
2052
    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
2053
    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
2054
    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
2055
    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
2056
    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
2057
    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
2058
    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
2059
    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
2060
    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
2061
    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
2062
    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
2063
    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
2064
    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
2065
    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
2066
    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
2067
    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
2068
    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
2069
    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
2070
    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
2071
    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
2072
    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
2073
    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
2074
    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
2075
    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
2076
    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
2077
    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
2078
    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
2079
    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
2080
    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
2081
    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
2082
    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
2083
    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
2084
    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
2085
    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
2086
    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
2087
    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
2088
    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
2089
    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
2090
    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
2091
    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
2092
    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
2093
    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
2094
    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
2095
    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
2096
    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
2097
    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
2098
    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
2099
    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
2100
    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
2101
    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
2102
    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
2103
    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
2104
    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
2105
    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
2106
    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
2107
},
2108
{
2109
    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
2110
    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
2111
    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
2112
    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
2113
    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
2114
    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
2115
    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
2116
    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
2117
    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
2118
    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
2119
    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
2120
    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
2121
    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
2122
    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
2123
    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
2124
    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
2125
    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
2126
    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
2127
    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
2128
    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
2129
2130
    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
2131
    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
2132
    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
2133
    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
2134
    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
2135
    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
2136
    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
2137
    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
2138
    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
2139
    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
2140
    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
2141
    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
2142
    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
2143
    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
2144
    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
2145
    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
2146
    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
2147
    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
2148
    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
2149
    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
2150
    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
2151
    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
2152
    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
2153
    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
2154
    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
2155
    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
2156
    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
2157
    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
2158
    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
2159
    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
2160
    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
2161
    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
2162
    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
2163
    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
2164
    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
2165
    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
2166
    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
2167
    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
2168
    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
2169
    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
2170
    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
2171
    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
2172
    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
2173
    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
2174
},
2175
{
2176
    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
2177
    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
2178
    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
2179
    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
2180
    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
2181
    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
2182
    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
2183
    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
2184
    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
2185
    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
2186
    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
2187
    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
2188
    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
2189
    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
2190
    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
2191
    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
2192
    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
2193
    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
2194
    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
2195
    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
2196
    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
2197
    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
2198
    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
2199
    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
2200
    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
2201
    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
2202
    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
2203
    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
2204
    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
2205
    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
2206
    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
2207
    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
2208
    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
2209
    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
2210
    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
2211
    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
2212
    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
2213
    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
2214
    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
2215
    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
2216
    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
2217
    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
2218
    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
2219
    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
2220
    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
2221
    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
2222
    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
2223
    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
2224
    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
2225
    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
2226
    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
2227
    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
2228
    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
2229
    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
2230
    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
2231
    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
2232
    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
2233
    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
2234
    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
2235
    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
2236
    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
2237
    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
2238
    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
2239
    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
2240
}
2241
};
2242
#endif /* __aarch64__ || !WOLFSSL_ARMASM */
2243
#endif /* HAVE_AES_DECRYPT */
2244
#endif /* WOLFSSL_AES_SMALL_TABLES */
2245
2246
#ifdef HAVE_AES_DECRYPT
2247
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
2248
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)
2249
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
2250
static const FLASH_QUALIFIER byte Td4[256] =
2251
{
2252
    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
2253
    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
2254
    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
2255
    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
2256
    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
2257
    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
2258
    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
2259
    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
2260
    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
2261
    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
2262
    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
2263
    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
2264
    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
2265
    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
2266
    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
2267
    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
2268
    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
2269
    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
2270
    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
2271
    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
2272
    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
2273
    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
2274
    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
2275
    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
2276
    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
2277
    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
2278
    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
2279
    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
2280
    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
2281
    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
2282
    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
2283
    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
2284
};
2285
#endif
2286
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
2287
#endif /* HAVE_AES_DECRYPT */
2288
2289
/* Extract octet y of word x.  Mask with 0xFF explicitly: a (byte) cast only
2290
 * truncates to 8 bits where a byte is 8 bits; on a wider-byte target (C28x,
2291
 * CHAR_BIT==16) it would leave a >8-bit Te/Td table index. */
2292
#define GETBYTE(x, y) (word32)(((x) >> (8 * (y))) & 0xFFU)
2293
2294
#ifdef WOLFSSL_AES_SMALL_TABLES
2295
static const byte Tsbox[256] = {
2296
    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
2297
    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
2298
    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
2299
    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
2300
    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
2301
    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
2302
    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
2303
    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
2304
    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
2305
    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
2306
    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
2307
    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
2308
    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
2309
    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
2310
    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
2311
    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
2312
    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
2313
    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
2314
    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
2315
    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
2316
    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
2317
    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
2318
    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
2319
    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
2320
    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
2321
    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
2322
    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
2323
    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
2324
    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
2325
    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
2326
    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
2327
    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
2328
};
2329
2330
#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
2331
2332
static WARN_UNUSED_RESULT word32 col_mul(
2333
    word32 t, int i2, int i3, int ia, int ib)
2334
{
2335
    byte t3 = GETBYTE(t, i3);
2336
    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
2337
2338
    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
2339
}
2340
2341
#if defined(HAVE_AES_DECRYPT) && \
2342
    (defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
2343
     defined(WOLFSSL_AES_DIRECT))
2344
static WARN_UNUSED_RESULT word32 inv_col_mul(
2345
    word32 t, int i9, int ib, int id, int ie)
2346
{
2347
    byte t9 = GETBYTE(t, i9);
2348
    byte tb = GETBYTE(t, ib);
2349
    byte td = GETBYTE(t, id);
2350
    byte te = GETBYTE(t, ie);
2351
    byte t0 = t9 ^ tb ^ td;
2352
    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
2353
}
2354
#endif /* HAVE_AES_DECRYPT && (HAVE_AES_CBC || HAVE_AES_ECB || WOLFSSL_AES_DIRECT) */
2355
#endif /* WOLFSSL_AES_SMALL_TABLES */
2356
#endif
2357
#endif
2358
2359
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
2360
                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
2361
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
2362
      defined(HAVE_AESCCM)
2363
2364
2365
#ifndef WC_AES_BITSLICED
2366
2367
#ifndef WC_CACHE_LINE_SZ
2368
    #if defined(__x86_64__) || defined(_M_X64) || \
2369
       (defined(__ILP32__) && (__ILP32__ >= 1))
2370
0
        #define WC_CACHE_LINE_SZ 64
2371
    #else
2372
        /* default cache line size */
2373
        #define WC_CACHE_LINE_SZ 32
2374
    #endif
2375
#endif
2376
2377
#ifndef WC_NO_CACHE_RESISTANT
2378
2379
#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
2380
    #define WOLFSSL_AES_TOUCH_LINES
2381
#endif
2382
2383
#ifndef WOLFSSL_AES_SMALL_TABLES
2384
/* load 4 Te Tables into cache by cache line stride */
2385
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
2386
0
{
2387
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2388
0
    volatile word32 x = 0;
2389
0
    int i;
2390
0
    int j;
2391
2392
0
    for (i = 0; i < 4; i++) {
2393
        /* 256 elements, each one is 4 bytes */
2394
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
2395
0
            x &= Te[i][j];
2396
0
        }
2397
0
    }
2398
2399
0
    return x;
2400
#else
2401
    return 0;
2402
#endif
2403
0
}
2404
#else
2405
/* load sbox into cache by cache line stride */
2406
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
2407
{
2408
#ifndef WOLFSSL_AES_TOUCH_LINES
2409
    volatile word32 x = 0;
2410
    int i;
2411
2412
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
2413
        x &= Tsbox[i];
2414
    }
2415
2416
    return x;
2417
#else
2418
    return 0;
2419
#endif
2420
}
2421
#endif
2422
#endif
2423
2424
#ifdef WOLFSSL_AES_TOUCH_LINES
2425
#if WC_CACHE_LINE_SZ == 128
2426
    #define WC_CACHE_LINE_BITS      5
2427
    #define WC_CACHE_LINE_MASK_HI   0xe0
2428
    #define WC_CACHE_LINE_MASK_LO   0x1f
2429
    #define WC_CACHE_LINE_ADD       0x20
2430
#elif WC_CACHE_LINE_SZ == 64
2431
    #define WC_CACHE_LINE_BITS      4
2432
    #define WC_CACHE_LINE_MASK_HI   0xf0
2433
    #define WC_CACHE_LINE_MASK_LO   0x0f
2434
    #define WC_CACHE_LINE_ADD       0x10
2435
#elif WC_CACHE_LINE_SZ == 32
2436
    #define WC_CACHE_LINE_BITS      3
2437
    #define WC_CACHE_LINE_MASK_HI   0xf8
2438
    #define WC_CACHE_LINE_MASK_LO   0x07
2439
    #define WC_CACHE_LINE_ADD       0x08
2440
#elif WC_CACHE_LINE_SZ == 16
2441
    #define WC_CACHE_LINE_BITS      2
2442
    #define WC_CACHE_LINE_MASK_HI   0xfc
2443
    #define WC_CACHE_LINE_MASK_LO   0x03
2444
    #define WC_CACHE_LINE_ADD       0x04
2445
#else
2446
    #error Cache line size not supported
2447
#endif
2448
2449
#ifndef WOLFSSL_AES_SMALL_TABLES
2450
static word32 GetTable(const word32* t, byte o)
2451
{
2452
#if WC_CACHE_LINE_SZ == 64
2453
    word32 e;
2454
    byte hi = o & 0xf0;
2455
    byte lo = o & 0x0f;
2456
2457
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2458
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2459
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2460
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2461
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2462
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2463
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2464
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2465
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2466
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2467
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2468
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2469
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2470
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2471
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2472
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2473
2474
    return e;
2475
#else
2476
    word32 e = 0;
2477
    int i;
2478
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2479
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2480
2481
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2482
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2483
        hi -= WC_CACHE_LINE_ADD;
2484
    }
2485
2486
    return e;
2487
#endif
2488
}
2489
#endif
2490
2491
#ifdef WOLFSSL_AES_SMALL_TABLES
2492
static byte GetTable8(const byte* t, byte o)
2493
{
2494
#if WC_CACHE_LINE_SZ == 64
2495
    byte e;
2496
    byte hi = o & 0xf0;
2497
    byte lo = o & 0x0f;
2498
2499
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2500
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2501
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2502
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2503
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2504
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2505
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2506
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2507
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2508
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2509
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2510
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2511
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2512
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2513
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
2514
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2515
2516
    return e;
2517
#else
2518
    byte e = 0;
2519
    int i;
2520
    byte hi = o & WC_CACHE_LINE_MASK_HI;
2521
    byte lo = o & WC_CACHE_LINE_MASK_LO;
2522
2523
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2524
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
2525
        hi -= WC_CACHE_LINE_ADD;
2526
    }
2527
2528
    return e;
2529
#endif
2530
}
2531
#endif
2532
2533
#ifndef WOLFSSL_AES_SMALL_TABLES
2534
static void GetTable_Multi(const word32* t, word32* t0, byte o0,
2535
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2536
{
2537
    word32 e0 = 0;
2538
    word32 e1 = 0;
2539
    word32 e2 = 0;
2540
    word32 e3 = 0;
2541
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2542
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2543
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2544
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2545
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2546
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2547
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2548
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2549
    int i;
2550
2551
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2552
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2553
        hi0 -= WC_CACHE_LINE_ADD;
2554
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2555
        hi1 -= WC_CACHE_LINE_ADD;
2556
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2557
        hi2 -= WC_CACHE_LINE_ADD;
2558
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2559
        hi3 -= WC_CACHE_LINE_ADD;
2560
    }
2561
    *t0 = e0;
2562
    *t1 = e1;
2563
    *t2 = e2;
2564
    *t3 = e3;
2565
}
2566
static void XorTable_Multi(const word32* t, word32* t0, byte o0,
2567
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
2568
{
2569
    word32 e0 = 0;
2570
    word32 e1 = 0;
2571
    word32 e2 = 0;
2572
    word32 e3 = 0;
2573
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2574
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2575
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2576
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2577
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2578
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2579
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2580
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2581
    int i;
2582
2583
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2584
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
2585
        hi0 -= WC_CACHE_LINE_ADD;
2586
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
2587
        hi1 -= WC_CACHE_LINE_ADD;
2588
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
2589
        hi2 -= WC_CACHE_LINE_ADD;
2590
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
2591
        hi3 -= WC_CACHE_LINE_ADD;
2592
    }
2593
    *t0 ^= e0;
2594
    *t1 ^= e1;
2595
    *t2 ^= e2;
2596
    *t3 ^= e3;
2597
}
2598
static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
2599
{
2600
    word32 e = 0;
2601
    int i;
2602
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
2603
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
2604
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
2605
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
2606
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
2607
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
2608
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
2609
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
2610
2611
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
2612
        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
2613
             << 24;
2614
        hi0 -= WC_CACHE_LINE_ADD;
2615
        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
2616
             << 16;
2617
        hi1 -= WC_CACHE_LINE_ADD;
2618
        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
2619
             <<  8;
2620
        hi2 -= WC_CACHE_LINE_ADD;
2621
        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
2622
             <<  0;
2623
        hi3 -= WC_CACHE_LINE_ADD;
2624
    }
2625
2626
    return e;
2627
}
2628
#endif
2629
#else
2630
2631
0
#define GetTable(t, o)  t[o]
2632
#define GetTable8(t, o) t[o]
2633
#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2634
    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
2635
#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
2636
    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
2637
#define GetTable8_4(t, o0, o1, o2, o3) \
2638
0
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
2639
0
     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
2640
#endif
2641
2642
#ifndef HAVE_CUDA
2643
/* Encrypt a block using AES.
2644
 *
2645
 * @param [in]  aes       AES object.
2646
 * @param [in]  inBlock   Block to encrypt.
2647
 * @param [out] outBlock  Encrypted block.
2648
 * @param [in]  r         Rounds divided by 2.
2649
 */
2650
#define WC_AES_HAVE_PREFETCH_ARG
2651
static int always_prefetch = 0;
2652
WC_MAYBE_UNUSED static int never_prefetch = 1;
2653
WC_ARGS_NOT_NULL((1, 2, 3, 5))
2654
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2655
        word32 r, int *prefetch_ptr)
2656
0
{
2657
0
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
2658
0
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
2659
0
    const word32* rk;
2660
#ifdef WOLFSSL_WIDE_BYTE
2661
    word32 stw[4]; /* octet-wise block I/O scratch (CHAR_BIT != 8) */
2662
#endif
2663
2664
#ifdef WC_C_DYNAMIC_FALLBACK
2665
    rk = aes->key_C_fallback;
2666
#else
2667
0
    rk = aes->key;
2668
0
#endif
2669
2670
    /*
2671
     * map byte array block to cipher state
2672
     * and add initial round key:
2673
     */
2674
#ifdef WOLFSSL_WIDE_BYTE
2675
    /* A C byte is wider than an octet here: the block is one octet per cell, so
2676
     * assemble the 4 big-endian state words octet-wise (no aliasing/reverse). */
2677
    WordsFromBytesBE32(stw, inBlock, 4);
2678
    s0 = stw[0]; s1 = stw[1]; s2 = stw[2]; s3 = stw[3];
2679
#else
2680
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
2681
0
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
2682
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
2683
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
2684
2685
0
#ifdef LITTLE_ENDIAN_ORDER
2686
0
    s0 = ByteReverseWord32(s0);
2687
0
    s1 = ByteReverseWord32(s1);
2688
0
    s2 = ByteReverseWord32(s2);
2689
0
    s3 = ByteReverseWord32(s3);
2690
0
#endif
2691
0
#endif /* WOLFSSL_WIDE_BYTE */
2692
2693
    /* AddRoundKey */
2694
0
    s0 ^= rk[0];
2695
0
    s1 ^= rk[1];
2696
0
    s2 ^= rk[2];
2697
0
    s3 ^= rk[3];
2698
2699
0
#ifndef WOLFSSL_AES_SMALL_TABLES
2700
2701
0
#ifndef WC_NO_CACHE_RESISTANT
2702
0
    if (*prefetch_ptr == 0) {
2703
0
        s0 |= PreFetchTe();
2704
0
        if (prefetch_ptr != &always_prefetch)
2705
0
            *prefetch_ptr = 1;
2706
0
    }
2707
#else
2708
    (void)prefetch_ptr;
2709
#endif
2710
2711
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2712
0
#define ENC_ROUND_T_S(o)                                                       \
2713
0
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
2714
0
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
2715
0
         rk[(o)+4];                                                            \
2716
0
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
2717
0
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
2718
0
         rk[(o)+5];                                                            \
2719
0
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
2720
0
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
2721
0
         rk[(o)+6];                                                            \
2722
0
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
2723
0
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
2724
0
         rk[(o)+7]
2725
0
#define ENC_ROUND_S_T(o)                                                       \
2726
0
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
2727
0
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
2728
0
         rk[(o)+0];                                                            \
2729
0
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
2730
0
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
2731
0
         rk[(o)+1];                                                            \
2732
0
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
2733
0
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
2734
0
         rk[(o)+2];                                                            \
2735
0
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
2736
0
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
2737
0
         rk[(o)+3]
2738
#else
2739
#define ENC_ROUND_T_S(o)                                                       \
2740
    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
2741
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
2742
    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
2743
                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
2744
    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
2745
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
2746
    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
2747
                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
2748
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
2749
2750
#define ENC_ROUND_S_T(o)                                                       \
2751
    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
2752
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
2753
    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
2754
                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
2755
    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
2756
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2757
    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
2758
                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
2759
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2760
#endif
2761
2762
0
#ifndef WOLFSSL_AES_NO_UNROLL
2763
/* Unroll the loop. */
2764
0
                       ENC_ROUND_T_S( 0);
2765
0
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2766
0
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2767
0
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2768
0
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2769
0
    if (r > 5) {
2770
0
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2771
0
        if (r > 6) {
2772
0
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2773
0
        }
2774
0
    }
2775
0
    rk += r * 8;
2776
#else
2777
    /*
2778
     * Nr - 1 full rounds:
2779
     */
2780
2781
    for (;;) {
2782
        ENC_ROUND_T_S(0);
2783
2784
        rk += 8;
2785
        if (--r == 0) {
2786
            break;
2787
        }
2788
2789
        ENC_ROUND_S_T(0);
2790
    }
2791
#endif
2792
2793
    /*
2794
     * apply last round and
2795
     * map cipher state to byte array block:
2796
     */
2797
2798
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2799
0
    s0 =
2800
0
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2801
0
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2802
0
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2803
0
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2804
0
        rk[0];
2805
0
    s1 =
2806
0
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2807
0
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2808
0
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2809
0
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2810
0
        rk[1];
2811
0
    s2 =
2812
0
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2813
0
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2814
0
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2815
0
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2816
0
        rk[2];
2817
0
    s3 =
2818
0
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2819
0
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2820
0
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2821
0
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2822
0
        rk[3];
2823
#else
2824
{
2825
    word32 u0;
2826
    word32 u1;
2827
    word32 u2;
2828
    word32 u3;
2829
2830
    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
2831
    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
2832
                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
2833
    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
2834
    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
2835
    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
2836
                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
2837
    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
2838
    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
2839
    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
2840
                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
2841
    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
2842
    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
2843
    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
2844
                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
2845
    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
2846
    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
2847
}
2848
#endif
2849
2850
#else /* WOLFSSL_AES_SMALL_TABLES */
2851
2852
#ifndef WC_NO_CACHE_RESISTANT
2853
    if (*prefetch_ptr == 0) {
2854
        s0 |= PreFetchSBox();
2855
        if (prefetch_ptr != &always_prefetch)
2856
            *prefetch_ptr = 1;
2857
    }
2858
#else
2859
    (void)prefetch_ptr;
2860
#endif
2861
2862
    r *= 2;
2863
    /* Two rounds at a time */
2864
    for (rk += 4; r > 1; r--, rk += 4) {
2865
        t0 =
2866
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2867
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2868
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2869
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2870
        t1 =
2871
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2872
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2873
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2874
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2875
        t2 =
2876
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2877
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2878
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2879
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2880
        t3 =
2881
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2882
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2883
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2884
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2885
2886
        s0 =
2887
            (col_mul(t0, 3, 2, 0, 1) << 24) ^
2888
            (col_mul(t0, 2, 1, 0, 3) << 16) ^
2889
            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
2890
            (col_mul(t0, 0, 3, 2, 1)      ) ^
2891
            rk[0];
2892
        s1 =
2893
            (col_mul(t1, 3, 2, 0, 1) << 24) ^
2894
            (col_mul(t1, 2, 1, 0, 3) << 16) ^
2895
            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
2896
            (col_mul(t1, 0, 3, 2, 1)      ) ^
2897
            rk[1];
2898
        s2 =
2899
            (col_mul(t2, 3, 2, 0, 1) << 24) ^
2900
            (col_mul(t2, 2, 1, 0, 3) << 16) ^
2901
            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
2902
            (col_mul(t2, 0, 3, 2, 1)      ) ^
2903
            rk[2];
2904
        s3 =
2905
            (col_mul(t3, 3, 2, 0, 1) << 24) ^
2906
            (col_mul(t3, 2, 1, 0, 3) << 16) ^
2907
            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
2908
            (col_mul(t3, 0, 3, 2, 1)      ) ^
2909
            rk[3];
2910
    }
2911
2912
    t0 =
2913
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2914
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2915
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2916
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2917
    t1 =
2918
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2919
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2920
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2921
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2922
    t2 =
2923
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2924
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2925
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2926
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2927
    t3 =
2928
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2929
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2930
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2931
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2932
    s0 = t0 ^ rk[0];
2933
    s1 = t1 ^ rk[1];
2934
    s2 = t2 ^ rk[2];
2935
    s3 = t3 ^ rk[3];
2936
2937
#endif /* WOLFSSL_AES_SMALL_TABLES */
2938
2939
    /* write out */
2940
#ifdef WOLFSSL_WIDE_BYTE
2941
    stw[0] = s0; stw[1] = s1; stw[2] = s2; stw[3] = s3;
2942
    BytesFromWordsBE32(outBlock, stw, WC_AES_BLOCK_SIZE);
2943
#else
2944
0
#ifdef LITTLE_ENDIAN_ORDER
2945
0
    s0 = ByteReverseWord32(s0);
2946
0
    s1 = ByteReverseWord32(s1);
2947
0
    s2 = ByteReverseWord32(s2);
2948
0
    s3 = ByteReverseWord32(s3);
2949
0
#endif
2950
2951
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2952
0
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2953
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2954
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2955
0
#endif /* WOLFSSL_WIDE_BYTE */
2956
0
}
2957
2958
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2959
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
2960
    !defined(MAX3266X_AES)
2961
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
2962
/* Encrypt a number of blocks using AES.
2963
 *
2964
 * @param [in]  aes  AES object.
2965
 * @param [in]  in   Block to encrypt.
2966
 * @param [out] out  Encrypted block.
2967
 * @param [in]  sz   Number of blocks to encrypt.
2968
 */
2969
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2970
{
2971
    word32 i;
2972
    int did_prefetches = 0;
2973
2974
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
2975
        AesEncrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
2976
        in += WC_AES_BLOCK_SIZE;
2977
        out += WC_AES_BLOCK_SIZE;
2978
    }
2979
}
2980
#endif
2981
#endif
2982
#else
2983
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2984
        word32 r);
2985
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2986
#endif /* HAVE_CUDA */
2987
2988
#else
2989
2990
/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
2991
 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
2992
 */
2993
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
2994
static void bs_sub_bytes(bs_word u[8])
2995
{
2996
    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
2997
    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
2998
    bs_word y20, y21;
2999
    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
3000
    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
3001
    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
3002
    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
3003
    bs_word t40, t41, t42, t43, t44, t45;
3004
    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
3005
    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
3006
    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
3007
    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
3008
    bs_word tc20, tc21, tc26;
3009
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
3010
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
3011
3012
    U0 = u[7];
3013
    U1 = u[6];
3014
    U2 = u[5];
3015
    U3 = u[4];
3016
    U4 = u[3];
3017
    U5 = u[2];
3018
    U6 = u[1];
3019
    U7 = u[0];
3020
3021
    y14 = U3 ^ U5;
3022
    y13 = U0 ^ U6;
3023
    y9 = U0 ^ U3;
3024
    y8 = U0 ^ U5;
3025
    t0 = U1 ^ U2;
3026
    y1 = t0 ^ U7;
3027
    y4 = y1 ^ U3;
3028
    y12 = y13 ^ y14;
3029
    y2 = y1 ^ U0;
3030
    y5 = y1 ^ U6;
3031
    y3 = y5 ^ y8;
3032
    t1 = U4 ^ y12;
3033
    y15 = t1 ^ U5;
3034
    y20 = t1 ^ U1;
3035
    y6 = y15 ^ U7;
3036
    y10 = y15 ^ t0;
3037
    y11 = y20 ^ y9;
3038
    y7 = U7 ^ y11;
3039
    y17 = y10 ^ y11;
3040
    y19 = y10 ^ y8;
3041
    y16 = t0 ^ y11;
3042
    y21 = y13 ^ y16;
3043
    y18 = U0 ^ y16;
3044
    t2 = y12 & y15;
3045
    t3 = y3 & y6;
3046
    t4 = t3 ^ t2;
3047
    t5 = y4 & U7;
3048
    t6 = t5 ^ t2;
3049
    t7 = y13 & y16;
3050
    t8 = y5 & y1;
3051
    t9 = t8 ^ t7;
3052
    t10 = y2 & y7;
3053
    t11 = t10 ^ t7;
3054
    t12 = y9 & y11;
3055
    t13 = y14 & y17;
3056
    t14 = t13 ^ t12;
3057
    t15 = y8 & y10;
3058
    t16 = t15 ^ t12;
3059
    t17 = t4 ^ y20;
3060
    t18 = t6 ^ t16;
3061
    t19 = t9 ^ t14;
3062
    t20 = t11 ^ t16;
3063
    t21 = t17 ^ t14;
3064
    t22 = t18 ^ y19;
3065
    t23 = t19 ^ y21;
3066
    t24 = t20 ^ y18;
3067
    t25 = t21 ^ t22;
3068
    t26 = t21 & t23;
3069
    t27 = t24 ^ t26;
3070
    t28 = t25 & t27;
3071
    t29 = t28 ^ t22;
3072
    t30 = t23 ^ t24;
3073
    t31 = t22 ^ t26;
3074
    t32 = t31 & t30;
3075
    t33 = t32 ^ t24;
3076
    t34 = t23 ^ t33;
3077
    t35 = t27 ^ t33;
3078
    t36 = t24 & t35;
3079
    t37 = t36 ^ t34;
3080
    t38 = t27 ^ t36;
3081
    t39 = t29 & t38;
3082
    t40 = t25 ^ t39;
3083
    t41 = t40 ^ t37;
3084
    t42 = t29 ^ t33;
3085
    t43 = t29 ^ t40;
3086
    t44 = t33 ^ t37;
3087
    t45 = t42 ^ t41;
3088
    z0 = t44 & y15;
3089
    z1 = t37 & y6;
3090
    z2 = t33 & U7;
3091
    z3 = t43 & y16;
3092
    z4 = t40 & y1;
3093
    z5 = t29 & y7;
3094
    z6 = t42 & y11;
3095
    z7 = t45 & y17;
3096
    z8 = t41 & y10;
3097
    z9 = t44 & y12;
3098
    z10 = t37 & y3;
3099
    z11 = t33 & y4;
3100
    z12 = t43 & y13;
3101
    z13 = t40 & y5;
3102
    z14 = t29 & y2;
3103
    z15 = t42 & y9;
3104
    z16 = t45 & y14;
3105
    z17 = t41 & y8;
3106
    tc1 = z15 ^ z16;
3107
    tc2 = z10 ^ tc1;
3108
    tc3 = z9 ^ tc2;
3109
    tc4 = z0 ^ z2;
3110
    tc5 = z1 ^ z0;
3111
    tc6 = z3 ^ z4;
3112
    tc7 = z12 ^ tc4;
3113
    tc8 = z7 ^ tc6;
3114
    tc9 = z8 ^ tc7;
3115
    tc10 = tc8 ^ tc9;
3116
    tc11 = tc6 ^ tc5;
3117
    tc12 = z3 ^ z5;
3118
    tc13 = z13 ^ tc1;
3119
    tc14 = tc4 ^ tc12;
3120
    S3 = tc3 ^ tc11;
3121
    tc16 = z6 ^ tc8;
3122
    tc17 = z14 ^ tc10;
3123
    tc18 = tc13 ^ tc14;
3124
    S7 = ~(z12 ^ tc18);
3125
    tc20 = z15 ^ tc16;
3126
    tc21 = tc2 ^ z11;
3127
    S0 = tc3 ^ tc16;
3128
    S6 = ~(tc10 ^ tc18);
3129
    S4 = tc14 ^ S3;
3130
    S1 = ~(S3 ^ tc16);
3131
    tc26 = tc17 ^ tc20;
3132
    S2 = ~(tc26 ^ z17);
3133
    S5 = tc21 ^ tc17;
3134
3135
    u[0] = S7;
3136
    u[1] = S6;
3137
    u[2] = S5;
3138
    u[3] = S4;
3139
    u[4] = S3;
3140
    u[5] = S2;
3141
    u[6] = S1;
3142
    u[7] = S0;
3143
}
3144
3145
#define BS_MASK_BIT_SET(w, j, bmask) \
3146
    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
3147
3148
#define BS_TRANS_8(t, o, w, bmask, s)                   \
3149
    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
3150
    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
3151
    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
3152
    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
3153
    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
3154
    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
3155
    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
3156
    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
3157
3158
static void bs_transpose(bs_word* t, bs_word* blocks)
3159
{
3160
    bs_word bmask = 1;
3161
    int i;
3162
3163
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
3164
3165
    for (i = 0; i < BS_WORD_SIZE; i++) {
3166
        int j;
3167
        int o = 0;
3168
        for (j = 0; j < BS_BLOCK_WORDS; j++) {
3169
        #ifdef LITTLE_ENDIAN_ORDER
3170
            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
3171
        #else
3172
            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
3173
        #endif
3174
    #ifdef WOLFSSL_AES_NO_UNROLL
3175
            int k;
3176
            for (k = 0; k < BS_WORD_SIZE; k++) {
3177
                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
3178
            }
3179
    #else
3180
            BS_TRANS_8(t, o, w, bmask,  0);
3181
        #if BS_WORD_SIZE >= 16
3182
            BS_TRANS_8(t, o, w, bmask,  8);
3183
        #endif
3184
        #if BS_WORD_SIZE >= 32
3185
            BS_TRANS_8(t, o, w, bmask, 16);
3186
            BS_TRANS_8(t, o, w, bmask, 24);
3187
        #endif
3188
        #if BS_WORD_SIZE >= 64
3189
            BS_TRANS_8(t, o, w, bmask, 32);
3190
            BS_TRANS_8(t, o, w, bmask, 40);
3191
            BS_TRANS_8(t, o, w, bmask, 48);
3192
            BS_TRANS_8(t, o, w, bmask, 56);
3193
        #endif
3194
    #endif
3195
            o += BS_WORD_SIZE;
3196
        }
3197
        bmask <<= 1;
3198
    }
3199
}
3200
3201
#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
3202
    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
3203
    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
3204
    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
3205
    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
3206
    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
3207
    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
3208
    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
3209
    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
3210
3211
static void bs_inv_transpose(bs_word* t, bs_word* blocks)
3212
{
3213
    int o;
3214
3215
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
3216
3217
    for (o = 0; o < BS_BLOCK_WORDS; o++) {
3218
        int i;
3219
        for (i = 0; i < BS_WORD_SIZE; i++) {
3220
        #ifdef LITTLE_ENDIAN_ORDER
3221
            bs_word bmask = (bs_word)1 << i;
3222
        #else
3223
            bs_word bmask = bs_bswap((bs_word)1 << i);
3224
        #endif
3225
            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
3226
    #ifdef WOLFSSL_AES_NO_UNROLL
3227
            int j;
3228
            for (j = 0; j < BS_WORD_SIZE; j++) {
3229
                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
3230
            }
3231
    #else
3232
            BS_INV_TRANS_8(t, o, w, bmask, 0);
3233
        #if BS_WORD_SIZE >= 16
3234
            BS_INV_TRANS_8(t, o, w, bmask, 8);
3235
        #endif
3236
        #if BS_WORD_SIZE >= 32
3237
            BS_INV_TRANS_8(t, o, w, bmask, 16);
3238
            BS_INV_TRANS_8(t, o, w, bmask, 24);
3239
        #endif
3240
        #if BS_WORD_SIZE >= 64
3241
            BS_INV_TRANS_8(t, o, w, bmask, 32);
3242
            BS_INV_TRANS_8(t, o, w, bmask, 40);
3243
            BS_INV_TRANS_8(t, o, w, bmask, 48);
3244
            BS_INV_TRANS_8(t, o, w, bmask, 56);
3245
        #endif
3246
    #endif
3247
        }
3248
    }
3249
}
3250
3251
#define BS_ROW_OFF_0    0
3252
#define BS_ROW_OFF_1    32
3253
#define BS_ROW_OFF_2    64
3254
#define BS_ROW_OFF_3    96
3255
3256
#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
3257
#define BS_IDX_MASK     0x7f
3258
3259
#define BS_ASSIGN_8(d, od, s, os)   \
3260
    d[(od) + 0] = s[(os) + 0];      \
3261
    d[(od) + 1] = s[(os) + 1];      \
3262
    d[(od) + 2] = s[(os) + 2];      \
3263
    d[(od) + 3] = s[(os) + 3];      \
3264
    d[(od) + 4] = s[(os) + 4];      \
3265
    d[(od) + 5] = s[(os) + 5];      \
3266
    d[(od) + 6] = s[(os) + 6];      \
3267
    d[(od) + 7] = s[(os) + 7]
3268
3269
static void bs_shift_rows(bs_word* t, bs_word* b)
3270
{
3271
    int i;
3272
3273
    for (i = 0; i < 128; i += 32) {
3274
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
3275
        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
3276
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
3277
        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
3278
    }
3279
}
3280
3281
#define BS_SHIFT_OFF_0  0
3282
#define BS_SHIFT_OFF_1  8
3283
#define BS_SHIFT_OFF_2  16
3284
#define BS_SHIFT_OFF_3  24
3285
3286
/* Shift rows and mix columns.
3287
 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
3288
 */
3289
3290
#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
3291
        of      = br0[7] ^ br1[7];                                  \
3292
        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
3293
        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
3294
        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
3295
        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
3296
        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
3297
        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
3298
        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
3299
        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
3300
3301
static void bs_shift_mix(bs_word* t, bs_word* b)
3302
{
3303
    int i;
3304
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
3305
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
3306
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
3307
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
3308
3309
    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
3310
        bs_word* br0 = b + or0;
3311
        bs_word* br1 = b + or1;
3312
        bs_word* br2 = b + or2;
3313
        bs_word* br3 = b + or3;
3314
        bs_word of;
3315
3316
        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
3317
        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
3318
        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
3319
        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
3320
3321
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3322
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3323
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3324
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3325
    }
3326
}
3327
3328
static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
3329
{
3330
    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
3331
}
3332
3333
static void bs_sub_bytes_blocks(bs_word* b)
3334
{
3335
    int i;
3336
3337
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
3338
        bs_sub_bytes(b + i);
3339
    }
3340
}
3341
3342
static const FLASH_QUALIFIER byte bs_rcon[] = {
3343
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
3344
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
3345
};
3346
3347
static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
3348
    bs_word block[AES_BLOCK_BITS];
3349
    bs_word trans[AES_BLOCK_BITS];
3350
3351
    XMEMSET(block, 0, sizeof(block));
3352
    XMEMCPY(block, in, 4);
3353
3354
    bs_transpose(trans, block);
3355
    bs_sub_bytes_blocks(trans);
3356
    bs_inv_transpose(block, trans);
3357
3358
    XMEMCPY(out, block, 4);
3359
}
3360
3361
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
3362
    /* Rotate left 8 bits. The key schedule is a byte array, so use the
3363
     * unaligned accessors. */
3364
#ifdef LITTLE_ENDIAN_ORDER
3365
    (void)writeUnalignedWord32(out, rotrFixed(readUnalignedWord32(in), 8));
3366
#else
3367
    (void)writeUnalignedWord32(out, rotlFixed(readUnalignedWord32(in), 8));
3368
#endif
3369
    bs_ke_sub_bytes(out, out);
3370
    /* On just the first byte, add 2^i to the byte */
3371
    out[0] ^= bs_rcon[i];
3372
}
3373
3374
/* r = a ^ b, on schedule words in byte arrays of unknown alignment. */
3375
static void bs_ke_xor(unsigned char* r, const unsigned char* a,
3376
    const unsigned char* b)
3377
{
3378
    (void)writeUnalignedWord32(r,
3379
        readUnalignedWord32(a) ^ readUnalignedWord32(b));
3380
}
3381
3382
static void bs_expand_key(unsigned char *in, word32 sz) {
3383
    unsigned char t[4];
3384
    word32 o;
3385
    word8 i = 0;
3386
3387
    if (sz == 176) {
3388
        /* Total of 11 rounds - AES-128. */
3389
        for (o = 16; o < sz; o += 16) {
3390
            bs_ke_transform(t, in + o - 4, i);
3391
            i++;
3392
            bs_ke_xor(in + o +  0, in + o - 16, t);
3393
            bs_ke_xor(in + o +  4, in + o - 12, in + o +  0);
3394
            bs_ke_xor(in + o +  8, in + o -  8, in + o +  4);
3395
            bs_ke_xor(in + o + 12, in + o -  4, in + o +  8);
3396
        }
3397
    }
3398
    else if (sz == 208) {
3399
        /* Total of 13 rounds - AES-192. */
3400
        for (o = 24; o < sz; o += 24) {
3401
            bs_ke_transform(t, in + o - 4, i);
3402
            i++;
3403
            bs_ke_xor(in + o +  0, in + o - 24, t);
3404
            bs_ke_xor(in + o +  4, in + o - 20, in + o +  0);
3405
            bs_ke_xor(in + o +  8, in + o - 16, in + o +  4);
3406
            bs_ke_xor(in + o + 12, in + o - 12, in + o +  8);
3407
            bs_ke_xor(in + o + 16, in + o -  8, in + o + 12);
3408
            bs_ke_xor(in + o + 20, in + o -  4, in + o + 16);
3409
        }
3410
    }
3411
    else if (sz == 240) {
3412
        /* Total of 15 rounds - AES-256. */
3413
        for (o = 32; o < sz; o += 16) {
3414
            if ((o & 0x1f) == 0) {
3415
                bs_ke_transform(t, in + o - 4, i);
3416
                i++;
3417
            }
3418
            else {
3419
                bs_ke_sub_bytes(t, in + o - 4);
3420
            }
3421
            bs_ke_xor(in + o +  0, in + o - 32, t);
3422
            bs_ke_xor(in + o +  4, in + o - 28, in + o +  0);
3423
            bs_ke_xor(in + o +  8, in + o - 24, in + o +  4);
3424
            bs_ke_xor(in + o + 12, in + o - 20, in + o +  8);
3425
        }
3426
    }
3427
}
3428
3429
static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
3430
    word32 rounds)
3431
{
3432
    int i;
3433
    byte bs_key[15 * WC_AES_BLOCK_SIZE];
3434
    int ksSz = (rounds + 1) * WC_AES_BLOCK_SIZE;
3435
    bs_word block[AES_BLOCK_BITS];
3436
3437
    /* Fist round. */
3438
    XMEMCPY(bs_key, key, keyLen);
3439
    bs_expand_key(bs_key, ksSz);
3440
3441
    for (i = 0; i < ksSz; i += WC_AES_BLOCK_SIZE) {
3442
        int k;
3443
3444
        XMEMCPY(block, bs_key + i, WC_AES_BLOCK_SIZE);
3445
        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
3446
            int l;
3447
            for (l = 0; l < BS_BLOCK_WORDS; l++) {
3448
                block[k + l] = block[l];
3449
            }
3450
        }
3451
        bs_transpose(rk, block);
3452
        rk += AES_BLOCK_BITS;
3453
    }
3454
}
3455
3456
static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
3457
{
3458
    word32 i;
3459
    bs_word trans[AES_BLOCK_BITS];
3460
3461
    bs_transpose(trans, state);
3462
3463
    bs_add_round_key(trans, trans, rk);
3464
    for (i = 1; i < r; i++) {
3465
        bs_sub_bytes_blocks(trans);
3466
        bs_shift_mix(state, trans);
3467
        rk += AES_BLOCK_BITS;
3468
        bs_add_round_key(trans, state, rk);
3469
    }
3470
    bs_sub_bytes_blocks(trans);
3471
    bs_shift_rows(state, trans);
3472
    rk += AES_BLOCK_BITS;
3473
    bs_add_round_key(trans, state, rk);
3474
    bs_inv_transpose(state, trans);
3475
}
3476
3477
#ifndef HAVE_CUDA
3478
/* Encrypt a block using AES.
3479
 *
3480
 * @param [in]  aes       AES object.
3481
 * @param [in]  inBlock   Block to encrypt.
3482
 * @param [out] outBlock  Encrypted block.
3483
 * @param [in]  r         Rounds divided by 2.
3484
 */
3485
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3486
        word32 r)
3487
{
3488
    bs_word state[AES_BLOCK_BITS];
3489
3490
    (void)r;
3491
3492
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
3493
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
3494
3495
    bs_encrypt(state, aes->bs_key, aes->rounds);
3496
3497
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
3498
}
3499
3500
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3501
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3502
/* Encrypt a number of blocks using AES.
3503
 *
3504
 * @param [in]  aes  AES object.
3505
 * @param [in]  in   Block to encrypt.
3506
 * @param [out] out  Encrypted block.
3507
 * @param [in]  sz   Number of blocks to encrypt.
3508
 */
3509
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3510
{
3511
    bs_word state[AES_BLOCK_BITS];
3512
3513
    while (sz >= BS_BLOCK_SIZE) {
3514
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3515
        bs_encrypt(state, aes->bs_key, aes->rounds);
3516
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3517
        sz  -= BS_BLOCK_SIZE;
3518
        in  += BS_BLOCK_SIZE;
3519
        out += BS_BLOCK_SIZE;
3520
    }
3521
    if (sz > 0) {
3522
        XMEMCPY(state, in, sz);
3523
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3524
        bs_encrypt(state, aes->bs_key, aes->rounds);
3525
        XMEMCPY(out, state, sz);
3526
    }
3527
}
3528
#endif
3529
#else
3530
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3531
        word32 r);
3532
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
3533
#endif /* HAVE_CUDA */
3534
3535
#endif /* !WC_AES_BITSLICED */
3536
3537
#ifdef WC_AES_HAVE_PREFETCH_ARG
3538
#define wc_AesEncrypt(aes, inBlock, outBlock) \
3539
0
    AesEncrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
3540
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesEncrypt_preFetchOpt(
3541
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
3542
#else
3543
#define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
3544
    wc_AesEncrypt(aes, inBlock, outBlock)
3545
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesEncrypt(
3546
    Aes* aes, const byte* inBlock, byte* outBlock)
3547
#endif
3548
0
{
3549
#if defined(MAX3266X_AES)
3550
    word32 keySize;
3551
#endif
3552
#if defined(MAX3266X_CB)
3553
    int ret_cb;
3554
#endif
3555
0
    word32 r;
3556
3557
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3558
    {
3559
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3560
        if (ret < 0)
3561
            return ret;
3562
    }
3563
#endif
3564
3565
0
    r = aes->rounds >> 1;
3566
3567
0
    if (r > 7 || r == 0) {
3568
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3569
0
        return KEYUSAGE_E;
3570
0
    }
3571
3572
#ifdef WOLFSSL_AESNI
3573
    if (aes->use_aesni) {
3574
        ASSERT_SAVED_VECTOR_REGISTERS();
3575
3576
        #ifdef DEBUG_AESNI
3577
            printf("about to aes encrypt\n");
3578
            printf("in  = %p\n", inBlock);
3579
            printf("out = %p\n", outBlock);
3580
            printf("aes->key = %p\n", aes->key);
3581
            printf("aes->rounds = %d\n", aes->rounds);
3582
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
3583
        #endif
3584
3585
        /* check alignment, decrypt doesn't need alignment */
3586
        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
3587
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
3588
            byte* tmp = (byte*)XMALLOC(WC_AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
3589
                                                      DYNAMIC_TYPE_TMP_BUFFER);
3590
            byte* tmp_align;
3591
            if (tmp == NULL)
3592
                return MEMORY_E;
3593
3594
            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
3595
3596
            XMEMCPY(tmp_align, inBlock, WC_AES_BLOCK_SIZE);
3597
            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, WC_AES_BLOCK_SIZE,
3598
                    (byte*)aes->key, (int)aes->rounds);
3599
            XMEMCPY(outBlock, tmp_align, WC_AES_BLOCK_SIZE);
3600
            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3601
            return 0;
3602
        #else
3603
            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
3604
            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
3605
            return BAD_ALIGN_E;
3606
        #endif
3607
        }
3608
3609
        AES_ECB_encrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3610
                        (int)aes->rounds);
3611
3612
        return 0;
3613
    }
3614
    else {
3615
        #ifdef DEBUG_AESNI
3616
            printf("Skipping AES-NI\n");
3617
        #endif
3618
    }
3619
#elif defined(WOLFSSL_ARMASM)
3620
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
3621
#if !defined(__aarch64__)
3622
#ifdef WOLFSSL_ARM32_AES_DISPATCH
3623
    if (aes->use_aes_hw_crypto) {
3624
        AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key,
3625
            (int)aes->rounds);
3626
    }
3627
    else
3628
#else
3629
    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
3630
#endif /* WOLFSSL_ARM32_AES_DISPATCH */
3631
#else
3632
    if (aes->use_aes_hw_crypto) {
3633
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3634
            (int)aes->rounds);
3635
    }
3636
    else
3637
#endif /* !__aarch64__ */
3638
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
3639
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
3640
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
3641
    {
3642
        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3643
            (const unsigned char*)aes->key, aes->rounds);
3644
    }
3645
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
3646
      defined(WOLFSSL_ARM32_AES_DISPATCH)
3647
    {
3648
        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
3649
            (const unsigned char*)aes->key, aes->rounds);
3650
    }
3651
#endif
3652
    return 0;
3653
#endif /* WOLFSSL_AESNI */
3654
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3655
    AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3656
    return 0;
3657
#endif
3658
3659
#if defined(WOLFSSL_IMXRT_DCP)
3660
    if (aes->keylen == 16) {
3661
        DCPAesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3662
        return 0;
3663
    }
3664
#endif
3665
3666
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3667
    if (aes->useSWCrypt == 0) {
3668
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3669
                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
3670
    }
3671
#endif
3672
3673
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3674
    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
3675
    if (wc_esp32AesSupportedKeyLen(aes)) {
3676
        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
3677
    }
3678
    else {
3679
        /* For example, the ESP32-S3 does not support HW for len = 24,
3680
         * so fall back to SW */
3681
    #ifdef DEBUG_WOLFSSL
3682
        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
3683
                      aes->keylen);
3684
    #endif
3685
    }
3686
#endif
3687
3688
#if defined(MAX3266X_AES)
3689
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3690
        return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3691
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3692
                                    outBlock, (unsigned int)keySize);
3693
    }
3694
#endif
3695
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3696
    #ifndef WOLF_CRYPTO_CB_FIND
3697
    if (aes->devId != INVALID_DEVID)
3698
    #endif
3699
    {
3700
        ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock,
3701
                                            WC_AES_BLOCK_SIZE);
3702
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3703
            return ret_cb;
3704
        /* fall-through when unavailable */
3705
    }
3706
#endif
3707
3708
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
3709
0
    AesEncrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
3710
#else
3711
    AesEncrypt_C(aes, inBlock, outBlock, r);
3712
#endif
3713
3714
0
    return 0;
3715
0
} /* wc_AesEncrypt */
3716
#endif
3717
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
3718
3719
#if defined(HAVE_AES_DECRYPT)
3720
#if ((defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
3721
     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)) && \
3722
    (defined(__aarch64__) || !defined(WOLFSSL_ARMASM))
3723
3724
#ifndef WC_AES_BITSLICED
3725
#ifndef WC_NO_CACHE_RESISTANT
3726
#ifndef WOLFSSL_AES_SMALL_TABLES
3727
/* load 4 Td Tables into cache by cache line stride */
3728
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
3729
0
{
3730
0
    volatile word32 x = 0;
3731
0
    int i;
3732
0
    int j;
3733
3734
0
    for (i = 0; i < 4; i++) {
3735
        /* 256 elements, each one is 4 bytes */
3736
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
3737
0
            x &= Td[i][j];
3738
0
        }
3739
0
    }
3740
3741
0
    return x;
3742
0
}
3743
#endif /* !WOLFSSL_AES_SMALL_TABLES */
3744
3745
/* load Td Table4 into cache by cache line stride */
3746
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
3747
0
{
3748
0
#ifndef WOLFSSL_AES_TOUCH_LINES
3749
0
    volatile word32 x = 0;
3750
0
    int i;
3751
3752
0
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
3753
0
        x &= (word32)Td4[i];
3754
0
    }
3755
3756
0
    return x;
3757
#else
3758
    return 0;
3759
#endif
3760
0
}
3761
#endif /* !WC_NO_CACHE_RESISTANT */
3762
3763
/* Decrypt a block using AES.
3764
 *
3765
 * @param [in]  aes       AES object.
3766
 * @param [in]  inBlock   Block to encrypt.
3767
 * @param [out] outBlock  Encrypted block.
3768
 * @param [in]  r         Rounds divided by 2.
3769
 */
3770
#ifndef WC_AES_HAVE_PREFETCH_ARG
3771
    #define WC_AES_HAVE_PREFETCH_ARG
3772
    static int always_prefetch = 0;
3773
    WC_MAYBE_UNUSED static int never_prefetch = 1;
3774
#endif
3775
WC_ARGS_NOT_NULL((1, 2, 3, 5))
3776
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3777
    word32 r, int *prefetch_ptr)
3778
0
{
3779
0
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
3780
0
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
3781
0
    const word32* rk;
3782
#ifdef WOLFSSL_WIDE_BYTE
3783
    word32 stw[4]; /* octet-wise block I/O scratch (CHAR_BIT != 8) */
3784
#endif
3785
3786
#ifdef WC_C_DYNAMIC_FALLBACK
3787
    rk = aes->key_C_fallback;
3788
#else
3789
0
    rk = aes->key;
3790
0
#endif
3791
3792
    /*
3793
     * map byte array block to cipher state
3794
     * and add initial round key:
3795
     */
3796
#ifdef WOLFSSL_WIDE_BYTE
3797
    /* A C byte is wider than an octet here: the block is one octet per cell, so
3798
     * assemble the 4 big-endian state words octet-wise (no aliasing/reverse). */
3799
    WordsFromBytesBE32(stw, inBlock, 4);
3800
    s0 = stw[0]; s1 = stw[1]; s2 = stw[2]; s3 = stw[3];
3801
#else
3802
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
3803
0
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
3804
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
3805
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
3806
3807
0
#ifdef LITTLE_ENDIAN_ORDER
3808
0
    s0 = ByteReverseWord32(s0);
3809
0
    s1 = ByteReverseWord32(s1);
3810
0
    s2 = ByteReverseWord32(s2);
3811
0
    s3 = ByteReverseWord32(s3);
3812
0
#endif
3813
0
#endif /* WOLFSSL_WIDE_BYTE */
3814
3815
0
    s0 ^= rk[0];
3816
0
    s1 ^= rk[1];
3817
0
    s2 ^= rk[2];
3818
0
    s3 ^= rk[3];
3819
3820
0
#ifndef WOLFSSL_AES_SMALL_TABLES
3821
3822
0
#ifndef WC_NO_CACHE_RESISTANT
3823
0
    if (*prefetch_ptr == 0) {
3824
0
        s0 |= PreFetchTd();
3825
        /* don't set the prefetched flag here -- PreFetchTd4() is called
3826
         * below.
3827
         */
3828
0
    }
3829
#else
3830
    (void)prefetch_ptr;
3831
#endif
3832
3833
0
#ifndef WOLFSSL_AES_TOUCH_LINES
3834
/* Unroll the loop. */
3835
0
#define DEC_ROUND_T_S(o)                                            \
3836
0
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
3837
0
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
3838
0
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
3839
0
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
3840
0
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
3841
0
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
3842
0
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
3843
0
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
3844
0
#define DEC_ROUND_S_T(o)                                            \
3845
0
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
3846
0
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
3847
0
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
3848
0
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
3849
0
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
3850
0
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
3851
0
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
3852
0
         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
3853
#else
3854
#define DEC_ROUND_T_S(o)                                                       \
3855
    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
3856
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
3857
    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
3858
                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
3859
    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
3860
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
3861
    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
3862
                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
3863
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
3864
3865
#define DEC_ROUND_S_T(o)                                                       \
3866
    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
3867
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
3868
    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
3869
                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
3870
    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
3871
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
3872
    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
3873
                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
3874
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
3875
#endif
3876
3877
0
#ifndef WOLFSSL_AES_NO_UNROLL
3878
0
                       DEC_ROUND_T_S( 0);
3879
0
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3880
0
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3881
0
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3882
0
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3883
0
    if (r > 5) {
3884
0
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3885
0
        if (r > 6) {
3886
0
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3887
0
        }
3888
0
    }
3889
0
    rk += r * 8;
3890
#else
3891
3892
    /*
3893
     * Nr - 1 full rounds:
3894
     */
3895
3896
    for (;;) {
3897
        DEC_ROUND_T_S(0);
3898
3899
        rk += 8;
3900
        if (--r == 0) {
3901
            break;
3902
        }
3903
3904
        DEC_ROUND_S_T(0);
3905
    }
3906
#endif
3907
    /*
3908
     * apply last round and
3909
     * map cipher state to byte array block:
3910
     */
3911
3912
0
#ifndef WC_NO_CACHE_RESISTANT
3913
0
    if (*prefetch_ptr == 0) {
3914
0
        t0 |= PreFetchTd4();
3915
0
        if (prefetch_ptr != &always_prefetch)
3916
0
            *prefetch_ptr = 1;
3917
0
    }
3918
#else
3919
    (void)prefetch_ptr;
3920
#endif
3921
3922
0
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3923
0
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3924
0
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3925
0
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3926
0
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3927
0
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3928
0
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3929
0
                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
3930
3931
#else /* WOLFSSL_AES_SMALL_TABLES */
3932
3933
#ifndef WC_NO_CACHE_RESISTANT
3934
    if (*prefetch_ptr == 0) {
3935
        s0 |= PreFetchTd4();
3936
        if (prefetch_ptr != &always_prefetch)
3937
            *prefetch_ptr = 1;
3938
    }
3939
#else
3940
    (void)prefetch_ptr;
3941
#endif
3942
3943
    r *= 2;
3944
    for (rk += 4; r > 1; r--, rk += 4) {
3945
        t0 =
3946
            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3947
            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3948
            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3949
            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
3950
            rk[0];
3951
        t1 =
3952
            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3953
            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3954
            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3955
            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
3956
            rk[1];
3957
        t2 =
3958
            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3959
            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3960
            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3961
            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
3962
            rk[2];
3963
        t3 =
3964
            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3965
            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3966
            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3967
            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
3968
            rk[3];
3969
3970
        s0 =
3971
            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
3972
            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
3973
            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
3974
            (inv_col_mul(t0, 1, 3, 2, 0)      );
3975
        s1 =
3976
            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
3977
            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
3978
            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
3979
            (inv_col_mul(t1, 1, 3, 2, 0)      );
3980
        s2 =
3981
            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
3982
            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
3983
            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
3984
            (inv_col_mul(t2, 1, 3, 2, 0)      );
3985
        s3 =
3986
            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
3987
            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
3988
            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
3989
            (inv_col_mul(t3, 1, 3, 2, 0)      );
3990
    }
3991
3992
    t0 =
3993
        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3994
        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3995
        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3996
        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
3997
    t1 =
3998
        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3999
        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
4000
        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
4001
        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
4002
    t2 =
4003
        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
4004
        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
4005
        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
4006
        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
4007
    t3 =
4008
        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
4009
        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
4010
        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
4011
        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
4012
    s0 = t0 ^ rk[0];
4013
    s1 = t1 ^ rk[1];
4014
    s2 = t2 ^ rk[2];
4015
    s3 = t3 ^ rk[3];
4016
4017
#endif /* WOLFSSL_AES_SMALL_TABLES */
4018
4019
    /* write out */
4020
#ifdef WOLFSSL_WIDE_BYTE
4021
    stw[0] = s0; stw[1] = s1; stw[2] = s2; stw[3] = s3;
4022
    BytesFromWordsBE32(outBlock, stw, WC_AES_BLOCK_SIZE);
4023
#else
4024
0
#ifdef LITTLE_ENDIAN_ORDER
4025
0
    s0 = ByteReverseWord32(s0);
4026
0
    s1 = ByteReverseWord32(s1);
4027
0
    s2 = ByteReverseWord32(s2);
4028
0
    s3 = ByteReverseWord32(s3);
4029
0
#endif
4030
4031
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
4032
0
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
4033
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
4034
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
4035
0
#endif /* WOLFSSL_WIDE_BYTE */
4036
4037
0
}
4038
4039
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
4040
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
4041
    !defined(MAX3266X_AES)
4042
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
4043
/* Decrypt a number of blocks using AES.
4044
 *
4045
 * @param [in]  aes  AES object.
4046
 * @param [in]  in   Block to encrypt.
4047
 * @param [out] out  Encrypted block.
4048
 * @param [in]  sz   Number of blocks to encrypt.
4049
 */
4050
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
4051
{
4052
    word32 i;
4053
    int did_prefetches = 0;
4054
4055
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
4056
        AesDecrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
4057
        in += WC_AES_BLOCK_SIZE;
4058
        out += WC_AES_BLOCK_SIZE;
4059
    }
4060
}
4061
#endif
4062
#endif
4063
4064
#else /* WC_AES_BITSLICED */
4065
4066
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
4067
static void bs_inv_sub_bytes(bs_word u[8])
4068
{
4069
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
4070
    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
4071
    bs_word RTL0, RTL1, RTL2;
4072
    bs_word sa0, sa1;
4073
    bs_word sb0, sb1;
4074
    bs_word ab0, ab1, ab2, ab3;
4075
    bs_word ab20, ab21, ab22, ab23;
4076
    bs_word al, ah, aa, bl, bh, bb;
4077
    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
4078
    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
4079
    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
4080
    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
4081
    bs_word rr1, rr2;
4082
    bs_word r10, r11;
4083
    bs_word cp1, cp2, cp3, cp4;
4084
    bs_word vr1, vr2, vr3;
4085
    bs_word pr1, pr2, pr3;
4086
    bs_word wr1, wr2, wr3;
4087
    bs_word qr1, qr2, qr3;
4088
    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
4089
    bs_word tinv10, tinv11, tinv12, tinv13;
4090
    bs_word t01, t02;
4091
    bs_word d0, d1, d2, d3;
4092
    bs_word dl, dd, dh;
4093
    bs_word sd0, sd1;
4094
    bs_word p0, p1, p2, p3, p4, p6, p7;
4095
    bs_word X11, X13, X14, X16, X18, X19;
4096
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
4097
4098
    U0 = u[7];
4099
    U1 = u[6];
4100
    U2 = u[5];
4101
    U3 = u[4];
4102
    U4 = u[3];
4103
    U5 = u[2];
4104
    U6 = u[1];
4105
    U7 = u[0];
4106
4107
    Y0 = U0 ^ U3;
4108
    Y2 = ~(U1 ^ U3);
4109
    Y4 = U0 ^ Y2;
4110
    RTL0 = U6 ^ U7;
4111
    Y1 = Y2 ^ RTL0;
4112
    Y7 = ~(U2 ^ Y1);
4113
    RTL1 = U3 ^ U4;
4114
    Y6 = ~(U7 ^ RTL1);
4115
    Y3 = Y1 ^ RTL1;
4116
    RTL2 = ~(U0 ^ U2);
4117
    Y5 = U5 ^ RTL2;
4118
    sa1 = Y0 ^ Y2;
4119
    sa0 = Y1 ^ Y3;
4120
    sb1 = Y4 ^ Y6;
4121
    sb0 = Y5 ^ Y7;
4122
    ah = Y0 ^ Y1;
4123
    al = Y2 ^ Y3;
4124
    aa = sa0 ^ sa1;
4125
    bh = Y4 ^ Y5;
4126
    bl = Y6 ^ Y7;
4127
    bb = sb0 ^ sb1;
4128
    ab20 = sa0 ^ sb0;
4129
    ab22 = al ^ bl;
4130
    ab23 = Y3 ^ Y7;
4131
    ab21 = sa1 ^ sb1;
4132
    abcd1 = ah & bh;
4133
    rr1 = Y0 & Y4;
4134
    ph11 = ab20 ^ abcd1;
4135
    t01 = Y1 & Y5;
4136
    ph01 = t01 ^ abcd1;
4137
    abcd2 = al & bl;
4138
    r1 = Y2 & Y6;
4139
    pl11 = ab22 ^ abcd2;
4140
    r2 = Y3 & Y7;
4141
    pl01 = r2 ^ abcd2;
4142
    r3 = sa0 & sb0;
4143
    vr1 = aa & bb;
4144
    pr1 = vr1 ^ r3;
4145
    wr1 = sa1 & sb1;
4146
    qr1 = wr1 ^ r3;
4147
    ab0 = ph11 ^ rr1;
4148
    ab1 = ph01 ^ ab21;
4149
    ab2 = pl11 ^ r1;
4150
    ab3 = pl01 ^ qr1;
4151
    cp1 = ab0 ^ pr1;
4152
    cp2 = ab1 ^ qr1;
4153
    cp3 = ab2 ^ pr1;
4154
    cp4 = ab3 ^ ab23;
4155
    tinv1 = cp3 ^ cp4;
4156
    tinv2 = cp3 & cp1;
4157
    tinv3 = cp2 ^ tinv2;
4158
    tinv4 = cp1 ^ cp2;
4159
    tinv5 = cp4 ^ tinv2;
4160
    tinv6 = tinv5 & tinv4;
4161
    tinv7 = tinv3 & tinv1;
4162
    d2 = cp4 ^ tinv7;
4163
    d0 = cp2 ^ tinv6;
4164
    tinv8 = cp1 & cp4;
4165
    tinv9 = tinv4 & tinv8;
4166
    tinv10 = tinv4 ^ tinv2;
4167
    d1 = tinv9 ^ tinv10;
4168
    tinv11 = cp2 & cp3;
4169
    tinv12 = tinv1 & tinv11;
4170
    tinv13 = tinv1 ^ tinv2;
4171
    d3 = tinv12 ^ tinv13;
4172
    sd1 = d1 ^ d3;
4173
    sd0 = d0 ^ d2;
4174
    dl = d0 ^ d1;
4175
    dh = d2 ^ d3;
4176
    dd = sd0 ^ sd1;
4177
    abcd3 = dh & bh;
4178
    rr2 = d3 & Y4;
4179
    t02 = d2 & Y5;
4180
    abcd4 = dl & bl;
4181
    r4 = d1 & Y6;
4182
    r5 = d0 & Y7;
4183
    r6 = sd0 & sb0;
4184
    vr2 = dd & bb;
4185
    wr2 = sd1 & sb1;
4186
    abcd5 = dh & ah;
4187
    r7 = d3 & Y0;
4188
    r8 = d2 & Y1;
4189
    abcd6 = dl & al;
4190
    r9 = d1 & Y2;
4191
    r10 = d0 & Y3;
4192
    r11 = sd0 & sa0;
4193
    vr3 = dd & aa;
4194
    wr3 = sd1 & sa1;
4195
    ph12 = rr2 ^ abcd3;
4196
    ph02 = t02 ^ abcd3;
4197
    pl12 = r4 ^ abcd4;
4198
    pl02 = r5 ^ abcd4;
4199
    pr2 = vr2 ^ r6;
4200
    qr2 = wr2 ^ r6;
4201
    p0 = ph12 ^ pr2;
4202
    p1 = ph02 ^ qr2;
4203
    p2 = pl12 ^ pr2;
4204
    p3 = pl02 ^ qr2;
4205
    ph13 = r7 ^ abcd5;
4206
    ph03 = r8 ^ abcd5;
4207
    pl13 = r9 ^ abcd6;
4208
    pl03 = r10 ^ abcd6;
4209
    pr3 = vr3 ^ r11;
4210
    qr3 = wr3 ^ r11;
4211
    p4 = ph13 ^ pr3;
4212
    S7 = ph03 ^ qr3;
4213
    p6 = pl13 ^ pr3;
4214
    p7 = pl03 ^ qr3;
4215
    S3 = p1 ^ p6;
4216
    S6 = p2 ^ p6;
4217
    S0 = p3 ^ p6;
4218
    X11 = p0 ^ p2;
4219
    S5 = S0 ^ X11;
4220
    X13 = p4 ^ p7;
4221
    X14 = X11 ^ X13;
4222
    S1 = S3 ^ X14;
4223
    X16 = p1 ^ S7;
4224
    S2 = X14 ^ X16;
4225
    X18 = p0 ^ p4;
4226
    X19 = S5 ^ X16;
4227
    S4 = X18 ^ X19;
4228
4229
    u[0] = S7;
4230
    u[1] = S6;
4231
    u[2] = S5;
4232
    u[3] = S4;
4233
    u[4] = S3;
4234
    u[5] = S2;
4235
    u[6] = S1;
4236
    u[7] = S0;
4237
}
4238
4239
static void bs_inv_shift_rows(bs_word* b)
4240
{
4241
    bs_word t[AES_BLOCK_BITS];
4242
    int i;
4243
4244
    for (i = 0; i < 128; i += 32) {
4245
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
4246
        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
4247
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
4248
        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
4249
    }
4250
4251
    XMEMCPY(b, t, sizeof(t));
4252
}
4253
4254
#define O0  0
4255
#define O1  8
4256
#define O2  16
4257
#define O3  24
4258
4259
#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
4260
    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
4261
          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
4262
    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
4263
          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
4264
    of2 =                     b[O0+7] ^             b[O1+7] ^               \
4265
                    b[O2+7] ^ b[O3+7];                                      \
4266
                                                                            \
4267
    br[0] =                                                   b[O1+0] ^     \
4268
            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
4269
    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
4270
            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
4271
    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
4272
            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
4273
    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
4274
            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
4275
    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
4276
            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
4277
    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
4278
            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
4279
    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
4280
            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
4281
    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
4282
            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
4283
4284
/* Inverse mix columns and shift rows. */
4285
static void bs_inv_mix_shift(bs_word* t, bs_word* b)
4286
{
4287
    bs_word* bp = b;
4288
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
4289
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
4290
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
4291
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
4292
    int i;
4293
4294
    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
4295
        bs_word* br;
4296
        bs_word of0;
4297
        bs_word of1;
4298
        bs_word of2;
4299
4300
        br = t + or0;
4301
        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
4302
        br = t + or1;
4303
        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
4304
        br = t + or2;
4305
        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
4306
        br = t + or3;
4307
        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
4308
4309
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4310
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4311
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4312
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
4313
4314
        bp += AES_BLOCK_BITS / 4;
4315
    }
4316
}
4317
4318
static void bs_inv_sub_bytes_blocks(bs_word* b)
4319
{
4320
    int i;
4321
4322
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
4323
        bs_inv_sub_bytes(b + i);
4324
    }
4325
}
4326
4327
static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
4328
{
4329
    int i;
4330
    bs_word trans[AES_BLOCK_BITS];
4331
4332
    bs_transpose(trans, state);
4333
4334
    rk += r * AES_BLOCK_BITS;
4335
    bs_add_round_key(trans, trans, rk);
4336
    bs_inv_shift_rows(trans);
4337
    bs_inv_sub_bytes_blocks(trans);
4338
    rk -= AES_BLOCK_BITS;
4339
    bs_add_round_key(trans, trans, rk);
4340
    for (i = (int)r - 2; i >= 0; i--) {
4341
        bs_inv_mix_shift(state, trans);
4342
        bs_inv_sub_bytes_blocks(state);
4343
        rk -= AES_BLOCK_BITS;
4344
        bs_add_round_key(trans, state, rk);
4345
    }
4346
4347
    bs_inv_transpose(state, trans);
4348
}
4349
4350
#ifdef WOLFSSL_AES_DIRECT
4351
/* Decrypt a block using AES.
4352
 *
4353
 * @param [in]  aes       AES object.
4354
 * @param [in]  inBlock   Block to encrypt.
4355
 * @param [out] outBlock  Encrypted block.
4356
 * @param [in]  r         Rounds divided by 2.
4357
 */
4358
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
4359
    word32 r)
4360
{
4361
    bs_word state[AES_BLOCK_BITS];
4362
4363
    (void)r;
4364
4365
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
4366
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
4367
4368
    bs_decrypt(state, aes->bs_key, aes->rounds);
4369
4370
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
4371
}
4372
#endif
4373
4374
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
4375
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
4376
/* Decrypt a number of blocks using AES.
4377
 *
4378
 * @param [in]  aes  AES object.
4379
 * @param [in]  in   Block to encrypt.
4380
 * @param [out] out  Encrypted block.
4381
 * @param [in]  sz   Number of blocks to encrypt.
4382
 */
4383
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
4384
{
4385
    bs_word state[AES_BLOCK_BITS];
4386
4387
    while (sz >= BS_BLOCK_SIZE) {
4388
        XMEMCPY(state, in, BS_BLOCK_SIZE);
4389
        bs_decrypt(state, aes->bs_key, aes->rounds);
4390
        XMEMCPY(out, state, BS_BLOCK_SIZE);
4391
        sz  -= BS_BLOCK_SIZE;
4392
        in  += BS_BLOCK_SIZE;
4393
        out += BS_BLOCK_SIZE;
4394
    }
4395
    if (sz > 0) {
4396
        XMEMCPY(state, in, sz);
4397
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
4398
        bs_decrypt(state, aes->bs_key, aes->rounds);
4399
        XMEMCPY(out, state, sz);
4400
    }
4401
}
4402
#endif
4403
4404
#endif /* !WC_AES_BITSLICED */
4405
#endif
4406
4407
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
4408
    defined(WOLFSSL_AES_DIRECT)
4409
#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
4410
#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
4411
/* Software AES - ECB Decrypt */
4412
4413
#ifdef WC_AES_HAVE_PREFETCH_ARG
4414
#define wc_AesDecrypt(aes, inBlock, outBlock) \
4415
    AesDecrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
4416
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesDecrypt_preFetchOpt(
4417
    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
4418
#else
4419
#define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
4420
    wc_AesDecrypt(aes, inBlock, outBlock)
4421
WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
4422
    Aes* aes, const byte* inBlock, byte* outBlock)
4423
#endif
4424
0
{
4425
#if defined(MAX3266X_AES)
4426
    word32 keySize;
4427
#endif
4428
#if defined(MAX3266X_CB)
4429
    int ret_cb;
4430
#endif
4431
0
    word32 r;
4432
4433
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4434
    {
4435
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4436
        if (ret < 0)
4437
            return ret;
4438
    }
4439
#endif
4440
4441
0
    r = aes->rounds >> 1;
4442
4443
0
    if (r > 7 || r == 0) {
4444
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
4445
0
        return KEYUSAGE_E;
4446
0
    }
4447
4448
#ifdef WOLFSSL_AESNI
4449
    if (aes->use_aesni) {
4450
        ASSERT_SAVED_VECTOR_REGISTERS();
4451
4452
        #ifdef DEBUG_AESNI
4453
            printf("about to aes decrypt\n");
4454
            printf("in  = %p\n", inBlock);
4455
            printf("out = %p\n", outBlock);
4456
            printf("aes->key = %p\n", aes->key);
4457
            printf("aes->rounds = %d\n", aes->rounds);
4458
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
4459
        #endif
4460
4461
        /* if input and output same will overwrite input iv */
4462
        if ((const byte*)aes->tmp != inBlock)
4463
            XMEMCPY(aes->tmp, inBlock, WC_AES_BLOCK_SIZE);
4464
        AES_ECB_decrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
4465
                        (int)aes->rounds);
4466
        return 0;
4467
    }
4468
    else {
4469
        #ifdef DEBUG_AESNI
4470
            printf("Skipping AES-NI\n");
4471
        #endif
4472
    }
4473
#elif defined(WOLFSSL_ARMASM)
4474
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
4475
#if !defined(__aarch64__)
4476
#ifdef WOLFSSL_ARM32_AES_DISPATCH
4477
    if (aes->use_aes_hw_crypto) {
4478
        AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key,
4479
            (int)aes->rounds);
4480
    }
4481
    else
4482
#else
4483
    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
4484
#endif /* WOLFSSL_ARM32_AES_DISPATCH */
4485
#else
4486
    if (aes->use_aes_hw_crypto) {
4487
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
4488
            (int)aes->rounds);
4489
    }
4490
    else
4491
#endif /* !__aarch64__ */
4492
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
4493
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
4494
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
4495
    {
4496
        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4497
            (const unsigned char*)aes->key, aes->rounds);
4498
    }
4499
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
4500
      defined(WOLFSSL_ARM32_AES_DISPATCH)
4501
    {
4502
        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
4503
            (const unsigned char*)aes->key, aes->rounds);
4504
    }
4505
#endif
4506
    return 0;
4507
#endif /* WOLFSSL_AESNI */
4508
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
4509
    return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
4510
#endif
4511
#if defined(WOLFSSL_IMXRT_DCP)
4512
    if (aes->keylen == 16) {
4513
        DCPAesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4514
        return 0;
4515
    }
4516
#endif
4517
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
4518
    if (aes->useSWCrypt == 0) {
4519
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
4520
                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
4521
    }
4522
#endif
4523
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
4524
    if (wc_esp32AesSupportedKeyLen(aes)) {
4525
        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
4526
    }
4527
    else {
4528
        /* For example, the ESP32-S3 does not support HW for len = 24,
4529
         * so fall back to SW */
4530
    #ifdef DEBUG_WOLFSSL
4531
        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
4532
                        "unsupported keylen = %d", aes->keylen);
4533
    #endif
4534
    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
4535
#endif
4536
4537
#if defined(MAX3266X_AES)
4538
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
4539
        return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
4540
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
4541
                                    outBlock, (unsigned int)keySize);
4542
    }
4543
#endif
4544
4545
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
4546
    #ifndef WOLF_CRYPTO_CB_FIND
4547
    if (aes->devId != INVALID_DEVID)
4548
    #endif
4549
    {
4550
        ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock,
4551
                                            WC_AES_BLOCK_SIZE);
4552
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4553
            return ret_cb;
4554
        /* fall-through when unavailable */
4555
    }
4556
#endif
4557
4558
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
4559
0
    AesDecrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
4560
#else
4561
    AesDecrypt_C(aes, inBlock, outBlock, r);
4562
#endif
4563
4564
0
    return 0;
4565
0
} /* wc_AesDecrypt[_SW]() */
4566
#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
4567
#endif
4568
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
4569
#endif /* HAVE_AES_DECRYPT */
4570
4571
#endif /* NEED_AES_TABLES */
4572
4573
#ifdef WOLF_CRYPTO_CB_ONLY_AES
4574
/* Under WOLF_CRYPTO_CB_ONLY_AES the per-block primitive is a thin shim over
4575
 * the cryptocb ECB callback. When the callback returns CRYPTOCB_UNAVAILABLE
4576
 * there is no software fallback, so the operation fails with NO_VALID_DEVID. */
4577
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
4578
    byte* outBlock)
4579
{
4580
    int ret;
4581
4582
    if (aes == NULL || inBlock == NULL || outBlock == NULL)
4583
        return BAD_FUNC_ARG;
4584
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4585
    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4586
    if (ret < 0)
4587
        return ret;
4588
#endif
4589
4590
    ret = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4591
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4592
        return ret;
4593
    return NO_VALID_DEVID;
4594
}
4595
4596
#ifdef HAVE_AES_DECRYPT
4597
static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
4598
    byte* outBlock)
4599
{
4600
    int ret;
4601
4602
    if (aes == NULL || inBlock == NULL || outBlock == NULL)
4603
        return BAD_FUNC_ARG;
4604
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4605
    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4606
    if (ret < 0)
4607
        return ret;
4608
#endif
4609
4610
    ret = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
4611
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4612
        return ret;
4613
    return NO_VALID_DEVID;
4614
}
4615
#endif /* HAVE_AES_DECRYPT */
4616
#endif /* WOLF_CRYPTO_CB_ONLY_AES */
4617
4618
#ifndef WC_AES_HAVE_PREFETCH_ARG
4619
    #ifndef AesEncrypt_preFetchOpt
4620
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4621
            wc_AesEncrypt(aes, inBlock, outBlock)
4622
    #endif
4623
    #ifndef AesDecrypt_preFetchOpt
4624
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
4625
            wc_AesDecrypt(aes, inBlock, outBlock)
4626
    #endif
4627
#endif
4628
4629
/* wc_AesSetKey */
4630
#if defined(STM32_CRYPTO)
4631
4632
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4633
            const byte* iv, int dir)
4634
    {
4635
        word32 *rk;
4636
4637
        (void)dir;
4638
4639
        if (aes == NULL || (keylen != 16 &&
4640
        #ifdef WOLFSSL_AES_192
4641
            keylen != 24 &&
4642
        #endif
4643
            keylen != 32)) {
4644
            return BAD_FUNC_ARG;
4645
        }
4646
4647
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4648
        {
4649
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4650
            if (ret < 0)
4651
                return ret;
4652
        }
4653
#endif
4654
4655
        rk = aes->key;
4656
        aes->keylen = keylen;
4657
        aes->keyInstalled = 1;
4658
        aes->rounds = keylen/4 + 6;
4659
        XMEMCPY(rk, userKey, keylen);
4660
    #ifdef WOLF_CRYPTO_CB
4661
        /* Keep a raw (non-reversed) copy for crypto-callback offload, e.g. the
4662
         * DHUK device reads the seed from devKey. Mirrors the generic
4663
         * wc_AesSetKey cryptocb path. */
4664
        if (keylen <= sizeof(aes->devKey)) {
4665
            XMEMCPY(aes->devKey, userKey, keylen);
4666
        }
4667
    #endif
4668
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
4669
        ByteReverseWords(rk, rk, keylen);
4670
    #endif
4671
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4672
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4673
        defined(WOLFSSL_AES_CTS)
4674
        aes->left = 0;
4675
    #endif
4676
        return wc_AesSetIV(aes, iv);
4677
    }
4678
    #if defined(WOLFSSL_AES_DIRECT)
4679
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4680
                            const byte* iv, int dir)
4681
        {
4682
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4683
        }
4684
    #endif
4685
4686
#elif defined(HAVE_COLDFIRE_SEC)
4687
    #if defined (HAVE_THREADX)
4688
        #include "memory_pools.h"
4689
        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
4690
    #endif
4691
4692
    #define AES_BUFFER_SIZE (WC_AES_BLOCK_SIZE * 64)
4693
    static unsigned char *AESBuffIn = NULL;
4694
    static unsigned char *AESBuffOut = NULL;
4695
    static byte *secReg;
4696
    static byte *secKey;
4697
    static volatile SECdescriptorType *secDesc;
4698
4699
    static wolfSSL_Mutex Mutex_AesSEC;
4700
4701
    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
4702
    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
4703
4704
    extern volatile unsigned char __MBAR[];
4705
4706
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4707
        const byte* iv, int dir)
4708
    {
4709
        if (AESBuffIn == NULL) {
4710
        #if defined (HAVE_THREADX)
4711
            int s1, s2, s3, s4, s5;
4712
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
4713
                                  sizeof(SECdescriptorType), TX_NO_WAIT);
4714
            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
4715
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4716
            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
4717
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
4718
            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
4719
                                  WC_AES_BLOCK_SIZE*2, TX_NO_WAIT);
4720
            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
4721
                                  WC_AES_BLOCK_SIZE, TX_NO_WAIT);
4722
4723
            if (s1 || s2 || s3 || s4 || s5)
4724
                return BAD_FUNC_ARG;
4725
        #else
4726
            #warning "Allocate non-Cache buffers"
4727
        #endif
4728
4729
            wc_InitMutex(&Mutex_AesSEC);
4730
        }
4731
4732
        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4733
            return BAD_FUNC_ARG;
4734
4735
        if (aes == NULL)
4736
            return BAD_FUNC_ARG;
4737
4738
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4739
        {
4740
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4741
            if (ret < 0)
4742
                return ret;
4743
        }
4744
#endif
4745
4746
        aes->keylen = keylen;
4747
        aes->keyInstalled = 1;
4748
        aes->rounds = keylen/4 + 6;
4749
        XMEMCPY(aes->key, userKey, keylen);
4750
4751
        if (iv)
4752
            XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4753
4754
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4755
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4756
        defined(WOLFSSL_AES_CTS)
4757
        aes->left = 0;
4758
    #endif
4759
4760
        return 0;
4761
    }
4762
#elif defined(FREESCALE_LTC)
4763
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
4764
        const byte* iv, int dir, int checkKeyLen)
4765
    {
4766
        if (aes == NULL)
4767
            return BAD_FUNC_ARG;
4768
4769
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4770
        {
4771
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4772
            if (ret < 0)
4773
                return ret;
4774
        }
4775
#endif
4776
4777
        if (checkKeyLen) {
4778
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
4779
                return BAD_FUNC_ARG;
4780
        }
4781
        (void)dir;
4782
4783
        aes->rounds = keylen/4 + 6;
4784
        XMEMCPY(aes->key, userKey, keylen);
4785
        aes->keyInstalled = 1;
4786
4787
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4788
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4789
        defined(WOLFSSL_AES_CTS)
4790
        aes->left = 0;
4791
    #endif
4792
4793
        return wc_AesSetIV(aes, iv);
4794
    }
4795
4796
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4797
        const byte* iv, int dir)
4798
    {
4799
        if (aes == NULL || userKey == NULL) {
4800
            return BAD_FUNC_ARG;
4801
        }
4802
        if (keylen > sizeof(aes->key)) {
4803
            return BAD_FUNC_ARG;
4804
        }
4805
4806
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4807
    }
4808
4809
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4810
                        const byte* iv, int dir)
4811
    {
4812
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4813
    }
4814
#elif defined(WOLFSSL_NRF51_AES)
4815
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4816
        const byte* iv, int dir)
4817
    {
4818
        int ret;
4819
4820
        (void)dir;
4821
        (void)iv;
4822
4823
        if (aes == NULL || keylen != 16)
4824
            return BAD_FUNC_ARG;
4825
4826
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4827
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4828
        if (ret < 0)
4829
            return ret;
4830
#endif
4831
4832
        aes->keylen = keylen;
4833
        aes->keyInstalled = 1;
4834
        aes->rounds = keylen/4 + 6;
4835
        XMEMCPY(aes->key, userKey, keylen);
4836
        ret = nrf51_aes_set_key(userKey);
4837
4838
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4839
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4840
        defined(WOLFSSL_AES_CTS)
4841
        aes->left = 0;
4842
    #endif
4843
4844
        return ret;
4845
    }
4846
4847
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4848
                        const byte* iv, int dir)
4849
    {
4850
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4851
    }
4852
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4853
    /* This is the only definition for HW only.
4854
     * but needs to be renamed when fallback needed.
4855
     * See call in wc_AesSetKey() */
4856
    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
4857
        const byte* iv, int dir)
4858
    {
4859
        (void)dir;
4860
        (void)iv;
4861
        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
4862
        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
4863
            return BAD_FUNC_ARG;
4864
        }
4865
4866
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4867
        {
4868
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4869
            if (ret < 0)
4870
                return ret;
4871
        }
4872
#endif
4873
4874
    #if !defined(WOLFSSL_AES_128)
4875
        if (keylen == 16) {
4876
            return BAD_FUNC_ARG;
4877
        }
4878
    #endif
4879
4880
    #if !defined(WOLFSSL_AES_192)
4881
        if (keylen == 24) {
4882
            return BAD_FUNC_ARG;
4883
        }
4884
    #endif
4885
4886
    #if !defined(WOLFSSL_AES_256)
4887
        if (keylen == 32) {
4888
            return BAD_FUNC_ARG;
4889
        }
4890
    #endif
4891
4892
        aes->keylen = keylen;
4893
        aes->keyInstalled = 1;
4894
        aes->rounds = keylen/4 + 6;
4895
4896
        XMEMCPY(aes->key, userKey, keylen);
4897
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4898
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4899
            defined(WOLFSSL_AES_CTS)
4900
            aes->left = 0;
4901
        #endif
4902
        return wc_AesSetIV(aes, iv);
4903
    } /* wc_AesSetKey */
4904
4905
    /* end #elif ESP32 */
4906
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
4907
4908
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
4909
                    int dir)
4910
    {
4911
        SaSiError_t ret = SASI_OK;
4912
        SaSiAesIv_t iv_aes;
4913
4914
        if (aes == NULL ||
4915
           (keylen != AES_128_KEY_SIZE &&
4916
            keylen != AES_192_KEY_SIZE &&
4917
            keylen != AES_256_KEY_SIZE)) {
4918
            return BAD_FUNC_ARG;
4919
        }
4920
4921
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4922
        {
4923
            int ret2 =
4924
                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4925
            if (ret2 < 0)
4926
                return ret2;
4927
        }
4928
#endif
4929
4930
    #if defined(AES_MAX_KEY_SIZE)
4931
        if (keylen > (AES_MAX_KEY_SIZE/8)) {
4932
            return BAD_FUNC_ARG;
4933
        }
4934
    #endif
4935
        if (dir != AES_ENCRYPTION &&
4936
            dir != AES_DECRYPTION) {
4937
            return BAD_FUNC_ARG;
4938
        }
4939
4940
        if (dir == AES_ENCRYPTION) {
4941
            aes->ctx.mode = SASI_AES_ENCRYPT;
4942
            SaSi_AesInit(&aes->ctx.user_ctx,
4943
                         SASI_AES_ENCRYPT,
4944
                         SASI_AES_MODE_CBC,
4945
                         SASI_AES_PADDING_NONE);
4946
        }
4947
        else {
4948
            aes->ctx.mode = SASI_AES_DECRYPT;
4949
            SaSi_AesInit(&aes->ctx.user_ctx,
4950
                         SASI_AES_DECRYPT,
4951
                         SASI_AES_MODE_CBC,
4952
                         SASI_AES_PADDING_NONE);
4953
        }
4954
4955
        aes->keylen = keylen;
4956
        aes->keyInstalled = 1;
4957
        aes->rounds = keylen/4 + 6;
4958
        XMEMCPY(aes->key, userKey, keylen);
4959
4960
        aes->ctx.key.pKey = (byte*)aes->key;
4961
        aes->ctx.key.keySize= keylen;
4962
4963
        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
4964
                             SASI_AES_USER_KEY,
4965
                             &aes->ctx.key,
4966
                             sizeof(aes->ctx.key));
4967
        if (ret != SASI_OK) {
4968
            return BAD_FUNC_ARG;
4969
        }
4970
4971
        ret = wc_AesSetIV(aes, iv);
4972
4973
        if (iv)
4974
            XMEMCPY(iv_aes, iv, WC_AES_BLOCK_SIZE);
4975
        else
4976
            XMEMSET(iv_aes,  0, WC_AES_BLOCK_SIZE);
4977
4978
4979
        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
4980
        if (ret != SASI_OK) {
4981
            return ret;
4982
        }
4983
       return ret;
4984
    }
4985
    #if defined(WOLFSSL_AES_DIRECT)
4986
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4987
                            const byte* iv, int dir)
4988
        {
4989
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4990
        }
4991
    #endif
4992
4993
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
4994
    && !defined(WOLFSSL_QNX_CAAM)
4995
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4996
4997
#elif defined(WOLFSSL_AFALG)
4998
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4999
5000
#elif defined(WOLFSSL_DEVCRYPTO_AES)
5001
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
5002
5003
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5004
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
5005
5006
#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
5007
     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
5008
    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
5009
5010
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
5011
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5012
            const byte* iv, int dir)
5013
    {
5014
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5015
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5016
        defined(WOLFSSL_AES_CTS)
5017
        aes->left = 0;
5018
    #endif
5019
5020
        aes->keylen = (int)keylen;
5021
        aes->rounds = (keylen/4) + 6;
5022
        aes->keyInstalled = 1;
5023
5024
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
5025
#ifdef WOLFSSL_ARM32_AES_DISPATCH
5026
        Check_CPU_support_HwCrypto(aes);
5027
        if (aes->use_aes_hw_crypto) {
5028
            AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5029
        }
5030
        else
5031
#else
5032
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5033
#endif /* WOLFSSL_ARM32_AES_DISPATCH */
5034
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
5035
#if defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || defined(WOLFSSL_ARM32_AES_DISPATCH)
5036
        {
5037
            AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5038
5039
        #ifdef HAVE_AES_DECRYPT
5040
            if (dir == AES_DECRYPTION) {
5041
                AES_invert_key((byte*)aes->key, aes->rounds);
5042
            }
5043
        #else
5044
            (void)dir;
5045
        #endif
5046
        }
5047
#endif
5048
        return wc_AesSetIV(aes, iv);
5049
    }
5050
5051
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5052
            const byte* iv, int dir)
5053
    {
5054
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
5055
        int cbRet;
5056
#endif
5057
        if ((aes == NULL) || (userKey == NULL)) {
5058
            return BAD_FUNC_ARG;
5059
        }
5060
5061
        switch (keylen) {
5062
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5063
        defined(WOLFSSL_AES_128)
5064
        case 16:
5065
    #endif
5066
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5067
        defined(WOLFSSL_AES_192)
5068
        case 24:
5069
    #endif
5070
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5071
        defined(WOLFSSL_AES_256)
5072
        case 32:
5073
    #endif
5074
            break;
5075
        default:
5076
            return BAD_FUNC_ARG;
5077
        }
5078
5079
    #ifdef WOLF_CRYPTO_CB
5080
        if (aes->devId != INVALID_DEVID) {
5081
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5082
            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5083
            if (ret == 0) {
5084
                /* Callback succeeded - SE owns the key */
5085
                aes->keylen = (int)keylen;
5086
                aes->keyInstalled = 1;
5087
                if (iv != NULL)
5088
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5089
                else
5090
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5091
                return 0;
5092
            }
5093
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5094
                aes->devCtx = NULL;
5095
                return ret;
5096
            }
5097
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5098
        #endif
5099
        #ifdef WOLF_CRYPTO_CB_SETKEY
5100
            cbRet = wc_CryptoCb_SetKey(aes->devId,
5101
                WC_SETKEY_AES, aes, (void*)userKey, keylen,
5102
                (void*)iv,
5103
                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
5104
            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5105
                if (cbRet == 0) {
5106
                    /* Callback succeeded - the device owns the key, so mark it
5107
                     * installed like the AES_SETKEY path above. */
5108
                    aes->keylen = (int)keylen;
5109
                    aes->keyInstalled = 1;
5110
                }
5111
                return cbRet;
5112
            }
5113
            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
5114
        #endif /* WOLF_CRYPTO_CB_SETKEY */
5115
            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
5116
            if (keylen > sizeof(aes->devKey)) {
5117
                return BAD_FUNC_ARG;
5118
            }
5119
            XMEMCPY(aes->devKey, userKey, keylen);
5120
        }
5121
    #endif
5122
5123
        return AesSetKey(aes, userKey, keylen, iv, dir);
5124
    }
5125
5126
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5127
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5128
        /* This function allows key sizes that are not 128/192/256 bits */
5129
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5130
                           const byte* iv, int dir)
5131
    {
5132
        if (aes == NULL) {
5133
            return BAD_FUNC_ARG;
5134
        }
5135
        if (keylen > sizeof(aes->key)) {
5136
            return BAD_FUNC_ARG;
5137
        }
5138
5139
        return AesSetKey(aes, userKey, keylen, iv, dir);
5140
    }
5141
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5142
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
5143
    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5144
            const byte* iv, int dir)
5145
    {
5146
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5147
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5148
        defined(WOLFSSL_AES_CTS)
5149
        aes->left = 0;
5150
    #endif
5151
5152
        aes->keylen = (int)keylen;
5153
        aes->rounds = (keylen/4) + 6;
5154
        aes->keyInstalled = 1;
5155
5156
        /* Determine base vs vector-crypto before the (dispatched) key setup so
5157
         * the schedule matches the mode functions that later consume it. */
5158
        Aes_SetCrypto();
5159
        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5160
5161
    #ifdef HAVE_AES_DECRYPT
5162
        if (dir == AES_DECRYPTION) {
5163
            AES_invert_key((byte*)aes->key, aes->rounds);
5164
        }
5165
    #else
5166
        (void)dir;
5167
    #endif
5168
        return wc_AesSetIV(aes, iv);
5169
    }
5170
5171
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5172
            const byte* iv, int dir)
5173
    {
5174
        if ((aes == NULL) || (userKey == NULL)) {
5175
            return BAD_FUNC_ARG;
5176
        }
5177
5178
        switch (keylen) {
5179
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5180
        defined(WOLFSSL_AES_128)
5181
        case 16:
5182
    #endif
5183
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5184
        defined(WOLFSSL_AES_192)
5185
        case 24:
5186
    #endif
5187
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5188
        defined(WOLFSSL_AES_256)
5189
        case 32:
5190
    #endif
5191
            break;
5192
        default:
5193
            return BAD_FUNC_ARG;
5194
        }
5195
5196
    #ifdef WOLF_CRYPTO_CB
5197
        if (aes->devId != INVALID_DEVID) {
5198
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5199
            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5200
            if (ret == 0) {
5201
                /* Callback succeeded - SE owns the key */
5202
                aes->keylen = (int)keylen;
5203
                aes->keyInstalled = 1;
5204
                if (iv != NULL)
5205
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5206
                else
5207
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5208
                return 0;
5209
            }
5210
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5211
                aes->devCtx = NULL;
5212
                return ret;
5213
            }
5214
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5215
        #endif
5216
            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
5217
            if (keylen > sizeof(aes->devKey)) {
5218
                return BAD_FUNC_ARG;
5219
            }
5220
            XMEMCPY(aes->devKey, userKey, keylen);
5221
        }
5222
    #endif
5223
5224
        return AesSetKey(aes, userKey, keylen, iv, dir);
5225
    }
5226
5227
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
5228
        /* AES-CTR and AES-DIRECT need to use this for key setup */
5229
        /* This function allows key sizes that are not 128/192/256 bits */
5230
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5231
                           const byte* iv, int dir)
5232
    {
5233
        if (aes == NULL) {
5234
            return BAD_FUNC_ARG;
5235
        }
5236
        if (keylen > sizeof(aes->key)) {
5237
            return BAD_FUNC_ARG;
5238
        }
5239
5240
        return AesSetKey(aes, userKey, keylen, iv, dir);
5241
    }
5242
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
5243
#elif defined(FREESCALE_MMCAU)
5244
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
5245
        const byte* iv, int dir, int checkKeyLen)
5246
    {
5247
        int ret;
5248
        byte* rk;
5249
        byte* tmpKey = (byte*)userKey;
5250
        int tmpKeyDynamic = 0;
5251
        word32 alignOffset = 0;
5252
5253
        (void)dir;
5254
5255
        if (aes == NULL)
5256
            return BAD_FUNC_ARG;
5257
5258
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5259
        {
5260
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5261
            if (ret < 0)
5262
                return ret;
5263
        }
5264
#endif
5265
5266
        if (checkKeyLen) {
5267
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
5268
                return BAD_FUNC_ARG;
5269
        }
5270
5271
        rk = (byte*)aes->key;
5272
        if (rk == NULL)
5273
            return BAD_FUNC_ARG;
5274
5275
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5276
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5277
        defined(WOLFSSL_AES_CTS)
5278
        aes->left = 0;
5279
    #endif
5280
5281
        aes->rounds = keylen/4 + 6;
5282
5283
    #ifdef FREESCALE_MMCAU_CLASSIC
5284
        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
5285
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
5286
            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
5287
                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5288
            if (tmp == NULL) {
5289
                return MEMORY_E;
5290
            }
5291
            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
5292
                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
5293
            tmpKey = tmp + alignOffset;
5294
            XMEMCPY(tmpKey, userKey, keylen);
5295
            tmpKeyDynamic = 1;
5296
        #else
5297
            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
5298
            return BAD_ALIGN_E;
5299
        #endif
5300
        }
5301
    #endif
5302
5303
        ret = wolfSSL_CryptHwMutexLock();
5304
        if(ret == 0) {
5305
        #ifdef FREESCALE_MMCAU_CLASSIC
5306
            cau_aes_set_key(tmpKey, keylen*8, rk);
5307
        #else
5308
            MMCAU_AES_SetKey(tmpKey, keylen, rk);
5309
        #endif
5310
            wolfSSL_CryptHwMutexUnLock();
5311
5312
            aes->keyInstalled = 1;
5313
5314
            ret = wc_AesSetIV(aes, iv);
5315
        }
5316
5317
        if (tmpKeyDynamic == 1) {
5318
            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5319
        }
5320
5321
        return ret;
5322
    }
5323
5324
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5325
        const byte* iv, int dir)
5326
    {
5327
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
5328
    }
5329
5330
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5331
                        const byte* iv, int dir)
5332
    {
5333
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
5334
    }
5335
5336
#elif defined(WOLFSSL_PSOC6_CRYPTO)
5337
5338
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
5339
        const byte* iv, int dir)
5340
    {
5341
        int ret;
5342
5343
        if (aes == NULL)
5344
            return BAD_FUNC_ARG;
5345
5346
        ret = wc_Psoc6_Aes_SetKey(aes, userKey, keylen, iv, dir);
5347
        if (ret == 0)
5348
            aes->keyInstalled = 1;
5349
        return ret;
5350
    }
5351
5352
    #if defined(WOLFSSL_AES_DIRECT)
5353
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
5354
                            const byte* iv, int dir)
5355
        {
5356
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
5357
        }
5358
    #endif /* WOLFSSL_AES_DIRECT */
5359
#else
5360
    #define NEED_SOFTWARE_AES_SETKEY
5361
#endif
5362
5363
/* Either we fell though with no HW support at all,
5364
 * or perhaps there's HW support for *some* keylengths
5365
 * and we need both HW and SW. */
5366
#ifdef NEED_SOFTWARE_AES_SETKEY
5367
5368
#ifdef NEED_AES_TABLES
5369
5370
#ifndef WC_AES_BITSLICED
5371
#if !defined(WOLFSSL_ARMASM)
5372
/* Set the AES key and expand.
5373
 *
5374
 * @param [in]  aes    AES object.
5375
 * @param [in]  key    Block to encrypt.
5376
 * @param [in]  keySz  Number of bytes in key.
5377
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
5378
 */
5379
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
5380
0
{
5381
#ifdef WC_C_DYNAMIC_FALLBACK
5382
    word32* rk = aes->key_C_fallback;
5383
#else
5384
0
    word32* rk = aes->key;
5385
0
#endif
5386
0
    word32 temp;
5387
0
    unsigned int i = 0;
5388
5389
#ifdef WOLFSSL_WIDE_BYTE
5390
    /* A C byte is wider than an octet: assemble the big-endian key schedule
5391
     * words octet-wise rather than aliasing the key byte buffer as word32. */
5392
    WordsFromBytesBE32(rk, key, keySz / 4);
5393
#else
5394
0
    XMEMCPY(rk, key, keySz);
5395
0
#endif
5396
0
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_WIDE_BYTE) && \
5397
0
    !defined(WOLFSSL_PIC32MZ_CRYPT) && \
5398
0
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
5399
0
    !defined(MAX3266X_AES)
5400
    /* Always reverse words when using only SW */
5401
0
    {
5402
0
        ByteReverseWords(rk, rk, keySz);
5403
0
    }
5404
#else
5405
    /* Sometimes reverse words when using supported HW */
5406
    #if defined(WOLFSSL_ESPIDF)
5407
        /* Some platforms may need SW fallback (e.g. AES192) */
5408
        #if defined(NEED_AES_HW_FALLBACK)
5409
        {
5410
            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
5411
            if (wc_esp32AesSupportedKeyLen(aes)) {
5412
                /* don't reverse for HW supported key lengths */
5413
            }
5414
            else {
5415
                ByteReverseWords(rk, rk, keySz);
5416
            }
5417
        }
5418
        #else
5419
            /* If we don't need SW fallback, don't need to reverse words. */
5420
        #endif /* NEED_AES_HW_FALLBACK */
5421
    #endif /* WOLFSSL_ESPIDF */
5422
#endif /* LITTLE_ENDIAN_ORDER, etc */
5423
5424
0
    switch (keySz) {
5425
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
5426
0
        defined(WOLFSSL_AES_128)
5427
0
    case 16:
5428
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5429
        temp = (word32)-1;
5430
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5431
    #endif
5432
0
        while (1)
5433
0
        {
5434
0
            temp  = rk[3];
5435
0
            rk[4] = rk[0] ^
5436
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5437
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5438
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5439
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5440
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5441
        #else
5442
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5443
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5444
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5445
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5446
        #endif
5447
0
                rcon[i];
5448
0
            rk[5] = rk[1] ^ rk[4];
5449
0
            rk[6] = rk[2] ^ rk[5];
5450
0
            rk[7] = rk[3] ^ rk[6];
5451
0
            if (++i == 10)
5452
0
                break;
5453
0
            rk += 4;
5454
0
        }
5455
0
        break;
5456
0
#endif /* 128 */
5457
5458
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
5459
0
        defined(WOLFSSL_AES_192)
5460
0
    case 24:
5461
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5462
        temp = (word32)-1;
5463
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5464
    #endif
5465
        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
5466
0
        while (1)
5467
0
        {
5468
0
            temp = rk[ 5];
5469
0
            rk[ 6] = rk[ 0] ^
5470
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5471
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5472
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5473
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5474
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5475
        #else
5476
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5477
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5478
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5479
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5480
        #endif
5481
0
                rcon[i];
5482
0
            rk[ 7] = rk[ 1] ^ rk[ 6];
5483
0
            rk[ 8] = rk[ 2] ^ rk[ 7];
5484
0
            rk[ 9] = rk[ 3] ^ rk[ 8];
5485
0
            if (++i == 8)
5486
0
                break;
5487
0
            rk[10] = rk[ 4] ^ rk[ 9];
5488
0
            rk[11] = rk[ 5] ^ rk[10];
5489
0
            rk += 6;
5490
0
        }
5491
0
        break;
5492
0
#endif /* 192 */
5493
5494
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
5495
0
        defined(WOLFSSL_AES_256)
5496
0
    case 32:
5497
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5498
        temp = (word32)-1;
5499
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
5500
    #endif
5501
0
        while (1)
5502
0
        {
5503
0
            temp = rk[ 7];
5504
0
            rk[ 8] = rk[ 0] ^
5505
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5506
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
5507
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
5508
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
5509
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
5510
        #else
5511
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
5512
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
5513
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
5514
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
5515
        #endif
5516
0
                rcon[i];
5517
0
            rk[ 9] = rk[ 1] ^ rk[ 8];
5518
0
            rk[10] = rk[ 2] ^ rk[ 9];
5519
0
            rk[11] = rk[ 3] ^ rk[10];
5520
0
            if (++i == 7)
5521
0
                break;
5522
0
            temp = rk[11];
5523
0
            rk[12] = rk[ 4] ^
5524
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
5525
0
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
5526
0
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
5527
0
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
5528
0
                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
5529
        #else
5530
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
5531
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
5532
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
5533
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
5534
        #endif
5535
0
            rk[13] = rk[ 5] ^ rk[12];
5536
0
            rk[14] = rk[ 6] ^ rk[13];
5537
0
            rk[15] = rk[ 7] ^ rk[14];
5538
5539
0
            rk += 8;
5540
0
        }
5541
0
        break;
5542
0
#endif /* 256 */
5543
0
    } /* switch */
5544
0
    ForceZero(&temp, sizeof(temp));
5545
5546
0
#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
5547
0
    if (dir == AES_DECRYPTION) {
5548
0
        unsigned int j;
5549
5550
#ifdef WC_C_DYNAMIC_FALLBACK
5551
        rk = aes->key_C_fallback;
5552
#else
5553
0
        rk = aes->key;
5554
0
#endif
5555
5556
        /* invert the order of the round keys: */
5557
0
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
5558
0
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
5559
0
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
5560
0
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
5561
0
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
5562
0
        }
5563
0
        ForceZero(&temp, sizeof(temp));
5564
0
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
5565
        /* apply the inverse MixColumn transform to all round keys but the
5566
           first and the last: */
5567
0
        for (i = 1; i < aes->rounds; i++) {
5568
0
            rk += 4;
5569
0
            rk[0] =
5570
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
5571
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
5572
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
5573
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
5574
0
            rk[1] =
5575
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
5576
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
5577
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
5578
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
5579
0
            rk[2] =
5580
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
5581
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
5582
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
5583
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
5584
0
            rk[3] =
5585
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
5586
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
5587
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
5588
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
5589
0
        }
5590
0
    #endif
5591
0
    }
5592
#else
5593
    (void)dir;
5594
#endif /* HAVE_AES_DECRYPT */
5595
5596
#ifdef WOLFSSL_CHECK_MEM_ZERO
5597
    wc_MemZero_Check(&temp, sizeof(temp));
5598
#else
5599
0
    (void)temp;
5600
0
#endif
5601
0
}
5602
#endif
5603
#else /* WC_AES_BITSLICED */
5604
/* Set the AES key and expand.
5605
 *
5606
 * @param [in]  aes    AES object.
5607
 * @param [in]  key    Block to encrypt.
5608
 * @param [in]  keySz  Number of bytes in key.
5609
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
5610
 */
5611
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
5612
{
5613
    /* No need to invert when decrypting. */
5614
    (void)dir;
5615
5616
    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
5617
}
5618
#endif /* WC_AES_BITSLICED */
5619
5620
#endif /* NEED_AES_TABLES */
5621
5622
    static WARN_UNUSED_RESULT int AesSetKeyLocal_body(
5623
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
5624
        int checkKeyLen);
5625
5626
    /* AES - SetKey (block schedule via generated asm on RISC-V)
5627
     *
5628
     * keyInstalled is derived from the return value here rather than set
5629
     * inside the body. The body has failure returns after the point where the
5630
     * key material is accepted (AES-NI SAVE_VECTOR_REGISTERS2/BAD_ALIGN_E, the
5631
     * hardware key installs), and marking the context keyed on those paths
5632
     * would let it pass WC_AES_KEY_IS_SET with an all-zero key schedule. */
5633
    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
5634
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
5635
        int checkKeyLen)
5636
0
    {
5637
0
        int ret;
5638
5639
0
        if (aes == NULL)
5640
0
            return BAD_FUNC_ARG;
5641
5642
0
        aes->keyInstalled = 0;
5643
0
        ret = AesSetKeyLocal_body(aes, userKey, keylen, iv, dir, checkKeyLen);
5644
0
        aes->keyInstalled = (ret == 0) ? 1 : 0;
5645
5646
0
        return ret;
5647
0
    }
5648
5649
    static WARN_UNUSED_RESULT int AesSetKeyLocal_body(
5650
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
5651
        int checkKeyLen)
5652
0
    {
5653
0
        int ret;
5654
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
5655
        int cbRet;
5656
#endif
5657
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5658
        byte   local[32];
5659
        word32 localSz = 32;
5660
    #endif
5661
5662
0
        if (aes == NULL)
5663
0
            return BAD_FUNC_ARG;
5664
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
5665
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
5666
        if (ret < 0)
5667
            return ret;
5668
#endif
5669
5670
0
        switch (keylen) {
5671
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
5672
0
        defined(WOLFSSL_AES_128)
5673
0
        case 16:
5674
0
    #endif
5675
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
5676
0
        defined(WOLFSSL_AES_192)
5677
0
        case 24:
5678
0
    #endif
5679
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
5680
0
        defined(WOLFSSL_AES_256)
5681
0
        case 32:
5682
0
    #endif
5683
0
            break;
5684
0
        default:
5685
0
            return BAD_FUNC_ARG;
5686
0
        }
5687
5688
    #ifdef WOLF_CRYPTO_CB
5689
        #ifndef WOLF_CRYPTO_CB_FIND
5690
        if (aes->devId != INVALID_DEVID)
5691
        #endif
5692
        {
5693
        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
5694
            ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
5695
            if (ret == 0) {
5696
                /* Callback succeeded - SE owns the key */
5697
                aes->keylen = (int)keylen;
5698
                if (iv != NULL)
5699
                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5700
                else
5701
                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5702
                return 0;
5703
            }
5704
            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5705
                aes->devCtx = NULL;
5706
                return ret;
5707
            }
5708
            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
5709
        #endif
5710
        #ifdef WOLF_CRYPTO_CB_SETKEY
5711
            cbRet = wc_CryptoCb_SetKey(aes->devId,
5712
                WC_SETKEY_AES, aes, (void*)userKey, keylen,
5713
                (void*)iv,
5714
                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
5715
            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
5716
                if (cbRet == 0) {
5717
                    /* Callback succeeded - the device owns the key. rounds is
5718
                     * left at 0: there is no software key schedule, and the
5719
                     * XTS entry points use that to reject the context. */
5720
                    aes->keylen = (int)keylen;
5721
                }
5722
                return cbRet;
5723
            }
5724
            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
5725
        #endif /* WOLF_CRYPTO_CB_SETKEY */
5726
            /* Standard CryptoCB path - copy key to devKey */
5727
            if (keylen > sizeof(aes->devKey)) {
5728
                return BAD_FUNC_ARG;
5729
            }
5730
            XMEMCPY(aes->devKey, userKey, keylen);
5731
        }
5732
    #endif
5733
5734
    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
5735
        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
5736
            return WC_HW_E;
5737
        }
5738
    #endif
5739
5740
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
5741
        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
5742
            keylen == (24 + WC_CAAM_BLOB_SZ) ||
5743
            keylen == (32 + WC_CAAM_BLOB_SZ)) {
5744
            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
5745
                return BAD_FUNC_ARG;
5746
            }
5747
5748
            /* set local values */
5749
            userKey = local;
5750
            keylen = localSz;
5751
        }
5752
    #endif
5753
5754
    #ifdef WOLFSSL_SECO_CAAM
5755
        /* if set to use hardware than import the key */
5756
        if (aes->devId == WOLFSSL_SECO_DEVID) {
5757
            int keyGroup = 1; /* group one was chosen arbitrarily */
5758
            unsigned int keyIdOut;
5759
            byte importiv[GCM_NONCE_MID_SZ];
5760
            int importivSz = GCM_NONCE_MID_SZ;
5761
            int keyType = 0;
5762
            WC_RNG rng;
5763
5764
            if (wc_InitRng(&rng) != 0) {
5765
                WOLFSSL_MSG("RNG init for IV failed");
5766
                return WC_HW_E;
5767
            }
5768
5769
            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
5770
                WOLFSSL_MSG("Generate IV failed");
5771
                wc_FreeRng(&rng);
5772
                return WC_HW_E;
5773
            }
5774
            wc_FreeRng(&rng);
5775
5776
            if (iv)
5777
                XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
5778
            else
5779
                XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
5780
5781
            switch (keylen) {
5782
                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
5783
                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
5784
                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
5785
            }
5786
5787
            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
5788
                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
5789
            if (keyIdOut == 0) {
5790
                return WC_HW_E;
5791
            }
5792
            aes->blackKey = keyIdOut;
5793
            return 0;
5794
        }
5795
    #endif
5796
5797
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
5798
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
5799
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) || \
5800
        defined(WOLFSSL_NXP_HASHCRYPT_AES)
5801
        #ifdef WOLF_CRYPTO_CB
5802
        #ifndef WOLF_CRYPTO_CB_FIND
5803
        if (aes->devId != INVALID_DEVID)
5804
        #endif
5805
        #endif
5806
        {
5807
            if (keylen > sizeof(aes->devKey)) {
5808
                return BAD_FUNC_ARG;
5809
            }
5810
            XMEMCPY(aes->devKey, userKey, keylen);
5811
        }
5812
    #endif
5813
5814
    #ifdef WOLF_CRYPTO_CB_ONLY_AES
5815
        /* No software AES schedule under CB_ONLY: aes->key[] (round keys) are
5816
         * unused because the static wc_AesEncrypt/wc_AesDecrypt are cryptocb-
5817
         * ECB shims. aes->rounds is still populated because wc_AesGetKeySize()
5818
         * reads it as the source of truth for the configured key size. */
5819
        aes->keylen = (int)keylen;
5820
        aes->rounds = (keylen / 4) + 6;
5821
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5822
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5823
            defined(WOLFSSL_AES_CTS)
5824
        aes->left = 0;
5825
        #endif
5826
        (void)dir;
5827
        return wc_AesSetIV(aes, iv);
5828
    #endif
5829
5830
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
5831
        if (checkKeyLen) {
5832
            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
5833
             * all key sizes. Otherwise this condition is never true. */
5834
            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
5835
                return BAD_FUNC_ARG;
5836
            }
5837
        }
5838
    #else
5839
0
        (void) checkKeyLen;
5840
0
    #endif
5841
5842
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
5843
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
5844
        defined(WOLFSSL_AES_CTS)
5845
        aes->left = 0;
5846
    #endif
5847
5848
0
        aes->keylen = (int)keylen;
5849
0
        aes->rounds = (keylen/4) + 6;
5850
0
        ret = wc_AesSetIV(aes, iv);
5851
0
        if (ret != 0)
5852
0
            return ret;
5853
5854
#ifdef WC_C_DYNAMIC_FALLBACK
5855
#ifdef NEED_AES_TABLES
5856
        AesSetKey_C(aes, userKey, keylen, dir);
5857
#endif /* NEED_AES_TABLES */
5858
#endif /* WC_C_DYNAMIC_FALLBACK */
5859
5860
    #ifdef WOLFSSL_AESNI
5861
5862
       /* The dynamics for determining whether AES-NI will be used are tricky.
5863
        *
5864
        * First, we check for CPU support and cache the result -- if AES-NI is
5865
        * missing, we always shortcut to the AesSetKey_C() path.
5866
        *
5867
        * Second, if the CPU supports AES-NI, we confirm on a per-call basis
5868
        * that it's safe to use in the caller context, using
5869
        * SAVE_VECTOR_REGISTERS2().  This is an always-true no-op in user-space
5870
        * builds, but has substantive logic behind it in kernel module builds.
5871
        *
5872
        * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on
5873
        * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with
5874
        * success but with AES-NI disabled (the earlier AesSetKey_C() allows
5875
        * future encrypt/decrypt calls to succeed), otherwise we fail.
5876
        *
5877
        * Upon successful return, aes->use_aesni will have a zero value if
5878
        * AES-NI is disabled, and a nonzero value if it's enabled.
5879
        *
5880
        * An additional, optional semantic is available via
5881
        * WC_FLAG_DONT_USE_VECTOR_OPS, and is used in some kernel module builds
5882
        * to let the caller inhibit AES-NI.  When this macro is defined,
5883
        * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of
5884
        * uninitialized data in aes->use_aesni.  That's why support for
5885
        * WC_FLAG_DONT_USE_VECTOR_OPS must remain optional -- wc_AesInit() was
5886
        * only added in release 3.11.0, so legacy applications inevitably call
5887
        * wc_AesSetKey() on uninitialized Aes contexts.  This must continue to
5888
        * function correctly with default build settings.
5889
        */
5890
5891
        if (checkedAESNI == 0) {
5892
            haveAESNI = Check_CPU_support_AES();
5893
            checkedAESNI = 1;
5894
        }
5895
        if (haveAESNI
5896
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS) && !defined(WC_C_DYNAMIC_FALLBACK)
5897
            && (aes->use_aesni != WC_FLAG_DONT_USE_VECTOR_OPS)
5898
#endif
5899
            )
5900
        {
5901
#if defined(WC_FLAG_DONT_USE_VECTOR_OPS)
5902
            if (aes->use_aesni == WC_FLAG_DONT_USE_VECTOR_OPS) {
5903
                aes->use_aesni = 0;
5904
                return 0;
5905
            }
5906
#endif
5907
            aes->use_aesni = 0;
5908
            #ifdef WOLFSSL_KERNEL_MODE
5909
            /* runtime alignment check */
5910
            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
5911
                ret = BAD_ALIGN_E;
5912
            }
5913
            else
5914
            #endif /* WOLFSSL_KERNEL_MODE */
5915
            {
5916
                ret = SAVE_VECTOR_REGISTERS2();
5917
            }
5918
            if (ret == 0) {
5919
                if (dir == AES_ENCRYPTION)
5920
                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5921
#ifdef HAVE_AES_DECRYPT
5922
                else
5923
                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
5924
#endif
5925
5926
                RESTORE_VECTOR_REGISTERS();
5927
5928
                if (ret == 0)
5929
                    aes->use_aesni = 1;
5930
                else {
5931
#ifdef WC_C_DYNAMIC_FALLBACK
5932
                    ret = 0;
5933
#endif
5934
                }
5935
                return ret;
5936
            } else {
5937
#ifdef WC_C_DYNAMIC_FALLBACK
5938
                return 0;
5939
#else
5940
                return ret;
5941
#endif
5942
            }
5943
        }
5944
        else {
5945
            aes->use_aesni = 0;
5946
#ifdef WC_C_DYNAMIC_FALLBACK
5947
            /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C()
5948
             * above.
5949
             */
5950
            return 0;
5951
#endif
5952
        }
5953
    #endif /* WOLFSSL_AESNI */
5954
5955
0
#ifndef WC_C_DYNAMIC_FALLBACK
5956
5957
#if defined(WOLFSSL_RISCV_ASM)
5958
        /* Generated RISC-V assembly key schedule (all paths). aes->rounds /
5959
         * aes->keylen were set above. */
5960
        AES_set_key_RISCV64(userKey, (int)keylen, (byte*)aes->key, dir);
5961
        return 0;
5962
#elif defined(WOLFSSL_ARMASM)
5963
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5964
    #ifndef __aarch64__
5965
      #ifdef WOLFSSL_ARM32_AES_DISPATCH
5966
        Check_CPU_support_HwCrypto(aes);
5967
        if (aes->use_aes_hw_crypto) {
5968
            AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5969
        }
5970
        else
5971
      #else
5972
        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
5973
      #endif /* WOLFSSL_ARM32_AES_DISPATCH */
5974
    #else
5975
        Check_CPU_support_HwCrypto(aes);
5976
        if (aes->use_aes_hw_crypto) {
5977
            AES_set_key_AARCH64(userKey, keylen, (byte*)aes->key, dir);
5978
        }
5979
        else
5980
    #endif /* __aarch64__ */
5981
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
5982
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
5983
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
5984
        {
5985
            AES_set_encrypt_key_NEON(userKey, keylen * 8, (byte*)aes->key);
5986
        #ifdef HAVE_AES_DECRYPT
5987
            if (dir == AES_DECRYPTION) {
5988
                AES_invert_key_NEON((byte*)aes->key, aes->rounds);
5989
            }
5990
        #else
5991
            (void)dir;
5992
        #endif
5993
        }
5994
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
5995
          defined(WOLFSSL_ARM32_AES_DISPATCH)
5996
        {
5997
            AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
5998
        #ifdef HAVE_AES_DECRYPT
5999
            if (dir == AES_DECRYPTION) {
6000
                AES_invert_key((byte*)aes->key, aes->rounds);
6001
            }
6002
        #else
6003
            (void)dir;
6004
        #endif
6005
        }
6006
    #endif
6007
        return 0;
6008
#else
6009
6010
    #ifdef WOLFSSL_KCAPI_AES
6011
        XMEMCPY(aes->devKey, userKey, keylen);
6012
        if (aes->init != 0) {
6013
            kcapi_cipher_destroy(aes->handle);
6014
            aes->handle = NULL;
6015
            aes->init = 0;
6016
        }
6017
        (void)dir;
6018
    #endif
6019
6020
0
        if (keylen > sizeof(aes->key)) {
6021
0
            return BAD_FUNC_ARG;
6022
0
        }
6023
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6024
        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
6025
                                  ((psa_algorithm_t)0), dir);
6026
#endif
6027
6028
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
6029
        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
6030
         * instead of SE05x crypto by setting useSWCrypt */
6031
        if (aes->useSWCrypt == 0) {
6032
            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
6033
            if (ret == 0) {
6034
                ret = wc_AesSetIV(aes, iv);
6035
            }
6036
            return ret;
6037
        }
6038
#endif
6039
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
6040
        if (keylen == TA_KEY_TYPE_AES128_SIZE) {
6041
            ret = wc_Microchip_aes_set_key(aes, userKey, keylen, iv, dir);
6042
            if (ret != 0) {
6043
                return ret;
6044
            }
6045
            ret = wc_AesSetIV(aes, iv);
6046
            if (ret != 0) {
6047
                return ret;
6048
            }
6049
        }
6050
#endif
6051
0
        XMEMCPY(aes->key, userKey, keylen);
6052
6053
0
#ifndef WC_AES_BITSLICED
6054
0
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
6055
0
        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
6056
0
        && !defined(MAX3266X_AES)
6057
6058
        /* software */
6059
0
        ByteReverseWords(aes->key, aes->key, keylen);
6060
6061
    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6062
        if (wc_esp32AesSupportedKeyLen(aes)) {
6063
            /* supported lengths don't get reversed */
6064
            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
6065
        }
6066
        else {
6067
            word32* rk = aes->key;
6068
6069
            /* For example, the ESP32-S3 does not support HW for len = 24,
6070
             * so fall back to SW */
6071
        #ifdef DEBUG_WOLFSSL
6072
            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
6073
        #endif
6074
            XMEMCPY(rk, userKey, keylen);
6075
            /* When not ESP32 HW, we need to reverse endianness */
6076
            ByteReverseWords(rk, rk, keylen);
6077
        }
6078
    #endif
6079
6080
    #ifdef WOLFSSL_IMXRT_DCP
6081
        {
6082
            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
6083
            word32 temp = 0;
6084
            if (keylen == 16)
6085
                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
6086
            if (temp != 0)
6087
                return WC_HW_E;
6088
        }
6089
    #endif
6090
0
#endif /* !WC_AES_BITSLICED */
6091
6092
0
#ifdef NEED_AES_TABLES
6093
0
        AesSetKey_C(aes, userKey, keylen, dir);
6094
0
#endif /* NEED_AES_TABLES */
6095
6096
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
6097
        XMEMCPY((byte*)aes->key, userKey, keylen);
6098
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
6099
            ByteReverseWords(aes->key, aes->key, 32);
6100
        }
6101
#endif
6102
6103
    #if defined(WOLFSSL_DEVCRYPTO) && \
6104
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
6105
        /* Release any session already held. The session was created with the
6106
         * previous key, so re-keying must tear it down rather than just mark
6107
         * the context uninitialized, which would orphan the descriptor and
6108
         * leave the stale key in use. */
6109
        wc_DevCryptoFree(&aes->ctx);
6110
        aes->ctx.inited = 0;
6111
        aes->ctx.cfd = -1; /* not set when no session was open */
6112
    #endif
6113
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
6114
    #ifdef WOLFSSL_CHECK_MEM_ZERO
6115
        wc_MemZero_Add("wc_AesSetKeyLocal local", local, sizeof(local));
6116
    #endif
6117
        ForceZero(local, sizeof(local));
6118
    #ifdef WOLFSSL_CHECK_MEM_ZERO
6119
        wc_MemZero_Check(local, sizeof(local));
6120
    #endif
6121
    #endif
6122
0
        return ret;
6123
0
#endif
6124
6125
0
#endif /* !WC_C_DYNAMIC_FALLBACK */
6126
6127
0
    } /* wc_AesSetKeyLocal */
6128
6129
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
6130
            const byte* iv, int dir)
6131
0
    {
6132
0
        if (aes == NULL) {
6133
0
            return BAD_FUNC_ARG;
6134
0
        }
6135
0
        if (keylen > sizeof(aes->key)) {
6136
0
            return BAD_FUNC_ARG;
6137
0
        }
6138
6139
    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
6140
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
6141
        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
6142
        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
6143
            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
6144
            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
6145
        }
6146
        else {
6147
        #if  defined(WOLFSSL_HW_METRICS)
6148
            /* It is interesting to know how many times we could not complete
6149
             * AES in hardware due to unsupported lengths. */
6150
            wc_esp32AesUnupportedLengthCountAdd();
6151
        #endif
6152
        #ifdef DEBUG_WOLFSSL
6153
            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
6154
                           keylen);
6155
        #endif
6156
        }
6157
    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
6158
6159
0
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
6160
6161
0
    } /* wc_AesSetKey() */
6162
6163
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
6164
        /* AES-CTR and AES-DIRECT need to use this for key setup */
6165
        /* This function allows key sizes that are not 128/192/256 bits */
6166
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
6167
                           const byte* iv, int dir)
6168
    {
6169
        if (aes == NULL) {
6170
            return BAD_FUNC_ARG;
6171
        }
6172
        if (keylen > sizeof(aes->key)) {
6173
            return BAD_FUNC_ARG;
6174
        }
6175
6176
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
6177
    }
6178
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
6179
#endif /* wc_AesSetKey block */
6180
6181
6182
/* wc_AesSetIV is shared between software and hardware */
6183
int wc_AesSetIV(Aes* aes, const byte* iv)
6184
0
{
6185
0
    if (aes == NULL)
6186
0
        return BAD_FUNC_ARG;
6187
6188
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
6189
    {
6190
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
6191
        if (ret < 0)
6192
            return ret;
6193
    }
6194
#endif
6195
6196
0
    if (iv)
6197
0
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
6198
0
    else
6199
0
        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
6200
6201
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
6202
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
6203
    defined(WOLFSSL_AES_CTS)
6204
    /* Clear any unused bytes from last cipher op. */
6205
    aes->left = 0;
6206
#endif
6207
6208
#ifdef WOLFSSL_KCAPI_AES
6209
    /* The kernel keeps the chaining state and takes the IV at stream setup
6210
     * time only, so tear the stream down for the new IV to take effect. It is
6211
     * set up again, from aes->reg, on the next cipher operation. */
6212
    if (aes->init != 0) {
6213
        kcapi_cipher_destroy(aes->handle);
6214
        aes->handle = NULL;
6215
        aes->init = 0;
6216
    }
6217
#endif
6218
6219
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6220
    {
6221
        /* PSA takes the IV at operation setup time only, so an operation
6222
         * already in progress must be aborted for the new IV to take effect. */
6223
        int ret = wc_psa_aes_reset_ctx(aes);
6224
        if (ret != 0)
6225
            return ret;
6226
    }
6227
#endif
6228
6229
0
    return 0;
6230
0
}
6231
6232
#ifdef WOLFSSL_AESNI
6233
6234
#ifdef WC_C_DYNAMIC_FALLBACK
6235
6236
#define VECTOR_REGISTERS_PUSH {                                      \
6237
        int orig_use_aesni = aes->use_aesni;                         \
6238
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
6239
            aes->use_aesni = 0;                                      \
6240
        }                                                            \
6241
        WC_DO_NOTHING
6242
6243
#define VECTOR_REGISTERS_PUSH2(fail_clause) {                        \
6244
        int orig_use_aesni = aes->use_aesni;                         \
6245
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
6246
            aes->use_aesni = 0;                                      \
6247
        }                                                            \
6248
        WC_DO_NOTHING
6249
6250
6251
#define VECTOR_REGISTERS_POP                                         \
6252
        if (aes->use_aesni)                                          \
6253
            RESTORE_VECTOR_REGISTERS();                              \
6254
        else                                                         \
6255
            aes->use_aesni = orig_use_aesni;                         \
6256
    }                                                                \
6257
    WC_DO_NOTHING
6258
6259
#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
6260
6261
#define VECTOR_REGISTERS_PUSH { \
6262
        WC_DO_NOTHING
6263
6264
#define VECTOR_REGISTERS_PUSH2(fail_clause) { \
6265
        WC_DO_NOTHING
6266
6267
#define VECTOR_REGISTERS_POP                                         \
6268
    }                                                                \
6269
    WC_DO_NOTHING
6270
6271
#else
6272
6273
#define VECTOR_REGISTERS_PUSH {                                          \
6274
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
6275
            return ret;                                                  \
6276
        }                                                                \
6277
        WC_DO_NOTHING
6278
6279
#define VECTOR_REGISTERS_PUSH2(fail_clause) {                            \
6280
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
6281
            { fail_clause }                                              \
6282
            return ret;                                                  \
6283
        }                                                                \
6284
        WC_DO_NOTHING
6285
6286
#define VECTOR_REGISTERS_POP \
6287
        if (aes->use_aesni) {                                            \
6288
            RESTORE_VECTOR_REGISTERS();                                  \
6289
        }                                                                \
6290
    }                                                                    \
6291
    WC_DO_NOTHING
6292
6293
#endif
6294
6295
#else /* !WOLFSSL_AESNI */
6296
6297
0
#define VECTOR_REGISTERS_PUSH WC_DO_NOTHING
6298
#define VECTOR_REGISTERS_PUSH2(fail_clause) WC_DO_NOTHING
6299
0
#define VECTOR_REGISTERS_POP WC_DO_NOTHING
6300
6301
#endif /* !WOLFSSL_AESNI */
6302
6303
6304
/* AES-DIRECT */
6305
#if defined(WOLFSSL_AES_DIRECT)
6306
    #if defined(HAVE_COLDFIRE_SEC)
6307
        #error "Coldfire SEC doesn't yet support AES direct"
6308
6309
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6310
        !defined(WOLFSSL_QNX_CAAM)
6311
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6312
6313
    #elif defined(WOLFSSL_AFALG)
6314
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6315
6316
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
6317
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6318
6319
    #else
6320
6321
        /* Allow direct access to one block encrypt */
6322
        /* Note, the in and out args are swapped compared to wc_AesEncrypt(). */
6323
        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
6324
        {
6325
            int ret;
6326
6327
            if (aes == NULL || out == NULL || in == NULL)
6328
                return BAD_FUNC_ARG;
6329
            if (!WC_AES_KEY_IS_SET(aes)) {
6330
                WOLFSSL_MSG("AES key not set");
6331
                return MISSING_KEY;
6332
            }
6333
            VECTOR_REGISTERS_PUSH;
6334
            ret = wc_AesEncrypt(aes, in, out);
6335
            VECTOR_REGISTERS_POP;
6336
            return ret;
6337
        }
6338
6339
        /* vector reg save/restore is explicit in all below calls to
6340
         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
6341
         * macro.
6342
         */
6343
        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
6344
6345
        #ifdef HAVE_AES_DECRYPT
6346
        /* Allow direct access to one block decrypt */
6347
        /* Note, the in and out args are swapped compared to wc_AesDecrypt(). */
6348
        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
6349
        {
6350
            int ret;
6351
6352
            if (aes == NULL)
6353
                return BAD_FUNC_ARG;
6354
            if (!WC_AES_KEY_IS_SET(aes)) {
6355
                WOLFSSL_MSG("AES key not set");
6356
                return MISSING_KEY;
6357
            }
6358
            VECTOR_REGISTERS_PUSH;
6359
            ret = wc_AesDecrypt(aes, in, out);
6360
            VECTOR_REGISTERS_POP;
6361
            return ret;
6362
        }
6363
6364
        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
6365
6366
        #endif /* HAVE_AES_DECRYPT */
6367
    #endif /* AES direct block */
6368
#endif /* WOLFSSL_AES_DIRECT */
6369
6370
6371
/* AES-CBC */
6372
#ifdef HAVE_AES_CBC
6373
#if defined(STM32_CRYPTO)
6374
6375
#ifdef WOLFSSL_STM32_BARE
6376
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6377
    {
6378
    #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6379
        if (sz % WC_AES_BLOCK_SIZE) {
6380
            return BAD_LENGTH_E;
6381
        }
6382
    #endif
6383
        if (sz == 0) {
6384
            return 0;
6385
        }
6386
    #ifdef WOLF_CRYPTO_CB
6387
        #ifndef WOLF_CRYPTO_CB_FIND
6388
        if (aes->devId != INVALID_DEVID)
6389
        #endif
6390
        {
6391
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6392
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6393
                return crypto_cb_ret;
6394
            /* fall-through when unavailable (normal-keyed Aes) */
6395
        }
6396
    #endif
6397
        /* DHUK / any crypto-callback device is routed above. wc_Stm32_Aes_Cbc
6398
         * processes whole blocks and ignores any sub-block remainder, matching
6399
         * the SW / CUBEMX CBC backends; define WOLFSSL_AES_CBC_LENGTH_CHECKS
6400
         * (above) to reject a non-block-multiple length with BAD_LENGTH_E. */
6401
        return wc_Stm32_Aes_Cbc(aes, out, in, sz, 1);
6402
    }
6403
    #ifdef HAVE_AES_DECRYPT
6404
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6405
    {
6406
    #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6407
        if (sz % WC_AES_BLOCK_SIZE) {
6408
            return BAD_LENGTH_E;
6409
        }
6410
    #endif
6411
        if (sz == 0) {
6412
            return 0;
6413
        }
6414
    #ifdef WOLF_CRYPTO_CB
6415
        #ifndef WOLF_CRYPTO_CB_FIND
6416
        if (aes->devId != INVALID_DEVID)
6417
        #endif
6418
        {
6419
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6420
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6421
                return crypto_cb_ret;
6422
            /* fall-through when unavailable (normal-keyed Aes) */
6423
        }
6424
    #endif
6425
        /* DHUK / any crypto-callback device is routed above. */
6426
        return wc_Stm32_Aes_Cbc(aes, out, in, sz, 0);
6427
    }
6428
    #endif /* HAVE_AES_DECRYPT */
6429
#elif defined(WOLFSSL_STM32_CUBEMX)
6430
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6431
    {
6432
        int ret = 0;
6433
        CRYP_HandleTypeDef hcryp;
6434
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6435
6436
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6437
        if (sz % WC_AES_BLOCK_SIZE) {
6438
            return BAD_LENGTH_E;
6439
        }
6440
#endif
6441
        if (blocks == 0)
6442
            return 0;
6443
6444
    #ifdef WOLF_CRYPTO_CB
6445
        #ifndef WOLF_CRYPTO_CB_FIND
6446
        if (aes->devId != INVALID_DEVID)
6447
        #endif
6448
        {
6449
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
6450
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6451
                return crypto_cb_ret;
6452
            /* fall-through when unavailable (normal-keyed Aes) */
6453
        }
6454
    #endif
6455
6456
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6457
        if (ret != 0)
6458
            return ret;
6459
6460
        ret = wolfSSL_CryptHwMutexLock();
6461
        if (ret != 0) {
6462
            return ret;
6463
        }
6464
6465
    #if defined(STM32_HAL_V2)
6466
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
6467
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
6468
    #elif defined(STM32_CRYPTO_AES_ONLY)
6469
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
6470
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
6471
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6472
    #endif
6473
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6474
        ret = HAL_CRYP_Init(&hcryp);
6475
6476
        if (ret == HAL_OK) {
6477
        #if defined(STM32_HAL_V2)
6478
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
6479
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6480
        #elif defined(STM32_CRYPTO_AES_ONLY)
6481
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
6482
                out, STM32_HAL_TIMEOUT);
6483
        #else
6484
            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
6485
                                        blocks * WC_AES_BLOCK_SIZE,
6486
                                        out, STM32_HAL_TIMEOUT);
6487
        #endif
6488
        }
6489
        if (ret != HAL_OK) {
6490
            ret = WC_TIMEOUT_E;
6491
        }
6492
6493
        /* store iv for next call */
6494
        XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6495
6496
        HAL_CRYP_DeInit(&hcryp);
6497
6498
        wolfSSL_CryptHwMutexUnLock();
6499
        wc_Stm32_Aes_Cleanup();
6500
6501
        return ret;
6502
    }
6503
    #ifdef HAVE_AES_DECRYPT
6504
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6505
    {
6506
        int ret = 0;
6507
        CRYP_HandleTypeDef hcryp;
6508
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6509
6510
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6511
        if (sz % WC_AES_BLOCK_SIZE) {
6512
            return BAD_LENGTH_E;
6513
        }
6514
#endif
6515
        if (blocks == 0)
6516
            return 0;
6517
6518
    #ifdef WOLF_CRYPTO_CB
6519
        #ifndef WOLF_CRYPTO_CB_FIND
6520
        if (aes->devId != INVALID_DEVID)
6521
        #endif
6522
        {
6523
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
6524
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6525
                return crypto_cb_ret;
6526
            /* fall-through when unavailable (normal-keyed Aes) */
6527
        }
6528
    #endif
6529
6530
        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
6531
        if (ret != 0)
6532
            return ret;
6533
6534
        ret = wolfSSL_CryptHwMutexLock();
6535
        if (ret != 0) {
6536
            return ret;
6537
        }
6538
6539
        /* if input and output same will overwrite input iv */
6540
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6541
6542
    #if defined(STM32_HAL_V2)
6543
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
6544
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
6545
    #elif defined(STM32_CRYPTO_AES_ONLY)
6546
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
6547
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
6548
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6549
    #endif
6550
6551
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6552
        ret = HAL_CRYP_Init(&hcryp);
6553
6554
        if (ret == HAL_OK) {
6555
        #if defined(STM32_HAL_V2)
6556
            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
6557
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6558
        #elif defined(STM32_CRYPTO_AES_ONLY)
6559
            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
6560
                out, STM32_HAL_TIMEOUT);
6561
        #else
6562
            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
6563
                                        blocks * WC_AES_BLOCK_SIZE,
6564
                out, STM32_HAL_TIMEOUT);
6565
        #endif
6566
        }
6567
        if (ret != HAL_OK) {
6568
            ret = WC_TIMEOUT_E;
6569
        }
6570
6571
        /* store iv for next call */
6572
        XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6573
6574
        HAL_CRYP_DeInit(&hcryp);
6575
        wolfSSL_CryptHwMutexUnLock();
6576
        wc_Stm32_Aes_Cleanup();
6577
6578
        return ret;
6579
    }
6580
    #endif /* HAVE_AES_DECRYPT */
6581
6582
#else /* Standard Peripheral Library */
6583
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6584
    {
6585
        int ret;
6586
        word32 *iv;
6587
        CRYP_InitTypeDef cryptInit;
6588
        CRYP_KeyInitTypeDef keyInit;
6589
        CRYP_IVInitTypeDef ivInit;
6590
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6591
6592
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6593
        if (sz % WC_AES_BLOCK_SIZE) {
6594
            return BAD_LENGTH_E;
6595
        }
6596
#endif
6597
        if (blocks == 0)
6598
            return 0;
6599
6600
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6601
        if (ret != 0)
6602
            return ret;
6603
6604
        ret = wolfSSL_CryptHwMutexLock();
6605
        if (ret != 0) {
6606
            return ret;
6607
        }
6608
6609
        /* reset registers to their default values */
6610
        CRYP_DeInit();
6611
6612
        /* set key */
6613
        CRYP_KeyInit(&keyInit);
6614
6615
        /* set iv */
6616
        iv = aes->reg;
6617
        CRYP_IVStructInit(&ivInit);
6618
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
6619
        ivInit.CRYP_IV0Left  = iv[0];
6620
        ivInit.CRYP_IV0Right = iv[1];
6621
        ivInit.CRYP_IV1Left  = iv[2];
6622
        ivInit.CRYP_IV1Right = iv[3];
6623
        CRYP_IVInit(&ivInit);
6624
6625
        /* set direction and mode */
6626
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
6627
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
6628
        CRYP_Init(&cryptInit);
6629
6630
        /* enable crypto processor */
6631
        CRYP_Cmd(ENABLE);
6632
6633
        while (blocks--) {
6634
            /* flush IN/OUT FIFOs */
6635
            CRYP_FIFOFlush();
6636
6637
            wc_Stm32_CrypAesBlock(in, out);
6638
6639
            /* store iv for next call */
6640
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6641
6642
            sz  -= WC_AES_BLOCK_SIZE;
6643
            in  += WC_AES_BLOCK_SIZE;
6644
            out += WC_AES_BLOCK_SIZE;
6645
        }
6646
6647
        /* disable crypto processor */
6648
        CRYP_Cmd(DISABLE);
6649
        wolfSSL_CryptHwMutexUnLock();
6650
        wc_Stm32_Aes_Cleanup();
6651
6652
        return ret;
6653
    }
6654
6655
    #ifdef HAVE_AES_DECRYPT
6656
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6657
    {
6658
        int ret;
6659
        word32 *iv;
6660
        CRYP_InitTypeDef cryptInit;
6661
        CRYP_KeyInitTypeDef keyInit;
6662
        CRYP_IVInitTypeDef ivInit;
6663
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6664
6665
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6666
        if (sz % WC_AES_BLOCK_SIZE) {
6667
            return BAD_LENGTH_E;
6668
        }
6669
#endif
6670
        if (blocks == 0)
6671
            return 0;
6672
6673
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6674
        if (ret != 0)
6675
            return ret;
6676
6677
        ret = wolfSSL_CryptHwMutexLock();
6678
        if (ret != 0) {
6679
            return ret;
6680
        }
6681
6682
        /* if input and output same will overwrite input iv */
6683
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6684
6685
        /* reset registers to their default values */
6686
        CRYP_DeInit();
6687
6688
        /* set direction and key */
6689
        CRYP_KeyInit(&keyInit);
6690
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
6691
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
6692
        CRYP_Init(&cryptInit);
6693
6694
        /* enable crypto processor */
6695
        CRYP_Cmd(ENABLE);
6696
6697
        /* wait until key has been prepared */
6698
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6699
6700
        /* set direction and mode */
6701
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
6702
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
6703
        CRYP_Init(&cryptInit);
6704
6705
        /* set iv */
6706
        iv = aes->reg;
6707
        CRYP_IVStructInit(&ivInit);
6708
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
6709
        ivInit.CRYP_IV0Left  = iv[0];
6710
        ivInit.CRYP_IV0Right = iv[1];
6711
        ivInit.CRYP_IV1Left  = iv[2];
6712
        ivInit.CRYP_IV1Right = iv[3];
6713
        CRYP_IVInit(&ivInit);
6714
6715
        /* enable crypto processor */
6716
        CRYP_Cmd(ENABLE);
6717
6718
        while (blocks--) {
6719
            /* flush IN/OUT FIFOs */
6720
            CRYP_FIFOFlush();
6721
6722
            wc_Stm32_CrypAesBlock(in, out);
6723
6724
            /* store iv for next call */
6725
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6726
6727
            in  += WC_AES_BLOCK_SIZE;
6728
            out += WC_AES_BLOCK_SIZE;
6729
        }
6730
6731
        /* disable crypto processor */
6732
        CRYP_Cmd(DISABLE);
6733
        wolfSSL_CryptHwMutexUnLock();
6734
        wc_Stm32_Aes_Cleanup();
6735
6736
        return ret;
6737
    }
6738
    #endif /* HAVE_AES_DECRYPT */
6739
#endif /* WOLFSSL_STM32_CUBEMX */
6740
6741
#elif defined(HAVE_COLDFIRE_SEC)
6742
    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
6743
        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
6744
    {
6745
        #ifdef DEBUG_WOLFSSL
6746
            int i; int stat1, stat2; int ret;
6747
        #endif
6748
6749
        int size;
6750
        volatile int v;
6751
6752
        if ((pi == NULL) || (po == NULL))
6753
            return BAD_FUNC_ARG;    /*wrong pointer*/
6754
6755
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6756
        if (sz % WC_AES_BLOCK_SIZE) {
6757
            return BAD_LENGTH_E;
6758
        }
6759
#endif
6760
6761
        wc_LockMutex(&Mutex_AesSEC);
6762
6763
        /* Set descriptor for SEC */
6764
        secDesc->length1 = 0x0;
6765
        secDesc->pointer1 = NULL;
6766
6767
        secDesc->length2 = WC_AES_BLOCK_SIZE;
6768
        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
6769
6770
        switch(aes->rounds) {
6771
            case 10: secDesc->length3 = 16; break;
6772
            case 12: secDesc->length3 = 24; break;
6773
            case 14: secDesc->length3 = 32; break;
6774
        }
6775
        XMEMCPY(secKey, aes->key, secDesc->length3);
6776
6777
        secDesc->pointer3 = (byte *)secKey;
6778
        secDesc->pointer4 = AESBuffIn;
6779
        secDesc->pointer5 = AESBuffOut;
6780
        secDesc->length6 = 0x0;
6781
        secDesc->pointer6 = NULL;
6782
        secDesc->length7 = 0x0;
6783
        secDesc->pointer7 = NULL;
6784
        secDesc->nextDescriptorPtr = NULL;
6785
6786
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6787
        size = AES_BUFFER_SIZE;
6788
#endif
6789
        while (sz) {
6790
            secDesc->header = descHeader;
6791
            XMEMCPY(secReg, aes->reg, WC_AES_BLOCK_SIZE);
6792
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6793
            sz -= AES_BUFFER_SIZE;
6794
#else
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
#endif
6803
6804
            secDesc->length4 = size;
6805
            secDesc->length5 = size;
6806
6807
            XMEMCPY(AESBuffIn, pi, size);
6808
            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
6809
                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-WC_AES_BLOCK_SIZE]),
6810
                        WC_AES_BLOCK_SIZE);
6811
            }
6812
6813
            /* Point SEC to the location of the descriptor */
6814
            MCF_SEC_FR0 = (uint32)secDesc;
6815
            /* Initialize SEC and wait for encryption to complete */
6816
            MCF_SEC_CCCR0 = 0x0000001a;
6817
            /* poll SISR to determine when channel is complete */
6818
            v=0;
6819
6820
            while ((secDesc->header>> 24) != 0xff) v++;
6821
6822
            #ifdef DEBUG_WOLFSSL
6823
                ret = MCF_SEC_SISRH;
6824
                stat1 = MCF_SEC_AESSR;
6825
                stat2 = MCF_SEC_AESISR;
6826
                if (ret & 0xe0000000) {
6827
                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
6828
                              "AESISR=%08x\n", i, ret, stat1, stat2);
6829
                }
6830
            #endif
6831
6832
            XMEMCPY(po, AESBuffOut, size);
6833
6834
            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
6835
                XMEMCPY((void*)aes->reg, (void*)&(po[size-WC_AES_BLOCK_SIZE]),
6836
                        WC_AES_BLOCK_SIZE);
6837
            } else {
6838
                XMEMCPY((void*)aes->reg, (void*)aes->tmp, WC_AES_BLOCK_SIZE);
6839
            }
6840
6841
            pi += size;
6842
            po += size;
6843
        }
6844
6845
        wc_UnLockMutex(&Mutex_AesSEC);
6846
        return 0;
6847
    }
6848
6849
    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6850
    {
6851
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
6852
    }
6853
6854
    #ifdef HAVE_AES_DECRYPT
6855
    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
6856
    {
6857
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
6858
    }
6859
    #endif /* HAVE_AES_DECRYPT */
6860
6861
#elif defined(FREESCALE_LTC)
6862
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6863
    {
6864
        word32 keySize;
6865
        status_t status;
6866
        byte *iv, *enc_key;
6867
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6868
6869
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6870
        if (sz % WC_AES_BLOCK_SIZE) {
6871
            return BAD_LENGTH_E;
6872
        }
6873
#endif
6874
        if (blocks == 0)
6875
            return 0;
6876
6877
        iv      = (byte*)aes->reg;
6878
        enc_key = (byte*)aes->key;
6879
6880
        status = wc_AesGetKeySize(aes, &keySize);
6881
        if (status != 0) {
6882
            return status;
6883
        }
6884
6885
        status = wolfSSL_CryptHwMutexLock();
6886
        if (status != 0)
6887
            return status;
6888
        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6889
            iv, enc_key, keySize);
6890
        wolfSSL_CryptHwMutexUnLock();
6891
6892
        /* store iv for next call */
6893
        if (status == kStatus_Success) {
6894
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6895
        }
6896
6897
        return (status == kStatus_Success) ? 0 : -1;
6898
    }
6899
6900
    #ifdef HAVE_AES_DECRYPT
6901
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6902
    {
6903
        word32 keySize;
6904
        status_t status;
6905
        byte* iv, *dec_key;
6906
        byte temp_block[WC_AES_BLOCK_SIZE];
6907
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6908
6909
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6910
        if (sz % WC_AES_BLOCK_SIZE) {
6911
            return BAD_LENGTH_E;
6912
        }
6913
#endif
6914
        if (blocks == 0)
6915
            return 0;
6916
6917
        iv      = (byte*)aes->reg;
6918
        dec_key = (byte*)aes->key;
6919
6920
        status = wc_AesGetKeySize(aes, &keySize);
6921
        if (status != 0) {
6922
            return status;
6923
        }
6924
6925
        /* get IV for next call */
6926
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6927
6928
        status = wolfSSL_CryptHwMutexLock();
6929
        if (status != 0)
6930
            return status;
6931
        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
6932
            iv, dec_key, keySize, kLTC_EncryptKey);
6933
        wolfSSL_CryptHwMutexUnLock();
6934
6935
        /* store IV for next call */
6936
        if (status == kStatus_Success) {
6937
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
6938
        }
6939
6940
        return (status == kStatus_Success) ? 0 : -1;
6941
    }
6942
    #endif /* HAVE_AES_DECRYPT */
6943
6944
#elif defined(FREESCALE_MMCAU) && !defined(WOLFSSL_ARMASM)
6945
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6946
    {
6947
        int offset = 0;
6948
        byte *iv;
6949
        byte temp_block[WC_AES_BLOCK_SIZE];
6950
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6951
        int ret;
6952
6953
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6954
        if (sz % WC_AES_BLOCK_SIZE) {
6955
            return BAD_LENGTH_E;
6956
        }
6957
#endif
6958
        if (blocks == 0)
6959
            return 0;
6960
6961
        iv = (byte*)aes->reg;
6962
6963
        while (blocks--) {
6964
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
6965
6966
            /* XOR block with IV for CBC */
6967
            xorbuf(temp_block, iv, WC_AES_BLOCK_SIZE);
6968
6969
            ret = wc_AesEncrypt(aes, temp_block, out + offset);
6970
            if (ret != 0)
6971
                return ret;
6972
6973
            offset += WC_AES_BLOCK_SIZE;
6974
6975
            /* store IV for next block */
6976
            XMEMCPY(iv, out + offset - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6977
        }
6978
6979
        return 0;
6980
    }
6981
    #ifdef HAVE_AES_DECRYPT
6982
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6983
    {
6984
        int ret;
6985
        int offset = 0;
6986
        byte* iv;
6987
        byte temp_block[WC_AES_BLOCK_SIZE];
6988
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
6989
6990
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
6991
        if (sz % WC_AES_BLOCK_SIZE) {
6992
            return BAD_LENGTH_E;
6993
        }
6994
#endif
6995
        if (blocks == 0)
6996
            return 0;
6997
6998
        iv = (byte*)aes->reg;
6999
7000
        while (blocks--) {
7001
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
7002
7003
            ret = wc_AesDecrypt(aes, in + offset, out + offset);
7004
            if (ret != 0)
7005
                return ret;
7006
7007
            /* XOR block with IV for CBC */
7008
            xorbuf(out + offset, iv, WC_AES_BLOCK_SIZE);
7009
7010
            /* store IV for next block */
7011
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
7012
7013
            offset += WC_AES_BLOCK_SIZE;
7014
        }
7015
        return 0;
7016
    }
7017
    #endif /* HAVE_AES_DECRYPT */
7018
7019
#elif defined(MAX3266X_AES)
7020
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7021
    {
7022
        word32 keySize;
7023
        int status;
7024
        byte *iv;
7025
7026
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
7027
            return BAD_FUNC_ARG;
7028
        }
7029
7030
        /* Always enforce a length check */
7031
        if (sz % WC_AES_BLOCK_SIZE) {
7032
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7033
            return BAD_LENGTH_E;
7034
        #else
7035
            return BAD_FUNC_ARG;
7036
        #endif
7037
        }
7038
        if (sz == 0) {
7039
            return 0;
7040
        }
7041
7042
        iv = (byte*)aes->reg;
7043
        status = wc_AesGetKeySize(aes, &keySize);
7044
        if (status != 0) {
7045
            return status;
7046
        }
7047
7048
        status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
7049
                                        MXC_TPU_MODE_CBC, sz, out,
7050
                                        (unsigned int)keySize);
7051
        /* store iv for next call */
7052
        if (status == 0) {
7053
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7054
        }
7055
        return (status == 0) ? 0 : -1;
7056
    }
7057
7058
    #ifdef HAVE_AES_DECRYPT
7059
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7060
    {
7061
        word32 keySize;
7062
        int status;
7063
        byte *iv;
7064
        byte temp_block[WC_AES_BLOCK_SIZE];
7065
7066
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
7067
            return BAD_FUNC_ARG;
7068
        }
7069
7070
        /* Always enforce a length check */
7071
        if (sz % WC_AES_BLOCK_SIZE) {
7072
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7073
            return BAD_LENGTH_E;
7074
        #else
7075
            return BAD_FUNC_ARG;
7076
        #endif
7077
        }
7078
        if (sz == 0) {
7079
            return 0;
7080
        }
7081
7082
        iv = (byte*)aes->reg;
7083
        status = wc_AesGetKeySize(aes, &keySize);
7084
        if (status != 0) {
7085
            return status;
7086
        }
7087
7088
        /* get IV for next call */
7089
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7090
        status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
7091
                                        MXC_TPU_MODE_CBC, sz, out,
7092
                                        keySize);
7093
7094
        /* store iv for next call */
7095
        if (status == 0) {
7096
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
7097
        }
7098
        return (status == 0) ? 0 : -1;
7099
    }
7100
    #endif /* HAVE_AES_DECRYPT */
7101
7102
7103
7104
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
7105
7106
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7107
    {
7108
        int ret;
7109
7110
        if (aes == NULL)
7111
            return BAD_FUNC_ARG;
7112
7113
        if (!WC_AES_KEY_IS_SET(aes)) {
7114
            WOLFSSL_MSG("AES key not set");
7115
            return MISSING_KEY;
7116
        }
7117
7118
        if (sz == 0)
7119
            return 0;
7120
7121
        /* hardware fails on input that is not a multiple of AES block size */
7122
        if (sz % WC_AES_BLOCK_SIZE != 0) {
7123
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7124
            return BAD_LENGTH_E;
7125
#else
7126
            return BAD_FUNC_ARG;
7127
#endif
7128
        }
7129
7130
        ret = wc_Pic32AesCrypt(
7131
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
7132
            out, in, sz, PIC32_ENCRYPTION,
7133
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
7134
7135
        /* store iv for next call */
7136
        if (ret == 0) {
7137
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7138
        }
7139
7140
        return ret;
7141
    }
7142
    #ifdef HAVE_AES_DECRYPT
7143
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7144
    {
7145
        int ret;
7146
        byte scratch[WC_AES_BLOCK_SIZE];
7147
7148
        if (aes == NULL)
7149
            return BAD_FUNC_ARG;
7150
7151
        if (!WC_AES_KEY_IS_SET(aes)) {
7152
            WOLFSSL_MSG("AES key not set");
7153
            return MISSING_KEY;
7154
        }
7155
7156
        if (sz == 0)
7157
            return 0;
7158
7159
        /* hardware fails on input that is not a multiple of AES block size */
7160
        if (sz % WC_AES_BLOCK_SIZE != 0) {
7161
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7162
            return BAD_LENGTH_E;
7163
#else
7164
            return BAD_FUNC_ARG;
7165
#endif
7166
        }
7167
        XMEMCPY(scratch, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7168
7169
        ret = wc_Pic32AesCrypt(
7170
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
7171
            out, in, sz, PIC32_DECRYPTION,
7172
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
7173
7174
        /* store iv for next call */
7175
        if (ret == 0) {
7176
            XMEMCPY((byte*)aes->reg, scratch, WC_AES_BLOCK_SIZE);
7177
        }
7178
7179
        return ret;
7180
    }
7181
    #endif /* HAVE_AES_DECRYPT */
7182
#elif defined(WOLFSSL_ESP32_CRYPT) && \
7183
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
7184
7185
    /* We'll use SW for fall back:
7186
     *   unsupported key lengths
7187
     *   hardware busy */
7188
    #define NEED_SW_AESCBC
7189
    #define NEED_AESCBC_HW_FALLBACK
7190
7191
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
7192
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7193
    {
7194
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
7195
    }
7196
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7197
    {
7198
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
7199
    }
7200
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
7201
        !defined(WOLFSSL_QNX_CAAM)
7202
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
7203
7204
#elif defined(WOLFSSL_AFALG)
7205
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
7206
7207
#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
7208
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
7209
7210
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
7211
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
7212
7213
#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
7214
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
7215
7216
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
7217
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
7218
7219
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
7220
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
7221
7222
#elif defined(WOLFSSL_PSOC6_CRYPTO)
7223
7224
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7225
    {
7226
        if (aes == NULL)
7227
            return BAD_FUNC_ARG;
7228
        if (!WC_AES_KEY_IS_SET(aes)) {
7229
            WOLFSSL_MSG("AES key not set");
7230
            return MISSING_KEY;
7231
        }
7232
        return wc_Psoc6_Aes_CbcEncrypt(aes, out, in, sz);
7233
    }
7234
7235
    #if defined(HAVE_AES_DECRYPT)
7236
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7237
    {
7238
        if (aes == NULL)
7239
            return BAD_FUNC_ARG;
7240
        if (!WC_AES_KEY_IS_SET(aes)) {
7241
            WOLFSSL_MSG("AES key not set");
7242
            return MISSING_KEY;
7243
        }
7244
        return wc_Psoc6_Aes_CbcDecrypt(aes, out, in, sz);
7245
    }
7246
    #endif /* HAVE_AES_DECRYPT */
7247
7248
#else
7249
    /* Reminder: Some HW implementations may also define this as needed.
7250
     * (e.g. for unsupported key length fallback)  */
7251
    #define NEED_SW_AESCBC
7252
#endif
7253
7254
#ifdef NEED_SW_AESCBC
7255
    /* Software AES - CBC Encrypt */
7256
7257
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7258
0
    {
7259
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7260
0
        word32 blocks;
7261
0
        int ret;
7262
0
#endif
7263
7264
0
        if (aes == NULL || out == NULL || in == NULL) {
7265
0
            return BAD_FUNC_ARG;
7266
0
        }
7267
7268
0
        if (sz == 0) {
7269
            /* Keep above the DCP/crypto-cb dispatches: they must not see
7270
             * sz == 0. A missing key is only reported when there is work. */
7271
0
            return 0;
7272
0
        }
7273
7274
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7275
0
        blocks = sz / WC_AES_BLOCK_SIZE;
7276
0
#endif
7277
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7278
        if (sz % WC_AES_BLOCK_SIZE) {
7279
            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
7280
            return BAD_LENGTH_E;
7281
        }
7282
#endif
7283
7284
    #ifdef WOLFSSL_IMXRT_DCP
7285
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
7286
        if (aes->keylen == 16)
7287
            return DCPAesCbcEncrypt(aes, out, in, sz);
7288
    #endif
7289
7290
    #ifdef WOLF_CRYPTO_CB
7291
        #ifndef WOLF_CRYPTO_CB_FIND
7292
        if (aes->devId != INVALID_DEVID)
7293
        #endif
7294
        {
7295
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
7296
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7297
                return crypto_cb_ret;
7298
            /* fall-through when unavailable */
7299
        }
7300
    #endif
7301
7302
        /* Single key guard after all offload dispatches. */
7303
0
        if (!WC_AES_KEY_IS_SET(aes)) {
7304
0
            WOLFSSL_MSG("AES key not set");
7305
0
            return MISSING_KEY;
7306
0
        }
7307
7308
#if defined(WOLFSSL_RISCV_ASM)
7309
        AES_CBC_encrypt_RISCV64(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7310
            (int)aes->rounds);
7311
        (void)blocks;
7312
        (void)ret;
7313
        return 0;
7314
#endif
7315
7316
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
7317
        /* if async and byte count above threshold */
7318
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
7319
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
7320
        #if defined(HAVE_CAVIUM)
7321
            return NitroxAesCbcEncrypt(aes, out, in, sz);
7322
        #elif defined(HAVE_INTEL_QA)
7323
            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
7324
                (const byte*)aes->devKey, aes->keylen,
7325
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7326
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
7327
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
7328
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
7329
                sw->aes.aes = aes;
7330
                sw->aes.out = out;
7331
                sw->aes.in = in;
7332
                sw->aes.sz = sz;
7333
                return WC_PENDING_E;
7334
            }
7335
        #endif
7336
        }
7337
    #endif /* WOLFSSL_ASYNC_CRYPT */
7338
7339
#if defined(WOLFSSL_ARMASM)
7340
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7341
    #if !defined(__aarch64__)
7342
      #ifdef WOLFSSL_ARM32_AES_DISPATCH
7343
        if (aes->use_aes_hw_crypto) {
7344
            AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
7345
                (byte*)aes->key, (int)aes->rounds);
7346
        }
7347
        else
7348
      #else
7349
        AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7350
            (int)aes->rounds);
7351
      #endif /* WOLFSSL_ARM32_AES_DISPATCH */
7352
    #else
7353
        if (aes->use_aes_hw_crypto) {
7354
            AES_CBC_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7355
                (byte*)aes->key, (int)aes->rounds);
7356
        }
7357
        else
7358
    #endif /* __aarch64__ */
7359
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7360
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
7361
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
7362
        {
7363
            AES_CBC_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
7364
                aes->rounds, (unsigned char*)aes->reg);
7365
        }
7366
    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
7367
          defined(WOLFSSL_ARM32_AES_DISPATCH)
7368
        {
7369
            AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
7370
                aes->rounds, (unsigned char*)aes->reg);
7371
        }
7372
    #endif
7373
        return 0;
7374
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7375
        AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
7376
            aes->rounds, (unsigned char*)aes->reg);
7377
        return 0;
7378
#else
7379
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
7380
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
7381
        if (aes->useSWCrypt == 0) {
7382
            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
7383
                                   kAlgorithm_SSS_AES_CBC);
7384
        }
7385
        else
7386
    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
7387
        if (wc_esp32AesSupportedKeyLen(aes)) {
7388
            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
7389
            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
7390
        }
7391
        else {
7392
            /* For example, the ESP32-S3 does not support HW for len = 24,
7393
             * so fall back to SW */
7394
        #ifdef DEBUG_WOLFSSL
7395
            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
7396
                          "unsupported keylen = %d", aes->keylen);
7397
        #endif
7398
        }
7399
    #elif defined(WOLFSSL_AESNI)
7400
        VECTOR_REGISTERS_PUSH;
7401
        if (aes->use_aesni) {
7402
            #ifdef DEBUG_AESNI
7403
                printf("about to aes cbc encrypt\n");
7404
                printf("in  = %p\n", in);
7405
                printf("out = %p\n", out);
7406
                printf("aes->key = %p\n", aes->key);
7407
                printf("aes->reg = %p\n", aes->reg);
7408
                printf("aes->rounds = %d\n", aes->rounds);
7409
                printf("sz = %d\n", sz);
7410
            #endif
7411
7412
            /* check alignment, decrypt doesn't need alignment */
7413
            if ((wc_ptr_t)in % AESNI_ALIGN) {
7414
            #ifndef NO_WOLFSSL_ALLOC_ALIGN
7415
                byte* tmp = (byte*)XMALLOC(sz + WC_AES_BLOCK_SIZE + AESNI_ALIGN,
7416
                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
7417
                byte* tmp_align;
7418
                if (tmp == NULL)
7419
                    ret = MEMORY_E;
7420
                else {
7421
                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
7422
                    XMEMCPY(tmp_align, in, sz);
7423
                #ifdef WOLFSSL_X86_64_BUILD
7424
                    AesCbcEncryptBlocks(tmp_align, tmp_align, (byte*)aes->reg, sz,
7425
                                        (byte*)aes->key, (int)aes->rounds);
7426
                #else
7427
                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
7428
                                          (byte*)aes->key, (int)aes->rounds);
7429
                #endif
7430
                    /* store iv for next call */
7431
                    XMEMCPY(aes->reg, tmp_align + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7432
7433
                    XMEMCPY(out, tmp_align, sz);
7434
                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
7435
                    ret = 0;
7436
                }
7437
            #else
7438
                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
7439
                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
7440
                ret = BAD_ALIGN_E;
7441
            #endif
7442
            } else {
7443
            #ifdef WOLFSSL_X86_64_BUILD
7444
                AesCbcEncryptBlocks(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7445
                                    (int)aes->rounds);
7446
            #else
7447
                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7448
                                      (int)aes->rounds);
7449
            #endif
7450
                /* store iv for next call */
7451
                XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7452
7453
                ret = 0;
7454
            }
7455
        }
7456
        else
7457
    #endif
7458
0
        {
7459
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
7460
0
            int did_prefetches = 0;
7461
0
#endif
7462
0
            ret = 0;
7463
0
            while (blocks--) {
7464
0
                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
7465
0
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
7466
0
                                                (byte*)aes->reg,
7467
0
                                                &did_prefetches);
7468
0
                if (ret != 0)
7469
0
                    break;
7470
0
                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
7471
7472
0
                out += WC_AES_BLOCK_SIZE;
7473
0
                in  += WC_AES_BLOCK_SIZE;
7474
0
            }
7475
0
        }
7476
7477
    #ifdef WOLFSSL_AESNI
7478
        VECTOR_REGISTERS_POP;
7479
    #endif
7480
7481
0
        return ret;
7482
0
#endif
7483
0
    } /* wc_AesCbcEncrypt */
7484
7485
#ifdef HAVE_AES_DECRYPT
7486
    /* Software AES - CBC Decrypt */
7487
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7488
0
    {
7489
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7490
0
        word32 blocks;
7491
0
        int ret;
7492
0
#endif
7493
7494
0
        if (aes == NULL || out == NULL || in == NULL) {
7495
0
            return BAD_FUNC_ARG;
7496
0
        }
7497
7498
0
        if (sz == 0) {
7499
            /* Keep above the DCP/crypto-cb dispatches: they must not see
7500
             * sz == 0. A missing key is only reported when there is work. */
7501
0
            return 0;
7502
0
        }
7503
7504
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
7505
        if (wc_esp32AesSupportedKeyLen(aes)) {
7506
            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
7507
            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
7508
        }
7509
        else {
7510
            /* For example, the ESP32-S3 does not support HW for len = 24,
7511
             * so fall back to SW */
7512
        #ifdef DEBUG_WOLFSSL
7513
            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
7514
                          "unsupported keylen = %d", aes->keylen);
7515
        #endif
7516
        }
7517
    #endif
7518
7519
0
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7520
0
        blocks = sz / WC_AES_BLOCK_SIZE;
7521
0
#endif
7522
0
        if (sz % WC_AES_BLOCK_SIZE) {
7523
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
7524
            return BAD_LENGTH_E;
7525
#else
7526
0
            return BAD_FUNC_ARG;
7527
0
#endif
7528
0
        }
7529
7530
    #ifdef WOLFSSL_IMXRT_DCP
7531
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
7532
        if (aes->keylen == 16)
7533
            return DCPAesCbcDecrypt(aes, out, in, sz);
7534
    #endif
7535
7536
    #ifdef WOLF_CRYPTO_CB
7537
        #ifndef WOLF_CRYPTO_CB_FIND
7538
        if (aes->devId != INVALID_DEVID)
7539
        #endif
7540
        {
7541
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
7542
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7543
                return crypto_cb_ret;
7544
            /* fall-through when unavailable */
7545
        }
7546
    #endif
7547
7548
        /* Single key guard after all offload dispatches. */
7549
0
        if (!WC_AES_KEY_IS_SET(aes)) {
7550
0
            WOLFSSL_MSG("AES key not set");
7551
0
            return MISSING_KEY;
7552
0
        }
7553
7554
#if defined(WOLFSSL_RISCV_ASM)
7555
        AES_CBC_decrypt_RISCV64(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7556
            (int)aes->rounds);
7557
        (void)blocks;
7558
        (void)ret;
7559
        return 0;
7560
#endif
7561
7562
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
7563
        /* if async and byte count above threshold */
7564
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
7565
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
7566
        #if defined(HAVE_CAVIUM)
7567
            return NitroxAesCbcDecrypt(aes, out, in, sz);
7568
        #elif defined(HAVE_INTEL_QA)
7569
            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
7570
                (const byte*)aes->devKey, aes->keylen,
7571
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7572
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
7573
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
7574
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
7575
                sw->aes.aes = aes;
7576
                sw->aes.out = out;
7577
                sw->aes.in = in;
7578
                sw->aes.sz = sz;
7579
                return WC_PENDING_E;
7580
            }
7581
        #endif
7582
        }
7583
    #endif
7584
7585
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
7586
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
7587
        if (aes->useSWCrypt == 0) {
7588
            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
7589
                                   kAlgorithm_SSS_AES_CBC);
7590
        }
7591
    #endif
7592
7593
#if defined(WOLFSSL_ARMASM)
7594
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
7595
    #if !defined(__aarch64__)
7596
      #ifdef WOLFSSL_ARM32_AES_DISPATCH
7597
        if (aes->use_aes_hw_crypto) {
7598
            AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg,
7599
                (byte*)aes->key, (int)aes->rounds);
7600
        }
7601
        else
7602
      #else
7603
        AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
7604
            (int)aes->rounds);
7605
      #endif /* WOLFSSL_ARM32_AES_DISPATCH */
7606
    #else
7607
        if (aes->use_aes_hw_crypto) {
7608
            AES_CBC_decrypt_AARCH64(in, out, sz, (byte*)aes->reg,
7609
                (byte*)aes->key, (int)aes->rounds);
7610
        }
7611
        else
7612
    #endif /* !__aarch64__ */
7613
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
7614
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
7615
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7616
        if (sz >= 64)
7617
    #endif
7618
        {
7619
            AES_CBC_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
7620
                aes->rounds, (unsigned char*)aes->reg);
7621
        }
7622
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
7623
        else
7624
    #endif
7625
    #endif /* __aarch64__ && !WOLFSSL_ARMASM_NO_NEON */
7626
    #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
7627
        defined(WOLFSSL_ARM32_AES_DISPATCH)
7628
    /* WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP drops the base (table) AES in favour
7629
     * of the constant-time NEON one - but only the AArch64 assembly has a NEON
7630
     * AES to replace it with, and only it leaves the base variants out.  The
7631
     * AArch32 assembly always provides them, so the call must be kept there. */
7632
    #if !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP) || !defined(__aarch64__)
7633
        {
7634
            AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
7635
                aes->rounds, (unsigned char*)aes->reg);
7636
        }
7637
    #endif
7638
    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO ||
7639
            * WOLFSSL_ARM32_AES_DISPATCH */
7640
        return 0;
7641
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
7642
        AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
7643
            aes->rounds, (unsigned char*)aes->reg);
7644
        return 0;
7645
#else
7646
0
        VECTOR_REGISTERS_PUSH;
7647
7648
    #ifdef WOLFSSL_AESNI
7649
        if (aes->use_aesni) {
7650
            #ifdef DEBUG_AESNI
7651
                printf("about to aes cbc decrypt\n");
7652
                printf("in  = %p\n", in);
7653
                printf("out = %p\n", out);
7654
                printf("aes->key = %p\n", aes->key);
7655
                printf("aes->reg = %p\n", aes->reg);
7656
                printf("aes->rounds = %d\n", aes->rounds);
7657
                printf("sz = %d\n", sz);
7658
            #endif
7659
7660
            /* if input and output same will overwrite input iv */
7661
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
7662
            #if defined(WOLFSSL_X86_64_BUILD)
7663
            AesCbcDecryptBlocks(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7664
                            (int)aes->rounds);
7665
            #elif defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
7666
            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7667
                            aes->rounds);
7668
            #elif defined(WOLFSSL_AESNI_BY6)
7669
            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7670
                            aes->rounds);
7671
            #else /* WOLFSSL_AESNI_BYx */
7672
            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
7673
                            (int)aes->rounds);
7674
            #endif /* WOLFSSL_AESNI_BYx */
7675
            /* store iv for next call */
7676
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7677
            ret = 0;
7678
        }
7679
        else
7680
    #endif
7681
0
        {
7682
0
            ret = 0;
7683
#ifdef WC_AES_BITSLICED
7684
            if (in != out) {
7685
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
7686
7687
                while (blocks > BS_WORD_SIZE) {
7688
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
7689
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7690
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
7691
                              WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
7692
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
7693
                            WC_AES_BLOCK_SIZE);
7694
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7695
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7696
                    blocks -= BS_WORD_SIZE;
7697
                }
7698
                if (blocks > 0) {
7699
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
7700
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7701
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
7702
                              WC_AES_BLOCK_SIZE * (blocks - 1));
7703
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (blocks - 1)),
7704
                            WC_AES_BLOCK_SIZE);
7705
                    blocks = 0;
7706
                }
7707
            }
7708
            else {
7709
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
7710
                int i;
7711
7712
                while (blocks > BS_WORD_SIZE) {
7713
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
7714
                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * WC_AES_BLOCK_SIZE,
7715
                            WC_AES_BLOCK_SIZE);
7716
                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
7717
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
7718
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
7719
                                  WC_AES_BLOCK_SIZE);
7720
                    }
7721
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7722
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7723
7724
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7725
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
7726
                    blocks -= BS_WORD_SIZE;
7727
                }
7728
                if (blocks > 0) {
7729
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
7730
                    XMEMCPY(aes->tmp, in + (blocks - 1) * WC_AES_BLOCK_SIZE,
7731
                            WC_AES_BLOCK_SIZE);
7732
                    for (i = blocks-1; i >= 1; i--) {
7733
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
7734
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
7735
                                  WC_AES_BLOCK_SIZE);
7736
                    }
7737
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
7738
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7739
7740
                    blocks = 0;
7741
                }
7742
            }
7743
#else
7744
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
7745
0
            {
7746
0
            int did_prefetches = 0;
7747
0
#endif
7748
0
            while (blocks--) {
7749
0
                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
7750
0
                ret = AesDecrypt_preFetchOpt(aes, in, out, &did_prefetches);
7751
0
                if (ret != 0)
7752
0
                    return ret;
7753
0
                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
7754
                /* store iv for next call */
7755
0
                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
7756
7757
0
                out += WC_AES_BLOCK_SIZE;
7758
0
                in  += WC_AES_BLOCK_SIZE;
7759
0
            }
7760
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
7761
0
            }
7762
0
#endif
7763
0
#endif
7764
0
        }
7765
7766
0
        VECTOR_REGISTERS_POP;
7767
7768
0
        return ret;
7769
0
#endif
7770
0
    }
7771
#endif /* HAVE_AES_DECRYPT */
7772
7773
#endif /* AES-CBC block */
7774
#endif /* HAVE_AES_CBC */
7775
7776
/* AES-CTR */
7777
#if defined(WOLFSSL_AES_COUNTER)
7778
7779
    #ifdef STM32_CRYPTO
7780
        #define NEED_AES_CTR_SOFT
7781
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
7782
7783
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
7784
        {
7785
        #ifdef WOLFSSL_STM32_BARE
7786
            /* CTR per-block transform: produce out = in XOR AES_ECB(counter).
7787
             * ECB-encrypt the counter aes->reg into a keystream block, then XOR
7788
             * with the plaintext 'in'. The caller (XTRANSFORM_AESCTRBLOCK loop)
7789
             * does not XOR and increments aes->reg after this returns. */
7790
            byte ks[WC_AES_BLOCK_SIZE];
7791
            int  ret = wc_Stm32_Aes_Ecb(aes, ks, (const byte*)aes->reg,
7792
                                        WC_AES_BLOCK_SIZE, 1);
7793
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7794
            wc_MemZero_Add("wc_AesCtrEncryptBlock ks", ks, sizeof(ks));
7795
        #endif
7796
            if (ret == 0) {
7797
                xorbufout(out, in, ks, WC_AES_BLOCK_SIZE);
7798
            }
7799
            else {
7800
                /* The CTR loop breaks on this non-zero return; zero the block
7801
                 * so a failed HW ECB does not leave stale/prior plaintext in
7802
                 * the output. */
7803
                ForceZero(out, WC_AES_BLOCK_SIZE);
7804
            }
7805
            ForceZero(ks, sizeof(ks));
7806
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7807
            wc_MemZero_Check(ks, sizeof(ks));
7808
        #endif
7809
            return ret;
7810
        #else
7811
            int ret = 0;
7812
        #ifdef WOLFSSL_STM32_CUBEMX
7813
            CRYP_HandleTypeDef hcryp;
7814
            #ifdef STM32_HAL_V2
7815
            word32 iv[WC_AES_BLOCK_SIZE/sizeof(word32)];
7816
            #endif
7817
        #else
7818
            word32 *iv;
7819
            CRYP_InitTypeDef cryptInit;
7820
            CRYP_KeyInitTypeDef keyInit;
7821
            CRYP_IVInitTypeDef ivInit;
7822
        #endif
7823
7824
        #ifdef WOLFSSL_STM32_CUBEMX
7825
            ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
7826
            if (ret != 0) {
7827
                return ret;
7828
            }
7829
7830
            ret = wolfSSL_CryptHwMutexLock();
7831
            if (ret != 0) {
7832
                return ret;
7833
            }
7834
7835
        #if defined(STM32_HAL_V2)
7836
            hcryp.Init.Algorithm  = CRYP_AES_CTR;
7837
            ByteReverseWords(iv, aes->reg, WC_AES_BLOCK_SIZE);
7838
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
7839
        #elif defined(STM32_CRYPTO_AES_ONLY)
7840
            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
7841
            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
7842
            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
7843
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
7844
        #else
7845
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
7846
        #endif
7847
            HAL_CRYP_Init(&hcryp);
7848
7849
        #if defined(STM32_HAL_V2)
7850
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, WC_AES_BLOCK_SIZE,
7851
                (uint32_t*)out, STM32_HAL_TIMEOUT);
7852
        #elif defined(STM32_CRYPTO_AES_ONLY)
7853
            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
7854
                out, STM32_HAL_TIMEOUT);
7855
        #else
7856
            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
7857
                out, STM32_HAL_TIMEOUT);
7858
        #endif
7859
            if (ret != HAL_OK) {
7860
                ret = WC_TIMEOUT_E;
7861
            }
7862
            HAL_CRYP_DeInit(&hcryp);
7863
7864
        #else /* Standard Peripheral Library */
7865
            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
7866
            if (ret != 0) {
7867
                return ret;
7868
            }
7869
7870
            ret = wolfSSL_CryptHwMutexLock();
7871
            if (ret != 0) {
7872
                return ret;
7873
            }
7874
7875
            /* reset registers to their default values */
7876
            CRYP_DeInit();
7877
7878
            /* set key */
7879
            CRYP_KeyInit(&keyInit);
7880
7881
            /* set iv */
7882
            iv = aes->reg;
7883
            CRYP_IVStructInit(&ivInit);
7884
            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
7885
            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
7886
            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
7887
            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
7888
            CRYP_IVInit(&ivInit);
7889
7890
            /* set direction and mode */
7891
            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
7892
            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
7893
            CRYP_Init(&cryptInit);
7894
7895
            /* enable crypto processor */
7896
            CRYP_Cmd(ENABLE);
7897
7898
            /* flush IN/OUT FIFOs */
7899
            CRYP_FIFOFlush();
7900
7901
            wc_Stm32_CrypAesBlock(in, out);
7902
7903
            /* disable crypto processor */
7904
            CRYP_Cmd(DISABLE);
7905
        #endif /* WOLFSSL_STM32_CUBEMX */
7906
7907
            wolfSSL_CryptHwMutexUnLock();
7908
            wc_Stm32_Aes_Cleanup();
7909
            return ret;
7910
        #endif /* !WOLFSSL_STM32_BARE */
7911
        }
7912
7913
7914
    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
7915
7916
        #define NEED_AES_CTR_SOFT
7917
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
7918
7919
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
7920
        {
7921
            word32 tmpIv[WC_AES_BLOCK_SIZE / sizeof(word32)];
7922
            XMEMCPY(tmpIv, aes->reg, WC_AES_BLOCK_SIZE);
7923
            return wc_Pic32AesCrypt(
7924
                aes->key, aes->keylen, tmpIv, WC_AES_BLOCK_SIZE,
7925
                out, in, WC_AES_BLOCK_SIZE,
7926
                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
7927
        }
7928
7929
    #elif defined(HAVE_COLDFIRE_SEC)
7930
        #error "Coldfire SEC doesn't currently support AES-CTR mode"
7931
7932
    #elif defined(FREESCALE_LTC)
7933
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
7934
        {
7935
            int ret = 0;
7936
            word32 keySize;
7937
            byte *iv, *enc_key;
7938
            byte* tmp;
7939
7940
            if (aes == NULL || out == NULL || in == NULL) {
7941
                return BAD_FUNC_ARG;
7942
            }
7943
7944
            /* consume any unused bytes left in aes->tmp */
7945
            tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
7946
            while (aes->left && sz) {
7947
                *(out++) = *(in++) ^ *(tmp++);
7948
                aes->left--;
7949
                sz--;
7950
            }
7951
7952
            if (sz) {
7953
                iv      = (byte*)aes->reg;
7954
                enc_key = (byte*)aes->key;
7955
7956
                ret = wc_AesGetKeySize(aes, &keySize);
7957
                if (ret != 0)
7958
                    return ret;
7959
7960
                ret = wolfSSL_CryptHwMutexLock();
7961
                if (ret != 0)
7962
                    return ret;
7963
                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
7964
                    iv, enc_key, keySize, (byte*)aes->tmp,
7965
                    (uint32_t*)&aes->left);
7966
                wolfSSL_CryptHwMutexUnLock();
7967
            }
7968
7969
            return ret;
7970
        }
7971
7972
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
7973
        !defined(WOLFSSL_QNX_CAAM)
7974
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
7975
7976
    #elif defined(WOLFSSL_AFALG)
7977
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
7978
7979
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
7980
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
7981
7982
    #elif defined(WOLFSSL_ESP32_CRYPT) && \
7983
        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
7984
        /* esp32 doesn't support CRT mode by hw.     */
7985
        /* use aes ecnryption plus sw implementation */
7986
        #define NEED_AES_CTR_SOFT
7987
7988
    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
7989
        /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
7990
7991
    #elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
7992
        /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
7993
7994
    #else
7995
7996
        /* Use software based AES counter */
7997
        #define NEED_AES_CTR_SOFT
7998
    #endif
7999
8000
    #ifdef NEED_AES_CTR_SOFT
8001
        #ifndef WOLFSSL_ARMASM
8002
        /* Increment AES counter */
8003
        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
8004
        {
8005
            /* in network byte order so start at end and work back */
8006
            int i;
8007
            for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
8008
                if (++inOutCtr[i])  /* we're done unless we overflow */
8009
                    return;
8010
            }
8011
        }
8012
        #endif
8013
8014
        /* Software AES - CTR Encrypt */
8015
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
8016
        {
8017
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
8018
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8019
            byte scratch[WC_AES_BLOCK_SIZE];
8020
    #endif
8021
    #if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
8022
            int ret = 0;
8023
    #endif
8024
            word32 processed;
8025
#ifdef WC_AES_HAVE_PREFETCH_ARG
8026
            int did_prefetches = 0;
8027
#endif
8028
8029
    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
8030
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
8031
            XMEMSET(scratch, 0, sizeof(scratch));
8032
    #endif
8033
8034
            if (aes == NULL || out == NULL || in == NULL) {
8035
                return BAD_FUNC_ARG;
8036
            }
8037
8038
            if (sz == 0) {
8039
                /* Keep above the crypto-cb dispatch: it must not see sz == 0.
8040
                 * A missing key is only reported when there is work. */
8041
                return 0;
8042
            }
8043
8044
        #ifdef WOLF_CRYPTO_CB
8045
            #ifndef WOLF_CRYPTO_CB_FIND
8046
            if (aes->devId != INVALID_DEVID)
8047
            #endif
8048
            {
8049
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
8050
                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
8051
                    return crypto_cb_ret;
8052
                /* fall-through when unavailable */
8053
            }
8054
        #endif
8055
8056
            /* Software/HW key schedule required from here on. */
8057
            if (!WC_AES_KEY_IS_SET(aes)) {
8058
                WOLFSSL_MSG("AES key not set");
8059
                return MISSING_KEY;
8060
            }
8061
8062
            /* consume any unused bytes left in aes->tmp */
8063
            processed = min(aes->left, sz);
8064
            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
8065
                      processed);
8066
            out += processed;
8067
            in += processed;
8068
            aes->left -= processed;
8069
            sz -= processed;
8070
8071
    #if defined(WOLFSSL_RISCV_ASM)
8072
            if (sz > 0) {
8073
                AES_CTR_encrypt_RISCV64(in, out, sz, (byte*)aes->reg,
8074
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left,
8075
                    (int)aes->rounds);
8076
            }
8077
            (void)scratch;
8078
            (void)ret;
8079
            return 0;
8080
    #endif
8081
8082
    #if defined(WOLFSSL_ARMASM)
8083
        #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
8084
            #ifndef __aarch64__
8085
              #ifdef WOLFSSL_ARM32_AES_DISPATCH
8086
            if (aes->use_aes_hw_crypto) {
8087
                AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
8088
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
8089
                return 0;
8090
            }
8091
            else
8092
              #else
8093
            AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
8094
                (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
8095
              #endif /* WOLFSSL_ARM32_AES_DISPATCH */
8096
            #else
8097
            if (aes->use_aes_hw_crypto) {
8098
                AES_CTR_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
8099
                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
8100
                return 0;
8101
            }
8102
            else
8103
            #endif /* !__aarch64__ */
8104
        #endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
8105
        #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
8106
            defined(WOLFSSL_ARM32_AES_DISPATCH)
8107
            {
8108
                word32 numBlocks;
8109
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
8110
                /* consume any unused bytes left in aes->tmp */
8111
                while ((aes->left != 0) && (sz != 0)) {
8112
                   *(out++) = *(in++) ^ *(tmp++);
8113
                   aes->left--;
8114
                   sz--;
8115
                }
8116
8117
                /* do as many block size ops as possible */
8118
                numBlocks = sz / WC_AES_BLOCK_SIZE;
8119
                if (numBlocks > 0) {
8120
                #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
8121
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
8122
                    if (sz >= 32)
8123
                #endif
8124
                    {
8125
                        AES_CTR_encrypt_NEON(in, out,
8126
                            numBlocks * WC_AES_BLOCK_SIZE, (byte*)aes->key,
8127
                            aes->rounds, (byte*)aes->reg);
8128
                    }
8129
                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
8130
                    else
8131
                #endif
8132
                #endif
8133
                /* Base AES is only left out on AArch64 - see wc_AesCbcDecrypt.
8134
                 */
8135
                #if !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP) || \
8136
                    !defined(__aarch64__)
8137
                    {
8138
                        AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
8139
                            (byte*)aes->key, aes->rounds, (byte*)aes->reg);
8140
                    }
8141
                #endif
8142
8143
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
8144
                    out += numBlocks * WC_AES_BLOCK_SIZE;
8145
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
8146
                }
8147
8148
                /* handle non block size remaining */
8149
                if (sz) {
8150
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
8151
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
8152
8153
                #if defined(__aarch64__) && \
8154
                    !defined(WOLFSSL_ARMASM_NO_NEON) && \
8155
                    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
8156
                    {
8157
                        AES_CTR_encrypt_NEON(zeros, (byte*)aes->tmp,
8158
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
8159
                            (byte*)aes->reg);
8160
                    }
8161
                #else
8162
                    {
8163
                        AES_CTR_encrypt(zeros, (byte*)aes->tmp,
8164
                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
8165
                            (byte*)aes->reg);
8166
                    }
8167
                #endif
8168
8169
                    aes->left = WC_AES_BLOCK_SIZE;
8170
                    tmp = (byte*)aes->tmp;
8171
8172
                    while (sz--) {
8173
                        *(out++) = *(in++) ^ *(tmp++);
8174
                        aes->left--;
8175
                    }
8176
                }
8177
            }
8178
        #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
8179
            return 0;
8180
    #elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
8181
            {
8182
                word32 numBlocks;
8183
                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
8184
                /* consume any unused bytes left in aes->tmp */
8185
                while ((aes->left != 0) && (sz != 0)) {
8186
                   *(out++) = *(in++) ^ *(tmp++);
8187
                   aes->left--;
8188
                   sz--;
8189
                }
8190
8191
                /* do as many block size ops as possible */
8192
                numBlocks = sz / WC_AES_BLOCK_SIZE;
8193
                if (numBlocks > 0) {
8194
                    AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
8195
                        (byte*)aes->key, aes->rounds, (byte*)aes->reg);
8196
8197
                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
8198
                    out += numBlocks * WC_AES_BLOCK_SIZE;
8199
                    in  += numBlocks * WC_AES_BLOCK_SIZE;
8200
                }
8201
8202
                /* handle non block size remaining */
8203
                if (sz) {
8204
                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
8205
                                                      0, 0, 0, 0, 0, 0, 0, 0 };
8206
8207
                    AES_CTR_encrypt(zeros, (byte*)aes->tmp,
8208
                        WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
8209
                        (byte*)aes->reg);
8210
8211
                    aes->left = WC_AES_BLOCK_SIZE;
8212
                    tmp = (byte*)aes->tmp;
8213
8214
                    while (sz--) {
8215
                        *(out++) = *(in++) ^ *(tmp++);
8216
                        aes->left--;
8217
                    }
8218
                }
8219
            }
8220
            return 0;
8221
    #else
8222
            VECTOR_REGISTERS_PUSH;
8223
8224
        #if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
8225
            if (aes->use_aesni && sz >= WC_AES_BLOCK_SIZE) {
8226
                word32 ctrBlocks = sz / WC_AES_BLOCK_SIZE;
8227
                word32 ctrBytes  = ctrBlocks * WC_AES_BLOCK_SIZE;
8228
                AesCtrEncryptBlocks(in, out, ctrBytes, (byte*)aes->key,
8229
                                    (int)aes->rounds, (byte*)aes->reg);
8230
                in  += ctrBytes;
8231
                out += ctrBytes;
8232
                sz  -= ctrBytes;
8233
                aes->left = 0;
8234
            }
8235
        #endif
8236
8237
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
8238
            !defined(XTRANSFORM_AESCTRBLOCK)
8239
            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
8240
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
8241
                byte* counter = (byte*)aes->reg;
8242
                byte* c = out;
8243
                while (blocks--) {
8244
                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
8245
                    c += WC_AES_BLOCK_SIZE;
8246
                    IncrementAesCounter(counter);
8247
                }
8248
8249
                /* reset number of blocks and then do encryption */
8250
                blocks = sz / WC_AES_BLOCK_SIZE;
8251
                ret = wc_AesEcbEncrypt(aes, out, out,
8252
                                       WC_AES_BLOCK_SIZE * blocks);
8253
                if (ret == 0) {
8254
                    xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
8255
                    in += WC_AES_BLOCK_SIZE * blocks;
8256
                    out += WC_AES_BLOCK_SIZE * blocks;
8257
                    sz -= blocks * WC_AES_BLOCK_SIZE;
8258
                }
8259
                else {
8260
                    ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
8261
                }
8262
            }
8263
            else
8264
        #endif
8265
            {
8266
            #ifdef WOLFSSL_CHECK_MEM_ZERO
8267
                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
8268
                    WC_AES_BLOCK_SIZE);
8269
            #endif
8270
                /* do as many block size ops as possible */
8271
                while (sz >= WC_AES_BLOCK_SIZE) {
8272
                #ifdef XTRANSFORM_AESCTRBLOCK
8273
                    ret = XTRANSFORM_AESCTRBLOCK(aes, out, in);
8274
                    if (ret != 0)
8275
                        break;
8276
                #else
8277
                    ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
8278
                                                    scratch,
8279
                                                    &did_prefetches);
8280
                    if (ret != 0)
8281
                        break;
8282
                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
8283
                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
8284
                #endif
8285
                    IncrementAesCounter((byte*)aes->reg);
8286
8287
                    out += WC_AES_BLOCK_SIZE;
8288
                    in  += WC_AES_BLOCK_SIZE;
8289
                    sz  -= WC_AES_BLOCK_SIZE;
8290
                    aes->left = 0;
8291
                }
8292
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
8293
            }
8294
8295
            /* handle non block size remaining and store unused byte count in left */
8296
            if ((ret == 0) && sz) {
8297
                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
8298
                                                (byte*)aes->tmp,
8299
                                                &did_prefetches);
8300
                if (ret == 0) {
8301
                    IncrementAesCounter((byte*)aes->reg);
8302
                    aes->left = WC_AES_BLOCK_SIZE - sz;
8303
                    xorbufout(out, in, aes->tmp, sz);
8304
                }
8305
            }
8306
8307
            if (ret < 0)
8308
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
8309
8310
        #ifdef WOLFSSL_CHECK_MEM_ZERO
8311
            wc_MemZero_Check(scratch, WC_AES_BLOCK_SIZE);
8312
        #endif
8313
8314
            VECTOR_REGISTERS_POP;
8315
8316
            return ret;
8317
    #endif
8318
        }
8319
8320
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
8321
                                        const byte* iv, int dir)
8322
        {
8323
            if (aes == NULL) {
8324
                return BAD_FUNC_ARG;
8325
            }
8326
            if (len > sizeof(aes->key)) {
8327
                return BAD_FUNC_ARG;
8328
            }
8329
8330
            return wc_AesSetKey(aes, key, len, iv, dir);
8331
        }
8332
8333
    #endif /* NEED_AES_CTR_SOFT */
8334
8335
#endif /* WOLFSSL_AES_COUNTER */
8336
8337
#ifndef WC_AES_HAVE_PREFETCH_ARG
8338
    #ifndef AesEncrypt_preFetchOpt
8339
        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
8340
            wc_AesEncrypt(aes, inBlock, outBlock)
8341
    #endif
8342
    #ifndef AesDecrypt_preFetchOpt
8343
        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
8344
            wc_AesDecrypt(aes, inBlock, outBlock)
8345
    #endif
8346
#endif
8347
8348
/*
8349
 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
8350
 * of two parts in order:
8351
 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
8352
 *      to the implicit IV.
8353
 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
8354
 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
8355
 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
8356
 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
8357
 * block counter during the encryption.
8358
 */
8359
8360
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
8361
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
8362
0
{
8363
0
    int i;
8364
0
    for (i = (int)ctrSz - 1; i >= 0; i--) {
8365
0
        if (++ctr[i])
8366
0
            break;
8367
0
    }
8368
0
}
8369
#endif /* HAVE_AESGCM || HAVE_AESCCM */
8370
8371
8372
#ifdef HAVE_AESGCM
8373
8374
#ifdef WOLFSSL_AESGCM_STREAM
8375
    /* Access initialization counter data. */
8376
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
8377
    /* Access counter data. */
8378
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
8379
    /* Access tag data. */
8380
    #define AES_TAG(aes)            ((aes)->streamData + 2 * WC_AES_BLOCK_SIZE)
8381
    /* Access last GHASH block. */
8382
    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE)
8383
    /* Access last encrypted block. */
8384
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
8385
8386
    #define GHASH_ONE_BLOCK     GHASH_ONE_BLOCK_SW
8387
#endif
8388
8389
#if defined(HAVE_COLDFIRE_SEC)
8390
    #error "Coldfire SEC doesn't currently support AES-GCM mode"
8391
8392
#endif
8393
8394
#if !defined(NO_INLINE) && defined(__GNUC__) && !defined(__cplusplus)
8395
/* Inline for callers here in aes.c, but a callable local function for outside
8396
 * callers.  Don't use WC_INLINE unconditionally, because we can't count on
8397
 * correct behavior beyond gcc/clang, and we don't want the the WC_MAYBE_UNUSED
8398
 * attribute in NO_INLINE builds.
8399
 */
8400
WC_INLINE
8401
#endif
8402
0
int wc_local_AesGcmCheckTagSz(word32 authTagSz) {
8403
#ifdef WC_AES_GCM_ALLOW_NONSTANDARD_TAG_LENGTH
8404
    #ifdef HAVE_FIPS
8405
        #error WC_AES_GCM_ALLOW_NONSTANDARD_TAG_LENGTH not allowed with FIPS 140.
8406
    #endif
8407
    wc_static_assert(WOLFSSL_MIN_AUTH_TAG_SZ >= 4);
8408
    if ((authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) ||
8409
        (authTagSz > WC_AES_BLOCK_SIZE))
8410
    {
8411
        WOLFSSL_MSG("AES-GCM unsupported authTagSz");
8412
        return BAD_FUNC_ARG;
8413
    }
8414
    else
8415
        return 0;
8416
#else
8417
    /* A switch is actually better for the optimizer than most hand-rolled
8418
     * equivalents, because it hands the compiler the exact value set and lets
8419
     * it pick the best lowering per WOLFSSL_MIN_AUTH_TAG_SZ configuration.
8420
     */
8421
0
    switch (authTagSz) {
8422
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 4
8423
    case 4:
8424
#endif
8425
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 8
8426
    case 8:
8427
#endif
8428
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 12
8429
0
    case 12:
8430
0
#endif
8431
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 13
8432
0
    case 13:
8433
0
#endif
8434
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 14
8435
0
    case 14:
8436
0
#endif
8437
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 15
8438
0
    case 15:
8439
0
#endif
8440
0
#if WOLFSSL_MIN_AUTH_TAG_SZ <= 16
8441
0
    case 16:
8442
0
#endif
8443
0
        return 0;
8444
0
    default:
8445
0
        WOLFSSL_MSG("AES-GCM unsupported authTagSz");
8446
0
        return BAD_FUNC_ARG;
8447
0
    }
8448
0
#endif
8449
0
}
8450
8451
#if defined(WOLFSSL_AFALG)
8452
    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
8453
8454
#elif defined(WOLFSSL_KCAPI_AES)
8455
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
8456
8457
#elif defined(WOLFSSL_DEVCRYPTO_AES)
8458
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
8459
8460
#else /* software + AESNI implementation */
8461
8462
#if !defined(FREESCALE_LTC_AES_GCM)
8463
#if (!(defined(__aarch64__) && defined(WOLFSSL_ARMASM))) || \
8464
    defined(WOLFSSL_AESGCM_STREAM)
8465
static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
8466
0
{
8467
0
    int i;
8468
8469
    /* in network byte order so start at end and work back */
8470
0
    for (i = WC_AES_BLOCK_SIZE - 1; i >= WC_AES_BLOCK_SIZE - CTR_SZ; i--) {
8471
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
8472
0
            return;
8473
0
    }
8474
0
}
8475
#endif
8476
#endif /* !FREESCALE_LTC_AES_GCM */
8477
8478
/* Alignment for the GHASH tag held on the stack.
8479
 *
8480
 * The tag is a byte array to the C code, but the assembly implementations
8481
 * transfer it a machine word at a time - the AArch32 and Thumb-2
8482
 * GCM_gmult_len write it back with stm, which faults on an unaligned address
8483
 * whatever SCTLR.A says - so it has to be aligned to the word size of the
8484
 * platform rather than left at the natural alignment of a byte array. */
8485
#ifdef WC_64BIT_CPU
8486
0
    #define ALIGN_GCM_TAG   ALIGN8
8487
#else
8488
    #define ALIGN_GCM_TAG   ALIGN4
8489
#endif
8490
8491
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8492
8493
static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
8494
0
{
8495
    /* Multiply the sz by 8 */
8496
0
    word32 szHi = (sz >> (8*sizeof(sz) - 3));
8497
0
    sz <<= 3;
8498
8499
    /* copy over the words of the sz into the destination buffer */
8500
0
    buf[0] = (byte)(szHi >> 24);
8501
0
    buf[1] = (byte)(szHi >> 16);
8502
0
    buf[2] = (byte)(szHi >>  8);
8503
0
    buf[3] = (byte)szHi;
8504
0
    buf[4] = (byte)(sz >> 24);
8505
0
    buf[5] = (byte)(sz >> 16);
8506
0
    buf[6] = (byte)(sz >>  8);
8507
0
    buf[7] = (byte)sz;
8508
0
}
8509
8510
8511
static WC_INLINE void RIGHTSHIFTX(byte* x)
8512
0
{
8513
0
    int i;
8514
0
    int carryIn = 0;
8515
0
    volatile byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
8516
8517
0
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
8518
0
        int carryOut = (x[i] & 0x01) << 7;
8519
0
        x[i] = (byte) ((x[i] >> 1) | carryIn);
8520
0
        carryIn = carryOut;
8521
0
    }
8522
0
    x[0] ^= borrow;
8523
0
}
8524
8525
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
8526
8527
8528
#ifdef GCM_TABLE
8529
8530
void GenerateM0(Gcm* gcm)
8531
{
8532
    int i, j;
8533
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
8534
8535
    XMEMCPY(m[128], gcm->H, WC_AES_BLOCK_SIZE);
8536
8537
    for (i = 64; i > 0; i /= 2) {
8538
        XMEMCPY(m[i], m[i*2], WC_AES_BLOCK_SIZE);
8539
        RIGHTSHIFTX(m[i]);
8540
    }
8541
8542
    for (i = 2; i < 256; i *= 2) {
8543
        for (j = 1; j < i; j++) {
8544
            XMEMCPY(m[i+j], m[i], WC_AES_BLOCK_SIZE);
8545
            xorbuf(m[i+j], m[j], WC_AES_BLOCK_SIZE);
8546
        }
8547
    }
8548
8549
#if defined(WOLFSSL_PPC64_ASM)
8550
    for (i = 1; i < 256; i++) {
8551
        word64* m64 = (word64*)gcm->M0[i];
8552
        m64[0] = ByteReverseWord64(m64[0]);
8553
        m64[1] = ByteReverseWord64(m64[1]);
8554
    }
8555
#endif
8556
    XMEMSET(m[0], 0, WC_AES_BLOCK_SIZE);
8557
}
8558
8559
#elif defined(GCM_TABLE_4BIT)
8560
8561
#if !defined(WC_16BIT_CPU)
8562
static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
8563
0
{
8564
0
    int i;
8565
0
    for (i = 15; i > 0; i--)
8566
0
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
8567
0
    r8[0] = (byte)(z8[0] >> 4);
8568
0
}
8569
#endif
8570
8571
void GenerateM0(Gcm* gcm)
8572
0
{
8573
0
#if !defined(WC_16BIT_CPU)
8574
0
    int i;
8575
0
#endif
8576
0
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
8577
8578
    /* 0 times -> 0x0 */
8579
0
    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
8580
    /* 1 times -> 0x8 */
8581
0
    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
8582
    /* 2 times -> 0x4 */
8583
0
    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
8584
0
    RIGHTSHIFTX(m[0x4]);
8585
    /* 4 times -> 0x2 */
8586
0
    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
8587
0
    RIGHTSHIFTX(m[0x2]);
8588
    /* 8 times -> 0x1 */
8589
0
    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
8590
0
    RIGHTSHIFTX(m[0x1]);
8591
8592
    /* 0x3 */
8593
0
    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
8594
0
    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
8595
8596
    /* 0x5 -> 0x7 */
8597
0
    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
8598
0
    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
8599
0
    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
8600
0
    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
8601
0
    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
8602
0
    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
8603
8604
    /* 0x9 -> 0xf */
8605
0
    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
8606
0
    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
8607
0
    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
8608
0
    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
8609
0
    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
8610
0
    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
8611
0
    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
8612
0
    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
8613
0
    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
8614
0
    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
8615
0
    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
8616
0
    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
8617
0
    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
8618
0
    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
8619
8620
0
#if !defined(WC_16BIT_CPU)
8621
0
    for (i = 0; i < 16; i++) {
8622
0
        Shift4_M0(m[16+i], m[i]);
8623
0
    }
8624
0
#endif
8625
8626
/* The 32-bit base assembly GHASH (GCM_gmult_len) consumes the M0 table with
8627
 * byte-reversed words, so apply that whenever it is compiled in: a no-crypto
8628
 * build, or a crypto build that keeps the base fallback for run-time selection
8629
 * (WOLFSSL_ARM32_AES_DISPATCH).  On AArch64 only the no-crypto build uses the
8630
 * M0-table GHASH (the crypto/NEON path hashes H directly). */
8631
#if defined(WOLFSSL_ARMASM) && (defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
8632
    defined(WOLFSSL_ARM32_AES_DISPATCH))
8633
    for (i = 0; i < 32; i++) {
8634
    #if !defined(__aarch64__)
8635
        word32* m32 = (word32*)gcm->M0[i];
8636
        m32[0] = ByteReverseWord32(m32[0]);
8637
        m32[1] = ByteReverseWord32(m32[1]);
8638
        m32[2] = ByteReverseWord32(m32[2]);
8639
        m32[3] = ByteReverseWord32(m32[3]);
8640
    #else
8641
        word64* m64 = (word64*)gcm->M0[i];
8642
        m64[0] = ByteReverseWord64(m64[0]);
8643
        m64[1] = ByteReverseWord64(m64[1]);
8644
    #endif
8645
    }
8646
#endif
8647
0
}
8648
8649
#endif /* GCM_TABLE */
8650
8651
#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
8652
    #define HAVE_INTEL_AVX1
8653
    #ifndef NO_AVX2_SUPPORT
8654
        #define HAVE_INTEL_AVX2
8655
    #endif
8656
    #ifdef WOLFSSL_X86_64_BUILD
8657
        #ifndef NO_VAES_SUPPORT
8658
            #define HAVE_INTEL_VAES
8659
        #endif
8660
        #ifndef NO_AVX512_SUPPORT
8661
            #define HAVE_INTEL_AVX512
8662
        #endif
8663
    #endif
8664
#endif
8665
8666
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \
8667
    defined(WC_C_DYNAMIC_FALLBACK)
8668
void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m)
8669
                           XASM_LINK("GCM_generate_m0_aesni");
8670
#ifdef HAVE_INTEL_AVX1
8671
void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m)
8672
                          XASM_LINK("GCM_generate_m0_avx1");
8673
#endif
8674
#ifdef HAVE_INTEL_AVX2
8675
void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
8676
                          XASM_LINK("GCM_generate_m0_avx2");
8677
#endif
8678
#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */
8679
8680
#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
8681
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) && defined(HAVE_AESGCM)
8682
/* Reflect the bits of each byte of a hash subkey, in place.
8683
 *
8684
 * AES_GCM_set_key_AARCH32 produces H in reflected form - what the PMULL bulk
8685
 * assembly wants - but the portable GHASH used for AES-GCM streaming needs
8686
 * plain H.  So the stored aes->gcm.H is un-reflected once at key set, and each
8687
 * bulk assembly call reflects its own copy.  The operation is its own inverse,
8688
 * so the same function serves both directions.
8689
 *
8690
 * @param [in, out] h  Hash subkey to reflect.
8691
 */
8692
static WC_INLINE void GcmReflectH(byte* h)
8693
{
8694
    int i;
8695
    int j;
8696
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
8697
        byte b = h[i];
8698
        byte r = 0;
8699
        for (j = 0; j < 8; j++) {
8700
            r = (byte)((r << 1) | (b & 1));
8701
            b >>= 1;
8702
        }
8703
        h[i] = r;
8704
    }
8705
}
8706
#endif
8707
8708
/* Software AES - GCM SetKey */
8709
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
8710
0
{
8711
0
    int  ret;
8712
0
    byte iv[WC_AES_BLOCK_SIZE];
8713
8714
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
8715
        byte   local[32];
8716
        word32 localSz = 32;
8717
8718
        if (len == (16 + WC_CAAM_BLOB_SZ) ||
8719
          len == (24 + WC_CAAM_BLOB_SZ) ||
8720
          len == (32 + WC_CAAM_BLOB_SZ)) {
8721
            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
8722
                 return BAD_FUNC_ARG;
8723
            }
8724
8725
            /* set local values */
8726
            key = local;
8727
            len = localSz;
8728
        }
8729
    #endif
8730
8731
0
    if (!((len == 16) || (len == 24) || (len == 32)))
8732
0
        return BAD_FUNC_ARG;
8733
8734
0
    if (aes == NULL || key == NULL) {
8735
#ifdef WOLFSSL_IMX6_CAAM_BLOB
8736
#ifdef WOLFSSL_CHECK_MEM_ZERO
8737
        wc_MemZero_Add("wc_AesGcmSetKey local", local, sizeof(local));
8738
#endif
8739
        ForceZero(local, sizeof(local));
8740
#ifdef WOLFSSL_CHECK_MEM_ZERO
8741
        wc_MemZero_Check(local, sizeof(local));
8742
#endif
8743
#endif
8744
0
        return BAD_FUNC_ARG;
8745
0
    }
8746
#ifdef OPENSSL_EXTRA
8747
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
8748
    aes->gcm.aadLen = 0;
8749
#endif
8750
0
    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
8751
0
    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
8752
#ifdef WOLF_CRYPTO_CB_ONLY_AES
8753
    /* do key scheduling so that ECB-only devices can still do GCM */
8754
    if (ret == 0) {
8755
        ret = wc_CryptoCb_AesEcbEncrypt(aes, aes->gcm.H, iv, WC_AES_BLOCK_SIZE);
8756
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8757
        if (ret == 0)
8758
            GenerateM0(&aes->gcm);
8759
#endif
8760
    }
8761
    return ret;
8762
#endif
8763
#ifdef WOLFSSL_AESGCM_STREAM
8764
    aes->gcmKeySet = 1;
8765
#endif
8766
    #if defined(WOLFSSL_SECO_CAAM)
8767
        if (aes->devId == WOLFSSL_SECO_DEVID) {
8768
            return ret;
8769
        }
8770
    #endif /* WOLFSSL_SECO_CAAM */
8771
8772
    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
8773
        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
8774
        return ret;
8775
    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
8776
8777
/* GCM setup needs one AES block encrypt of the all-zero IV to generate
8778
 * the hash subkey H. STM32_CRYPTO stores only the raw key (no expanded
8779
 * key schedule), so the ARMASM AES_ECB_encrypt helpers used here cannot
8780
 * be used. Excluding STM32_CRYPTO from this block falls back to the
8781
 * non-ARMASM wc_AesEncrypt implementation, which on STM32 routes to
8782
 * CRYP. */
8783
#if defined(WOLFSSL_ARMASM) && !defined(STM32_CRYPTO)
8784
    if (ret == 0) {
8785
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
8786
    #if !defined(__aarch64__)
8787
      #ifdef WOLFSSL_ARM32_AES_DISPATCH
8788
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
8789
            AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H,
8790
                aes->rounds);
8791
            /* Undo the reflection the assembly applied, so the stored H is
8792
             * plain H for the portable streaming GHASH and for GenerateM0
8793
             * below.  Each bulk assembly call reflects its own copy. */
8794
            GcmReflectH(aes->gcm.H);
8795
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8796
            GenerateM0(&aes->gcm);
8797
        #endif
8798
        }
8799
        else
8800
      #else
8801
        AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
8802
        /* Undo the reflection the assembly applied, so the stored H is plain
8803
         * H for the portable streaming GHASH and for GenerateM0 below.  Each
8804
         * bulk assembly call reflects its own copy. */
8805
        GcmReflectH(aes->gcm.H);
8806
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8807
        GenerateM0(&aes->gcm);
8808
        #endif
8809
      #endif /* WOLFSSL_ARM32_AES_DISPATCH */
8810
    #else
8811
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
8812
            AES_GCM_set_key_AARCH64(iv, (byte*)aes->key, aes->gcm.H,
8813
                aes->rounds);
8814
        }
8815
        else
8816
    #endif /* !__aarch64__ */
8817
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
8818
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
8819
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
8820
        {
8821
            AES_ECB_encrypt_NEON(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
8822
                (const unsigned char*)aes->key, aes->rounds);
8823
        }
8824
#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
8825
      defined(WOLFSSL_ARM32_AES_DISPATCH)
8826
        {
8827
            AES_ECB_encrypt(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
8828
                (const unsigned char*)aes->key, aes->rounds);
8829
        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8830
            GenerateM0(&aes->gcm);
8831
        #endif /* GCM_TABLE */
8832
        }
8833
#endif
8834
    }
8835
#else
8836
0
#if !defined(FREESCALE_LTC_AES_GCM) && !defined(WOLFSSL_PSOC6_CRYPTO)
8837
8838
8839
#ifdef WOLF_CRYPTO_CB_AES_SETKEY
8840
    if ((ret == 0) && (aes->devId != INVALID_DEVID && aes->devCtx != NULL)) {
8841
        /* SE owns key - skip H and M table generation */
8842
    }
8843
    else
8844
#endif
8845
0
    if (ret == 0) {
8846
0
        VECTOR_REGISTERS_PUSH;
8847
8848
#if defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM) && \
8849
    !defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
8850
        /* Compute H reflected for the carryless-multiply GHASH; the scalar
8851
         * GHASH uses no M0 table.  (Vector crypto supersedes scalar and needs H
8852
         * unreflected, so it falls through to the generic E(0) path below.) */
8853
        AES_GCM_set_key_RISCV64(iv, (byte*)aes->key, aes->gcm.H,
8854
            (int)aes->rounds);
8855
#else
8856
        /* Generate H = AES_Encrypt(key, 0^128) */
8857
0
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
8858
8859
0
        if (ret == 0) {
8860
0
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
8861
    #if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT)
8862
            if (aes->use_aesni) {
8863
        #if defined(WC_C_DYNAMIC_FALLBACK)
8864
            #ifdef HAVE_INTEL_AVX2
8865
                if (IS_INTEL_AVX2(intel_flags)) {
8866
                    GCM_generate_m0_avx2(aes->gcm.H,
8867
                        (byte*)aes->gcm.M0);
8868
                }
8869
                else
8870
            #endif
8871
            #if defined(HAVE_INTEL_AVX1)
8872
                if (IS_INTEL_AVX1(intel_flags)) {
8873
                    GCM_generate_m0_avx1(aes->gcm.H,
8874
                        (byte*)aes->gcm.M0);
8875
                }
8876
                else
8877
            #endif
8878
                {
8879
                    GCM_generate_m0_aesni(aes->gcm.H,
8880
                        (byte*)aes->gcm.M0);
8881
                }
8882
        #endif /* WC_C_DYNAMIC_FALLBACK */
8883
            }
8884
            else
8885
    #endif /* AESNI */
8886
0
            {
8887
0
                GenerateM0(&aes->gcm);
8888
0
            }
8889
0
#endif /* GCM_TABLE || GCM_TABLE_4BIT */
8890
0
        }
8891
0
#endif /* WOLFSSL_RISCV_SCALAR_CRYPTO_ASM */
8892
8893
0
        VECTOR_REGISTERS_POP;
8894
0
    }
8895
0
#endif /* !FREESCALE_LTC_AES_GCM && !WOLFSSL_PSOC6_CRYPTO */
8896
0
#endif
8897
8898
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
8899
    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
8900
#endif
8901
8902
#ifdef WOLF_CRYPTO_CB
8903
    if (aes->devId != INVALID_DEVID) {
8904
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
8905
        if (aes->devCtx != NULL) {
8906
            /* SE owns key - don't copy to devKey */
8907
        }
8908
        else
8909
    #endif
8910
        {
8911
            XMEMCPY(aes->devKey, key, len);
8912
        }
8913
    }
8914
#endif
8915
8916
#ifdef WOLFSSL_IMX6_CAAM_BLOB
8917
#ifdef WOLFSSL_CHECK_MEM_ZERO
8918
    wc_MemZero_Add("wc_AesGcmSetKey local", local, sizeof(local));
8919
#endif
8920
    ForceZero(local, sizeof(local));
8921
#ifdef WOLFSSL_CHECK_MEM_ZERO
8922
    wc_MemZero_Check(local, sizeof(local));
8923
#endif
8924
#endif
8925
0
    return ret;
8926
0
}
8927
8928
8929
#ifdef WOLFSSL_AESNI
8930
8931
void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
8932
                     const unsigned char* addt, const unsigned char* ivec,
8933
                     unsigned char *tag, word32 nbytes,
8934
                     word32 abytes, word32 ibytes,
8935
                     word32 tbytes, const unsigned char* key, int nr)
8936
                     XASM_LINK("AES_GCM_encrypt_aesni");
8937
#ifdef HAVE_INTEL_AVX1
8938
void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
8939
                          const unsigned char* addt, const unsigned char* ivec,
8940
                          unsigned char *tag, word32 nbytes,
8941
                          word32 abytes, word32 ibytes,
8942
                          word32 tbytes, const unsigned char* key,
8943
                          int nr)
8944
                          XASM_LINK("AES_GCM_encrypt_avx1");
8945
#ifdef HAVE_INTEL_AVX2
8946
void AES_GCM_encrypt_avx2(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_avx2");
8953
#ifdef HAVE_INTEL_AVX512
8954
void AES_GCM_encrypt_avx512(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_avx512");
8961
#endif
8962
#ifdef HAVE_INTEL_VAES
8963
void AES_GCM_encrypt_vaes(const unsigned char *in, unsigned char *out,
8964
                          const unsigned char* addt, const unsigned char* ivec,
8965
                          unsigned char *tag, word32 nbytes,
8966
                          word32 abytes, word32 ibytes,
8967
                          word32 tbytes, const unsigned char* key,
8968
                          int nr)
8969
                          XASM_LINK("AES_GCM_encrypt_vaes");
8970
#endif
8971
#endif /* HAVE_INTEL_AVX2 */
8972
#endif /* HAVE_INTEL_AVX1 */
8973
8974
#ifdef HAVE_AES_DECRYPT
8975
void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
8976
                     const unsigned char* addt, const unsigned char* ivec,
8977
                     const unsigned char *tag, word32 nbytes, word32 abytes,
8978
                     word32 ibytes, word32 tbytes, const unsigned char* key,
8979
                     int nr, int* res)
8980
                     XASM_LINK("AES_GCM_decrypt_aesni");
8981
#ifdef HAVE_INTEL_AVX1
8982
void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
8983
                          const unsigned char* addt, const unsigned char* ivec,
8984
                          const unsigned char *tag, word32 nbytes,
8985
                          word32 abytes, word32 ibytes, word32 tbytes,
8986
                          const unsigned char* key, int nr, int* res)
8987
                          XASM_LINK("AES_GCM_decrypt_avx1");
8988
#ifdef HAVE_INTEL_AVX2
8989
void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
8990
                          const unsigned char* addt, const unsigned char* ivec,
8991
                          const unsigned char *tag, word32 nbytes,
8992
                          word32 abytes, word32 ibytes, word32 tbytes,
8993
                          const unsigned char* key, int nr, int* res)
8994
                          XASM_LINK("AES_GCM_decrypt_avx2");
8995
#ifdef HAVE_INTEL_AVX512
8996
void AES_GCM_decrypt_avx512(const unsigned char *in, unsigned char *out,
8997
                          const unsigned char* addt, const unsigned char* ivec,
8998
                          const unsigned char *tag, word32 nbytes,
8999
                          word32 abytes, word32 ibytes, word32 tbytes,
9000
                          const unsigned char* key, int nr, int* res)
9001
                          XASM_LINK("AES_GCM_decrypt_avx512");
9002
#endif
9003
#ifdef HAVE_INTEL_VAES
9004
void AES_GCM_decrypt_vaes(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_vaes");
9010
#endif
9011
#endif /* HAVE_INTEL_AVX2 */
9012
#endif /* HAVE_INTEL_AVX1 */
9013
#endif /* HAVE_AES_DECRYPT */
9014
9015
#endif /* WOLFSSL_AESNI */
9016
9017
#if defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM) && defined(HAVE_AESGCM) && \
9018
    !defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
9019
/* GHASH using the RISC-V scalar carryless-multiply (Zbc) helper.  Vector crypto
9020
 * supersedes it (fused vghsh/vgmul), so this scalar path yields when both are on.
9021
 *
9022
 * H is stored reflected by AES_GCM_set_key_RISCV64, which is the form
9023
 * GHASH_RISCV64 expects.  GHASH_RISCV64(x, h, in, blocks) computes, for each
9024
 * 16-byte block, x = (x ^ block) * H in GF(2^128) (reflecting x in/out so the
9025
 * caller sees the standard domain).  A single padded/length block is therefore
9026
 * just GHASH_RISCV64(x, h, block, 1) - no software GMULT or M0 table is needed.
9027
 *
9028
 * @param [in]  gcm  GCM object.
9029
 * @param [in]  a    Additional Authentication Data (AAD).
9030
 * @param [in]  aSz  Length of AAD in bytes.
9031
 * @param [in]  c    Cipher text.
9032
 * @param [in]  cSz  Length of cipher text in bytes.
9033
 * @param [out] s    Hash result.
9034
 * @param [in]  sSz  Number of bytes to output.
9035
 */
9036
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9037
    word32 cSz, byte* s, word32 sSz)
9038
{
9039
    ALIGN8 byte x[WC_AES_BLOCK_SIZE];
9040
    ALIGN8 byte scratch[WC_AES_BLOCK_SIZE];
9041
    word32 blocks, partial;
9042
    byte* h = gcm->H;
9043
9044
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9045
9046
    /* Hash in A, the Additional Authentication Data */
9047
    if (aSz != 0 && a != NULL) {
9048
        blocks = aSz / WC_AES_BLOCK_SIZE;
9049
        partial = aSz % WC_AES_BLOCK_SIZE;
9050
        if (blocks > 0) {
9051
            GHASH_RISCV64(x, h, a, blocks);
9052
            a += blocks * WC_AES_BLOCK_SIZE;
9053
        }
9054
        if (partial != 0) {
9055
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9056
            XMEMCPY(scratch, a, partial);
9057
            GHASH_RISCV64(x, h, scratch, 1);
9058
        }
9059
    }
9060
9061
    /* Hash in C, the Ciphertext */
9062
    if (cSz != 0 && c != NULL) {
9063
        blocks = cSz / WC_AES_BLOCK_SIZE;
9064
        partial = cSz % WC_AES_BLOCK_SIZE;
9065
        if (blocks > 0) {
9066
            GHASH_RISCV64(x, h, c, blocks);
9067
            c += blocks * WC_AES_BLOCK_SIZE;
9068
        }
9069
        if (partial != 0) {
9070
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9071
            XMEMCPY(scratch, c, partial);
9072
            GHASH_RISCV64(x, h, scratch, 1);
9073
        }
9074
    }
9075
9076
    /* Hash in the lengths of A and C in bits */
9077
    FlattenSzInBits(&scratch[0], aSz);
9078
    FlattenSzInBits(&scratch[8], cSz);
9079
    GHASH_RISCV64(x, h, scratch, 1);
9080
9081
    /* Copy the result into s. */
9082
    XMEMCPY(s, x, sSz);
9083
}
9084
9085
#ifdef WOLFSSL_AESGCM_STREAM
9086
/* No extra initialization for the carryless-multiply implementation.
9087
 *
9088
 * @param [in] aes  AES GCM object.
9089
 */
9090
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9091
9092
/* GHASH one block of data into the streaming tag.
9093
 *
9094
 * x = (tag ^ block) * H using the carryless-multiply helper (reflected H).
9095
 *
9096
 * @param [in, out] aes    AES GCM object.
9097
 * @param [in]      block  Block of AAD or cipher text.
9098
 */
9099
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
9100
    GHASH_RISCV64(AES_TAG(aes), (aes)->gcm.H, block, 1)
9101
#endif /* WOLFSSL_AESGCM_STREAM */
9102
9103
#define HAVE_GHASH
9104
#elif defined(GCM_SMALL)
9105
static void GMULT(byte* X, byte* Y)
9106
{
9107
    byte Z[WC_AES_BLOCK_SIZE];
9108
    byte V[WC_AES_BLOCK_SIZE];
9109
    int i, j;
9110
9111
    XMEMSET(Z, 0, WC_AES_BLOCK_SIZE);
9112
    XMEMCPY(V, X, WC_AES_BLOCK_SIZE);
9113
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++)
9114
    {
9115
        byte y = Y[i];
9116
        for (j = 0; j < 8; j++)
9117
        {
9118
            if (y & 0x80) {
9119
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
9120
            }
9121
9122
            RIGHTSHIFTX(V);
9123
            y = y << 1;
9124
        }
9125
    }
9126
    XMEMCPY(X, Z, WC_AES_BLOCK_SIZE);
9127
}
9128
9129
9130
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9131
    word32 cSz, byte* s, word32 sSz)
9132
{
9133
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
9134
    byte scratch[WC_AES_BLOCK_SIZE];
9135
    word32 blocks, partial;
9136
    byte* h;
9137
9138
    h = gcm->H;
9139
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9140
9141
    /* Hash in A, the Additional Authentication Data */
9142
    if (aSz != 0 && a != NULL) {
9143
        blocks = aSz / WC_AES_BLOCK_SIZE;
9144
        partial = aSz % WC_AES_BLOCK_SIZE;
9145
        while (blocks--) {
9146
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
9147
            GMULT(x, h);
9148
            a += WC_AES_BLOCK_SIZE;
9149
        }
9150
        if (partial != 0) {
9151
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9152
            XMEMCPY(scratch, a, partial);
9153
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9154
            GMULT(x, h);
9155
        }
9156
    }
9157
9158
    /* Hash in C, the Ciphertext */
9159
    if (cSz != 0 && c != NULL) {
9160
        blocks = cSz / WC_AES_BLOCK_SIZE;
9161
        partial = cSz % WC_AES_BLOCK_SIZE;
9162
        while (blocks--) {
9163
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
9164
            GMULT(x, h);
9165
            c += WC_AES_BLOCK_SIZE;
9166
        }
9167
        if (partial != 0) {
9168
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9169
            XMEMCPY(scratch, c, partial);
9170
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9171
            GMULT(x, h);
9172
        }
9173
    }
9174
9175
    /* Hash in the lengths of A and C in bits */
9176
    FlattenSzInBits(&scratch[0], aSz);
9177
    FlattenSzInBits(&scratch[8], cSz);
9178
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9179
    GMULT(x, h);
9180
9181
    /* Copy the result into s. */
9182
    XMEMCPY(s, x, sSz);
9183
}
9184
9185
#ifdef WOLFSSL_AESGCM_STREAM
9186
/* No extra initialization for small implementation.
9187
 *
9188
 * @param [in] aes  AES GCM object.
9189
 */
9190
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9191
9192
/* GHASH one block of data..
9193
 *
9194
 * XOR block into tag and GMULT with H.
9195
 *
9196
 * @param [in, out] aes    AES GCM object.
9197
 * @param [in]      block  Block of AAD or cipher text.
9198
 */
9199
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9200
    do {                                                \
9201
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
9202
        GMULT(AES_TAG(aes), (aes)->gcm.H);              \
9203
    }                                                   \
9204
    while (0)
9205
#endif /* WOLFSSL_AESGCM_STREAM */
9206
9207
#if defined(WOLFSSL_ARMASM) && (!defined(__aarch64__) || \
9208
    defined(WOLFSSL_ARMASM_NO_NEON))
9209
/* Unused when the batch GHASH is done in assembly (32-bit ARMv8 crypto), which
9210
 * only pulls in the streaming software GMULT. */
9211
static WC_MAYBE_UNUSED void GCM_gmult_len_armasm_C(
9212
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
9213
{
9214
    byte Z[AES_BLOCK_SIZE];
9215
    byte V[AES_BLOCK_SIZE];
9216
    int i;
9217
    int j;
9218
9219
    while (len >= AES_BLOCK_SIZE) {
9220
        xorbuf(x, a, AES_BLOCK_SIZE);
9221
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
9222
        XMEMCPY(V, x, AES_BLOCK_SIZE);
9223
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
9224
            byte y = h[i];
9225
            for (j = 0; j < 8; j++) {
9226
                if (y & 0x80) {
9227
                    xorbuf(Z, V, AES_BLOCK_SIZE);
9228
                }
9229
                RIGHTSHIFTX(V);
9230
                y = y << 1;
9231
            }
9232
        }
9233
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
9234
        len -= AES_BLOCK_SIZE;
9235
        a += AES_BLOCK_SIZE;
9236
    }
9237
}
9238
9239
#define GCM_GMULT_LEN(gcm, x, a, len) \
9240
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
9241
#elif defined(WOLFSSL_ARMASM)
9242
#define GCM_GMULT_LEN(gcm, x, a, len) \
9243
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
9244
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
9245
static void GCM_gmult_len_armasm_C(
9246
    byte* x, const byte* h, const unsigned char* a, unsigned long len)
9247
{
9248
    byte Z[AES_BLOCK_SIZE];
9249
    byte V[AES_BLOCK_SIZE];
9250
    int i;
9251
    int j;
9252
9253
    while (len >= AES_BLOCK_SIZE) {
9254
        xorbuf(x, a, AES_BLOCK_SIZE);
9255
        XMEMSET(Z, 0, AES_BLOCK_SIZE);
9256
        XMEMCPY(V, x, AES_BLOCK_SIZE);
9257
        for (i = 0; i < AES_BLOCK_SIZE; i++) {
9258
            byte y = h[i];
9259
            for (j = 0; j < 8; j++) {
9260
                if (y & 0x80) {
9261
                    xorbuf(Z, V, AES_BLOCK_SIZE);
9262
                }
9263
                RIGHTSHIFTX(V);
9264
                y = y << 1;
9265
            }
9266
        }
9267
        XMEMCPY(x, Z, AES_BLOCK_SIZE);
9268
        len -= AES_BLOCK_SIZE;
9269
        a += AES_BLOCK_SIZE;
9270
    }
9271
}
9272
9273
#define GCM_GMULT_LEN(gcm, x, a, len) \
9274
    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
9275
#endif
9276
9277
#elif defined(GCM_TABLE)
9278
9279
/* ARM assembly.  A 32-bit run-time dispatch build is deliberately not here: the
9280
 * generated AArch32 GHASH is for the 4-bit table, not this 256-entry one.  It
9281
 * gets a C GCM_GMULT_LEN() built on GMULT() below. */
9282
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
9283
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
9284
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
9285
#define GCM_GMULT_LEN(gcm, x, a, len) \
9286
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
9287
#else
9288
#define GCM_GMULT_LEN(gcm, x, a, len) \
9289
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9290
#endif
9291
#elif defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
9292
#define GCM_GMULT_LEN(gcm, x, a, len) \
9293
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9294
#else
9295
ALIGN16 static const byte R[256][2] = {
9296
    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
9297
    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
9298
    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
9299
    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
9300
    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
9301
    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
9302
    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
9303
    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
9304
    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
9305
    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
9306
    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
9307
    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
9308
    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
9309
    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
9310
    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
9311
    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
9312
    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
9313
    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
9314
    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
9315
    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
9316
    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
9317
    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
9318
    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
9319
    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
9320
    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
9321
    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
9322
    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
9323
    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
9324
    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
9325
    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
9326
    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
9327
    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
9328
    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
9329
    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
9330
    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
9331
    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
9332
    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
9333
    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
9334
    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
9335
    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
9336
    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
9337
    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
9338
    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
9339
    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
9340
    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
9341
    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
9342
    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
9343
    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
9344
    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
9345
    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
9346
    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
9347
    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
9348
    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
9349
    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
9350
    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
9351
    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
9352
    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
9353
    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
9354
    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
9355
    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
9356
    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
9357
    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
9358
    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
9359
    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
9360
9361
9362
static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE])
9363
{
9364
#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
9365
    int i, j;
9366
    byte Z[WC_AES_BLOCK_SIZE];
9367
    byte a;
9368
9369
    XMEMSET(Z, 0, sizeof(Z));
9370
9371
    for (i = 15; i > 0; i--) {
9372
        xorbuf(Z, m[x[i]], WC_AES_BLOCK_SIZE);
9373
        a = Z[15];
9374
9375
        for (j = 15; j > 0; j--) {
9376
            Z[j] = Z[j-1];
9377
        }
9378
9379
        Z[0]  = R[a][0];
9380
        Z[1] ^= R[a][1];
9381
    }
9382
    xorbuf(Z, m[x[0]], WC_AES_BLOCK_SIZE);
9383
9384
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
9385
#elif defined(WC_32BIT_CPU)
9386
#ifndef WOLFSSL_USE_ALIGN
9387
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
9388
    byte a;
9389
    word32* pZ;
9390
    word32* pm;
9391
    word32* px = (word32*)(x);
9392
    int i;
9393
9394
    pZ = (word32*)(Z + 15 + 1);
9395
    pm = (word32*)(m[x[15]]);
9396
    pZ[0] = pm[0];
9397
    pZ[1] = pm[1];
9398
    pZ[2] = pm[2];
9399
    pZ[3] = pm[3];
9400
    a = Z[16 + 15];
9401
    Z[15]  = R[a][0];
9402
    Z[16] ^= R[a][1];
9403
    for (i = 14; i > 0; i--) {
9404
        pZ = (word32*)(Z + i + 1);
9405
        pm = (word32*)(m[x[i]]);
9406
        pZ[0] ^= pm[0];
9407
        pZ[1] ^= pm[1];
9408
        pZ[2] ^= pm[2];
9409
        pZ[3] ^= pm[3];
9410
        a = Z[16 + i];
9411
        Z[i]    = R[a][0];
9412
        Z[i+1] ^= R[a][1];
9413
    }
9414
    pZ = (word32*)(Z + 1);
9415
    pm = (word32*)(m[x[0]]);
9416
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
9417
    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
9418
#else
9419
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
9420
    byte a;
9421
    int i;
9422
9423
    XMEMCPY(Z + 16, m[x[15]], WC_AES_BLOCK_SIZE);
9424
    a = Z[16 + 15];
9425
    Z[15]  = R[a][0];
9426
    Z[16] ^= R[a][1];
9427
    for (i = 14; i > 0; i--) {
9428
        xorbuf(Z + i + 1, m[x[i]], WC_AES_BLOCK_SIZE);
9429
        a = Z[16 + i];
9430
        Z[i]    = R[a][0];
9431
        Z[i+1] ^= R[a][1];
9432
    }
9433
    xorbuf(Z + 1, m[x[0]], WC_AES_BLOCK_SIZE);
9434
    XMEMCPY(x, Z + 1, WC_AES_BLOCK_SIZE);
9435
#endif
9436
#else
9437
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
9438
    byte a;
9439
    word64* pZ;
9440
    word64* pm;
9441
    word64* px = (word64*)(x);
9442
    int i;
9443
9444
    pZ = (word64*)(Z + 15 + 1);
9445
    pm = (word64*)(m[x[15]]);
9446
    pZ[0] = pm[0];
9447
    pZ[1] = pm[1];
9448
    a = Z[16 + 15];
9449
    Z[15]  = R[a][0];
9450
    Z[16] ^= R[a][1];
9451
    for (i = 14; i > 0; i--) {
9452
        pZ = (word64*)(Z + i + 1);
9453
        pm = (word64*)(m[x[i]]);
9454
        pZ[0] ^= pm[0];
9455
        pZ[1] ^= pm[1];
9456
        a = Z[16 + i];
9457
        Z[i]    = R[a][0];
9458
        Z[i+1] ^= R[a][1];
9459
    }
9460
    pZ = (word64*)(Z + 1);
9461
    pm = (word64*)(m[x[0]]);
9462
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
9463
#endif
9464
}
9465
#endif
9466
9467
#if defined(WOLFSSL_ARM32_AES_DISPATCH) && !defined(GCM_GMULT_LEN)
9468
/* A 32-bit Arm run-time dispatch build reaches AES_GCM_encrypt_ASM() and
9469
 * AES_GCM_decrypt_ASM() on a CPU without the crypto extension, and they call
9470
 * GCM_GMULT_LEN() unconditionally.  The generated AArch32 GHASH assembly only
9471
 * handles the 4-bit table, so hash the blocks with the 256-entry GMULT(). */
9472
static void GCM_gmult_len_table_C(byte* x, byte m[256][WC_AES_BLOCK_SIZE],
9473
    const unsigned char* a, unsigned long len)
9474
{
9475
    while (len >= WC_AES_BLOCK_SIZE) {
9476
        xorbuf(x, a, WC_AES_BLOCK_SIZE);
9477
        GMULT(x, m);
9478
        len -= WC_AES_BLOCK_SIZE;
9479
        a += WC_AES_BLOCK_SIZE;
9480
    }
9481
}
9482
9483
#define GCM_GMULT_LEN(gcm, x, a, len) \
9484
    GCM_gmult_len_table_C(x, (gcm)->M0, a, len)
9485
#endif
9486
9487
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9488
    word32 cSz, byte* s, word32 sSz)
9489
{
9490
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
9491
    byte scratch[WC_AES_BLOCK_SIZE];
9492
    word32 blocks, partial;
9493
9494
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9495
9496
    /* Hash in A, the Additional Authentication Data */
9497
    if (aSz != 0 && a != NULL) {
9498
        blocks = aSz / WC_AES_BLOCK_SIZE;
9499
        partial = aSz % WC_AES_BLOCK_SIZE;
9500
    #ifdef GCM_GMULT_LEN
9501
        if (blocks > 0) {
9502
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
9503
            a += blocks * WC_AES_BLOCK_SIZE;
9504
        }
9505
        if (partial != 0) {
9506
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9507
            XMEMCPY(scratch, a, partial);
9508
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9509
        }
9510
    #else
9511
        while (blocks--) {
9512
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
9513
            GMULT(x, gcm->M0);
9514
            a += WC_AES_BLOCK_SIZE;
9515
        }
9516
        if (partial != 0) {
9517
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9518
            XMEMCPY(scratch, a, partial);
9519
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9520
            GMULT(x, gcm->M0);
9521
        }
9522
    #endif
9523
    }
9524
9525
    /* Hash in C, the Ciphertext */
9526
    if (cSz != 0 && c != NULL) {
9527
        blocks = cSz / WC_AES_BLOCK_SIZE;
9528
        partial = cSz % WC_AES_BLOCK_SIZE;
9529
    #ifdef GCM_GMULT_LEN
9530
        if (blocks > 0) {
9531
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
9532
            c += blocks * WC_AES_BLOCK_SIZE;
9533
        }
9534
        if (partial != 0) {
9535
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9536
            XMEMCPY(scratch, c, partial);
9537
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9538
        }
9539
    #else
9540
        while (blocks--) {
9541
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
9542
            GMULT(x, gcm->M0);
9543
            c += WC_AES_BLOCK_SIZE;
9544
        }
9545
        if (partial != 0) {
9546
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
9547
            XMEMCPY(scratch, c, partial);
9548
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9549
            GMULT(x, gcm->M0);
9550
        }
9551
    #endif
9552
    }
9553
9554
    /* Hash in the lengths of A and C in bits */
9555
    FlattenSzInBits(&scratch[0], aSz);
9556
    FlattenSzInBits(&scratch[8], cSz);
9557
#ifdef GCM_GMULT_LEN
9558
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
9559
#else
9560
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
9561
    GMULT(x, gcm->M0);
9562
#endif
9563
9564
    /* Copy the result into s. */
9565
    XMEMCPY(s, x, sSz);
9566
}
9567
9568
#ifdef WOLFSSL_AESGCM_STREAM
9569
/* No extra initialization for table implementation.
9570
 *
9571
 * @param [in] aes  AES GCM object.
9572
 */
9573
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
9574
9575
#ifdef GCM_GMULT_LEN
9576
/* GHASH one block of data.
9577
 *
9578
 * Defer to the length-based implementation with a length of one block - it
9579
 * does the XOR into the tag as well as the multiply.
9580
 *
9581
 * @param [in, out] aes    AES GCM object.
9582
 * @param [in]      block  Block of AAD or cipher text.
9583
 */
9584
#define GHASH_ONE_BLOCK_SW(aes, block)                                  \
9585
   GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
9586
#else
9587
/* GHASH one block of data..
9588
 *
9589
 * XOR block into tag and GMULT with H using pre-computed table.
9590
 *
9591
 * @param [in, out] aes    AES GCM object.
9592
 * @param [in]      block  Block of AAD or cipher text.
9593
 */
9594
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
9595
    do {                                                \
9596
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
9597
        GMULT(AES_TAG(aes), aes->gcm.M0);               \
9598
    }                                                   \
9599
    while (0)
9600
#endif
9601
#endif /* WOLFSSL_AESGCM_STREAM */
9602
/* end GCM_TABLE */
9603
#elif defined(GCM_TABLE_4BIT)
9604
/* ARM assembly */
9605
#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
9606
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
9607
    defined(WOLFSSL_ARM32_AES_DISPATCH))
9608
#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
9609
#define GCM_GMULT_LEN(gcm, x, a, len) \
9610
    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
9611
#define GMULT(x, m)                                                      \
9612
    GCM_gmult_NEON(x, (const byte**)m)
9613
#else
9614
#define GCM_GMULT_LEN(gcm, x, a, len) \
9615
    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
9616
#define GMULT(x, m)                                                      \
9617
    GCM_gmult(x, (const byte**)m)
9618
#endif
9619
9620
/* PPC64 assembly */
9621
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
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
9627
#else
9628
/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
9629
 *  R shifts right a reverse bit pair of bytes such that:
9630
 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
9631
 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
9632
 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
9633
 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
9634
 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
9635
 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
9636
 *  To calculate te rest, XOR result for each bit.
9637
 *   e.g. 6 = 4 ^ 2 => 48,c0
9638
 *
9639
 * Second half is same values rotated by 4-bits.
9640
 */
9641
#if defined(WC_16BIT_CPU)
9642
static const byte R[16][2] = {
9643
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
9644
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
9645
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
9646
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
9647
};
9648
#elif defined(BIG_ENDIAN_ORDER)
9649
static const word16 R[32] = {
9650
          0x0000,       0x1c20,       0x3840,       0x2460,
9651
          0x7080,       0x6ca0,       0x48c0,       0x54e0,
9652
          0xe100,       0xfd20,       0xd940,       0xc560,
9653
          0x9180,       0x8da0,       0xa9c0,       0xb5e0,
9654
9655
          0x0000,       0x01c2,       0x0384,       0x0246,
9656
          0x0708,       0x06ca,       0x048c,       0x054e,
9657
          0x0e10,       0x0fd2,       0x0d94,       0x0c56,
9658
          0x0918,       0x08da,       0x0a9c,       0x0b5e,
9659
};
9660
#else
9661
static const word16 R[32] = {
9662
          0x0000,       0x201c,       0x4038,       0x6024,
9663
          0x8070,       0xa06c,       0xc048,       0xe054,
9664
          0x00e1,       0x20fd,       0x40d9,       0x60c5,
9665
          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
9666
9667
          0x0000,       0xc201,       0x8403,       0x4602,
9668
          0x0807,       0xca06,       0x8c04,       0x4e05,
9669
          0x100e,       0xd20f,       0x940d,       0x560c,
9670
          0x1809,       0xda08,       0x9c0a,       0x5e0b,
9671
};
9672
#endif
9673
9674
/* Multiply in GF(2^128) defined by polynomial:
9675
 *   x^128 + x^7 + x^2 + x^1 + 1.
9676
 *
9677
 * H: hash key = encrypt(key, 0)
9678
 * x = x * H in field
9679
 *
9680
 * x: cumulative result
9681
 * m: 4-bit table
9682
 *    [0..15] * H
9683
 */
9684
#if defined(WC_16BIT_CPU)
9685
static void GMULT(byte *x, byte m[16][WC_AES_BLOCK_SIZE])
9686
{
9687
    int i, j, n;
9688
    byte Z[WC_AES_BLOCK_SIZE];
9689
    byte a;
9690
9691
    XMEMSET(Z, 0, sizeof(Z));
9692
9693
    for (i = 15; i >= 0; i--) {
9694
        for (n = 0; n < 2; n++) {
9695
            if (n == 0)
9696
                xorbuf(Z, m[x[i] & 0xf], WC_AES_BLOCK_SIZE);
9697
            else {
9698
                xorbuf(Z, m[x[i] >> 4], WC_AES_BLOCK_SIZE);
9699
                if (i == 0)
9700
                    break;
9701
            }
9702
            a = Z[15] & 0xf;
9703
9704
            for (j = 15; j > 0; j--)
9705
                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
9706
            Z[0] >>= 4;
9707
9708
            Z[0] ^= R[a][0];
9709
            Z[1] ^= R[a][1];
9710
        }
9711
    }
9712
9713
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
9714
}
9715
#elif defined(WC_32BIT_CPU) && defined(BIG_ENDIAN_ORDER)
9716
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9717
{
9718
    int i;
9719
    word32 z8[4] = {0, 0, 0, 0};
9720
    byte a;
9721
    word32* x8 = (word32*)x;
9722
    word32* m8;
9723
    byte xi;
9724
9725
    for (i = 15; i > 0; i--) {
9726
        xi = x[i];
9727
9728
        /* XOR in (msn * H) */
9729
        m8 = (word32*)m[xi & 0xf];
9730
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9731
9732
        /* Cache top byte for remainder calculations - lost in rotate. */
9733
        a = (byte)(z8[3] & 0xff);
9734
9735
        /* Rotate Z by 8-bits */
9736
        z8[3] = (z8[2] << 24) | (z8[3] >> 8);
9737
        z8[2] = (z8[1] << 24) | (z8[2] >> 8);
9738
        z8[1] = (z8[0] << 24) | (z8[1] >> 8);
9739
        z8[0] >>= 8;
9740
9741
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9742
        z8[0] ^= ((word32)R[16 + (a & 0xf)]) << 16;
9743
9744
        xi >>= 4;
9745
        /* XOR in next significant nibble (XORed with H) * remainder */
9746
        m8 = (word32*)m[xi];
9747
        a ^= (byte)(m8[3] >> 12) & 0xf;
9748
        a ^= (byte)((m8[3] << 4) & 0xf0);
9749
        z8[0] ^= ((word32)R[a >> 4]) << 16;
9750
9751
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9752
        m8 = (word32*)m[16 + xi];
9753
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
9754
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
9755
    }
9756
9757
    xi = x[0];
9758
9759
    /* XOR in most significant nibble * H */
9760
    m8 = (word32*)m[xi & 0xf];
9761
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9762
9763
    /* Cache top byte for remainder calculations - lost in rotate. */
9764
    a = (byte)(z8[3] & 0x0f);
9765
9766
    z8[3] = (z8[2] << 28) | (z8[3] >> 4);
9767
    z8[2] = (z8[1] << 28) | (z8[2] >> 4);
9768
    z8[1] = (z8[0] << 28) | (z8[1] >> 4);
9769
    z8[0] >>= 4;
9770
9771
    /* XOR in most significant nibble * remainder */
9772
    z8[0] ^= ((word32)R[a]) << 16;
9773
    /* XOR in next significant nibble * H */
9774
    m8 = (word32*)m[xi >> 4];
9775
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9776
9777
    /* Write back result. */
9778
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
9779
}
9780
#elif defined(WC_32BIT_CPU)
9781
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9782
{
9783
    int i;
9784
    word32 z8[4] = {0, 0, 0, 0};
9785
    byte a;
9786
    word32* x8 = (word32*)x;
9787
    word32* m8;
9788
    byte xi;
9789
    word32 n7, n6, n5, n4, n3, n2, n1, n0;
9790
9791
    for (i = 15; i > 0; i--) {
9792
        xi = x[i];
9793
9794
        /* XOR in (msn * H) */
9795
        m8 = (word32*)m[xi & 0xf];
9796
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9797
9798
        /* Cache top byte for remainder calculations - lost in rotate. */
9799
        a = (byte)(z8[3] >> 24);
9800
9801
        /* Rotate Z by 8-bits */
9802
        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
9803
        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
9804
        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
9805
        z8[0] <<= 8;
9806
9807
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9808
        z8[0] ^= (word32)R[16 + (a & 0xf)];
9809
9810
        xi >>= 4;
9811
        /* XOR in next significant nibble (XORed with H) * remainder */
9812
        m8 = (word32*)m[xi];
9813
        a ^= (byte)(m8[3] >> 20);
9814
        z8[0] ^= (word32)R[a >> 4];
9815
9816
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9817
        m8 = (word32*)m[16 + xi];
9818
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
9819
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
9820
    }
9821
9822
    xi = x[0];
9823
9824
    /* XOR in most significant nibble * H */
9825
    m8 = (word32*)m[xi & 0xf];
9826
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9827
9828
    /* Cache top byte for remainder calculations - lost in rotate. */
9829
    a = (z8[3] >> 24) & 0xf;
9830
9831
    /* Rotate z by 4-bits */
9832
    n7 = z8[3] & 0xf0f0f0f0ULL;
9833
    n6 = z8[3] & 0x0f0f0f0fULL;
9834
    n5 = z8[2] & 0xf0f0f0f0ULL;
9835
    n4 = z8[2] & 0x0f0f0f0fULL;
9836
    n3 = z8[1] & 0xf0f0f0f0ULL;
9837
    n2 = z8[1] & 0x0f0f0f0fULL;
9838
    n1 = z8[0] & 0xf0f0f0f0ULL;
9839
    n0 = z8[0] & 0x0f0f0f0fULL;
9840
    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
9841
    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
9842
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
9843
    z8[0] = (n1 >> 4) | (n0 << 12);
9844
9845
    /* XOR in most significant nibble * remainder */
9846
    z8[0] ^= (word32)R[a];
9847
    /* XOR in next significant nibble * H */
9848
    m8 = (word32*)m[xi >> 4];
9849
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
9850
9851
    /* Write back result. */
9852
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
9853
}
9854
#elif defined(WC_64BIT_CPU) && defined(BIG_ENDIAN_ORDER)
9855
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9856
{
9857
    int i;
9858
    word64 z8[2] = {0, 0};
9859
    byte a;
9860
    word64* x8 = (word64*)x;
9861
    word64* m8;
9862
    byte xi;
9863
9864
    for (i = 15; i > 0; i--) {
9865
        xi = x[i];
9866
9867
        /* XOR in (msn * H) */
9868
        m8 = (word64*)m[xi & 0xf];
9869
        z8[0] ^= m8[0];
9870
        z8[1] ^= m8[1];
9871
9872
        /* Cache top byte for remainder calculations - lost in rotate. */
9873
        a = (byte)(z8[1] & 0xff);
9874
9875
        /* Rotate Z by 8-bits */
9876
        z8[1] = (z8[0] << 56) | (z8[1] >> 8);
9877
        z8[0] >>= 8;
9878
9879
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9880
        m8 = (word64*)m[16 + (xi >> 4)];
9881
        z8[0] ^= m8[0];
9882
        z8[1] ^= m8[1];
9883
9884
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9885
        z8[0] ^= ((word64)R[16 + (a & 0xf)]) << 48;
9886
        /* XOR in next significant nibble (XORed with H) * remainder */
9887
        m8 = (word64*)m[xi >> 4];
9888
        a ^= (byte)(m8[1] >> 12) & 0xf;
9889
        a ^= (byte)((m8[1] << 4) & 0xf0);
9890
        z8[0] ^= ((word64)R[a >> 4]) << 48;
9891
    }
9892
9893
    xi = x[0];
9894
9895
    /* XOR in most significant nibble * H */
9896
    m8 = (word64*)m[xi & 0xf];
9897
    z8[0] ^= m8[0];
9898
    z8[1] ^= m8[1];
9899
9900
    /* Cache top byte for remainder calculations - lost in rotate. */
9901
    a = (byte)(z8[1] & 0x0f);
9902
9903
    /* Rotate z by 4-bits */
9904
    z8[1] = (z8[0] << 60) | (z8[1] >> 4);
9905
    z8[0] >>= 4;
9906
9907
    /* XOR in next significant nibble * H */
9908
    m8 = (word64*)m[xi >> 4];
9909
    z8[0] ^= m8[0];
9910
    z8[1] ^= m8[1];
9911
    /* XOR in most significant nibble * remainder */
9912
    z8[0] ^= ((word64)R[a]) << 48;
9913
9914
    /* Write back result. */
9915
    x8[0] = z8[0];
9916
    x8[1] = z8[1];
9917
}
9918
#else
9919
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
9920
0
{
9921
0
    int i;
9922
0
    word64 z8[2] = {0, 0};
9923
0
    byte a;
9924
0
    word64* x8 = (word64*)x;
9925
0
    word64* m8;
9926
0
    word64 n0, n1, n2, n3;
9927
0
    byte xi;
9928
9929
0
    for (i = 15; i > 0; i--) {
9930
0
        xi = x[i];
9931
9932
        /* XOR in (msn * H) */
9933
0
        m8 = (word64*)m[xi & 0xf];
9934
0
        z8[0] ^= m8[0];
9935
0
        z8[1] ^= m8[1];
9936
9937
        /* Cache top byte for remainder calculations - lost in rotate. */
9938
0
        a = (byte)(z8[1] >> 56);
9939
9940
        /* Rotate Z by 8-bits */
9941
0
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
9942
0
        z8[0] <<= 8;
9943
9944
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
9945
0
        m8 = (word64*)m[16 + (xi >> 4)];
9946
0
        z8[0] ^= m8[0];
9947
0
        z8[1] ^= m8[1];
9948
9949
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
9950
0
        z8[0] ^= (word64)R[16 + (a & 0xf)];
9951
        /* XOR in next significant nibble (XORed with H) * remainder */
9952
0
        m8 = (word64*)m[xi >> 4];
9953
0
        a ^= (byte)(m8[1] >> 52);
9954
0
        z8[0] ^= (word64)R[a >> 4];
9955
0
    }
9956
9957
0
    xi = x[0];
9958
9959
    /* XOR in most significant nibble * H */
9960
0
    m8 = (word64*)m[xi & 0xf];
9961
0
    z8[0] ^= m8[0];
9962
0
    z8[1] ^= m8[1];
9963
9964
    /* Cache top byte for remainder calculations - lost in rotate. */
9965
0
    a = (z8[1] >> 56) & 0xf;
9966
9967
    /* Rotate z by 4-bits */
9968
0
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
9969
0
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
9970
0
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
9971
0
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
9972
0
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
9973
0
    z8[0] = (n1 >> 4) | (n0 << 12);
9974
9975
    /* XOR in next significant nibble * H */
9976
0
    m8 = (word64*)m[xi >> 4];
9977
0
    z8[0] ^= m8[0];
9978
0
    z8[1] ^= m8[1];
9979
    /* XOR in most significant nibble * remainder */
9980
0
    z8[0] ^= (word64)R[a];
9981
9982
    /* Write back result. */
9983
0
    x8[0] = z8[0];
9984
0
    x8[1] = z8[1];
9985
0
}
9986
#endif
9987
#endif
9988
9989
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
9990
    word32 cSz, byte* s, word32 sSz)
9991
0
{
9992
0
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
9993
0
    byte scratch[WC_AES_BLOCK_SIZE];
9994
0
    word32 blocks, partial;
9995
9996
0
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
9997
9998
    /* Hash in A, the Additional Authentication Data */
9999
0
    if (aSz != 0 && a != NULL) {
10000
0
        blocks = aSz / WC_AES_BLOCK_SIZE;
10001
0
        partial = aSz % WC_AES_BLOCK_SIZE;
10002
    #ifdef GCM_GMULT_LEN
10003
        if (blocks > 0) {
10004
            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
10005
            a += blocks * WC_AES_BLOCK_SIZE;
10006
        }
10007
        if (partial != 0) {
10008
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10009
            XMEMCPY(scratch, a, partial);
10010
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
10011
        }
10012
    #else
10013
0
        while (blocks--) {
10014
0
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
10015
0
            GMULT(x, gcm->M0);
10016
0
            a += WC_AES_BLOCK_SIZE;
10017
0
        }
10018
0
        if (partial != 0) {
10019
0
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10020
0
            XMEMCPY(scratch, a, partial);
10021
0
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
10022
0
            GMULT(x, gcm->M0);
10023
0
        }
10024
0
    #endif
10025
0
    }
10026
10027
    /* Hash in C, the Ciphertext */
10028
0
    if (cSz != 0 && c != NULL) {
10029
0
        blocks = cSz / WC_AES_BLOCK_SIZE;
10030
0
        partial = cSz % WC_AES_BLOCK_SIZE;
10031
    #ifdef GCM_GMULT_LEN
10032
        if (blocks > 0) {
10033
            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
10034
            c += blocks * WC_AES_BLOCK_SIZE;
10035
        }
10036
        if (partial != 0) {
10037
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10038
            XMEMCPY(scratch, c, partial);
10039
            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
10040
        }
10041
    #else
10042
0
        while (blocks--) {
10043
0
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
10044
0
            GMULT(x, gcm->M0);
10045
0
            c += WC_AES_BLOCK_SIZE;
10046
0
        }
10047
0
        if (partial != 0) {
10048
0
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10049
0
            XMEMCPY(scratch, c, partial);
10050
0
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
10051
0
            GMULT(x, gcm->M0);
10052
0
        }
10053
0
    #endif
10054
0
    }
10055
10056
    /* Hash in the lengths of A and C in bits */
10057
0
    FlattenSzInBits(&scratch[0], aSz);
10058
0
    FlattenSzInBits(&scratch[8], cSz);
10059
#ifdef GCM_GMULT_LEN
10060
    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
10061
#else
10062
0
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
10063
0
    GMULT(x, gcm->M0);
10064
0
#endif
10065
10066
    /* Copy the result into s. */
10067
0
    XMEMCPY(s, x, sSz);
10068
0
}
10069
10070
#ifdef WOLFSSL_AESGCM_STREAM
10071
/* No extra initialization for 4-bit table implementation.
10072
 *
10073
 * @param [in] aes  AES GCM object.
10074
 */
10075
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
10076
10077
#ifdef GCM_GMULT_LEN
10078
/* GHASH one block of data.
10079
 *
10080
 * Defer to the length-based implementation with a length of one block - it
10081
 * does the XOR into the tag as well as the multiply.
10082
 *
10083
 * @param [in, out] aes    AES GCM object.
10084
 * @param [in]      block  Block of AAD or cipher text.
10085
 */
10086
#define GHASH_ONE_BLOCK_SW(aes, block)                                  \
10087
   GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
10088
#else
10089
/* GHASH one block of data.
10090
 *
10091
 * XOR block into tag and GMULT with H using pre-computed table.
10092
 *
10093
 * @param [in, out] aes    AES GCM object.
10094
 * @param [in]      block  Block of AAD or cipher text.
10095
 */
10096
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
10097
    do {                                                \
10098
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
10099
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
10100
    }                                                   \
10101
    while (0)
10102
#endif
10103
#endif /* WOLFSSL_AESGCM_STREAM */
10104
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
10105
10106
#if !defined(FREESCALE_LTC_AES_GCM)
10107
static void GMULT(word64* X, word64* Y)
10108
{
10109
    word64 Z[2] = {0,0};
10110
    word64 V[2];
10111
    int i, j;
10112
    word64 v1;
10113
    V[0] = X[0];  V[1] = X[1];
10114
10115
    for (i = 0; i < 2; i++)
10116
    {
10117
        word64 y = Y[i];
10118
        for (j = 0; j < 64; j++)
10119
        {
10120
#ifndef AES_GCM_GMULT_NCT
10121
            word64 mask = 0 - (y >> 63);
10122
            Z[0] ^= V[0] & mask;
10123
            Z[1] ^= V[1] & mask;
10124
#else
10125
            if (y & 0x8000000000000000ULL) {
10126
                Z[0] ^= V[0];
10127
                Z[1] ^= V[1];
10128
            }
10129
#endif
10130
10131
            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
10132
            V[1] >>= 1;
10133
            V[1] |= V[0] << 63;
10134
            V[0] >>= 1;
10135
            V[0] ^= v1;
10136
            y <<= 1;
10137
        }
10138
    }
10139
    X[0] = Z[0];
10140
    X[1] = Z[1];
10141
}
10142
10143
10144
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
10145
    word32 cSz, byte* s, word32 sSz)
10146
{
10147
    word64 x[2] = {0,0};
10148
    word32 blocks, partial;
10149
    word64 bigH[2];
10150
10151
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
10152
    #ifdef LITTLE_ENDIAN_ORDER
10153
        ByteReverseWords64(bigH, bigH, WC_AES_BLOCK_SIZE);
10154
    #endif
10155
10156
    /* Hash in A, the Additional Authentication Data */
10157
    if (aSz != 0 && a != NULL) {
10158
        word64 bigA[2];
10159
        blocks = aSz / WC_AES_BLOCK_SIZE;
10160
        partial = aSz % WC_AES_BLOCK_SIZE;
10161
        while (blocks--) {
10162
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
10163
            #ifdef LITTLE_ENDIAN_ORDER
10164
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
10165
            #endif
10166
            x[0] ^= bigA[0];
10167
            x[1] ^= bigA[1];
10168
            GMULT(x, bigH);
10169
            a += WC_AES_BLOCK_SIZE;
10170
        }
10171
        if (partial != 0) {
10172
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
10173
            XMEMCPY(bigA, a, partial);
10174
            #ifdef LITTLE_ENDIAN_ORDER
10175
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
10176
            #endif
10177
            x[0] ^= bigA[0];
10178
            x[1] ^= bigA[1];
10179
            GMULT(x, bigH);
10180
        }
10181
#ifdef OPENSSL_EXTRA
10182
        /* store AAD partial tag for next call */
10183
        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
10184
        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
10185
        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
10186
        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
10187
#endif
10188
    }
10189
10190
    /* Hash in C, the Ciphertext */
10191
    if (cSz != 0 && c != NULL) {
10192
        word64 bigC[2];
10193
        blocks = cSz / WC_AES_BLOCK_SIZE;
10194
        partial = cSz % WC_AES_BLOCK_SIZE;
10195
#ifdef OPENSSL_EXTRA
10196
        /* Start from last AAD partial tag */
10197
        if(gcm->aadLen) {
10198
            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
10199
            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
10200
         }
10201
#endif
10202
        while (blocks--) {
10203
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
10204
            #ifdef LITTLE_ENDIAN_ORDER
10205
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
10206
            #endif
10207
            x[0] ^= bigC[0];
10208
            x[1] ^= bigC[1];
10209
            GMULT(x, bigH);
10210
            c += WC_AES_BLOCK_SIZE;
10211
        }
10212
        if (partial != 0) {
10213
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
10214
            XMEMCPY(bigC, c, partial);
10215
            #ifdef LITTLE_ENDIAN_ORDER
10216
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
10217
            #endif
10218
            x[0] ^= bigC[0];
10219
            x[1] ^= bigC[1];
10220
            GMULT(x, bigH);
10221
        }
10222
    }
10223
10224
    /* Hash in the lengths in bits of A and C */
10225
    {
10226
        word64 len[2];
10227
        len[0] = aSz; len[1] = cSz;
10228
#ifdef OPENSSL_EXTRA
10229
        if (gcm->aadLen)
10230
            len[0] = (word64)gcm->aadLen;
10231
#endif
10232
        /* Lengths are in bytes. Convert to bits. */
10233
        len[0] *= 8;
10234
        len[1] *= 8;
10235
10236
        x[0] ^= len[0];
10237
        x[1] ^= len[1];
10238
        GMULT(x, bigH);
10239
    }
10240
    #ifdef LITTLE_ENDIAN_ORDER
10241
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
10242
    #endif
10243
    XMEMCPY(s, x, sSz);
10244
}
10245
#endif /* !FREESCALE_LTC_AES_GCM */
10246
10247
#ifdef WOLFSSL_AESGCM_STREAM
10248
10249
#ifdef LITTLE_ENDIAN_ORDER
10250
10251
/* No extra initialization for small implementation.
10252
 *
10253
 * @param [in] aes  AES GCM object.
10254
 */
10255
#define GHASH_INIT_EXTRA(aes)                                               \
10256
    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, WC_AES_BLOCK_SIZE)
10257
10258
/* GHASH one block of data..
10259
 *
10260
 * XOR block into tag and GMULT with H.
10261
 *
10262
 * @param [in, out] aes    AES GCM object.
10263
 * @param [in]      block  Block of AAD or cipher text.
10264
 */
10265
#define GHASH_ONE_BLOCK_SW(aes, block)                              \
10266
    do {                                                            \
10267
        word64* x = (word64*)AES_TAG(aes);                          \
10268
        word64* h = (word64*)aes->gcm.H;                            \
10269
        word64 block64[2];                                          \
10270
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);                 \
10271
        ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE);    \
10272
        x[0] ^= block64[0];                                         \
10273
        x[1] ^= block64[1];                                         \
10274
        GMULT(x, h);                                                \
10275
    }                                                               \
10276
    while (0)
10277
10278
#ifdef OPENSSL_EXTRA
10279
/* GHASH in AAD and cipher text lengths in bits.
10280
 *
10281
 * Convert tag back to little-endian.
10282
 *
10283
 * @param [in, out] aes  AES GCM object.
10284
 */
10285
#define GHASH_LEN_BLOCK(aes)                            \
10286
    do {                                                \
10287
        word64* x = (word64*)AES_TAG(aes);              \
10288
        word64* h = (word64*)aes->gcm.H;                \
10289
        word64 len[2];                                  \
10290
        len[0] = aes->aSz; len[1] = aes->cSz;           \
10291
        if (aes->gcm.aadLen)                            \
10292
            len[0] = (word64)aes->gcm.aadLen;           \
10293
        /* Lengths are in bytes. Convert to bits. */    \
10294
        len[0] *= 8;                                    \
10295
        len[1] *= 8;                                    \
10296
                                                        \
10297
        x[0] ^= len[0];                                 \
10298
        x[1] ^= len[1];                                 \
10299
        GMULT(x, h);                                    \
10300
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
10301
    }                                                   \
10302
    while (0)
10303
#else
10304
/* GHASH in AAD and cipher text lengths in bits.
10305
 *
10306
 * Convert tag back to little-endian.
10307
 *
10308
 * @param [in, out] aes  AES GCM object.
10309
 */
10310
#define GHASH_LEN_BLOCK(aes)                            \
10311
    do {                                                \
10312
        word64* x = (word64*)AES_TAG(aes);              \
10313
        word64* h = (word64*)aes->gcm.H;                \
10314
        word64 len[2];                                  \
10315
        len[0] = aes->aSz; len[1] = aes->cSz;           \
10316
        /* Lengths are in bytes. Convert to bits. */    \
10317
        len[0] *= 8;                                    \
10318
        len[1] *= 8;                                    \
10319
                                                        \
10320
        x[0] ^= len[0];                                 \
10321
        x[1] ^= len[1];                                 \
10322
        GMULT(x, h);                                    \
10323
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
10324
    }                                                   \
10325
    while (0)
10326
#endif
10327
10328
#else
10329
10330
/* No extra initialization for small implementation.
10331
 *
10332
 * @param [in] aes  AES GCM object.
10333
 */
10334
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
10335
10336
/* GHASH one block of data..
10337
 *
10338
 * XOR block into tag and GMULT with H.
10339
 *
10340
 * @param [in, out] aes    AES GCM object.
10341
 * @param [in]      block  Block of AAD or cipher text.
10342
 */
10343
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
10344
    do {                                                \
10345
        word64* x = (word64*)AES_TAG(aes);              \
10346
        word64* h = (word64*)aes->gcm.H;                \
10347
        word64 block64[2];                              \
10348
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);        \
10349
        x[0] ^= block64[0];                             \
10350
        x[1] ^= block64[1];                             \
10351
        GMULT(x, h);                                    \
10352
    }                                                   \
10353
    while (0)
10354
10355
#ifdef OPENSSL_EXTRA
10356
/* GHASH in AAD and cipher text lengths in bits.
10357
 *
10358
 * Convert tag back to little-endian.
10359
 *
10360
 * @param [in, out] aes  AES GCM object.
10361
 */
10362
#define GHASH_LEN_BLOCK(aes)                            \
10363
    do {                                                \
10364
        word64* x = (word64*)AES_TAG(aes);              \
10365
        word64* h = (word64*)aes->gcm.H;                \
10366
        word64 len[2];                                  \
10367
        len[0] = aes->aSz; len[1] = aes->cSz;           \
10368
        if (aes->gcm.aadLen)                            \
10369
            len[0] = (word64)aes->gcm.aadLen;           \
10370
        /* Lengths are in bytes. Convert to bits. */    \
10371
        len[0] *= 8;                                    \
10372
        len[1] *= 8;                                    \
10373
                                                        \
10374
        x[0] ^= len[0];                                 \
10375
        x[1] ^= len[1];                                 \
10376
        GMULT(x, h);                                    \
10377
    }                                                   \
10378
    while (0)
10379
#else
10380
/* GHASH in AAD and cipher text lengths in bits.
10381
 *
10382
 * Convert tag back to little-endian.
10383
 *
10384
 * @param [in, out] aes  AES GCM object.
10385
 */
10386
#define GHASH_LEN_BLOCK(aes)                            \
10387
    do {                                                \
10388
        word64* x = (word64*)AES_TAG(aes);              \
10389
        word64* h = (word64*)aes->gcm.H;                \
10390
        word64 len[2];                                  \
10391
        len[0] = aes->aSz; len[1] = aes->cSz;           \
10392
        /* Lengths are in bytes. Convert to bits. */    \
10393
        len[0] *= 8;                                    \
10394
        len[1] *= 8;                                    \
10395
                                                        \
10396
        x[0] ^= len[0];                                 \
10397
        x[1] ^= len[1];                                 \
10398
        GMULT(x, h);                                    \
10399
    }                                                   \
10400
    while (0)
10401
#endif
10402
10403
#endif /* !LITTLE_ENDIAN_ORDER */
10404
10405
#endif /* WOLFSSL_AESGCM_STREAM */
10406
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
10407
#else /* GCM_WORD32 */
10408
10409
static void GMULT(word32* X, word32* Y)
10410
{
10411
    word32 Z[4] = {0,0,0,0};
10412
    word32 V[4];
10413
    int i, j;
10414
10415
    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
10416
10417
    for (i = 0; i < 4; i++)
10418
    {
10419
        word32 y = Y[i];
10420
        for (j = 0; j < 32; j++)
10421
        {
10422
            if (y & 0x80000000) {
10423
                Z[0] ^= V[0];
10424
                Z[1] ^= V[1];
10425
                Z[2] ^= V[2];
10426
                Z[3] ^= V[3];
10427
            }
10428
10429
            if (V[3] & 0x00000001) {
10430
                V[3] >>= 1;
10431
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
10432
                V[2] >>= 1;
10433
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
10434
                V[1] >>= 1;
10435
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
10436
                V[0] >>= 1;
10437
                V[0] ^= 0xE1000000;
10438
            } else {
10439
                V[3] >>= 1;
10440
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
10441
                V[2] >>= 1;
10442
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
10443
                V[1] >>= 1;
10444
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
10445
                V[0] >>= 1;
10446
            }
10447
            y <<= 1;
10448
        }
10449
    }
10450
    X[0] = Z[0];
10451
    X[1] = Z[1];
10452
    X[2] = Z[2];
10453
    X[3] = Z[3];
10454
}
10455
10456
10457
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
10458
    word32 cSz, byte* s, word32 sSz)
10459
{
10460
    word32 x[4] = {0,0,0,0};
10461
    word32 blocks, partial;
10462
    word32 bigH[4];
10463
10464
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
10465
    #ifdef LITTLE_ENDIAN_ORDER
10466
        ByteReverseWords(bigH, bigH, WC_AES_BLOCK_SIZE);
10467
    #endif
10468
10469
    /* Hash in A, the Additional Authentication Data */
10470
    if (aSz != 0 && a != NULL) {
10471
        word32 bigA[4];
10472
        blocks = aSz / WC_AES_BLOCK_SIZE;
10473
        partial = aSz % WC_AES_BLOCK_SIZE;
10474
        while (blocks--) {
10475
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
10476
            #ifdef LITTLE_ENDIAN_ORDER
10477
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
10478
            #endif
10479
            x[0] ^= bigA[0];
10480
            x[1] ^= bigA[1];
10481
            x[2] ^= bigA[2];
10482
            x[3] ^= bigA[3];
10483
            GMULT(x, bigH);
10484
            a += WC_AES_BLOCK_SIZE;
10485
        }
10486
        if (partial != 0) {
10487
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
10488
            XMEMCPY(bigA, a, partial);
10489
            #ifdef LITTLE_ENDIAN_ORDER
10490
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
10491
            #endif
10492
            x[0] ^= bigA[0];
10493
            x[1] ^= bigA[1];
10494
            x[2] ^= bigA[2];
10495
            x[3] ^= bigA[3];
10496
            GMULT(x, bigH);
10497
        }
10498
    }
10499
10500
    /* Hash in C, the Ciphertext */
10501
    if (cSz != 0 && c != NULL) {
10502
        word32 bigC[4];
10503
        blocks = cSz / WC_AES_BLOCK_SIZE;
10504
        partial = cSz % WC_AES_BLOCK_SIZE;
10505
        while (blocks--) {
10506
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
10507
            #ifdef LITTLE_ENDIAN_ORDER
10508
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
10509
            #endif
10510
            x[0] ^= bigC[0];
10511
            x[1] ^= bigC[1];
10512
            x[2] ^= bigC[2];
10513
            x[3] ^= bigC[3];
10514
            GMULT(x, bigH);
10515
            c += WC_AES_BLOCK_SIZE;
10516
        }
10517
        if (partial != 0) {
10518
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
10519
            XMEMCPY(bigC, c, partial);
10520
            #ifdef LITTLE_ENDIAN_ORDER
10521
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
10522
            #endif
10523
            x[0] ^= bigC[0];
10524
            x[1] ^= bigC[1];
10525
            x[2] ^= bigC[2];
10526
            x[3] ^= bigC[3];
10527
            GMULT(x, bigH);
10528
        }
10529
    }
10530
10531
    /* Hash in the lengths in bits of A and C */
10532
    {
10533
        word32 len[4];
10534
10535
        /* Lengths are in bytes. Convert to bits. */
10536
        len[0] = (aSz >> (8*sizeof(aSz) - 3));
10537
        len[1] = aSz << 3;
10538
        len[2] = (cSz >> (8*sizeof(cSz) - 3));
10539
        len[3] = cSz << 3;
10540
10541
        x[0] ^= len[0];
10542
        x[1] ^= len[1];
10543
        x[2] ^= len[2];
10544
        x[3] ^= len[3];
10545
        GMULT(x, bigH);
10546
    }
10547
    #ifdef LITTLE_ENDIAN_ORDER
10548
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
10549
    #endif
10550
    XMEMCPY(s, x, sSz);
10551
}
10552
10553
#ifdef WOLFSSL_AESGCM_STREAM
10554
#ifdef LITTLE_ENDIAN_ORDER
10555
/* Little-endian 32-bit word implementation requires byte reversal of H.
10556
 *
10557
 * H is all-zeros block encrypted with key.
10558
 *
10559
 * @param [in, out] aes  AES GCM object.
10560
 */
10561
#define GHASH_INIT_EXTRA(aes) \
10562
    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, WC_AES_BLOCK_SIZE)
10563
10564
/* GHASH one block of data..
10565
 *
10566
 * XOR block, in big-endian form, into tag and GMULT with H.
10567
 *
10568
 * @param [in, out] aes    AES GCM object.
10569
 * @param [in]      block  Block of AAD or cipher text.
10570
 */
10571
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
10572
    do {                                                        \
10573
        word32* x = (word32*)AES_TAG(aes);                      \
10574
        word32* h = (word32*)aes->gcm.H;                        \
10575
        word32 bigEnd[4];                                       \
10576
        XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE);              \
10577
        ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE);    \
10578
        x[0] ^= bigEnd[0];                                      \
10579
        x[1] ^= bigEnd[1];                                      \
10580
        x[2] ^= bigEnd[2];                                      \
10581
        x[3] ^= bigEnd[3];                                      \
10582
        GMULT(x, h);                                            \
10583
    }                                                           \
10584
    while (0)
10585
10586
/* GHASH in AAD and cipher text lengths in bits.
10587
 *
10588
 * Convert tag back to little-endian.
10589
 *
10590
 * @param [in, out] aes  AES GCM object.
10591
 */
10592
#define GHASH_LEN_BLOCK(aes)                                \
10593
    do {                                                    \
10594
        word32 len[4];                                      \
10595
        word32* x = (word32*)AES_TAG(aes);                  \
10596
        word32* h = (word32*)aes->gcm.H;                    \
10597
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
10598
        len[1] = aes->aSz << 3;                             \
10599
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
10600
        len[3] = aes->cSz << 3;                             \
10601
        x[0] ^= len[0];                                     \
10602
        x[1] ^= len[1];                                     \
10603
        x[2] ^= len[2];                                     \
10604
        x[3] ^= len[3];                                     \
10605
        GMULT(x, h);                                        \
10606
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);          \
10607
    }                                                       \
10608
    while (0)
10609
#else
10610
/* No extra initialization for 32-bit word implementation.
10611
 *
10612
 * @param [in] aes  AES GCM object.
10613
 */
10614
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
10615
10616
/* GHASH one block of data..
10617
 *
10618
 * XOR block into tag and GMULT with H.
10619
 *
10620
 * @param [in, out] aes    AES GCM object.
10621
 * @param [in]      block  Block of AAD or cipher text.
10622
 */
10623
#define GHASH_ONE_BLOCK_SW(aes, block)                      \
10624
    do {                                                    \
10625
        word32* x = (word32*)AES_TAG(aes);                  \
10626
        word32* h = (word32*)aes->gcm.H;                    \
10627
        word32 block32[4];                                  \
10628
        XMEMCPY(block32, block, WC_AES_BLOCK_SIZE);         \
10629
        x[0] ^= block32[0];                                 \
10630
        x[1] ^= block32[1];                                 \
10631
        x[2] ^= block32[2];                                 \
10632
        x[3] ^= block32[3];                                 \
10633
        GMULT(x, h);                                        \
10634
    }                                                       \
10635
    while (0)
10636
10637
/* GHASH in AAD and cipher text lengths in bits.
10638
 *
10639
 * @param [in, out] aes  AES GCM object.
10640
 */
10641
#define GHASH_LEN_BLOCK(aes)                                \
10642
    do {                                                    \
10643
        word32 len[4];                                      \
10644
        word32* x = (word32*)AES_TAG(aes);                  \
10645
        word32* h = (word32*)aes->gcm.H;                    \
10646
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
10647
        len[1] = aes->aSz << 3;                             \
10648
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
10649
        len[3] = aes->cSz << 3;                             \
10650
        x[0] ^= len[0];                                     \
10651
        x[1] ^= len[1];                                     \
10652
        x[2] ^= len[2];                                     \
10653
        x[3] ^= len[3];                                     \
10654
        GMULT(x, h);                                        \
10655
    }                                                       \
10656
    while (0)
10657
#endif /* LITTLE_ENDIAN_ORDER */
10658
#endif /* WOLFSSL_AESGCM_STREAM */
10659
#endif /* end GCM_WORD32 */
10660
10661
#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
10662
#ifdef WOLFSSL_AESGCM_STREAM
10663
#ifndef GHASH_LEN_BLOCK
10664
/* Hash in the lengths of the AAD and cipher text in bits.
10665
 *
10666
 * Default implementation.
10667
 *
10668
 * @param [in, out] aes  AES GCM object.
10669
 */
10670
#define GHASH_LEN_BLOCK(aes)                      \
10671
    do {                                          \
10672
        byte scratch[WC_AES_BLOCK_SIZE];          \
10673
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
10674
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
10675
        GHASH_ONE_BLOCK(aes, scratch);            \
10676
    }                                             \
10677
    while (0)
10678
#endif
10679
10680
/* Initialize a GHASH for streaming operations.
10681
 *
10682
 * @param [in, out] aes  AES GCM object.
10683
 */
10684
static void GHASH_INIT(Aes* aes) {
10685
    /* Set tag to all zeros as initial value. */
10686
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
10687
    /* Reset counts of AAD and cipher text. */
10688
    aes->aOver = 0;
10689
    aes->cOver = 0;
10690
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10691
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10692
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10693
        ; /* Don't do extra initialization. */
10694
    }
10695
    else
10696
#endif
10697
    {
10698
        /* Extra initialization based on implementation. */
10699
        GHASH_INIT_EXTRA(aes);
10700
    }
10701
}
10702
10703
/* Update the GHASH with AAD and/or cipher text.
10704
 *
10705
 * @param [in,out] aes   AES GCM object.
10706
 * @param [in]     a     Additional authentication data buffer.
10707
 * @param [in]     aSz   Size of data in AAD buffer.
10708
 * @param [in]     c     Cipher text buffer.
10709
 * @param [in]     cSz   Size of data in cipher text buffer.
10710
 */
10711
static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
10712
    word32 cSz)
10713
{
10714
    word32 blocks;
10715
    word32 partial;
10716
10717
    /* Hash in A, the Additional Authentication Data */
10718
    if (aSz != 0 && a != NULL) {
10719
        /* Update count of AAD we have hashed. */
10720
        aes->aSz += aSz;
10721
        /* Check if we have unprocessed data. */
10722
        if (aes->aOver > 0) {
10723
            /* Calculate amount we can use - fill up the block. */
10724
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10725
            if (sz > aSz) {
10726
                sz = (byte)aSz;
10727
            }
10728
            /* Copy extra into last GHASH block array and update count. */
10729
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
10730
            aes->aOver = (byte)(aes->aOver + sz);
10731
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
10732
                /* We have filled up the block and can process. */
10733
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10734
                /* Reset count. */
10735
                aes->aOver = 0;
10736
            }
10737
            /* Used up some data. */
10738
            aSz -= sz;
10739
            a += sz;
10740
        }
10741
10742
        /* Calculate number of blocks of AAD and the leftover. */
10743
        blocks = aSz / WC_AES_BLOCK_SIZE;
10744
        partial = aSz % WC_AES_BLOCK_SIZE;
10745
        /* GHASH full blocks now. */
10746
        while (blocks--) {
10747
            GHASH_ONE_BLOCK(aes, a);
10748
            a += WC_AES_BLOCK_SIZE;
10749
        }
10750
        if (partial != 0) {
10751
            /* Cache the partial block. */
10752
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
10753
            aes->aOver = (byte)partial;
10754
        }
10755
    }
10756
    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
10757
        /* No more AAD coming and we have a partial block. */
10758
        /* Fill the rest of the block with zeros. */
10759
        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
10760
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
10761
        /* GHASH last AAD block. */
10762
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10763
        /* Clear partial count for next time through. */
10764
        aes->aOver = 0;
10765
    }
10766
10767
    /* Hash in C, the Ciphertext */
10768
    if (cSz != 0 && c != NULL) {
10769
        /* Update count of cipher text we have hashed. */
10770
        aes->cSz += cSz;
10771
        if (aes->cOver > 0) {
10772
            /* Calculate amount we can use - fill up the block. */
10773
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
10774
            if (sz > cSz) {
10775
                sz = (byte)cSz;
10776
            }
10777
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
10778
            /* Update count of unused encrypted counter. */
10779
            aes->cOver = (byte)(aes->cOver + sz);
10780
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
10781
                /* We have filled up the block and can process. */
10782
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10783
                /* Reset count. */
10784
                aes->cOver = 0;
10785
            }
10786
            /* Used up some data. */
10787
            cSz -= sz;
10788
            c += sz;
10789
        }
10790
10791
        /* Calculate number of blocks of cipher text and the leftover. */
10792
        blocks = cSz / WC_AES_BLOCK_SIZE;
10793
        partial = cSz % WC_AES_BLOCK_SIZE;
10794
        /* GHASH full blocks now. */
10795
        while (blocks--) {
10796
            GHASH_ONE_BLOCK(aes, c);
10797
            c += WC_AES_BLOCK_SIZE;
10798
        }
10799
        if (partial != 0) {
10800
            /* Cache the partial block. */
10801
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
10802
            aes->cOver = (byte)partial;
10803
        }
10804
    }
10805
}
10806
10807
/* Finalize the GHASH calculation.
10808
 *
10809
 * Complete hashing cipher text and hash the AAD and cipher text lengths.
10810
 *
10811
 * @param [in, out] aes  AES GCM object.
10812
 * @param [out]     s    Authentication tag.
10813
 * @param [in]      sSz  Size of authentication tag required.
10814
 */
10815
static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
10816
{
10817
    /* AAD block incomplete when > 0 */
10818
    byte over = aes->aOver;
10819
10820
    if (aes->cOver > 0) {
10821
        /* Cipher text block incomplete. */
10822
        over = aes->cOver;
10823
    }
10824
    if (over > 0) {
10825
        /* Zeroize the unused part of the block. */
10826
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
10827
            (size_t)WC_AES_BLOCK_SIZE - over);
10828
        /* Hash the last block of cipher text. */
10829
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
10830
    }
10831
    /* Hash in the lengths of AAD and cipher text in bits */
10832
    GHASH_LEN_BLOCK(aes);
10833
    /* Copy the result into s. */
10834
    XMEMCPY(s, AES_TAG(aes), sSz);
10835
    /* reset aes->gcm.H in case of reuse */
10836
    GHASH_INIT_EXTRA(aes);
10837
}
10838
#endif /* WOLFSSL_AESGCM_STREAM */
10839
10840
10841
#ifdef FREESCALE_LTC_AES_GCM
10842
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10843
                   const byte* iv, word32 ivSz,
10844
                   byte* authTag, word32 authTagSz,
10845
                   const byte* authIn, word32 authInSz)
10846
{
10847
    status_t status;
10848
    word32 keySize;
10849
10850
    /* argument checks */
10851
    if (aes == NULL || ivSz == 0) {
10852
        return BAD_FUNC_ARG;
10853
    }
10854
10855
    status = wc_local_AesGcmCheckTagSz(authTagSz);
10856
    if (status != 0)
10857
        return status;
10858
10859
    status = wc_AesGetKeySize(aes, &keySize);
10860
    if (status)
10861
        return status;
10862
10863
    status = wolfSSL_CryptHwMutexLock();
10864
    if (status != 0)
10865
        return status;
10866
10867
    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
10868
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
10869
    wolfSSL_CryptHwMutexUnLock();
10870
10871
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
10872
}
10873
10874
#else
10875
10876
#ifdef STM32_CRYPTO_AES_GCM
10877
10878
/* The Cube HAL always transfers the GCM auth header to the peripheral one
10879
 * 32-bit word at a time, including the trailing partial word (ST advisory
10880
 * SA0076), and casts the header pointer to uint32_t*, so the buffer it is
10881
 * handed must be both zero padded up to a word and word aligned -- even
10882
 * where STM_CRYPT_HEADER_WIDTH is 1 and the header size is in bytes.
10883
 * authPadSz is the length reported to the HAL and is deliberately not
10884
 * changed here, so the GHASH length block, and with it the hardware tag,
10885
 * is unaffected.
10886
 * tmpBuf is a caller supplied word aligned scratch buffer, used when it is
10887
 * large enough, otherwise the padded copy is allocated and *wasAlloc is set
10888
 * so the caller frees it. When no padding or realignment is needed
10889
 * *authInPadded aliases authIn and no copy is made.
10890
 * Returns 0 on success, MEMORY_E or BAD_FUNC_ARG on failure. */
10891
static WARN_UNUSED_RESULT int wc_AesGcmAuthPad_STM32(Aes* aes,
10892
    const byte* authIn, word32 authInSz, word32 authPadSz,
10893
    word32* tmpBuf, word32 tmpBufSz, byte** authInPadded, int* wasAlloc)
10894
{
10895
    word32 padWidth = (word32)STM_CRYPT_HEADER_PAD_WIDTH;
10896
    word32 authBufSz;
10897
10898
    *wasAlloc = 0;
10899
10900
    /* the HAL reads the larger of the two, and some HAL work arounds leave
10901
     * authPadSz smaller than authInSz, so cover both */
10902
    authBufSz = authPadSz;
10903
    if (authBufSz < authInSz) {
10904
        authBufSz = authInSz;
10905
    }
10906
    if (authBufSz > (WOLFSSL_MAX_32BIT - padWidth)) {
10907
        return BAD_FUNC_ARG; /* the round up below would wrap */
10908
    }
10909
    if ((authBufSz % padWidth) != 0) {
10910
        authBufSz += padWidth - (authBufSz % padWidth);
10911
    }
10912
    if ((authBufSz == authInSz) &&
10913
            (((wc_ptr_t)authIn % sizeof(word32)) == 0)) {
10914
        /* whole number of words and word aligned, the HAL can read it */
10915
        *authInPadded = (byte*)authIn;
10916
        return 0;
10917
    }
10918
10919
    if (authBufSz <= tmpBufSz) {
10920
        *authInPadded = (byte*)tmpBuf;
10921
    }
10922
    else {
10923
        *authInPadded = (byte*)XMALLOC(authBufSz, aes->heap,
10924
            DYNAMIC_TYPE_TMP_BUFFER);
10925
        if (*authInPadded == NULL) {
10926
            return MEMORY_E;
10927
        }
10928
        *wasAlloc = 1;
10929
    }
10930
    XMEMSET(*authInPadded, 0, authBufSz);
10931
    if (authIn != NULL) {
10932
        XMEMCPY(*authInPadded, authIn, authInSz);
10933
    }
10934
    return 0;
10935
}
10936
10937
/* this function supports inline encrypt */
10938
/* Not static: the CubeMX crypto-callback device (port/st/stm32.c) calls this to
10939
 * service AES-GCM in-callback on the HAL engine. */
10940
WOLFSSL_LOCAL WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
10941
                                  Aes* aes, byte* out, const byte* in, word32 sz,
10942
                                  const byte* iv, word32 ivSz,
10943
                                  byte* authTag, word32 authTagSz,
10944
                                  const byte* authIn, word32 authInSz)
10945
{
10946
    int ret;
10947
#ifdef WOLFSSL_STM32_CUBEMX
10948
    CRYP_HandleTypeDef hcryp;
10949
#else
10950
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
10951
#endif
10952
    word32 keySize;
10953
#ifdef WOLFSSL_STM32_CUBEMX
10954
    int status = HAL_OK;
10955
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10956
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
10957
#else
10958
    int status = SUCCESS;
10959
#endif
10960
    word32 partial = sz % WC_AES_BLOCK_SIZE;
10961
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
10962
    word32 ctrInit[WC_AES_BLOCK_SIZE/sizeof(word32)];
10963
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10964
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10965
    byte* authInPadded = NULL;
10966
    word32 authPadSz;
10967
    int wasAlloc = 0, useSwGhash = 0;
10968
10969
    ret = wc_AesGetKeySize(aes, &keySize);
10970
    if (ret != 0)
10971
        return ret;
10972
10973
#ifdef WOLFSSL_STM32_CUBEMX
10974
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
10975
    if (ret != 0)
10976
        return ret;
10977
#endif
10978
10979
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
10980
    if (ivSz == GCM_NONCE_MID_SZ) {
10981
        byte* pCtr = (byte*)ctr;
10982
        XMEMCPY(ctr, iv, ivSz);
10983
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
10984
    }
10985
    else {
10986
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
10987
    }
10988
    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
10989
10990
    /* Authentication buffer */
10991
#if STM_CRYPT_HEADER_WIDTH == 1
10992
    authPadSz = 0; /* CubeHAL supports byte mode */
10993
#else
10994
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
10995
#endif
10996
#ifdef WOLFSSL_STM32MP13
10997
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
10998
     * minimum of 16 bytes for the auth */
10999
    if ((authInSz > 0) && (authInSz < 16)) {
11000
        authPadSz = 16 - authInSz;
11001
    }
11002
#endif
11003
    if (authPadSz != 0) {
11004
        if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) {
11005
            authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
11006
        }
11007
    }
11008
    else {
11009
        authPadSz = authInSz;
11010
    }
11011
    /* Zero pad and word align the buffer the HAL reads the auth header
11012
     * from (SA0076). authPadSz, the length reported to the HAL, is
11013
     * unchanged, so the hardware tag is unaffected. */
11014
    ret = wc_AesGcmAuthPad_STM32(aes, authIn, authInSz, authPadSz,
11015
        authhdr, (word32)sizeof(authhdr), &authInPadded, &wasAlloc);
11016
    if (ret != 0) {
11017
        wc_Stm32_Aes_Cleanup();
11018
        return ret;
11019
    }
11020
11021
    /* for cases where hardware cannot be used for authTag calculate it */
11022
    /* if IV is not 12 calculate GHASH using software */
11023
    if (ivSz != GCM_NONCE_MID_SZ
11024
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
11025
        /* or hardware that does not support partial block */
11026
        || sz == 0 || partial != 0
11027
    #endif
11028
    #if STM_CRYPT_HEADER_WIDTH == 4
11029
        /* or authIn is not a multiple of 4  */
11030
        || authPadSz != authInSz
11031
    #endif
11032
    ) {
11033
        useSwGhash = 1;
11034
    }
11035
11036
    /* Hardware requires counter + 1 */
11037
    IncrementGcmCounter((byte*)ctr);
11038
11039
    ret = wolfSSL_CryptHwMutexLock();
11040
    if (ret != 0) {
11041
        if (wasAlloc) {
11042
            XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11043
        }
11044
        wc_Stm32_Aes_Cleanup();
11045
        return ret;
11046
    }
11047
11048
#ifdef WOLFSSL_STM32_CUBEMX
11049
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11050
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
11051
11052
#if defined(STM32_HAL_V2)
11053
    hcryp.Init.Algorithm = CRYP_AES_GCM;
11054
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
11055
    #ifdef CRYP_KEYIVCONFIG_ONCE
11056
    /* allows repeated calls to HAL_CRYP_Encrypt */
11057
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
11058
    #endif
11059
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
11060
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11061
    HAL_CRYP_Init(&hcryp);
11062
11063
    #ifndef CRYP_KEYIVCONFIG_ONCE
11064
    /* GCM payload phase - can handle partial blocks */
11065
    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
11066
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
11067
    #else
11068
    /* GCM payload phase - blocks */
11069
    if (blocks) {
11070
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
11071
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
11072
    }
11073
    /* GCM payload phase - partial remainder */
11074
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11075
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11076
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11077
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
11078
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
11079
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11080
    }
11081
    #endif
11082
    if (status == HAL_OK && !useSwGhash) {
11083
        /* Compute the authTag */
11084
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
11085
            STM32_HAL_TIMEOUT);
11086
    }
11087
#elif defined(STM32_CRYPTO_AES_ONLY)
11088
    /* Set the CRYP parameters */
11089
    hcryp.Init.HeaderSize = authPadSz;
11090
    if (authPadSz == 0)
11091
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
11092
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
11093
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
11094
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
11095
    HAL_CRYP_Init(&hcryp);
11096
11097
    /* GCM init phase */
11098
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11099
    if (status == HAL_OK) {
11100
        /* GCM header phase */
11101
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
11102
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11103
    }
11104
    if (status == HAL_OK) {
11105
        /* GCM payload phase - blocks */
11106
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
11107
        if (blocks) {
11108
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
11109
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11110
        }
11111
    }
11112
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
11113
        /* GCM payload phase - partial remainder */
11114
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11115
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11116
        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
11117
                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
11118
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11119
    }
11120
    if (status == HAL_OK && !useSwGhash) {
11121
        /* GCM final phase */
11122
        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
11123
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
11124
    }
11125
#else
11126
    hcryp.Init.HeaderSize = authPadSz;
11127
    HAL_CRYP_Init(&hcryp);
11128
    if (blocks) {
11129
        /* GCM payload phase - blocks */
11130
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
11131
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11132
    }
11133
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11134
        /* GCM payload phase - partial remainder */
11135
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11136
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11137
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
11138
            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
11139
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11140
    }
11141
    if (status == HAL_OK && !useSwGhash) {
11142
        /* Compute the authTag */
11143
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
11144
    }
11145
#endif
11146
11147
    if (status != HAL_OK)
11148
        ret = AES_GCM_AUTH_E;
11149
    HAL_CRYP_DeInit(&hcryp);
11150
11151
#else /* Standard Peripheral Library */
11152
    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
11153
    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
11154
                         (uint8_t*)keyCopy,      keySize * 8,
11155
                         (uint8_t*)in,           sz,
11156
                         (uint8_t*)authInPadded, authInSz,
11157
                         (uint8_t*)out,          (uint8_t*)tag);
11158
    if (status != SUCCESS)
11159
        ret = AES_GCM_AUTH_E;
11160
#endif /* WOLFSSL_STM32_CUBEMX */
11161
    wolfSSL_CryptHwMutexUnLock();
11162
    wc_Stm32_Aes_Cleanup();
11163
11164
    if (ret == 0) {
11165
        /* return authTag */
11166
        if (authTag) {
11167
            if (useSwGhash) {
11168
                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
11169
                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
11170
                if (ret == 0) {
11171
                    xorbuf(authTag, tag, authTagSz);
11172
                }
11173
            }
11174
            else {
11175
                /* use hardware calculated tag */
11176
                XMEMCPY(authTag, tag, authTagSz);
11177
            }
11178
        }
11179
    }
11180
11181
    /* Free memory */
11182
    if (wasAlloc) {
11183
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11184
    }
11185
11186
    return ret;
11187
}
11188
11189
#endif /* STM32_CRYPTO_AES_GCM */
11190
11191
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11192
#ifdef WOLFSSL_AESNI
11193
/* For performance reasons, this code needs to be not inlined. */
11194
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
11195
                      Aes* aes, byte* out, const byte* in, word32 sz,
11196
                      const byte* iv, word32 ivSz,
11197
                      byte* authTag, word32 authTagSz,
11198
                      const byte* authIn, word32 authInSz);
11199
#else
11200
static
11201
#endif
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
0
{
11208
0
    int ret = 0;
11209
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
11210
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
11211
0
    const byte* p = in;
11212
0
    byte* c = out;
11213
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
11214
0
    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
11215
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
11216
0
#ifdef WC_AES_HAVE_PREFETCH_ARG
11217
0
    int did_prefetches = 0;
11218
0
#endif
11219
11220
0
    if (ivSz == GCM_NONCE_MID_SZ) {
11221
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
11222
0
        XMEMCPY(counter, iv, ivSz);
11223
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
11224
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
11225
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
11226
0
    }
11227
0
    else {
11228
        /* Counter is GHASH of IV. */
11229
#ifdef OPENSSL_EXTRA
11230
        word32 aadTemp = aes->gcm.aadLen;
11231
        aes->gcm.aadLen = 0;
11232
#endif
11233
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
11234
#ifdef OPENSSL_EXTRA
11235
        aes->gcm.aadLen = aadTemp;
11236
#endif
11237
0
    }
11238
0
    XMEMCPY(initialCounter, counter, WC_AES_BLOCK_SIZE);
11239
11240
#ifdef WOLFSSL_PIC32MZ_CRYPT
11241
    if (blocks) {
11242
        /* use initial IV for HW, but don't use it below */
11243
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
11244
11245
        ret = wc_Pic32AesCrypt(
11246
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
11247
            out, in, (blocks * WC_AES_BLOCK_SIZE),
11248
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
11249
        if (ret != 0)
11250
            return ret;
11251
    }
11252
    /* process remainder using partial handling */
11253
#endif
11254
11255
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
11256
    /* some hardware acceleration can gain performance from doing AES encryption
11257
     * of the whole buffer at once */
11258
    if (c != p && blocks > 0) { /* can not handle inline encryption */
11259
        while (blocks--) {
11260
            IncrementGcmCounter(counter);
11261
            XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
11262
            c += WC_AES_BLOCK_SIZE;
11263
        }
11264
11265
        /* reset number of blocks and then do encryption */
11266
        blocks = sz / WC_AES_BLOCK_SIZE;
11267
        ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
11268
        if (ret != 0) {
11269
            ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
11270
            return ret;
11271
        }
11272
        xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
11273
        p += WC_AES_BLOCK_SIZE * blocks;
11274
    }
11275
    else
11276
#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
11277
0
    {
11278
0
        while (blocks--) {
11279
0
            IncrementGcmCounter(counter);
11280
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
11281
0
            ret = AesEncrypt_preFetchOpt(aes, counter, scratch,
11282
0
                                            &did_prefetches);
11283
0
            if (ret != 0)
11284
0
                return ret;
11285
0
            xorbufout(c, scratch, p, WC_AES_BLOCK_SIZE);
11286
0
        #endif
11287
0
            p += WC_AES_BLOCK_SIZE;
11288
0
            c += WC_AES_BLOCK_SIZE;
11289
0
        }
11290
0
    }
11291
11292
0
    if (partial != 0) {
11293
0
        IncrementGcmCounter(counter);
11294
0
        ret = AesEncrypt_preFetchOpt(aes, counter, scratch, &did_prefetches);
11295
0
        if (ret != 0)
11296
0
            return ret;
11297
0
        xorbufout(c, scratch, p, partial);
11298
0
    }
11299
0
    if (authTag) {
11300
0
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
11301
0
        ret = AesEncrypt_preFetchOpt(aes, initialCounter, scratch,
11302
0
                                        &did_prefetches);
11303
0
        if (ret != 0)
11304
0
            return ret;
11305
0
        xorbuf(authTag, scratch, authTagSz);
11306
#ifdef OPENSSL_EXTRA
11307
        if (!in && !sz)
11308
            /* store AAD size for next call */
11309
            aes->gcm.aadLen = authInSz;
11310
#endif
11311
0
    }
11312
11313
0
    return ret;
11314
0
}
11315
#elif (defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
11316
      defined(WOLFSSL_ARM32_AES_DISPATCH) || \
11317
      (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11318
static int AES_GCM_encrypt_ASM(Aes* aes, byte* out, const byte* in,
11319
    word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
11320
    const byte* authIn, word32 authInSz)
11321
{
11322
    word32 blocks;
11323
    word32 partial;
11324
    byte counter[WC_AES_BLOCK_SIZE];
11325
    byte initialCounter[WC_AES_BLOCK_SIZE];
11326
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
11327
    byte scratch[WC_AES_BLOCK_SIZE];
11328
11329
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
11330
    if (ivSz == GCM_NONCE_MID_SZ) {
11331
        XMEMCPY(initialCounter, iv, ivSz);
11332
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
11333
    }
11334
    else {
11335
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
11336
    }
11337
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
11338
11339
    /* Hash in the Additional Authentication Data */
11340
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
11341
    if (authInSz != 0 && authIn != NULL) {
11342
        blocks = authInSz / WC_AES_BLOCK_SIZE;
11343
        partial = authInSz % WC_AES_BLOCK_SIZE;
11344
        if (blocks > 0) {
11345
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
11346
            authIn += blocks * WC_AES_BLOCK_SIZE;
11347
        }
11348
        if (partial != 0) {
11349
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11350
            XMEMCPY(scratch, authIn, partial);
11351
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11352
        }
11353
    }
11354
11355
    /* do as many blocks as possible */
11356
    blocks = sz / WC_AES_BLOCK_SIZE;
11357
    partial = sz % WC_AES_BLOCK_SIZE;
11358
    if (blocks > 0) {
11359
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
11360
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11361
        if (sz >= 32)
11362
    #endif
11363
        {
11364
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
11365
                (const unsigned char*)aes->key, aes->rounds, counter);
11366
        }
11367
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
11368
        else
11369
    #endif
11370
    #endif
11371
    /* Base AES is only left out on AArch64 - see wc_AesCbcDecrypt. */
11372
    #if !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP) || !defined(__aarch64__)
11373
        {
11374
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
11375
                (const unsigned char*)aes->key, aes->rounds, counter);
11376
        }
11377
    #endif
11378
        GCM_GMULT_LEN(&aes->gcm, x, out, blocks * WC_AES_BLOCK_SIZE);
11379
        in += blocks * WC_AES_BLOCK_SIZE;
11380
        out += blocks * WC_AES_BLOCK_SIZE;
11381
    }
11382
    /* take care of partial block sizes leftover */
11383
    if (partial != 0) {
11384
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
11385
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
11386
        {
11387
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
11388
                (const unsigned char*)aes->key, aes->rounds, counter);
11389
        }
11390
    #else
11391
        {
11392
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
11393
                (const unsigned char*)aes->key, aes->rounds, counter);
11394
        }
11395
    #endif
11396
        XMEMCPY(out, scratch, partial);
11397
11398
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11399
        XMEMCPY(scratch, out, partial);
11400
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11401
    }
11402
11403
    /* Hash in the lengths of A and C in bits */
11404
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
11405
    FlattenSzInBits(&scratch[0], authInSz);
11406
    FlattenSzInBits(&scratch[8], sz);
11407
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
11408
    if (authTagSz > WC_AES_BLOCK_SIZE) {
11409
        XMEMCPY(authTag, x, WC_AES_BLOCK_SIZE);
11410
    }
11411
    else {
11412
        /* authTagSz can be smaller than WC_AES_BLOCK_SIZE */
11413
        XMEMCPY(authTag, x, authTagSz);
11414
    }
11415
11416
    /* Auth tag calculation. */
11417
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
11418
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
11419
    {
11420
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
11421
            (const unsigned char*)aes->key, aes->rounds);
11422
    }
11423
#else
11424
    {
11425
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
11426
            (const unsigned char*)aes->key, aes->rounds);
11427
    }
11428
#endif
11429
    xorbuf(authTag, scratch, authTagSz);
11430
11431
    return 0;
11432
}
11433
#endif
11434
11435
#if defined(WOLFSSL_RISCV_ASM)
11436
/* Pointer passed as "H" to the RISC-V GCM asm.  Scalar/vector crypto use the
11437
 * raw hash subkey gcm.H.  Base (software GHASH) uses the precomputed M0 table
11438
 * for GCM_TABLE/GCM_TABLE_4BIT, but gcm.H for the table-free GCM_WORD32/
11439
 * GCM_SMALL builds (which have no M0 member). */
11440
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) || \
11441
    defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
11442
    #define AES_GCM_H_PTR(aes) ((aes)->gcm.H)
11443
#elif defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
11444
    #define AES_GCM_H_PTR(aes) ((byte*)(aes)->gcm.M0)
11445
#else
11446
    #define AES_GCM_H_PTR(aes) ((byte*)(aes)->gcm.H)
11447
#endif
11448
#endif /* WOLFSSL_RISCV_ASM */
11449
11450
/* Software AES - GCM Encrypt */
11451
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
11452
                   const byte* iv, word32 ivSz,
11453
                   byte* authTag, word32 authTagSz,
11454
                   const byte* authIn, word32 authInSz)
11455
0
{
11456
0
    int ret;
11457
11458
    /* argument checks */
11459
    /* If sz is non-zero, both in and out must be set; if sz is 0, in and
11460
     * out are don't cares (GMAC case), matching wc_AesGcmDecrypt. */
11461
0
    if (aes == NULL || iv == NULL || ivSz == 0 ||
11462
0
        (sz != 0 && (in == NULL || out == NULL)) ||
11463
0
        authTag == NULL ||
11464
0
        ((authInSz > 0) && (authIn == NULL)))
11465
0
    {
11466
0
        return BAD_FUNC_ARG;
11467
0
    }
11468
11469
0
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
11470
0
    if (ret != 0)
11471
0
        return ret;
11472
11473
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
11474
    if (ivSz < GCM_NONCE_MID_SZ)
11475
        return FIPS_BAD_VALUE_E;
11476
#endif
11477
11478
#ifdef WOLF_CRYPTO_CB
11479
    #ifndef WOLF_CRYPTO_CB_FIND
11480
    if (aes->devId != INVALID_DEVID)
11481
    #endif
11482
    {
11483
        int crypto_cb_ret =
11484
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
11485
                                      authTagSz, authIn, authInSz);
11486
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11487
            return crypto_cb_ret;
11488
        /* fall-through when unavailable */
11489
    }
11490
#endif
11491
11492
    /* Software/HW key schedule (and hash subkey H) required from here on. */
11493
0
    if (!WC_AES_KEY_IS_SET(aes)) {
11494
0
        WOLFSSL_MSG("AES key not set");
11495
0
        return MISSING_KEY;
11496
0
    }
11497
11498
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
11499
    /* if async and byte count above threshold */
11500
    /* only 12-byte IV is supported in HW */
11501
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
11502
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
11503
    #if defined(HAVE_CAVIUM)
11504
        #ifdef HAVE_CAVIUM_V
11505
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
11506
            return NitroxAesGcmEncrypt(aes, out, in, sz,
11507
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
11508
                authTag, authTagSz, authIn, authInSz);
11509
        }
11510
        #endif
11511
    #elif defined(HAVE_INTEL_QA)
11512
        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
11513
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
11514
            authTag, authTagSz, authIn, authInSz);
11515
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
11516
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
11517
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
11518
            sw->aes.aes = aes;
11519
            sw->aes.out = out;
11520
            sw->aes.in = in;
11521
            sw->aes.sz = sz;
11522
            sw->aes.iv = iv;
11523
            sw->aes.ivSz = ivSz;
11524
            sw->aes.authTag = authTag;
11525
            sw->aes.authTagSz = authTagSz;
11526
            sw->aes.authIn = authIn;
11527
            sw->aes.authInSz = authInSz;
11528
            return WC_PENDING_E;
11529
        }
11530
    #endif
11531
    }
11532
#endif /* WOLFSSL_ASYNC_CRYPT */
11533
11534
#ifdef WOLFSSL_SILABS_SE_ACCEL
11535
    return wc_AesGcmEncrypt_silabs(
11536
        aes, out, in, sz,
11537
        iv, ivSz,
11538
        authTag, authTagSz,
11539
        authIn, authInSz);
11540
#endif
11541
11542
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
11543
#ifndef TA_AES_GCM_MAX_DATA_SIZE
11544
    #define TA_AES_GCM_MAX_DATA_SIZE 996u
11545
#endif
11546
    if (aes != NULL &&
11547
        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
11548
        ivSz == TA_AES_GCM_IV_LENGTH &&
11549
        authTagSz == TA_AES_GCM_TAG_LENGTH &&
11550
        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
11551
        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
11552
        return wc_Microchip_AesGcmEncrypt(
11553
            aes, out, in, sz,
11554
            iv, ivSz,
11555
            authTag, authTagSz,
11556
            authIn, authInSz);
11557
    }
11558
#endif
11559
11560
/* Not under WOLF_CRYPTO_CB_ONLY_AES: that mode leaves aes->key empty (the key
11561
 * lives in aes->devKey), so the HW GCM must be reached through the STM32
11562
 * crypto-callback device, which stages the key first. */
11563
#if defined(WOLFSSL_STM32_BARE) && defined(STM32_CRYPTO) && \
11564
    !defined(WOLF_CRYPTO_CB_ONLY_AES)
11565
    ret = wc_Stm32_Aes_Gcm(aes, out, in, sz, iv, ivSz,
11566
                           authTag, authTagSz,
11567
                           authIn, authInSz, 1 /* enc */);
11568
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11569
        return ret;
11570
    /* fall through to SW GCM (still uses HW AES via wc_AesEncrypt) */
11571
#endif /* WOLFSSL_STM32_BARE && STM32_CRYPTO && !WOLF_CRYPTO_CB_ONLY_AES */
11572
11573
11574
#ifdef STM32_CRYPTO_AES_GCM
11575
    return wc_AesGcmEncrypt_STM32(
11576
        aes, out, in, sz, iv, ivSz,
11577
        authTag, authTagSz, authIn, authInSz);
11578
#endif /* STM32_CRYPTO_AES_GCM */
11579
11580
#if defined(WOLFSSL_PSOC6_CRYPTO)
11581
    return wc_Psoc6_Aes_GcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
11582
                                   authTagSz, authIn, authInSz);
11583
#endif /* WOLFSSL_PSOC6_CRYPTO */
11584
11585
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) || \
11586
    defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
11587
    AES_GCM_encrypt_RISCV64(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
11588
        authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
11589
        (int)aes->rounds);
11590
    return 0;
11591
#elif defined(WOLFSSL_RISCV_ASM)
11592
    AES_GCM_encrypt_RISCV64(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
11593
        authInSz, (byte*)aes->key, AES_GCM_H_PTR(aes), (byte*)aes->tmp,
11594
        (byte*)aes->reg, (int)aes->rounds);
11595
    return 0;
11596
#endif
11597
11598
0
    VECTOR_REGISTERS_PUSH;
11599
11600
#if defined(WOLFSSL_ARMASM)
11601
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
11602
#if !defined(__aarch64__)
11603
  #ifdef WOLFSSL_ARM32_AES_DISPATCH
11604
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11605
        /* Reflect a copy of H into the form the PMULL assembly wants - the
11606
         * stored H must stay un-reflected for the portable GHASH. */
11607
        byte h[WC_AES_BLOCK_SIZE];
11608
11609
        XMEMCPY(h, aes->gcm.H, WC_AES_BLOCK_SIZE);
11610
        GcmReflectH(h);
11611
        AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
11612
            authIn, authInSz, (byte*)aes->key, h, (byte*)aes->tmp,
11613
            (byte*)aes->reg, aes->rounds);
11614
        ForceZero(h, sizeof(h));
11615
        ret = 0;
11616
    }
11617
    else
11618
  #else
11619
    {
11620
        /* Reflect a copy of H into the form the PMULL assembly wants - the
11621
         * stored H must stay un-reflected for the portable GHASH. */
11622
        byte h[WC_AES_BLOCK_SIZE];
11623
11624
        XMEMCPY(h, aes->gcm.H, WC_AES_BLOCK_SIZE);
11625
        GcmReflectH(h);
11626
        AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
11627
            authIn, authInSz, (byte*)aes->key, h, (byte*)aes->tmp,
11628
            (byte*)aes->reg, aes->rounds);
11629
        ForceZero(h, sizeof(h));
11630
    }
11631
    ret = 0;
11632
  #endif /* WOLFSSL_ARM32_AES_DISPATCH */
11633
#else
11634
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11635
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11636
        if (aes->use_sha3_hw_crypto) {
11637
            AES_GCM_encrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
11638
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11639
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
11640
        }
11641
        else
11642
    #endif
11643
        {
11644
            AES_GCM_encrypt_AARCH64(in, out, sz, iv, ivSz, authTag, authTagSz,
11645
                authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
11646
                (byte*)aes->reg, aes->rounds);
11647
        }
11648
        ret = 0;
11649
    }
11650
    else
11651
#endif /* !__aarch64__ */
11652
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
11653
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
11654
    defined(WOLFSSL_ARM32_AES_DISPATCH)
11655
    {
11656
        ret = AES_GCM_encrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
11657
            authTagSz, authIn, authInSz);
11658
    }
11659
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO ||
11660
        * WOLFSSL_ARM32_AES_DISPATCH */
11661
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
11662
    ret = AES_GCM_encrypt_ASM(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11663
        authIn, authInSz);
11664
#else
11665
#ifdef WOLFSSL_AESNI
11666
    if (aes->use_aesni) {
11667
#ifdef HAVE_INTEL_AVX512
11668
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11669
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11670
            AES_GCM_encrypt_avx512(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11671
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11672
            ret = 0;
11673
        }
11674
        else
11675
#endif
11676
#ifdef HAVE_INTEL_VAES
11677
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
11678
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
11679
            AES_GCM_encrypt_vaes(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11680
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11681
            ret = 0;
11682
        }
11683
        else
11684
#endif
11685
#ifdef HAVE_INTEL_AVX2
11686
        if (IS_INTEL_AVX2(intel_flags)) {
11687
            AES_GCM_encrypt_avx2(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
#if defined(HAVE_INTEL_AVX1)
11694
        if (IS_INTEL_AVX1(intel_flags)) {
11695
            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11696
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
11697
            ret = 0;
11698
        } else
11699
#endif
11700
        {
11701
            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11702
                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
11703
            ret = 0;
11704
        }
11705
    }
11706
    else
11707
#endif /* WOLFSSL_AESNI */
11708
0
    {
11709
0
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11710
0
                                authIn, authInSz);
11711
0
    }
11712
0
#endif
11713
11714
0
    VECTOR_REGISTERS_POP;
11715
11716
0
    return ret;
11717
0
}
11718
#endif
11719
11720
11721
/* AES GCM Decrypt */
11722
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
11723
#ifdef FREESCALE_LTC_AES_GCM
11724
int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
11725
                   const byte* iv, word32 ivSz,
11726
                   const byte* authTag, word32 authTagSz,
11727
                   const byte* authIn, word32 authInSz)
11728
{
11729
    int ret;
11730
    word32 keySize;
11731
    status_t status;
11732
11733
    /* argument checks */
11734
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
11735
     * in and out are don't cares, as this is is the GMAC case. */
11736
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
11737
        authTag == NULL || ivSz == 0 ||
11738
        ((authInSz > 0) && (authIn == NULL)))
11739
    {
11740
        return BAD_FUNC_ARG;
11741
    }
11742
11743
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
11744
    if (ret != 0)
11745
        return ret;
11746
11747
    ret = wc_AesGetKeySize(aes, &keySize);
11748
    if (ret != 0) {
11749
        return ret;
11750
    }
11751
11752
    status = wolfSSL_CryptHwMutexLock();
11753
    if (status != 0)
11754
        return status;
11755
11756
    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
11757
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
11758
    wolfSSL_CryptHwMutexUnLock();
11759
11760
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
11761
}
11762
11763
#else
11764
11765
#ifdef STM32_CRYPTO_AES_GCM
11766
/* this function supports inline decrypt */
11767
/* Not static: called by the CubeMX crypto-callback device (see encrypt). */
11768
WOLFSSL_LOCAL WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
11769
                                  Aes* aes, byte* out,
11770
                                  const byte* in, word32 sz,
11771
                                  const byte* iv, word32 ivSz,
11772
                                  const byte* authTag, word32 authTagSz,
11773
                                  const byte* authIn, word32 authInSz)
11774
{
11775
    int ret;
11776
#ifdef WOLFSSL_STM32_CUBEMX
11777
    int status = HAL_OK;
11778
    CRYP_HandleTypeDef hcryp;
11779
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
11780
#else
11781
    int status = SUCCESS;
11782
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
11783
#endif
11784
    word32 keySize;
11785
    word32 partial = sz % WC_AES_BLOCK_SIZE;
11786
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
11787
    word32 tagExpected[WC_AES_BLOCK_SIZE/sizeof(word32)];
11788
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
11789
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
11790
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
11791
    byte* authInPadded = NULL;
11792
    word32 authPadSz;
11793
    int wasAlloc = 0, tagComputed = 0;
11794
11795
    ret = wc_AesGetKeySize(aes, &keySize);
11796
    if (ret != 0)
11797
        return ret;
11798
11799
#ifdef WOLFSSL_STM32_CUBEMX
11800
    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
11801
    if (ret != 0)
11802
        return ret;
11803
#endif
11804
11805
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
11806
    if (ivSz == GCM_NONCE_MID_SZ) {
11807
        byte* pCtr = (byte*)ctr;
11808
        XMEMCPY(ctr, iv, ivSz);
11809
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
11810
    }
11811
    else {
11812
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
11813
    }
11814
11815
    /* Make copy of expected authTag, which could get corrupted in some
11816
     * Cube HAL versions without proper partial block support.
11817
     * For TLS blocks the authTag is after the output buffer, so save it */
11818
    XMEMCPY(tagExpected, authTag, authTagSz);
11819
11820
    /* Authentication buffer */
11821
#if STM_CRYPT_HEADER_WIDTH == 1
11822
    authPadSz = 0; /* CubeHAL supports byte mode */
11823
#else
11824
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
11825
#endif
11826
#ifdef WOLFSSL_STM32MP13
11827
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
11828
     * minimum of 16 bytes for the auth */
11829
    if ((authInSz > 0) && (authInSz < 16)) {
11830
        authPadSz = 16 - authInSz;
11831
    }
11832
#else
11833
    if (authPadSz != 0) {
11834
        authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
11835
    }
11836
    else {
11837
        authPadSz = authInSz;
11838
    }
11839
#endif
11840
11841
    /* for cases where hardware cannot be used for authTag calculate it */
11842
    /* if IV is not 12 calculate GHASH using software */
11843
    if (ivSz != GCM_NONCE_MID_SZ
11844
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
11845
        /* or hardware that does not support partial block */
11846
        || sz == 0 || partial != 0
11847
    #endif
11848
    #if STM_CRYPT_HEADER_WIDTH == 4
11849
        /* or authIn is not a multiple of 4  */
11850
        || authPadSz != authInSz
11851
    #endif
11852
    ) {
11853
        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
11854
        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
11855
        if (ret != 0) {
11856
            wc_Stm32_Aes_Cleanup();
11857
            return ret;
11858
        }
11859
        xorbuf(tag, partialBlock, sizeof(tag));
11860
        tagComputed = 1;
11861
    }
11862
11863
    /* Zero pad and word align the buffer the HAL reads the auth header
11864
     * from (SA0076). authPadSz, the length reported to the HAL, is
11865
     * unchanged, so the hardware tag is unaffected.
11866
     * This must NOT be gated on !tagComputed. tagComputed only selects
11867
     * who produces the tag; hcryp.Init.Header and HeaderSize are still
11868
     * handed to the HAL below and are still read during the header phase
11869
     * of the payload call, which the HAL runs whether or not we later ask
11870
     * it for the tag. The over read happens on the software tag path too. */
11871
    ret = wc_AesGcmAuthPad_STM32(aes, authIn, authInSz, authPadSz,
11872
        authhdr, (word32)sizeof(authhdr), &authInPadded, &wasAlloc);
11873
    if (ret != 0) {
11874
        wc_Stm32_Aes_Cleanup();
11875
        return ret;
11876
    }
11877
11878
    /* Hardware requires counter + 1 */
11879
    IncrementGcmCounter((byte*)ctr);
11880
11881
    ret = wolfSSL_CryptHwMutexLock();
11882
    if (ret != 0) {
11883
        if (wasAlloc) {
11884
            XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
11885
        }
11886
        wc_Stm32_Aes_Cleanup();
11887
        return ret;
11888
    }
11889
11890
#ifdef WOLFSSL_STM32_CUBEMX
11891
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11892
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
11893
11894
#if defined(STM32_HAL_V2)
11895
    hcryp.Init.Algorithm = CRYP_AES_GCM;
11896
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
11897
    #ifdef CRYP_KEYIVCONFIG_ONCE
11898
    /* allows repeated calls to HAL_CRYP_Decrypt */
11899
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
11900
    #endif
11901
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
11902
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
11903
    HAL_CRYP_Init(&hcryp);
11904
11905
    #ifndef CRYP_KEYIVCONFIG_ONCE
11906
    /* GCM payload phase - can handle partial blocks */
11907
    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
11908
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
11909
    #else
11910
    /* GCM payload phase - blocks */
11911
    if (blocks) {
11912
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
11913
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
11914
    }
11915
    /* GCM payload phase - partial remainder */
11916
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11917
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11918
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11919
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
11920
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
11921
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11922
    }
11923
    #endif
11924
    if (status == HAL_OK && !tagComputed) {
11925
        /* Compute the authTag */
11926
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
11927
            STM32_HAL_TIMEOUT);
11928
    }
11929
#elif defined(STM32_CRYPTO_AES_ONLY)
11930
    /* Set the CRYP parameters */
11931
    hcryp.Init.HeaderSize = authPadSz;
11932
    if (authPadSz == 0)
11933
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
11934
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
11935
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
11936
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
11937
    HAL_CRYP_Init(&hcryp);
11938
11939
    /* GCM init phase */
11940
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11941
    if (status == HAL_OK) {
11942
        /* GCM header phase */
11943
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
11944
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
11945
    }
11946
    if (status == HAL_OK) {
11947
        /* GCM payload phase - blocks */
11948
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
11949
        if (blocks) {
11950
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
11951
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11952
        }
11953
    }
11954
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
11955
        /* GCM payload phase - partial remainder */
11956
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11957
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11958
        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
11959
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
11960
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11961
    }
11962
    if (status == HAL_OK && tagComputed == 0) {
11963
        /* GCM final phase */
11964
        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
11965
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
11966
    }
11967
#else
11968
    hcryp.Init.HeaderSize = authPadSz;
11969
    HAL_CRYP_Init(&hcryp);
11970
    if (blocks) {
11971
        /* GCM payload phase - blocks */
11972
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
11973
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
11974
    }
11975
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
11976
        /* GCM payload phase - partial remainder */
11977
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
11978
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
11979
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
11980
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
11981
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
11982
    }
11983
    if (status == HAL_OK && tagComputed == 0) {
11984
        /* Compute the authTag */
11985
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
11986
    }
11987
#endif
11988
11989
    if (status != HAL_OK)
11990
        ret = AES_GCM_AUTH_E;
11991
11992
    HAL_CRYP_DeInit(&hcryp);
11993
11994
#else /* Standard Peripheral Library */
11995
    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
11996
11997
    /* Input size and auth size need to be the actual sizes, even though
11998
     * they are not block aligned, because this length (in bits) is used
11999
     * in the final GHASH. */
12000
    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
12001
    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
12002
                         (uint8_t*)keyCopy,      keySize * 8,
12003
                         (uint8_t*)in,           sz,
12004
                         (uint8_t*)authInPadded, authInSz,
12005
                         (uint8_t*)out,          (uint8_t*)partialBlock);
12006
    if (status != SUCCESS)
12007
        ret = AES_GCM_AUTH_E;
12008
    if (tagComputed == 0)
12009
        XMEMCPY(tag, partialBlock, authTagSz);
12010
#endif /* WOLFSSL_STM32_CUBEMX */
12011
    wolfSSL_CryptHwMutexUnLock();
12012
    wc_Stm32_Aes_Cleanup();
12013
12014
    /* Check authentication tag */
12015
    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
12016
        ret = AES_GCM_AUTH_E;
12017
    }
12018
12019
    /* Free memory */
12020
    if (wasAlloc) {
12021
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
12022
    }
12023
12024
    return ret;
12025
}
12026
12027
#endif /* STM32_CRYPTO_AES_GCM */
12028
12029
#if !defined(WOLFSSL_ARMASM) && !(defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
12030
#ifdef WOLFSSL_AESNI
12031
/* For performance reasons, this code needs to be not inlined. */
12032
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
12033
                      Aes* aes, byte* out, const byte* in, word32 sz,
12034
                      const byte* iv, word32 ivSz,
12035
                      const byte* authTag, word32 authTagSz,
12036
                      const byte* authIn, word32 authInSz);
12037
#else
12038
static
12039
#endif
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
0
{
12046
0
    int ret;
12047
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
12048
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
12049
0
    const byte* c = in;
12050
0
    byte* p = out;
12051
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
12052
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
12053
0
    ALIGN16 byte Tprime[WC_AES_BLOCK_SIZE];
12054
0
    ALIGN16 byte EKY0[WC_AES_BLOCK_SIZE];
12055
0
    volatile sword32 res;
12056
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
12057
0
    byte mask;
12058
0
    word32 i;
12059
0
#endif
12060
12061
0
    if (ivSz == GCM_NONCE_MID_SZ) {
12062
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
12063
0
        XMEMCPY(counter, iv, ivSz);
12064
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
12065
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
12066
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
12067
0
    }
12068
0
    else {
12069
        /* Counter is GHASH of IV. */
12070
#ifdef OPENSSL_EXTRA
12071
        word32 aadTemp = aes->gcm.aadLen;
12072
        aes->gcm.aadLen = 0;
12073
#endif
12074
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
12075
#ifdef OPENSSL_EXTRA
12076
        aes->gcm.aadLen = aadTemp;
12077
#endif
12078
0
    }
12079
12080
    /* Calc the authTag again using received auth data and the cipher text */
12081
0
    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
12082
0
    ret = wc_AesEncrypt(aes, counter, EKY0);
12083
0
    if (ret != 0)
12084
0
        return ret;
12085
0
    xorbuf(Tprime, EKY0, sizeof(Tprime));
12086
#ifdef WC_AES_GCM_DEC_AUTH_EARLY
12087
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
12088
     * the pairwise bytes in the strings.
12089
     */
12090
    res = ConstantCompare(authTag, Tprime, authTagSz);
12091
    /* convert positive retval from ConstantCompare() to all-1s word, in
12092
     * constant time.
12093
     */
12094
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
12095
    ret = res & AES_GCM_AUTH_E;
12096
    if (ret != 0)
12097
        return ret;
12098
#endif
12099
12100
#ifdef OPENSSL_EXTRA
12101
    if (!out) {
12102
        /* authenticated, non-confidential data */
12103
        /* store AAD size for next call */
12104
        aes->gcm.aadLen = authInSz;
12105
    }
12106
#endif
12107
12108
#if defined(WOLFSSL_PIC32MZ_CRYPT)
12109
    if (blocks) {
12110
        /* use initial IV for HW, but don't use it below */
12111
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
12112
12113
        ret = wc_Pic32AesCrypt(
12114
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
12115
            out, in, (blocks * WC_AES_BLOCK_SIZE),
12116
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
12117
        if (ret != 0)
12118
            return ret;
12119
    }
12120
    /* process remainder using partial handling */
12121
#endif
12122
12123
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
12124
    /* some hardware acceleration can gain performance from doing AES encryption
12125
     * of the whole buffer at once */
12126
    if (c != p && blocks > 0) { /* can not handle inline decryption */
12127
        while (blocks--) {
12128
            IncrementGcmCounter(counter);
12129
            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
12130
            p += WC_AES_BLOCK_SIZE;
12131
        }
12132
12133
        /* reset number of blocks and then do encryption */
12134
        blocks = sz / WC_AES_BLOCK_SIZE;
12135
12136
        ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
12137
        if (ret != 0) {
12138
            ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
12139
            return ret;
12140
        }
12141
        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
12142
        c += WC_AES_BLOCK_SIZE * blocks;
12143
    }
12144
    else
12145
#endif /* HAVE_AES_ECB && !PIC32MZ */
12146
0
    {
12147
0
        while (blocks--) {
12148
0
            IncrementGcmCounter(counter);
12149
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
12150
0
            ret = wc_AesEncrypt(aes, counter, scratch);
12151
0
            if (ret != 0)
12152
0
                return ret;
12153
0
            xorbufout(p, scratch, c, WC_AES_BLOCK_SIZE);
12154
0
        #endif
12155
0
            p += WC_AES_BLOCK_SIZE;
12156
0
            c += WC_AES_BLOCK_SIZE;
12157
0
        }
12158
0
    }
12159
12160
0
    if (partial != 0) {
12161
0
        IncrementGcmCounter(counter);
12162
0
        ret = wc_AesEncrypt(aes, counter, scratch);
12163
0
        if (ret != 0)
12164
0
            return ret;
12165
0
        xorbuf(scratch, c, partial);
12166
0
        XMEMCPY(p, scratch, partial);
12167
0
    }
12168
12169
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
12170
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
12171
     * the pairwise bytes in the strings.
12172
     */
12173
0
    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
12174
    /* convert positive retval from ConstantCompare() to all-1s word, in
12175
     * constant time.
12176
     */
12177
0
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
12178
    /* now use res as a mask for constant time return of ret, unless tag
12179
     * mismatch, whereupon AES_GCM_AUTH_E is returned.
12180
     */
12181
0
    ret = (ret & ~res);
12182
0
    ret |= (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
12183
    /* Mask the output on auth failure instead of branching, to keep the tag
12184
     * compare constant time. res is all-ones on mismatch, zero on match. A
12185
     * single vectorizable pass is cheaper than folding the mask into the
12186
     * decrypt loop. Not needed for WC_AES_GCM_DEC_AUTH_EARLY: there the tag is
12187
     * checked before decryption, so out is never written on a mismatch. */
12188
0
    mask = (byte)res;
12189
0
    for (i = 0; i < sz; i++) {
12190
0
        out[i] &= (byte)~mask;
12191
0
    }
12192
0
#endif
12193
0
    return ret;
12194
0
}
12195
#elif (defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
12196
      defined(WOLFSSL_ARM32_AES_DISPATCH) || \
12197
      (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
12198
static int AES_GCM_decrypt_ASM(Aes* aes, byte* out, const byte* in,
12199
    word32 sz, const byte* iv, word32 ivSz, const byte* authTag,
12200
    word32 authTagSz, const byte* authIn, word32 authInSz)
12201
{
12202
    word32 blocks;
12203
    word32 partial;
12204
    byte counter[WC_AES_BLOCK_SIZE];
12205
    byte initialCounter[WC_AES_BLOCK_SIZE];
12206
    byte scratch[WC_AES_BLOCK_SIZE];
12207
    ALIGN_GCM_TAG byte x[WC_AES_BLOCK_SIZE];
12208
12209
    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
12210
    if (ivSz == GCM_NONCE_MID_SZ) {
12211
        XMEMCPY(initialCounter, iv, ivSz);
12212
        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
12213
    }
12214
    else {
12215
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
12216
    }
12217
    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
12218
12219
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
12220
    /* Hash in the Additional Authentication Data */
12221
    if (authInSz != 0 && authIn != NULL) {
12222
        blocks = authInSz / WC_AES_BLOCK_SIZE;
12223
        partial = authInSz % WC_AES_BLOCK_SIZE;
12224
        if (blocks > 0) {
12225
            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
12226
            authIn += blocks * WC_AES_BLOCK_SIZE;
12227
        }
12228
        if (partial != 0) {
12229
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
12230
            XMEMCPY(scratch, authIn, partial);
12231
            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
12232
        }
12233
    }
12234
12235
    blocks = sz / WC_AES_BLOCK_SIZE;
12236
    partial = sz % WC_AES_BLOCK_SIZE;
12237
    /* do as many blocks as possible */
12238
    if (blocks > 0) {
12239
        GCM_GMULT_LEN(&aes->gcm, x, in, blocks * WC_AES_BLOCK_SIZE);
12240
12241
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
12242
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
12243
        if (sz >= 32)
12244
    #endif
12245
        {
12246
            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
12247
                (const unsigned char*)aes->key, aes->rounds, counter);
12248
        }
12249
    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
12250
        else
12251
    #endif
12252
    #endif
12253
    /* Base AES is only left out on AArch64 - see wc_AesCbcDecrypt. */
12254
    #if !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP) || !defined(__aarch64__)
12255
        {
12256
            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
12257
                (const unsigned char*)aes->key, aes->rounds, counter);
12258
        }
12259
    #endif
12260
        in += blocks * WC_AES_BLOCK_SIZE;
12261
        out += blocks * WC_AES_BLOCK_SIZE;
12262
    }
12263
    if (partial != 0) {
12264
        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
12265
        XMEMCPY(scratch, in, partial);
12266
        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
12267
12268
    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
12269
        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
12270
        {
12271
            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
12272
                (const unsigned char*)aes->key, aes->rounds, counter);
12273
        }
12274
    #else
12275
        {
12276
            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
12277
                (const unsigned char*)aes->key, aes->rounds, counter);
12278
        }
12279
    #endif
12280
        XMEMCPY(out, scratch, partial);
12281
    }
12282
12283
    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
12284
    FlattenSzInBits(&scratch[0], authInSz);
12285
    FlattenSzInBits(&scratch[8], sz);
12286
    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
12287
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
12288
    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
12289
    {
12290
        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
12291
            (const unsigned char*)aes->key, aes->rounds);
12292
    }
12293
#else
12294
    {
12295
        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
12296
            (const unsigned char*)aes->key, aes->rounds);
12297
    }
12298
#endif
12299
    xorbuf(x, scratch, authTagSz);
12300
    if (authTag != NULL) {
12301
        if (ConstantCompare(authTag, x, authTagSz) != 0) {
12302
            return AES_GCM_AUTH_E;
12303
        }
12304
    }
12305
12306
    return 0;
12307
}
12308
#endif
12309
12310
/* Software AES - GCM Decrypt */
12311
int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
12312
                     const byte* iv, word32 ivSz,
12313
                     const byte* authTag, word32 authTagSz,
12314
                     const byte* authIn, word32 authInSz)
12315
0
{
12316
0
    int ret;
12317
#ifdef WOLFSSL_AESNI
12318
    int res = WC_NO_ERR_TRACE(AES_GCM_AUTH_E);
12319
#endif
12320
12321
    /* argument checks */
12322
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
12323
     * in and out are don't cares, as this is is the GMAC case. */
12324
0
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
12325
0
        authTag == NULL || ivSz == 0)
12326
0
    {
12327
0
        return BAD_FUNC_ARG;
12328
0
    }
12329
12330
0
    ret = wc_local_AesGcmCheckTagSz(authTagSz);
12331
0
    if (ret != 0)
12332
0
        return ret;
12333
12334
    /* No FIPS check on ivSz in decrypt mode -- SP 800-38D IV
12335
     * construction requirements bind encryption only; decryption must
12336
     * accept externally generated IVs of any supported length.
12337
     */
12338
12339
#ifdef WOLF_CRYPTO_CB
12340
    #ifndef WOLF_CRYPTO_CB_FIND
12341
    if (aes->devId != INVALID_DEVID)
12342
    #endif
12343
    {
12344
        int crypto_cb_ret =
12345
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
12346
                                      authTag, authTagSz, authIn, authInSz);
12347
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
12348
            return crypto_cb_ret;
12349
        /* fall-through when unavailable */
12350
    }
12351
#endif
12352
12353
    /* Software/HW key schedule (and hash subkey H) required from here on. */
12354
0
    if (!WC_AES_KEY_IS_SET(aes)) {
12355
0
        WOLFSSL_MSG("AES key not set");
12356
0
        return MISSING_KEY;
12357
0
    }
12358
12359
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
12360
    /* if async and byte count above threshold */
12361
    /* only 12-byte IV is supported in HW */
12362
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
12363
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
12364
    #if defined(HAVE_CAVIUM)
12365
        #ifdef HAVE_CAVIUM_V
12366
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
12367
            return NitroxAesGcmDecrypt(aes, out, in, sz,
12368
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
12369
                authTag, authTagSz, authIn, authInSz);
12370
        }
12371
        #endif
12372
    #elif defined(HAVE_INTEL_QA)
12373
        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
12374
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
12375
            authTag, authTagSz, authIn, authInSz);
12376
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
12377
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
12378
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
12379
            sw->aes.aes = aes;
12380
            sw->aes.out = out;
12381
            sw->aes.in = in;
12382
            sw->aes.sz = sz;
12383
            sw->aes.iv = iv;
12384
            sw->aes.ivSz = ivSz;
12385
            sw->aes.authTag = (byte*)authTag;
12386
            sw->aes.authTagSz = authTagSz;
12387
            sw->aes.authIn = authIn;
12388
            sw->aes.authInSz = authInSz;
12389
            return WC_PENDING_E;
12390
        }
12391
    #endif
12392
    }
12393
#endif /* WOLFSSL_ASYNC_CRYPT */
12394
12395
#ifdef WOLFSSL_SILABS_SE_ACCEL
12396
    return wc_AesGcmDecrypt_silabs(
12397
        aes, out, in, sz, iv, ivSz,
12398
        authTag, authTagSz, authIn, authInSz);
12399
12400
#endif
12401
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
12402
#ifndef TA_AES_GCM_MAX_DATA_SIZE
12403
    #define TA_AES_GCM_MAX_DATA_SIZE 996u
12404
#endif
12405
    if (aes != NULL &&
12406
        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
12407
        ivSz == TA_AES_GCM_IV_LENGTH &&
12408
        authTagSz == TA_AES_GCM_TAG_LENGTH &&
12409
        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
12410
        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
12411
        return wc_Microchip_AesGcmDecrypt(
12412
            aes, out, in, sz, iv, ivSz,
12413
            authTag, authTagSz, authIn, authInSz);
12414
    }
12415
#endif
12416
12417
#if defined(WOLFSSL_STM32_BARE) && defined(STM32_CRYPTO) && \
12418
    !defined(WOLF_CRYPTO_CB_ONLY_AES)
12419
    /* BARE: HW GCM decrypt-verify on both AES IPs -- the TinyAES GCM engine
12420
     * (H5/U5/L5/U3/WBA/...) and the CRYP IP (F2/F4/F7/H7/MP13), the latter
12421
     * validated on NUCLEO-F439ZI against the SP 800-38D vectors;
12422
     * otherwise wc_Stm32_Aes_Gcm returns CRYPTOCB_UNAVAILABLE and the well-tested
12423
     * SW path runs (its AES blocks still on HW via wc_AesEncrypt). The received
12424
     * tag is verified inside wc_Stm32_Aes_Gcm (const cast: it compares, never
12425
     * writes, on the decrypt path). Excluded under WOLF_CRYPTO_CB_ONLY_AES for
12426
     * the same reason as the encrypt path above -- the key is only in
12427
     * aes->devKey there, so HW GCM must go through the crypto-cb device. */
12428
    ret = wc_Stm32_Aes_Gcm(aes, out, in, sz, iv, ivSz,
12429
                           (byte*)authTag, authTagSz,
12430
                           authIn, authInSz, 0 /* dec */);
12431
    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
12432
        return ret;
12433
    /* fall through to SW GCM decrypt */
12434
#endif /* WOLFSSL_STM32_BARE && STM32_CRYPTO && !WOLF_CRYPTO_CB_ONLY_AES */
12435
12436
#ifdef STM32_CRYPTO_AES_GCM
12437
    /* The STM standard peripheral library API's doesn't support partial blocks */
12438
    return wc_AesGcmDecrypt_STM32(
12439
        aes, out, in, sz, iv, ivSz,
12440
        authTag, authTagSz, authIn, authInSz);
12441
#endif /* STM32_CRYPTO_AES_GCM */
12442
12443
#if defined(WOLFSSL_PSOC6_CRYPTO)
12444
    return wc_Psoc6_Aes_GcmDecrypt(aes, out, in, sz, iv, ivSz, authTag,
12445
                                   authTagSz, authIn, authInSz);
12446
#endif /* WOLFSSL_PSOC6_CRYPTO */
12447
12448
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) || \
12449
    defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
12450
    return AES_GCM_decrypt_RISCV64((byte*)in, out, sz, iv, ivSz, authTag,
12451
        authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
12452
        (byte*)aes->tmp, (byte*)aes->reg, (int)aes->rounds);
12453
#elif defined(WOLFSSL_RISCV_ASM)
12454
    return AES_GCM_decrypt_RISCV64((byte*)in, out, sz, iv, ivSz, authTag,
12455
        authTagSz, authIn, authInSz, (byte*)aes->key, AES_GCM_H_PTR(aes),
12456
        (byte*)aes->tmp, (byte*)aes->reg, (int)aes->rounds);
12457
#endif
12458
12459
0
    VECTOR_REGISTERS_PUSH;
12460
12461
#if defined(WOLFSSL_ARMASM)
12462
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
12463
#ifndef __aarch64__
12464
  #ifdef WOLFSSL_ARM32_AES_DISPATCH
12465
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto)
12466
  #endif
12467
    {
12468
    #ifdef OPENSSL_EXTRA
12469
        word32 reg[WC_AES_BLOCK_SIZE / sizeof(word32)];
12470
    #endif
12471
        /* Reflect a copy of H into the form the PMULL assembly wants - the
12472
         * stored H must stay un-reflected for the portable GHASH. */
12473
        byte h[WC_AES_BLOCK_SIZE];
12474
12475
    #ifdef OPENSSL_EXTRA
12476
        XMEMCPY(reg, aes->reg, sizeof(reg));
12477
    #endif
12478
        XMEMCPY(h, aes->gcm.H, WC_AES_BLOCK_SIZE);
12479
        GcmReflectH(h);
12480
        ret = AES_GCM_decrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
12481
            authIn, authInSz, (byte*)aes->key, h, (byte*)aes->tmp,
12482
            (byte*)aes->reg, aes->rounds);
12483
        ForceZero(h, sizeof(h));
12484
    #ifdef OPENSSL_EXTRA
12485
        XMEMCPY(aes->reg, reg, sizeof(reg));
12486
    #endif
12487
    }
12488
  #ifdef WOLFSSL_ARM32_AES_DISPATCH
12489
    else
12490
  #endif
12491
#else
12492
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12493
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12494
        if (aes->use_sha3_hw_crypto) {
12495
            ret = AES_GCM_decrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
12496
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
12497
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
12498
        }
12499
        else
12500
    #endif
12501
        {
12502
            ret = AES_GCM_decrypt_AARCH64(in, out, sz, iv, ivSz, authTag,
12503
                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
12504
                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
12505
        }
12506
    }
12507
    else
12508
#endif /* !__aarch64__ */
12509
#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
12510
#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
12511
    defined(WOLFSSL_ARM32_AES_DISPATCH)
12512
    {
12513
        ret = AES_GCM_decrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
12514
            authTagSz, authIn, authInSz);
12515
    }
12516
#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO ||
12517
        * WOLFSSL_ARM32_AES_DISPATCH */
12518
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
12519
    {
12520
        ret = AES_GCM_decrypt_ASM(aes, out, in, sz, iv, ivSz, authTag,
12521
            authTagSz, authIn, authInSz);
12522
    }
12523
#else
12524
#ifdef WOLFSSL_AESNI
12525
    if (aes->use_aesni) {
12526
#ifdef HAVE_INTEL_AVX512
12527
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
12528
            IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12529
            AES_GCM_decrypt_avx512(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12530
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12531
            if (res == 0)
12532
                ret = AES_GCM_AUTH_E;
12533
            else
12534
                ret = 0;
12535
        }
12536
        else
12537
#endif
12538
#ifdef HAVE_INTEL_VAES
12539
        if ((sz >= WC_AES_BLOCK_SIZE * WC_VAES_GCM_MIN_BLOCKS) &&
12540
            IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12541
            AES_GCM_decrypt_vaes(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12542
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12543
            if (res == 0)
12544
                ret = AES_GCM_AUTH_E;
12545
            else
12546
                ret = 0;
12547
        }
12548
        else
12549
#endif
12550
#ifdef HAVE_INTEL_AVX2
12551
        if (IS_INTEL_AVX2(intel_flags)) {
12552
            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12553
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12554
            if (res == 0)
12555
                ret = AES_GCM_AUTH_E;
12556
            else
12557
                ret = 0;
12558
        }
12559
        else
12560
#endif
12561
#if defined(HAVE_INTEL_AVX1)
12562
        if (IS_INTEL_AVX1(intel_flags)) {
12563
            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12564
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12565
            if (res == 0)
12566
                ret = AES_GCM_AUTH_E;
12567
            else
12568
                ret = 0;
12569
        }
12570
        else
12571
#endif
12572
        {
12573
            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
12574
                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
12575
            if (res == 0)
12576
                ret = AES_GCM_AUTH_E;
12577
            else
12578
                ret = 0;
12579
        }
12580
    }
12581
    else
12582
#endif /* WOLFSSL_AESNI */
12583
0
    {
12584
0
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
12585
0
                                                             authIn, authInSz);
12586
0
    }
12587
0
#endif
12588
12589
0
    VECTOR_REGISTERS_POP;
12590
12591
0
    return ret;
12592
0
}
12593
#endif
12594
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
12595
12596
#ifdef WOLFSSL_AESGCM_STREAM
12597
12598
/* Initialize the AES GCM cipher with an IV. C implementation.
12599
 *
12600
 * @param [in, out] aes   AES object.
12601
 * @param [in]      iv    IV/nonce buffer.
12602
 * @param [in]      ivSz  Length of IV/nonce data.
12603
 */
12604
static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
12605
{
12606
    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
12607
    int ret;
12608
12609
    if (ivSz == GCM_NONCE_MID_SZ) {
12610
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
12611
        XMEMCPY(counter, iv, ivSz);
12612
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
12613
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
12614
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
12615
    }
12616
    else {
12617
        /* Counter is GHASH of IV. */
12618
    #ifdef OPENSSL_EXTRA
12619
        word32 aadTemp = aes->gcm.aadLen;
12620
        aes->gcm.aadLen = 0;
12621
    #endif
12622
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
12623
    #ifdef OPENSSL_EXTRA
12624
        aes->gcm.aadLen = aadTemp;
12625
    #endif
12626
    }
12627
12628
    /* Copy in the counter for use with cipher. */
12629
    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
12630
    /* Encrypt initial counter into a buffer for GCM. */
12631
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
12632
    if (ret != 0)
12633
        return ret;
12634
    /* Reset state fields. */
12635
    aes->over = 0;
12636
    aes->aSz = 0;
12637
    aes->cSz = 0;
12638
    /* Initialization for GHASH. */
12639
    GHASH_INIT(aes);
12640
12641
    return 0;
12642
}
12643
12644
/* Update the AES GCM cipher with data. C implementation.
12645
 *
12646
 * Only enciphers data.
12647
 *
12648
 * @param [in, out] aes  AES object.
12649
 * @param [in]      out  Cipher text or plaintext buffer.
12650
 * @param [in]      in   Plaintext or cipher text buffer.
12651
 * @param [in]      sz   Length of data.
12652
 */
12653
static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
12654
    Aes* aes, byte* out, const byte* in, word32 sz)
12655
{
12656
    word32 blocks;
12657
    word32 partial;
12658
    int ret;
12659
12660
    /* Check if previous encrypted block was not used up. */
12661
    if (aes->over > 0) {
12662
        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
12663
        if (pSz > sz) pSz = (byte)sz;
12664
12665
        /* Use some/all of last encrypted block. */
12666
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
12667
        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
12668
12669
        /* Some data used. */
12670
        sz  -= pSz;
12671
        in  += pSz;
12672
        out += pSz;
12673
    }
12674
12675
    /* Calculate the number of blocks needing to be encrypted and any leftover.
12676
     */
12677
    blocks  = sz / WC_AES_BLOCK_SIZE;
12678
    partial = sz & (WC_AES_BLOCK_SIZE - 1);
12679
12680
#if defined(HAVE_AES_ECB)
12681
    /* Some hardware acceleration can gain performance from doing AES encryption
12682
     * of the whole buffer at once.
12683
     * Overwrites the cipher text before using plaintext - no inline encryption.
12684
     */
12685
    if ((out != in) && blocks > 0) {
12686
        word32 b;
12687
        /* Place incrementing counter blocks into cipher text. */
12688
        for (b = 0; b < blocks; b++) {
12689
            IncrementGcmCounter(AES_COUNTER(aes));
12690
            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
12691
        }
12692
12693
        /* Encrypt counter blocks. */
12694
        ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
12695
        if (ret != 0) {
12696
            ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
12697
            return ret;
12698
        }
12699
        /* XOR in plaintext. */
12700
        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
12701
        /* Skip over processed data. */
12702
        in += WC_AES_BLOCK_SIZE * blocks;
12703
        out += WC_AES_BLOCK_SIZE * blocks;
12704
    }
12705
    else
12706
#endif /* HAVE_AES_ECB */
12707
    {
12708
        /* Encrypt block by block. */
12709
        while (blocks--) {
12710
            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
12711
            IncrementGcmCounter(AES_COUNTER(aes));
12712
            /* Encrypt counter into a buffer. */
12713
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
12714
            if (ret != 0)
12715
                return ret;
12716
            /* XOR plain text into encrypted counter into cipher text buffer. */
12717
            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
12718
            /* Data complete. */
12719
            in  += WC_AES_BLOCK_SIZE;
12720
            out += WC_AES_BLOCK_SIZE;
12721
        }
12722
    }
12723
12724
    if (partial != 0) {
12725
        /* Generate an extra block and use up as much as needed. */
12726
        IncrementGcmCounter(AES_COUNTER(aes));
12727
        /* Encrypt counter into cache. */
12728
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
12729
        if (ret != 0)
12730
            return ret;
12731
        /* XOR plain text into encrypted counter into cipher text buffer. */
12732
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
12733
        /* Keep amount of encrypted block used. */
12734
        aes->over = (byte)partial;
12735
    }
12736
12737
    return 0;
12738
}
12739
12740
/* Calculates authentication tag for AES GCM. C implementation.
12741
 *
12742
 * @param [in, out] aes        AES object.
12743
 * @param [out]     authTag    Buffer to store authentication tag in.
12744
 * @param [in]      authTagSz  Length of tag to create.
12745
 */
12746
static WARN_UNUSED_RESULT int AesGcmFinal_C(
12747
    Aes* aes, byte* authTag, word32 authTagSz)
12748
{
12749
    /* Calculate authentication tag. */
12750
    GHASH_FINAL(aes, authTag, authTagSz);
12751
    /* XOR in as much of encrypted counter as is required. */
12752
    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
12753
#ifdef OPENSSL_EXTRA
12754
    /* store AAD size for next call */
12755
    aes->gcm.aadLen = aes->aSz;
12756
#endif
12757
    /* Zeroize last block to protect sensitive data. */
12758
    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
12759
12760
    return 0;
12761
}
12762
12763
#ifdef WOLFSSL_AESNI
12764
12765
#ifdef __cplusplus
12766
    extern "C" {
12767
#endif
12768
12769
/* Assembly code implementations in: aes_gcm_asm.S */
12770
#ifdef HAVE_INTEL_AVX2
12771
extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
12772
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12773
    unsigned char* counter, unsigned char* initCtr);
12774
#ifdef HAVE_INTEL_AVX512
12775
extern void AES_GCM_init_avx512(const unsigned char* key, int nr,
12776
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12777
    unsigned char* counter, unsigned char* initCtr);
12778
#endif
12779
#ifdef HAVE_INTEL_VAES
12780
extern void AES_GCM_init_vaes(const unsigned char* key, int nr,
12781
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12782
    unsigned char* counter, unsigned char* initCtr);
12783
#endif
12784
extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
12785
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12786
#ifdef HAVE_INTEL_AVX512
12787
extern void AES_GCM_aad_update_avx512(const unsigned char* addt,
12788
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12789
#endif
12790
#ifdef HAVE_INTEL_VAES
12791
extern void AES_GCM_aad_update_vaes(const unsigned char* addt,
12792
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12793
#endif
12794
extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
12795
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12796
#ifdef HAVE_INTEL_AVX512
12797
extern void AES_GCM_encrypt_block_avx512(const unsigned char* key, int nr,
12798
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12799
#endif
12800
#ifdef HAVE_INTEL_VAES
12801
extern void AES_GCM_encrypt_block_vaes(const unsigned char* key, int nr,
12802
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12803
#endif
12804
extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
12805
    unsigned char* tag, unsigned char* h);
12806
#ifdef HAVE_INTEL_AVX512
12807
extern void AES_GCM_ghash_block_avx512(const unsigned char* data,
12808
    unsigned char* tag, unsigned char* h);
12809
#endif
12810
#ifdef HAVE_INTEL_VAES
12811
extern void AES_GCM_ghash_block_vaes(const unsigned char* data,
12812
    unsigned char* tag, unsigned char* h);
12813
#endif
12814
12815
extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
12816
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12817
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12818
#ifdef HAVE_INTEL_AVX512
12819
extern void AES_GCM_encrypt_update_avx512(const unsigned char* key, int nr,
12820
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12821
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12822
#endif
12823
#ifdef HAVE_INTEL_VAES
12824
extern void AES_GCM_encrypt_update_vaes(const unsigned char* key, int nr,
12825
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12826
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12827
#endif
12828
extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
12829
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12830
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12831
#ifdef HAVE_INTEL_AVX512
12832
extern void AES_GCM_encrypt_final_avx512(unsigned char* tag,
12833
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12834
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12835
#endif
12836
#ifdef HAVE_INTEL_VAES
12837
extern void AES_GCM_encrypt_final_vaes(unsigned char* tag,
12838
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12839
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12840
#endif
12841
#endif
12842
#ifdef HAVE_INTEL_AVX1
12843
extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
12844
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12845
    unsigned char* counter, unsigned char* initCtr);
12846
extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
12847
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12848
extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
12849
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12850
extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
12851
    unsigned char* tag, unsigned char* h);
12852
12853
extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
12854
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12855
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12856
extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
12857
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12858
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12859
#endif
12860
extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
12861
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
12862
    unsigned char* counter, unsigned char* initCtr);
12863
extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
12864
    unsigned int abytes, unsigned char* tag, unsigned char* h);
12865
extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
12866
    unsigned char* out, const unsigned char* in, unsigned char* counter);
12867
extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
12868
    unsigned char* tag, unsigned char* h);
12869
12870
extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
12871
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
12872
    unsigned char* tag, unsigned char* h, unsigned char* counter);
12873
extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
12874
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
12875
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
12876
12877
#ifdef __cplusplus
12878
    } /* extern "C" */
12879
#endif
12880
12881
/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
12882
 *
12883
 * @param [in, out] aes   AES object.
12884
 * @param [in]      iv    IV/nonce buffer.
12885
 * @param [in]      ivSz  Length of IV/nonce data.
12886
 */
12887
static WARN_UNUSED_RESULT int AesGcmInit_aesni(
12888
    Aes* aes, const byte* iv, word32 ivSz)
12889
{
12890
    ASSERT_SAVED_VECTOR_REGISTERS();
12891
12892
    /* Reset state fields. */
12893
    aes->over = 0;
12894
    aes->aSz = 0;
12895
    aes->cSz = 0;
12896
    /* Set tag to all zeros as initial value. */
12897
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
12898
    /* Reset counts of AAD and cipher text. */
12899
    aes->aOver = 0;
12900
    aes->cOver = 0;
12901
12902
#ifdef HAVE_INTEL_AVX512
12903
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12904
        AES_GCM_init_avx512((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12905
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12906
    }
12907
    else
12908
#endif
12909
#ifdef HAVE_INTEL_VAES
12910
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12911
        AES_GCM_init_vaes((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12912
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12913
    }
12914
    else
12915
#endif
12916
#ifdef HAVE_INTEL_AVX2
12917
    if (IS_INTEL_AVX2(intel_flags)) {
12918
        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12919
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12920
    }
12921
    else
12922
#endif
12923
#ifdef HAVE_INTEL_AVX1
12924
    if (IS_INTEL_AVX1(intel_flags)) {
12925
        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12926
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12927
    }
12928
    else
12929
#endif
12930
    {
12931
        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
12932
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
12933
    }
12934
12935
    return 0;
12936
}
12937
12938
/* Update the AES GCM for encryption with authentication data.
12939
 *
12940
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
12941
 *
12942
 * @param [in, out] aes   AES object.
12943
 * @param [in]      a     Buffer holding authentication data.
12944
 * @param [in]      aSz   Length of authentication data in bytes.
12945
 * @param [in]      endA  Whether no more authentication data is expected.
12946
 */
12947
static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
12948
    Aes* aes, const byte* a, word32 aSz, int endA)
12949
{
12950
    word32 blocks;
12951
    int partial;
12952
12953
    ASSERT_SAVED_VECTOR_REGISTERS();
12954
12955
    if (aSz != 0 && a != NULL) {
12956
        /* Total count of AAD updated. */
12957
        aes->aSz += aSz;
12958
        /* Check if we have unprocessed data. */
12959
        if (aes->aOver > 0) {
12960
            /* Calculate amount we can use - fill up the block. */
12961
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
12962
            if (sz > aSz) {
12963
                sz = (byte)aSz;
12964
            }
12965
            /* Copy extra into last GHASH block array and update count. */
12966
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
12967
            aes->aOver = (byte)(aes->aOver + sz);
12968
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
12969
                /* We have filled up the block and can process. */
12970
#ifdef HAVE_INTEL_AVX512
12971
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12972
                    AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
12973
                                             aes->gcm.H);
12974
                }
12975
                else
12976
#endif
12977
#ifdef HAVE_INTEL_VAES
12978
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
12979
                    AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
12980
                                             aes->gcm.H);
12981
                }
12982
                else
12983
#endif
12984
            #ifdef HAVE_INTEL_AVX2
12985
                if (IS_INTEL_AVX2(intel_flags)) {
12986
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
12987
                                             aes->gcm.H);
12988
                }
12989
                else
12990
            #endif
12991
            #ifdef HAVE_INTEL_AVX1
12992
                if (IS_INTEL_AVX1(intel_flags)) {
12993
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
12994
                                             aes->gcm.H);
12995
                }
12996
                else
12997
            #endif
12998
                {
12999
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
13000
                                              aes->gcm.H);
13001
                }
13002
                /* Reset count. */
13003
                aes->aOver = 0;
13004
            }
13005
            /* Used up some data. */
13006
            aSz -= sz;
13007
            a += sz;
13008
        }
13009
13010
        /* Calculate number of blocks of AAD and the leftover. */
13011
        blocks = aSz / WC_AES_BLOCK_SIZE;
13012
        partial = aSz % WC_AES_BLOCK_SIZE;
13013
        if (blocks > 0) {
13014
            /* GHASH full blocks now. */
13015
#ifdef HAVE_INTEL_AVX512
13016
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13017
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13018
                AES_GCM_aad_update_avx512(a, blocks * WC_AES_BLOCK_SIZE,
13019
                                        AES_TAG(aes), aes->gcm.H);
13020
            }
13021
            else
13022
#endif
13023
#ifdef HAVE_INTEL_VAES
13024
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13025
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13026
                AES_GCM_aad_update_vaes(a, blocks * WC_AES_BLOCK_SIZE,
13027
                                        AES_TAG(aes), aes->gcm.H);
13028
            }
13029
            else
13030
#endif
13031
        #ifdef HAVE_INTEL_AVX2
13032
            if (IS_INTEL_AVX2(intel_flags)) {
13033
                AES_GCM_aad_update_avx2(a, blocks * WC_AES_BLOCK_SIZE,
13034
                                        AES_TAG(aes), aes->gcm.H);
13035
            }
13036
            else
13037
        #endif
13038
        #ifdef HAVE_INTEL_AVX1
13039
            if (IS_INTEL_AVX1(intel_flags)) {
13040
                AES_GCM_aad_update_avx1(a, blocks * WC_AES_BLOCK_SIZE,
13041
                                        AES_TAG(aes), aes->gcm.H);
13042
            }
13043
            else
13044
        #endif
13045
            {
13046
                AES_GCM_aad_update_aesni(a, blocks * WC_AES_BLOCK_SIZE,
13047
                                         AES_TAG(aes), aes->gcm.H);
13048
            }
13049
            /* Skip over to end of AAD blocks. */
13050
            a += blocks * WC_AES_BLOCK_SIZE;
13051
        }
13052
        if (partial != 0) {
13053
            /* Cache the partial block. */
13054
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
13055
            aes->aOver = (byte)partial;
13056
        }
13057
    }
13058
    if (endA && (aes->aOver > 0)) {
13059
        /* No more AAD coming and we have a partial block. */
13060
        /* Fill the rest of the block with zeros. */
13061
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
13062
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
13063
        /* GHASH last AAD block. */
13064
#ifdef HAVE_INTEL_AVX512
13065
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13066
            AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
13067
                                     aes->gcm.H);
13068
        }
13069
        else
13070
#endif
13071
#ifdef HAVE_INTEL_VAES
13072
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13073
            AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
13074
                                     aes->gcm.H);
13075
        }
13076
        else
13077
#endif
13078
    #ifdef HAVE_INTEL_AVX2
13079
        if (IS_INTEL_AVX2(intel_flags)) {
13080
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
13081
                                     aes->gcm.H);
13082
        }
13083
        else
13084
    #endif
13085
    #ifdef HAVE_INTEL_AVX1
13086
        if (IS_INTEL_AVX1(intel_flags)) {
13087
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
13088
                                     aes->gcm.H);
13089
        }
13090
        else
13091
    #endif
13092
        {
13093
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
13094
                                      aes->gcm.H);
13095
        }
13096
        /* Clear partial count for next time through. */
13097
        aes->aOver = 0;
13098
    }
13099
13100
    return 0;
13101
}
13102
13103
/* Update the AES GCM for encryption with data and/or authentication data.
13104
 *
13105
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
13106
 *
13107
 * @param [in, out] aes  AES object.
13108
 * @param [out]     c    Buffer to hold cipher text.
13109
 * @param [in]      p    Buffer holding plaintext.
13110
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13111
 * @param [in]      a    Buffer holding authentication data.
13112
 * @param [in]      aSz  Length of authentication data in bytes.
13113
 */
13114
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
13115
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
13116
{
13117
    word32 blocks;
13118
    int partial;
13119
    int ret;
13120
13121
    ASSERT_SAVED_VECTOR_REGISTERS();
13122
13123
    /* Hash in A, the Authentication Data */
13124
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
13125
    if (ret != 0)
13126
        return ret;
13127
13128
    /* Encrypt plaintext and Hash in C, the Cipher text */
13129
    if (cSz != 0 && c != NULL) {
13130
        /* Update count of cipher text we have hashed. */
13131
        aes->cSz += cSz;
13132
        if (aes->cOver > 0) {
13133
            /* Calculate amount we can use - fill up the block. */
13134
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13135
            if (sz > cSz) {
13136
                sz = (byte)cSz;
13137
            }
13138
            /* Encrypt some of the plaintext. */
13139
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
13140
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13141
            /* Update count of unused encrypted counter. */
13142
            aes->cOver = (byte)(aes->cOver + sz);
13143
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13144
                /* We have filled up the block and can process. */
13145
#ifdef HAVE_INTEL_AVX512
13146
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13147
                    AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
13148
                                             aes->gcm.H);
13149
                }
13150
                else
13151
#endif
13152
#ifdef HAVE_INTEL_VAES
13153
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13154
                    AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
13155
                                             aes->gcm.H);
13156
                }
13157
                else
13158
#endif
13159
            #ifdef HAVE_INTEL_AVX2
13160
                if (IS_INTEL_AVX2(intel_flags)) {
13161
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
13162
                                             aes->gcm.H);
13163
                }
13164
                else
13165
            #endif
13166
            #ifdef HAVE_INTEL_AVX1
13167
                if (IS_INTEL_AVX1(intel_flags)) {
13168
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
13169
                                             aes->gcm.H);
13170
                }
13171
                else
13172
            #endif
13173
                {
13174
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
13175
                                              aes->gcm.H);
13176
                }
13177
                /* Reset count. */
13178
                aes->cOver = 0;
13179
            }
13180
            /* Used up some data. */
13181
            cSz -= sz;
13182
            p += sz;
13183
            c += sz;
13184
        }
13185
13186
        /* Calculate number of blocks of plaintext and the leftover. */
13187
        blocks = cSz / WC_AES_BLOCK_SIZE;
13188
        partial = cSz % WC_AES_BLOCK_SIZE;
13189
        if (blocks > 0) {
13190
            /* Encrypt and GHASH full blocks now. */
13191
#ifdef HAVE_INTEL_AVX512
13192
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13193
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13194
                AES_GCM_encrypt_update_avx512((byte*)aes->key, (int)aes->rounds,
13195
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13196
                    AES_COUNTER(aes));
13197
            }
13198
            else
13199
#endif
13200
#ifdef HAVE_INTEL_VAES
13201
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13202
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13203
                AES_GCM_encrypt_update_vaes((byte*)aes->key, (int)aes->rounds,
13204
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13205
                    AES_COUNTER(aes));
13206
            }
13207
            else
13208
#endif
13209
        #ifdef HAVE_INTEL_AVX2
13210
            if (IS_INTEL_AVX2(intel_flags)) {
13211
                AES_GCM_encrypt_update_avx2((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_AVX1
13218
            if (IS_INTEL_AVX1(intel_flags)) {
13219
                AES_GCM_encrypt_update_avx1((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
            {
13226
                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
13227
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13228
                    AES_COUNTER(aes));
13229
            }
13230
            /* Skip over to end of blocks. */
13231
            p += blocks * WC_AES_BLOCK_SIZE;
13232
            c += blocks * WC_AES_BLOCK_SIZE;
13233
        }
13234
        if (partial != 0) {
13235
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
13236
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13237
#ifdef HAVE_INTEL_AVX512
13238
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13239
                AES_GCM_encrypt_block_avx512((byte*)aes->key, (int)aes->rounds,
13240
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13241
            }
13242
            else
13243
#endif
13244
#ifdef HAVE_INTEL_VAES
13245
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13246
                AES_GCM_encrypt_block_vaes((byte*)aes->key, (int)aes->rounds,
13247
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13248
            }
13249
            else
13250
#endif
13251
        #ifdef HAVE_INTEL_AVX2
13252
            if (IS_INTEL_AVX2(intel_flags)) {
13253
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
13254
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13255
            }
13256
            else
13257
        #endif
13258
        #ifdef HAVE_INTEL_AVX1
13259
            if (IS_INTEL_AVX1(intel_flags)) {
13260
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
13261
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13262
            }
13263
            else
13264
        #endif
13265
            {
13266
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
13267
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13268
            }
13269
            /* XOR the remaining plaintext to calculate cipher text.
13270
             * Keep cipher text for GHASH of last partial block.
13271
             */
13272
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
13273
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
13274
            /* Update count of the block used. */
13275
            aes->cOver = (byte)partial;
13276
        }
13277
    }
13278
    return 0;
13279
}
13280
13281
/* Finalize the AES GCM for encryption and calculate the authentication tag.
13282
 *
13283
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
13284
 *
13285
 * @param [in, out] aes        AES object.
13286
 * @param [in]      authTag    Buffer to hold authentication tag.
13287
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13288
 * @return  0 on success.
13289
 */
13290
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
13291
    Aes* aes, byte* authTag, word32 authTagSz)
13292
{
13293
    /* AAD block incomplete when > 0 */
13294
    byte over = aes->aOver;
13295
13296
    ASSERT_SAVED_VECTOR_REGISTERS();
13297
13298
    if (aes->cOver > 0) {
13299
        /* Cipher text block incomplete. */
13300
        over = aes->cOver;
13301
    }
13302
    if (over > 0) {
13303
        /* Fill the rest of the block with zeros. */
13304
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
13305
        /* GHASH last cipher block. */
13306
#ifdef HAVE_INTEL_AVX512
13307
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13308
            AES_GCM_ghash_block_avx512(AES_LASTGBLOCK(aes), AES_TAG(aes),
13309
                                     aes->gcm.H);
13310
        }
13311
        else
13312
#endif
13313
#ifdef HAVE_INTEL_VAES
13314
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13315
            AES_GCM_ghash_block_vaes(AES_LASTGBLOCK(aes), AES_TAG(aes),
13316
                                     aes->gcm.H);
13317
        }
13318
        else
13319
#endif
13320
    #ifdef HAVE_INTEL_AVX2
13321
        if (IS_INTEL_AVX2(intel_flags)) {
13322
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
13323
                                     aes->gcm.H);
13324
        }
13325
        else
13326
    #endif
13327
    #ifdef HAVE_INTEL_AVX1
13328
        if (IS_INTEL_AVX1(intel_flags)) {
13329
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
13330
                                     aes->gcm.H);
13331
        }
13332
        else
13333
    #endif
13334
        {
13335
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
13336
                                      aes->gcm.H);
13337
        }
13338
    }
13339
    /* Calculate the authentication tag. */
13340
#ifdef HAVE_INTEL_AVX512
13341
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13342
        AES_GCM_encrypt_final_avx512(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13343
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13344
    }
13345
    else
13346
#endif
13347
#ifdef HAVE_INTEL_VAES
13348
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13349
        AES_GCM_encrypt_final_vaes(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13350
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13351
    }
13352
    else
13353
#endif
13354
#ifdef HAVE_INTEL_AVX2
13355
    if (IS_INTEL_AVX2(intel_flags)) {
13356
        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13357
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13358
    }
13359
    else
13360
#endif
13361
#ifdef HAVE_INTEL_AVX1
13362
    if (IS_INTEL_AVX1(intel_flags)) {
13363
        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13364
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13365
    }
13366
    else
13367
#endif
13368
    {
13369
        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13370
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13371
    }
13372
13373
    return 0;
13374
}
13375
13376
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
13377
13378
#ifdef __cplusplus
13379
    extern "C" {
13380
#endif
13381
13382
/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
13383
#ifdef HAVE_INTEL_AVX2
13384
extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
13385
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13386
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13387
#ifdef HAVE_INTEL_AVX512
13388
extern void AES_GCM_decrypt_update_avx512(const unsigned char* key, int nr,
13389
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13390
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13391
#endif
13392
#ifdef HAVE_INTEL_VAES
13393
extern void AES_GCM_decrypt_update_vaes(const unsigned char* key, int nr,
13394
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13395
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13396
#endif
13397
extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
13398
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13399
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13400
#ifdef HAVE_INTEL_AVX512
13401
extern void AES_GCM_decrypt_final_avx512(unsigned char* tag,
13402
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13403
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13404
#endif
13405
#ifdef HAVE_INTEL_VAES
13406
extern void AES_GCM_decrypt_final_vaes(unsigned char* tag,
13407
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13408
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13409
#endif
13410
#endif
13411
#ifdef HAVE_INTEL_AVX1
13412
extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
13413
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13414
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13415
extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
13416
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13417
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13418
#endif
13419
extern void AES_GCM_decrypt_update_aesni(const unsigned char* key, int nr,
13420
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
13421
    unsigned char* tag, unsigned char* h, unsigned char* counter);
13422
extern void AES_GCM_decrypt_final_aesni(unsigned char* tag,
13423
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
13424
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
13425
13426
#ifdef __cplusplus
13427
    } /* extern "C" */
13428
#endif
13429
13430
/* Update the AES GCM for decryption with data and/or authentication data.
13431
 *
13432
 * @param [in, out] aes  AES object.
13433
 * @param [out]     p    Buffer to hold plaintext.
13434
 * @param [in]      c    Buffer holding cipher text.
13435
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13436
 * @param [in]      a    Buffer holding authentication data.
13437
 * @param [in]      aSz  Length of authentication data in bytes.
13438
 */
13439
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
13440
    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
13441
{
13442
    word32 blocks;
13443
    int partial;
13444
    int ret;
13445
13446
    ASSERT_SAVED_VECTOR_REGISTERS();
13447
13448
    /* Hash in A, the Authentication Data */
13449
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
13450
    if (ret != 0)
13451
        return ret;
13452
13453
    /* Hash in C, the Cipher text, and decrypt. */
13454
    if (cSz != 0 && p != NULL) {
13455
        /* Update count of cipher text we have hashed. */
13456
        aes->cSz += cSz;
13457
        if (aes->cOver > 0) {
13458
            /* Calculate amount we can use - fill up the block. */
13459
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13460
            if (sz > cSz) {
13461
                sz = (byte)cSz;
13462
            }
13463
            /* Keep a copy of the cipher text for GHASH. */
13464
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
13465
            /* Decrypt some of the cipher text. */
13466
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
13467
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13468
            /* Update count of unused encrypted counter. */
13469
            aes->cOver = (byte)(aes->cOver + sz);
13470
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13471
                /* We have filled up the block and can process. */
13472
#ifdef HAVE_INTEL_AVX512
13473
                if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13474
                    AES_GCM_ghash_block_avx512(AES_LASTBLOCK(aes), AES_TAG(aes),
13475
                                             aes->gcm.H);
13476
                }
13477
                else
13478
#endif
13479
#ifdef HAVE_INTEL_VAES
13480
                if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13481
                    AES_GCM_ghash_block_vaes(AES_LASTBLOCK(aes), AES_TAG(aes),
13482
                                             aes->gcm.H);
13483
                }
13484
                else
13485
#endif
13486
            #ifdef HAVE_INTEL_AVX2
13487
                if (IS_INTEL_AVX2(intel_flags)) {
13488
                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
13489
                                             aes->gcm.H);
13490
                }
13491
                else
13492
            #endif
13493
            #ifdef HAVE_INTEL_AVX1
13494
                if (IS_INTEL_AVX1(intel_flags)) {
13495
                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
13496
                                             aes->gcm.H);
13497
                }
13498
                else
13499
            #endif
13500
                {
13501
                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
13502
                                              aes->gcm.H);
13503
                }
13504
                /* Reset count. */
13505
                aes->cOver = 0;
13506
            }
13507
            /* Used up some data. */
13508
            cSz -= sz;
13509
            c += sz;
13510
            p += sz;
13511
        }
13512
13513
        /* Calculate number of blocks of plaintext and the leftover. */
13514
        blocks = cSz / WC_AES_BLOCK_SIZE;
13515
        partial = cSz % WC_AES_BLOCK_SIZE;
13516
        if (blocks > 0) {
13517
            /* Decrypt and GHASH full blocks now. */
13518
#ifdef HAVE_INTEL_AVX512
13519
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13520
                IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13521
                AES_GCM_decrypt_update_avx512((byte*)aes->key, (int)aes->rounds,
13522
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13523
                    AES_COUNTER(aes));
13524
            }
13525
            else
13526
#endif
13527
#ifdef HAVE_INTEL_VAES
13528
            if ((blocks >= WC_VAES_GCM_MIN_BLOCKS) &&
13529
                IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13530
                AES_GCM_decrypt_update_vaes((byte*)aes->key, (int)aes->rounds,
13531
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13532
                    AES_COUNTER(aes));
13533
            }
13534
            else
13535
#endif
13536
        #ifdef HAVE_INTEL_AVX2
13537
            if (IS_INTEL_AVX2(intel_flags)) {
13538
                AES_GCM_decrypt_update_avx2((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_AVX1
13545
            if (IS_INTEL_AVX1(intel_flags)) {
13546
                AES_GCM_decrypt_update_avx1((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
            {
13553
                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
13554
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
13555
                    AES_COUNTER(aes));
13556
            }
13557
            /* Skip over to end of blocks. */
13558
            c += blocks * WC_AES_BLOCK_SIZE;
13559
            p += blocks * WC_AES_BLOCK_SIZE;
13560
        }
13561
        if (partial != 0) {
13562
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
13563
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13564
#ifdef HAVE_INTEL_AVX512
13565
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13566
                AES_GCM_encrypt_block_avx512((byte*)aes->key, (int)aes->rounds,
13567
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13568
            }
13569
            else
13570
#endif
13571
#ifdef HAVE_INTEL_VAES
13572
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13573
                AES_GCM_encrypt_block_vaes((byte*)aes->key, (int)aes->rounds,
13574
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13575
            }
13576
            else
13577
#endif
13578
        #ifdef HAVE_INTEL_AVX2
13579
            if (IS_INTEL_AVX2(intel_flags)) {
13580
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
13581
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13582
            }
13583
            else
13584
        #endif
13585
        #ifdef HAVE_INTEL_AVX1
13586
            if (IS_INTEL_AVX1(intel_flags)) {
13587
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
13588
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13589
            }
13590
            else
13591
        #endif
13592
            {
13593
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
13594
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13595
            }
13596
            /* Keep cipher text for GHASH of last partial block. */
13597
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
13598
            /* XOR the remaining cipher text to calculate plaintext. */
13599
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
13600
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
13601
            /* Update count of the block used. */
13602
            aes->cOver = (byte)partial;
13603
        }
13604
    }
13605
13606
    return 0;
13607
}
13608
13609
/* Finalize the AES GCM for decryption and check the authentication tag.
13610
 *
13611
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
13612
 *
13613
 * @param [in, out] aes        AES object.
13614
 * @param [in]      authTag    Buffer holding authentication tag.
13615
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13616
 * @return  0 on success.
13617
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
13618
 *          value.
13619
 */
13620
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
13621
    Aes* aes, const byte* authTag, word32 authTagSz)
13622
{
13623
    int ret = 0;
13624
    int res;
13625
    /* AAD block incomplete when > 0 */
13626
    byte over = aes->aOver;
13627
    byte *lastBlock = AES_LASTGBLOCK(aes);
13628
13629
    ASSERT_SAVED_VECTOR_REGISTERS();
13630
13631
    if (aes->cOver > 0) {
13632
        /* Cipher text block incomplete. */
13633
        over = aes->cOver;
13634
        lastBlock = AES_LASTBLOCK(aes);
13635
    }
13636
    if (over > 0) {
13637
        /* Zeroize the unused part of the block. */
13638
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
13639
        /* Hash the last block of cipher text. */
13640
#ifdef HAVE_INTEL_AVX512
13641
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13642
            AES_GCM_ghash_block_avx512(lastBlock, AES_TAG(aes), aes->gcm.H);
13643
        }
13644
        else
13645
#endif
13646
#ifdef HAVE_INTEL_VAES
13647
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13648
            AES_GCM_ghash_block_vaes(lastBlock, AES_TAG(aes), aes->gcm.H);
13649
        }
13650
        else
13651
#endif
13652
    #ifdef HAVE_INTEL_AVX2
13653
        if (IS_INTEL_AVX2(intel_flags)) {
13654
            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
13655
        }
13656
        else
13657
    #endif
13658
    #ifdef HAVE_INTEL_AVX1
13659
        if (IS_INTEL_AVX1(intel_flags)) {
13660
            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
13661
        }
13662
        else
13663
    #endif
13664
        {
13665
            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
13666
        }
13667
    }
13668
    /* Calculate and compare the authentication tag. */
13669
#ifdef HAVE_INTEL_AVX512
13670
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13671
        AES_GCM_decrypt_final_avx512(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13672
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13673
    }
13674
    else
13675
#endif
13676
#ifdef HAVE_INTEL_VAES
13677
    if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
13678
        AES_GCM_decrypt_final_vaes(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13679
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13680
    }
13681
    else
13682
#endif
13683
#ifdef HAVE_INTEL_AVX2
13684
    if (IS_INTEL_AVX2(intel_flags)) {
13685
        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13686
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13687
    }
13688
    else
13689
#endif
13690
#ifdef HAVE_INTEL_AVX1
13691
    if (IS_INTEL_AVX1(intel_flags)) {
13692
        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13693
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13694
    }
13695
    else
13696
#endif
13697
    {
13698
        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
13699
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
13700
    }
13701
13702
    /* Return error code when calculated doesn't match input. */
13703
    if (res == 0) {
13704
        ret = AES_GCM_AUTH_E;
13705
    }
13706
    return ret;
13707
}
13708
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
13709
#endif /* WOLFSSL_AESNI */
13710
13711
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13712
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13713
/* Initialize the AES GCM cipher with an IV. Aarch64 HW Crypto implementations.
13714
 *
13715
 * @param [in, out] aes   AES object.
13716
 * @param [in]      iv    IV/nonce buffer.
13717
 * @param [in]      ivSz  Length of IV/nonce data.
13718
 */
13719
static WARN_UNUSED_RESULT int AesGcmInit_AARCH64(Aes* aes, const byte* iv,
13720
    word32 ivSz)
13721
{
13722
    /* Reset state fields. */
13723
    aes->over = 0;
13724
    aes->aSz = 0;
13725
    aes->cSz = 0;
13726
    /* Set tag to all zeros as initial value. */
13727
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
13728
    /* Reset counts of AAD and cipher text. */
13729
    aes->aOver = 0;
13730
    aes->cOver = 0;
13731
13732
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13733
    if (aes->use_sha3_hw_crypto) {
13734
        AES_GCM_init_AARCH64_EOR3((byte*)aes->key, (int)aes->rounds, iv, ivSz,
13735
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
13736
    }
13737
    else
13738
#endif
13739
    {
13740
        AES_GCM_init_AARCH64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
13741
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
13742
    }
13743
13744
    return 0;
13745
}
13746
13747
/* Update the AES GCM for encryption with authentication data.
13748
 *
13749
 * Implementation uses AARCH64 optimized assembly code.
13750
 *
13751
 * @param [in, out] aes   AES object.
13752
 * @param [in]      a     Buffer holding authentication data.
13753
 * @param [in]      aSz   Length of authentication data in bytes.
13754
 * @param [in]      endA  Whether no more authentication data is expected.
13755
 */
13756
static WARN_UNUSED_RESULT int AesGcmAadUpdate_AARCH64(
13757
    Aes* aes, const byte* a, word32 aSz, int endA)
13758
{
13759
    word32 blocks;
13760
    int partial;
13761
13762
    if (aSz != 0 && a != NULL) {
13763
        /* Total count of AAD updated. */
13764
        aes->aSz += aSz;
13765
        /* Check if we have unprocessed data. */
13766
        if (aes->aOver > 0) {
13767
            /* Calculate amount we can use - fill up the block. */
13768
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
13769
            if (sz > aSz) {
13770
                sz = (byte)aSz;
13771
            }
13772
            /* Copy extra into last GHASH block array and update count. */
13773
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
13774
            aes->aOver = (byte)(aes->aOver + sz);
13775
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
13776
                /* We have filled up the block and can process. */
13777
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13778
                if (aes->use_sha3_hw_crypto) {
13779
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13780
                        AES_TAG(aes), aes->gcm.H);
13781
                }
13782
                else
13783
            #endif
13784
                {
13785
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13786
                        AES_TAG(aes), aes->gcm.H);
13787
                }
13788
                /* Reset count. */
13789
                aes->aOver = 0;
13790
            }
13791
            /* Used up some data. */
13792
            aSz -= sz;
13793
            a += sz;
13794
        }
13795
13796
        /* Calculate number of blocks of AAD and the leftover. */
13797
        blocks = aSz / WC_AES_BLOCK_SIZE;
13798
        partial = aSz % WC_AES_BLOCK_SIZE;
13799
        if (blocks > 0) {
13800
            /* GHASH full blocks now. */
13801
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13802
            if (aes->use_sha3_hw_crypto) {
13803
                AES_GCM_aad_update_AARCH64_EOR3(a, blocks * WC_AES_BLOCK_SIZE,
13804
                    AES_TAG(aes), aes->gcm.H);
13805
            }
13806
            else
13807
        #endif
13808
            {
13809
                AES_GCM_aad_update_AARCH64(a, blocks * WC_AES_BLOCK_SIZE,
13810
                    AES_TAG(aes), aes->gcm.H);
13811
            }
13812
            /* Skip over to end of AAD blocks. */
13813
            a += blocks * WC_AES_BLOCK_SIZE;
13814
        }
13815
        if (partial != 0) {
13816
            /* Cache the partial block. */
13817
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
13818
            aes->aOver = (byte)partial;
13819
        }
13820
    }
13821
    if (endA && (aes->aOver > 0)) {
13822
        /* No more AAD coming and we have a partial block. */
13823
        /* Fill the rest of the block with zeros. */
13824
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
13825
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
13826
        /* GHASH last AAD block. */
13827
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13828
        if (aes->use_sha3_hw_crypto) {
13829
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13830
                AES_TAG(aes), aes->gcm.H);
13831
        }
13832
        else
13833
    #endif
13834
        {
13835
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13836
                AES_TAG(aes), aes->gcm.H);
13837
        }
13838
        /* Clear partial count for next time through. */
13839
        aes->aOver = 0;
13840
    }
13841
13842
    return 0;
13843
}
13844
13845
/* Update the AES GCM for encryption with data and/or authentication data.
13846
 *
13847
 * Implementation uses AARCH64 optimized assembly code.
13848
 *
13849
 * @param [in, out] aes  AES object.
13850
 * @param [out]     c    Buffer to hold cipher text.
13851
 * @param [in]      p    Buffer holding plaintext.
13852
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
13853
 * @param [in]      a    Buffer holding authentication data.
13854
 * @param [in]      aSz  Length of authentication data in bytes.
13855
 */
13856
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_AARCH64(
13857
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
13858
{
13859
    word32 blocks;
13860
    int partial;
13861
    int ret;
13862
13863
    /* Hash in A, the Authentication Data */
13864
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, (cSz > 0) && (c != NULL));
13865
    if (ret != 0)
13866
        return ret;
13867
13868
    /* Encrypt plaintext and Hash in C, the Cipher text */
13869
    if (cSz != 0 && c != NULL) {
13870
        /* Update count of cipher text we have hashed. */
13871
        aes->cSz += cSz;
13872
        if (aes->cOver > 0) {
13873
            /* Calculate amount we can use - fill up the block. */
13874
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
13875
            if (sz > cSz) {
13876
                sz = (byte)cSz;
13877
            }
13878
            /* Encrypt some of the plaintext. */
13879
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
13880
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
13881
            /* Update count of unused encrypted counter. */
13882
            aes->cOver = (byte)(aes->cOver + sz);
13883
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
13884
                /* We have filled up the block and can process. */
13885
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13886
                if (aes->use_sha3_hw_crypto) {
13887
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
13888
                        AES_TAG(aes), aes->gcm.H);
13889
                }
13890
                else
13891
            #endif
13892
                {
13893
                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
13894
                        AES_TAG(aes), aes->gcm.H);
13895
                }
13896
                /* Reset count. */
13897
                aes->cOver = 0;
13898
            }
13899
            /* Used up some data. */
13900
            cSz -= sz;
13901
            p += sz;
13902
            c += sz;
13903
        }
13904
13905
        /* Calculate number of blocks of plaintext and the leftover. */
13906
        blocks = cSz / WC_AES_BLOCK_SIZE;
13907
        partial = cSz % WC_AES_BLOCK_SIZE;
13908
        if (blocks > 0) {
13909
            /* Encrypt and GHASH full blocks now. */
13910
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13911
            if (aes->use_sha3_hw_crypto) {
13912
                AES_GCM_encrypt_update_AARCH64_EOR3((byte*)aes->key,
13913
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
13914
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13915
            }
13916
            else
13917
        #endif
13918
            {
13919
                AES_GCM_encrypt_update_AARCH64((byte*)aes->key,
13920
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
13921
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
13922
            }
13923
            /* Skip over to end of blocks. */
13924
            p += blocks * WC_AES_BLOCK_SIZE;
13925
            c += blocks * WC_AES_BLOCK_SIZE;
13926
        }
13927
        if (partial != 0) {
13928
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
13929
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
13930
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13931
            if (aes->use_sha3_hw_crypto) {
13932
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
13933
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
13934
                    AES_COUNTER(aes));
13935
            }
13936
            else
13937
        #endif
13938
            {
13939
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
13940
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
13941
            }
13942
            /* XOR the remaining plaintext to calculate cipher text.
13943
             * Keep cipher text for GHASH of last partial block.
13944
             */
13945
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
13946
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
13947
            /* Update count of the block used. */
13948
            aes->cOver = (byte)partial;
13949
        }
13950
    }
13951
    return 0;
13952
}
13953
13954
/* Finalize the AES GCM for encryption and calculate the authentication tag.
13955
 *
13956
 * Calls ARCH64 optimized assembly code.
13957
 *
13958
 * @param [in, out] aes        AES object.
13959
 * @param [in]      authTag    Buffer to hold authentication tag.
13960
 * @param [in]      authTagSz  Length of authentication tag in bytes.
13961
 * @return  0 on success.
13962
 */
13963
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_AARCH64(Aes* aes,
13964
    byte* authTag, word32 authTagSz)
13965
{
13966
    /* AAD block incomplete when > 0 */
13967
    byte over = aes->aOver;
13968
13969
    ASSERT_SAVED_VECTOR_REGISTERS();
13970
13971
    if (aes->cOver > 0) {
13972
        /* Cipher text block incomplete. */
13973
        over = aes->cOver;
13974
    }
13975
    if (over > 0) {
13976
        /* Fill the rest of the block with zeros. */
13977
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
13978
            (size_t)WC_AES_BLOCK_SIZE - over);
13979
        /* GHASH last cipher block. */
13980
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13981
        if (aes->use_sha3_hw_crypto) {
13982
            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes), AES_TAG(aes),
13983
                aes->gcm.H);
13984
        }
13985
        else
13986
    #endif
13987
        {
13988
            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes), AES_TAG(aes),
13989
                aes->gcm.H);
13990
        }
13991
    }
13992
    /* Calculate the authentication tag. */
13993
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
13994
    if (aes->use_sha3_hw_crypto) {
13995
        AES_GCM_encrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
13996
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
13997
    }
13998
    else
13999
#endif
14000
    {
14001
        AES_GCM_encrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
14002
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
14003
    }
14004
14005
    return 0;
14006
}
14007
14008
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
14009
/* Update the AES GCM for decryption with data and/or authentication data.
14010
 *
14011
 * @param [in, out] aes  AES object.
14012
 * @param [out]     p    Buffer to hold plaintext.
14013
 * @param [in]      c    Buffer holding cipher text.
14014
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
14015
 * @param [in]      a    Buffer holding authentication data.
14016
 * @param [in]      aSz  Length of authentication data in bytes.
14017
 */
14018
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_AARCH64(Aes* aes, byte* p,
14019
    const byte* c, word32 cSz, const byte* a, word32 aSz)
14020
{
14021
    word32 blocks;
14022
    int partial;
14023
    int ret;
14024
14025
    /* Hash in A, the Authentication Data */
14026
    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, cSz > 0);
14027
    if (ret != 0)
14028
        return ret;
14029
14030
    /* Hash in C, the Cipher text, and decrypt. */
14031
    if (cSz != 0 && p != NULL) {
14032
        /* Update count of cipher text we have hashed. */
14033
        aes->cSz += cSz;
14034
        if (aes->cOver > 0) {
14035
            /* Calculate amount we can use - fill up the block. */
14036
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
14037
            if (sz > cSz) {
14038
                sz = (byte)cSz;
14039
            }
14040
            /* Keep a copy of the cipher text for GHASH. */
14041
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
14042
            /* Decrypt some of the cipher text. */
14043
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
14044
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
14045
            /* Update count of unused encrypted counter. */
14046
            aes->cOver = (byte)(aes->cOver + sz);
14047
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
14048
                /* We have filled up the block and can process. */
14049
            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14050
                if (aes->use_sha3_hw_crypto) {
14051
                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTBLOCK(aes),
14052
                        AES_TAG(aes), aes->gcm.H);
14053
                }
14054
                else
14055
            #endif
14056
                {
14057
                    AES_GCM_ghash_block_AARCH64(AES_LASTBLOCK(aes),
14058
                        AES_TAG(aes), aes->gcm.H);
14059
                }
14060
                /* Reset count. */
14061
                aes->cOver = 0;
14062
            }
14063
            /* Used up some data. */
14064
            cSz -= sz;
14065
            c += sz;
14066
            p += sz;
14067
        }
14068
14069
        /* Calculate number of blocks of plaintext and the leftover. */
14070
        blocks = cSz / WC_AES_BLOCK_SIZE;
14071
        partial = cSz % WC_AES_BLOCK_SIZE;
14072
        if (blocks > 0) {
14073
            /* Decrypt and GHASH full blocks now. */
14074
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14075
            if (aes->use_sha3_hw_crypto) {
14076
                AES_GCM_decrypt_update_AARCH64_EOR3((byte*)aes->key,
14077
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
14078
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
14079
            }
14080
            else
14081
        #endif
14082
            {
14083
                AES_GCM_decrypt_update_AARCH64((byte*)aes->key,
14084
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
14085
                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
14086
            }
14087
            /* Skip over to end of blocks. */
14088
            c += blocks * WC_AES_BLOCK_SIZE;
14089
            p += blocks * WC_AES_BLOCK_SIZE;
14090
        }
14091
        if (partial != 0) {
14092
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
14093
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
14094
        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14095
            if (aes->use_sha3_hw_crypto) {
14096
                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
14097
                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
14098
                    AES_COUNTER(aes));
14099
            }
14100
            else
14101
        #endif
14102
            {
14103
                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
14104
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
14105
            }
14106
            /* Keep cipher text for GHASH of last partial block. */
14107
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
14108
            /* XOR the remaining cipher text to calculate plaintext. */
14109
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
14110
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
14111
            /* Update count of the block used. */
14112
            aes->cOver = (byte)partial;
14113
        }
14114
    }
14115
14116
    return 0;
14117
}
14118
14119
/* Finalize the AES GCM for decryption and check the authentication tag.
14120
 *
14121
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
14122
 *
14123
 * @param [in, out] aes        AES object.
14124
 * @param [in]      authTag    Buffer holding authentication tag.
14125
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14126
 * @return  0 on success.
14127
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
14128
 *          value.
14129
 */
14130
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_AARCH64(
14131
    Aes* aes, const byte* authTag, word32 authTagSz)
14132
{
14133
    int ret = 0;
14134
    int res;
14135
    /* AAD block incomplete when > 0 */
14136
    byte over = aes->aOver;
14137
    byte *lastBlock = AES_LASTGBLOCK(aes);
14138
14139
    ASSERT_SAVED_VECTOR_REGISTERS();
14140
14141
    if (aes->cOver > 0) {
14142
        /* Cipher text block incomplete. */
14143
        over = aes->cOver;
14144
        lastBlock = AES_LASTBLOCK(aes);
14145
    }
14146
    if (over > 0) {
14147
        /* Zeroize the unused part of the block. */
14148
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
14149
        /* Hash the last block of cipher text. */
14150
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14151
        if (aes->use_sha3_hw_crypto) {
14152
            AES_GCM_ghash_block_AARCH64_EOR3(lastBlock, AES_TAG(aes),
14153
                aes->gcm.H);
14154
        }
14155
        else
14156
    #endif
14157
        {
14158
            AES_GCM_ghash_block_AARCH64(lastBlock, AES_TAG(aes), aes->gcm.H);
14159
        }
14160
    }
14161
    /* Calculate and compare the authentication tag. */
14162
#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
14163
    if (aes->use_sha3_hw_crypto) {
14164
        AES_GCM_decrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
14165
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
14166
    }
14167
    else
14168
#endif
14169
    {
14170
        AES_GCM_decrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
14171
            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
14172
    }
14173
14174
    /* Return error code when calculated doesn't match input. */
14175
    if (res == 0) {
14176
        ret = AES_GCM_AUTH_E;
14177
    }
14178
    return ret;
14179
}
14180
#endif
14181
#endif
14182
14183
/* AES_GCM_H_PTR is defined earlier (before wc_AesGcmEncrypt). */
14184
#if defined(WOLFSSL_RISCV_ASM) && defined(WOLFSSL_AESGCM_STREAM)
14185
14186
static WARN_UNUSED_RESULT int AesGcmInit_RISCV64(Aes* aes, const byte* iv,
14187
    word32 ivSz)
14188
{
14189
    /* Reset state fields. */
14190
    aes->over = 0;
14191
    aes->aSz = 0;
14192
    aes->cSz = 0;
14193
    /* Set tag to all zeros as initial value. */
14194
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
14195
    /* Reset counts of AAD and cipher text. */
14196
    aes->aOver = 0;
14197
    aes->cOver = 0;
14198
14199
    {
14200
        AES_GCM_init_RISCV64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
14201
            AES_GCM_H_PTR(aes), AES_COUNTER(aes), AES_INITCTR(aes));
14202
    }
14203
14204
    return 0;
14205
}
14206
14207
/* Update the AES GCM for encryption with authentication data.
14208
 *
14209
 * Implementation uses RISC-V optimized assembly code.
14210
 *
14211
 * @param [in, out] aes   AES object.
14212
 * @param [in]      a     Buffer holding authentication data.
14213
 * @param [in]      aSz   Length of authentication data in bytes.
14214
 * @param [in]      endA  Whether no more authentication data is expected.
14215
 */
14216
static WARN_UNUSED_RESULT int AesGcmAadUpdate_RISCV64(
14217
    Aes* aes, const byte* a, word32 aSz, int endA)
14218
{
14219
    word32 blocks;
14220
    int partial;
14221
14222
    if (aSz != 0 && a != NULL) {
14223
        /* Total count of AAD updated. */
14224
        aes->aSz += aSz;
14225
        /* Check if we have unprocessed data. */
14226
        if (aes->aOver > 0) {
14227
            /* Calculate amount we can use - fill up the block. */
14228
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
14229
            if (sz > aSz) {
14230
                sz = (byte)aSz;
14231
            }
14232
            /* Copy extra into last GHASH block array and update count. */
14233
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
14234
            aes->aOver = (byte)(aes->aOver + sz);
14235
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
14236
                /* We have filled up the block and can process. */
14237
                {
14238
                    AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes),
14239
                        AES_TAG(aes), AES_GCM_H_PTR(aes));
14240
                }
14241
                /* Reset count. */
14242
                aes->aOver = 0;
14243
            }
14244
            /* Used up some data. */
14245
            aSz -= sz;
14246
            a += sz;
14247
        }
14248
14249
        /* Calculate number of blocks of AAD and the leftover. */
14250
        blocks = aSz / WC_AES_BLOCK_SIZE;
14251
        partial = aSz % WC_AES_BLOCK_SIZE;
14252
        if (blocks > 0) {
14253
            /* GHASH full blocks now. */
14254
            {
14255
                AES_GCM_aad_update_RISCV64(a, blocks * WC_AES_BLOCK_SIZE,
14256
                    AES_TAG(aes), AES_GCM_H_PTR(aes));
14257
            }
14258
            /* Skip over to end of AAD blocks. */
14259
            a += blocks * WC_AES_BLOCK_SIZE;
14260
        }
14261
        if (partial != 0) {
14262
            /* Cache the partial block. */
14263
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
14264
            aes->aOver = (byte)partial;
14265
        }
14266
    }
14267
    if (endA && (aes->aOver > 0)) {
14268
        /* No more AAD coming and we have a partial block. */
14269
        /* Fill the rest of the block with zeros. */
14270
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
14271
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
14272
        /* GHASH last AAD block. */
14273
        {
14274
            AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes),
14275
                AES_TAG(aes), AES_GCM_H_PTR(aes));
14276
        }
14277
        /* Clear partial count for next time through. */
14278
        aes->aOver = 0;
14279
    }
14280
14281
    return 0;
14282
}
14283
14284
/* Update the AES GCM for encryption with data and/or authentication data.
14285
 *
14286
 * Implementation uses RISC-V optimized assembly code.
14287
 *
14288
 * @param [in, out] aes  AES object.
14289
 * @param [out]     c    Buffer to hold cipher text.
14290
 * @param [in]      p    Buffer holding plaintext.
14291
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
14292
 * @param [in]      a    Buffer holding authentication data.
14293
 * @param [in]      aSz  Length of authentication data in bytes.
14294
 */
14295
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_RISCV64(
14296
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
14297
{
14298
    word32 blocks;
14299
    int partial;
14300
    int ret;
14301
14302
    /* Hash in A, the Authentication Data */
14303
    ret = AesGcmAadUpdate_RISCV64(aes, a, aSz, (cSz > 0) && (c != NULL));
14304
    if (ret != 0)
14305
        return ret;
14306
14307
    /* Encrypt plaintext and Hash in C, the Cipher text */
14308
    if (cSz != 0 && c != NULL) {
14309
        /* Update count of cipher text we have hashed. */
14310
        aes->cSz += cSz;
14311
        if (aes->cOver > 0) {
14312
            /* Calculate amount we can use - fill up the block. */
14313
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
14314
            if (sz > cSz) {
14315
                sz = (byte)cSz;
14316
            }
14317
            /* Encrypt some of the plaintext. */
14318
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
14319
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
14320
            /* Update count of unused encrypted counter. */
14321
            aes->cOver = (byte)(aes->cOver + sz);
14322
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
14323
                /* We have filled up the block and can process. */
14324
                {
14325
                    AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes),
14326
                        AES_TAG(aes), AES_GCM_H_PTR(aes));
14327
                }
14328
                /* Reset count. */
14329
                aes->cOver = 0;
14330
            }
14331
            /* Used up some data. */
14332
            cSz -= sz;
14333
            p += sz;
14334
            c += sz;
14335
        }
14336
14337
        /* Calculate number of blocks of plaintext and the leftover. */
14338
        blocks = cSz / WC_AES_BLOCK_SIZE;
14339
        partial = cSz % WC_AES_BLOCK_SIZE;
14340
        if (blocks > 0) {
14341
            /* Encrypt and GHASH full blocks now. */
14342
            {
14343
                AES_GCM_encrypt_update_RISCV64((byte*)aes->key,
14344
                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
14345
                    AES_TAG(aes), AES_GCM_H_PTR(aes), AES_COUNTER(aes));
14346
            }
14347
            /* Skip over to end of blocks. */
14348
            p += blocks * WC_AES_BLOCK_SIZE;
14349
            c += blocks * WC_AES_BLOCK_SIZE;
14350
        }
14351
        if (partial != 0) {
14352
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
14353
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
14354
            {
14355
                AES_GCM_encrypt_block_RISCV64((byte*)aes->key, (int)aes->rounds,
14356
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
14357
            }
14358
            /* XOR the remaining plaintext to calculate cipher text.
14359
             * Keep cipher text for GHASH of last partial block.
14360
             */
14361
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
14362
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
14363
            /* Update count of the block used. */
14364
            aes->cOver = (byte)partial;
14365
        }
14366
    }
14367
    return 0;
14368
}
14369
14370
/* Finalize the AES GCM for encryption and calculate the authentication tag.
14371
 *
14372
 * Calls ARCH64 optimized assembly code.
14373
 *
14374
 * @param [in, out] aes        AES object.
14375
 * @param [in]      authTag    Buffer to hold authentication tag.
14376
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14377
 * @return  0 on success.
14378
 */
14379
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_RISCV64(Aes* aes,
14380
    byte* authTag, word32 authTagSz)
14381
{
14382
    /* AAD block incomplete when > 0 */
14383
    byte over = aes->aOver;
14384
14385
14386
    if (aes->cOver > 0) {
14387
        /* Cipher text block incomplete. */
14388
        over = aes->cOver;
14389
    }
14390
    if (over > 0) {
14391
        /* Fill the rest of the block with zeros. */
14392
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
14393
            (size_t)WC_AES_BLOCK_SIZE - over);
14394
        /* GHASH last cipher block. */
14395
        {
14396
            AES_GCM_ghash_block_RISCV64(AES_LASTGBLOCK(aes), AES_TAG(aes),
14397
                AES_GCM_H_PTR(aes));
14398
        }
14399
    }
14400
    /* Calculate the authentication tag. */
14401
    {
14402
        AES_GCM_encrypt_final_RISCV64(AES_TAG(aes), authTag, authTagSz,
14403
            aes->cSz, aes->aSz, AES_GCM_H_PTR(aes), AES_INITCTR(aes));
14404
    }
14405
14406
    return 0;
14407
}
14408
14409
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
14410
/* Update the AES GCM for decryption with data and/or authentication data.
14411
 *
14412
 * @param [in, out] aes  AES object.
14413
 * @param [out]     p    Buffer to hold plaintext.
14414
 * @param [in]      c    Buffer holding cipher text.
14415
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
14416
 * @param [in]      a    Buffer holding authentication data.
14417
 * @param [in]      aSz  Length of authentication data in bytes.
14418
 */
14419
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_RISCV64(Aes* aes, byte* p,
14420
    const byte* c, word32 cSz, const byte* a, word32 aSz)
14421
{
14422
    word32 blocks;
14423
    int partial;
14424
    int ret;
14425
14426
    /* Hash in A, the Authentication Data */
14427
    ret = AesGcmAadUpdate_RISCV64(aes, a, aSz, cSz > 0);
14428
    if (ret != 0)
14429
        return ret;
14430
14431
    /* Hash in C, the Cipher text, and decrypt. */
14432
    if (cSz != 0 && p != NULL) {
14433
        /* Update count of cipher text we have hashed. */
14434
        aes->cSz += cSz;
14435
        if (aes->cOver > 0) {
14436
            /* Calculate amount we can use - fill up the block. */
14437
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
14438
            if (sz > cSz) {
14439
                sz = (byte)cSz;
14440
            }
14441
            /* Keep a copy of the cipher text for GHASH. */
14442
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
14443
            /* Decrypt some of the cipher text. */
14444
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
14445
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
14446
            /* Update count of unused encrypted counter. */
14447
            aes->cOver = (byte)(aes->cOver + sz);
14448
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
14449
                /* We have filled up the block and can process. */
14450
                {
14451
                    AES_GCM_ghash_block_RISCV64(AES_LASTBLOCK(aes),
14452
                        AES_TAG(aes), AES_GCM_H_PTR(aes));
14453
                }
14454
                /* Reset count. */
14455
                aes->cOver = 0;
14456
            }
14457
            /* Used up some data. */
14458
            cSz -= sz;
14459
            c += sz;
14460
            p += sz;
14461
        }
14462
14463
        /* Calculate number of blocks of plaintext and the leftover. */
14464
        blocks = cSz / WC_AES_BLOCK_SIZE;
14465
        partial = cSz % WC_AES_BLOCK_SIZE;
14466
        if (blocks > 0) {
14467
            /* Decrypt and GHASH full blocks now. */
14468
            {
14469
                AES_GCM_decrypt_update_RISCV64((byte*)aes->key,
14470
                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
14471
                    AES_TAG(aes), AES_GCM_H_PTR(aes), AES_COUNTER(aes));
14472
            }
14473
            /* Skip over to end of blocks. */
14474
            c += blocks * WC_AES_BLOCK_SIZE;
14475
            p += blocks * WC_AES_BLOCK_SIZE;
14476
        }
14477
        if (partial != 0) {
14478
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
14479
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
14480
            {
14481
                AES_GCM_encrypt_block_RISCV64((byte*)aes->key, (int)aes->rounds,
14482
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
14483
            }
14484
            /* Keep cipher text for GHASH of last partial block. */
14485
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
14486
            /* XOR the remaining cipher text to calculate plaintext. */
14487
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
14488
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
14489
            /* Update count of the block used. */
14490
            aes->cOver = (byte)partial;
14491
        }
14492
    }
14493
14494
    return 0;
14495
}
14496
14497
/* Finalize the AES GCM for decryption and check the authentication tag.
14498
 *
14499
 * Implementation uses RISC-V optimized assembly code.
14500
 *
14501
 * @param [in, out] aes        AES object.
14502
 * @param [in]      authTag    Buffer holding authentication tag.
14503
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14504
 * @return  0 on success.
14505
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
14506
 *          value.
14507
 */
14508
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_RISCV64(
14509
    Aes* aes, const byte* authTag, word32 authTagSz)
14510
{
14511
    int ret = 0;
14512
    int res;
14513
    /* AAD block incomplete when > 0 */
14514
    byte over = aes->aOver;
14515
    byte *lastBlock = AES_LASTGBLOCK(aes);
14516
14517
14518
    if (aes->cOver > 0) {
14519
        /* Cipher text block incomplete. */
14520
        over = aes->cOver;
14521
        lastBlock = AES_LASTBLOCK(aes);
14522
    }
14523
    if (over > 0) {
14524
        /* Zeroize the unused part of the block. */
14525
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
14526
        /* Hash the last block of cipher text. */
14527
        {
14528
            AES_GCM_ghash_block_RISCV64(lastBlock, AES_TAG(aes), AES_GCM_H_PTR(aes));
14529
        }
14530
    }
14531
    /* Calculate and compare the authentication tag. */
14532
    {
14533
        AES_GCM_decrypt_final_RISCV64(AES_TAG(aes), authTag, authTagSz,
14534
            aes->cSz, aes->aSz, AES_GCM_H_PTR(aes), AES_INITCTR(aes), &res);
14535
    }
14536
14537
    /* Return error code when calculated doesn't match input. */
14538
    if (res == 0) {
14539
        ret = AES_GCM_AUTH_E;
14540
    }
14541
    return ret;
14542
}
14543
#endif
14544
#endif /* WOLFSSL_RISCV_ASM && WOLFSSL_AESGCM_STREAM */
14545
14546
/* Initialize an AES GCM cipher for encryption or decryption.
14547
 *
14548
 * Must call wc_AesInit() before calling this function.
14549
 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
14550
 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
14551
 *
14552
 * @param [in, out] aes   AES object.
14553
 * @param [in]      key   Buffer holding key.
14554
 * @param [in]      len   Length of key in bytes.
14555
 * @param [in]      iv    Buffer holding IV/nonce.
14556
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14557
 * @return  0 on success.
14558
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
14559
 *          is NULL, or the IV is NULL and no previous IV has been set.
14560
 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
14561
 */
14562
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
14563
    word32 ivSz)
14564
{
14565
    int ret = 0;
14566
14567
    /* Check validity of parameters. */
14568
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
14569
            ((ivSz == 0) && (iv != NULL)) ||
14570
            ((ivSz > 0) && (iv == NULL))) {
14571
        ret = BAD_FUNC_ARG;
14572
    }
14573
14574
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
14575
    if ((ret == 0) && (aes->streamData == NULL)) {
14576
        /* Allocate buffers for streaming. */
14577
        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
14578
        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
14579
                                                              DYNAMIC_TYPE_AES);
14580
        if (aes->streamData == NULL) {
14581
            ret = MEMORY_E;
14582
        }
14583
    }
14584
#endif
14585
14586
    /* Set the key if passed in. */
14587
    if ((ret == 0) && (key != NULL)) {
14588
        ret = wc_AesGcmSetKey(aes, key, len);
14589
    }
14590
14591
#if defined(WOLFSSL_ARM32_AES_DISPATCH) && defined(WOLFSSL_AESGCM_STREAM)
14592
    /* Streaming AES-GCM drives the counter through the base AES_ECB_encrypt,
14593
     * which needs the base key schedule, and there is no AES_GCM_init AArch32
14594
     * assembly - so an object entering the streaming API has to move to the
14595
     * base implementation.  Doing it here rather than in wc_AesGcmSetKey()
14596
     * leaves one-shot AES-GCM on the crypto extension in builds that merely
14597
     * compile the streaming API in.
14598
     *
14599
     * Only the key schedule needs rebuilding: wc_AesGcmSetKey() stores gcm.H
14600
     * un-reflected whichever path computed it, and the tables derived from it
14601
     * with it, so the hashing state carries over as-is.  Round key 0 of either
14602
     * schedule is the cipher key itself, so the base schedule is rebuilt in
14603
     * place without keeping a copy of the key. */
14604
    if ((ret == 0) && aes->use_aes_hw_crypto) {
14605
        byte rawKey[AES_MAX_KEY_SIZE / 8];
14606
14607
        XMEMCPY(rawKey, aes->key, aes->keylen);
14608
        aes->use_aes_hw_crypto = 0;
14609
        aes->use_pmull_hw_crypto = 0;
14610
        AES_set_encrypt_key(rawKey, (word32)aes->keylen * 8, (byte*)aes->key);
14611
        ForceZero(rawKey, sizeof(rawKey));
14612
    }
14613
#endif
14614
14615
    if (ret == 0) {
14616
        if (iv != NULL) {
14617
            if (ivSz <= WC_AES_BLOCK_SIZE) {
14618
                /* Set the IV passed in if it is smaller than a block. */
14619
                XMEMMOVE((byte*)aes->reg, iv, ivSz);
14620
                aes->nonceSz = ivSz;
14621
            }
14622
            else {
14623
                /* FIPS short-nonce detection depends on aes->nonceSz == 0
14624
                 * signifying that supplied ivSz > WC_AES_BLOCK_SIZE.
14625
                 */
14626
                aes->nonceSz = 0;
14627
            }
14628
        }
14629
        else {
14630
            /* No IV passed in, check for cached IV. */
14631
            if (aes->nonceSz != 0) {
14632
                /* Use the cached copy. */
14633
                iv = (byte*)aes->reg;
14634
                ivSz = aes->nonceSz;
14635
            }
14636
        }
14637
14638
        if (iv != NULL) {
14639
            /* Initialize with the IV. */
14640
14641
        #ifdef WOLFSSL_AESNI
14642
            if (aes->use_aesni) {
14643
                ret = SAVE_VECTOR_REGISTERS2();
14644
                if (ret == 0) {
14645
                    ret = AesGcmInit_aesni(aes, iv, ivSz);
14646
                    RESTORE_VECTOR_REGISTERS();
14647
                }
14648
                else {
14649
#ifdef WC_C_DYNAMIC_FALLBACK
14650
                    aes->use_aesni = 0;
14651
                    ret = AesGcmInit_C(aes, iv, ivSz);
14652
#else
14653
                    return ret;
14654
#endif
14655
                }
14656
            }
14657
            else
14658
        #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14659
              !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14660
            if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14661
                ret = AesGcmInit_AARCH64(aes, iv, ivSz);
14662
            }
14663
            else
14664
        #elif defined(WOLFSSL_RISCV_ASM)
14665
            ret = AesGcmInit_RISCV64(aes, iv, ivSz);
14666
            if (0)
14667
        #endif /* WOLFSSL_AESNI */
14668
            {
14669
                ret = AesGcmInit_C(aes, iv, ivSz);
14670
            }
14671
14672
            if (ret == 0)
14673
                aes->nonceSet = 1;
14674
        }
14675
    }
14676
14677
    return ret;
14678
}
14679
14680
/* Initialize an AES GCM cipher for encryption.
14681
 *
14682
 * Must call wc_AesInit() before calling this function.
14683
 *
14684
 * @param [in, out] aes   AES object.
14685
 * @param [in]      key   Buffer holding key.
14686
 * @param [in]      len   Length of key in bytes.
14687
 * @param [in]      iv    Buffer holding IV/nonce.
14688
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14689
 * @return  0 on success.
14690
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
14691
 *          is NULL, or the IV is NULL and no previous IV has been set.
14692
 */
14693
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
14694
    word32 ivSz)
14695
{
14696
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
14697
    /* Note iv is an optional arg to wc_AesGcmEncryptInit(), so we tolerate zero ivSz
14698
     * here.
14699
     */
14700
    if ((ivSz > 0) && (ivSz < GCM_NONCE_MID_SZ))
14701
        return FIPS_BAD_VALUE_E;
14702
#endif
14703
14704
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
14705
}
14706
14707
/* Initialize an AES GCM cipher for encryption. Get IV.
14708
 *
14709
 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
14710
 * function.
14711
 * Must call wc_AesInit() before calling this function.
14712
 *
14713
 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
14714
 *
14715
 * @param [in, out] aes   AES object.
14716
 * @param [in]      key   Buffer holding key.
14717
 * @param [in]      len   Length of key in bytes.
14718
 * @param [in]      iv    Buffer holding IV/nonce.
14719
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14720
 * @return  0 on success.
14721
 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
14722
 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
14723
 *          nonce size.
14724
 */
14725
int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
14726
    word32 ivOutSz)
14727
{
14728
    int ret;
14729
14730
    /* Check validity of parameters. */
14731
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
14732
        ret = BAD_FUNC_ARG;
14733
    }
14734
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
14735
    else if (ivOutSz < GCM_NONCE_MID_SZ) {
14736
        ret = FIPS_BAD_VALUE_E;
14737
    }
14738
#endif
14739
    else {
14740
        /* Copy out the IV including generated part for decryption. */
14741
        XMEMCPY(ivOut, aes->reg, ivOutSz);
14742
        /* Initialize AES GCM cipher with key and cached Iv. */
14743
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
14744
    }
14745
14746
    return ret;
14747
}
14748
14749
/* Update the AES GCM for encryption with data and/or authentication data. */
14750
int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
14751
    const byte* authIn, word32 authInSz)
14752
{
14753
    int ret = 0;
14754
14755
    /* Check validity of parameters. */
14756
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
14757
            ((out == NULL) || (in == NULL)))) {
14758
        ret = BAD_FUNC_ARG;
14759
    }
14760
14761
    /* Check key has been set. */
14762
    if ((ret == 0) && (!aes->gcmKeySet)) {
14763
        ret = MISSING_KEY;
14764
    }
14765
    /* Check IV has been set. */
14766
    if ((ret == 0) && (!aes->nonceSet)) {
14767
        ret = MISSING_IV;
14768
    }
14769
14770
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
14771
    if ((ret == 0) && (aes->nonceSz != 0) && (aes->nonceSz < GCM_NONCE_MID_SZ))
14772
        ret = FIPS_BAD_VALUE_E;
14773
#endif
14774
14775
    /* Prevent overflow of aes->cSz and ->aSz.  Per NIST SP 800-38D section
14776
     * 5.2.1.1, the maximum allowed ciphertext limit is 2^32 - 2 blocks, but we
14777
     * currently pass around the cumulative sizes in bytes as word32s, so we
14778
     * can't currently support the maximum allowed.
14779
     */
14780
    if ((ret == 0) &&
14781
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
14782
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
14783
    {
14784
        ret = AES_GCM_OVERFLOW_E;
14785
    }
14786
14787
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
14788
        aes->invokeCtr[0]++;
14789
        if (aes->invokeCtr[0] == 0) {
14790
            aes->invokeCtr[1]++;
14791
            if (aes->invokeCtr[1] == 0)
14792
                ret = AES_GCM_OVERFLOW_E;
14793
        }
14794
    }
14795
14796
    if (ret == 0) {
14797
        /* Encrypt with AAD and/or plaintext. */
14798
14799
    #ifdef WOLFSSL_AESNI
14800
        if (aes->use_aesni) {
14801
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14802
            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
14803
            RESTORE_VECTOR_REGISTERS();
14804
        }
14805
        else
14806
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14807
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14808
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14809
            ret = AesGcmEncryptUpdate_AARCH64(aes, out, in, sz, authIn,
14810
                authInSz);
14811
        }
14812
        else
14813
    #elif defined(WOLFSSL_RISCV_ASM)
14814
        ret = AesGcmEncryptUpdate_RISCV64(aes, out, in, sz, authIn, authInSz);
14815
        if (0)
14816
    #endif
14817
        {
14818
            /* Encrypt the plaintext. */
14819
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
14820
            if (ret == 0) {
14821
                /* Update the authentication tag with any authentication data and the
14822
                 * new cipher text. */
14823
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
14824
            }
14825
        }
14826
    }
14827
14828
    return ret;
14829
}
14830
14831
/* Finalize the AES GCM for encryption and return the authentication tag.
14832
 *
14833
 * Must set key and IV before calling this function.
14834
 * Must call wc_AesGcmInit() before calling this function.
14835
 *
14836
 * @param [in, out] aes        AES object.
14837
 * @param [out]     authTag    Buffer to hold authentication tag.
14838
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14839
 * @return  0 on success.
14840
 */
14841
int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
14842
{
14843
    int ret = 0;
14844
14845
    /* Check validity of parameters. */
14846
    if ((aes == NULL) || (authTag == NULL)) {
14847
        ret = BAD_FUNC_ARG;
14848
    }
14849
14850
    if (ret == 0)
14851
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
14852
14853
    /* Check key has been set. */
14854
    if ((ret == 0) && (!aes->gcmKeySet)) {
14855
        ret = MISSING_KEY;
14856
    }
14857
    /* Check IV has been set. */
14858
    if ((ret == 0) && (!aes->nonceSet)) {
14859
        ret = MISSING_IV;
14860
    }
14861
14862
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
14863
    if ((ret == 0) && (aes->nonceSz != 0) && (aes->nonceSz < GCM_NONCE_MID_SZ))
14864
        ret = FIPS_BAD_VALUE_E;
14865
#endif
14866
14867
    if (ret == 0) {
14868
        /* Calculate authentication tag. */
14869
    #ifdef WOLFSSL_AESNI
14870
        if (aes->use_aesni) {
14871
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14872
            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
14873
            RESTORE_VECTOR_REGISTERS();
14874
        }
14875
        else
14876
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14877
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14878
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14879
            ret = AesGcmEncryptFinal_AARCH64(aes, authTag, authTagSz);
14880
        }
14881
        else
14882
    #elif defined(WOLFSSL_RISCV_ASM)
14883
        ret = AesGcmEncryptFinal_RISCV64(aes, authTag, authTagSz);
14884
        if (0)
14885
    #endif
14886
        {
14887
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
14888
        }
14889
    }
14890
14891
    if ((ret == 0) && aes->ctrSet) {
14892
        IncCtr((byte*)aes->reg, aes->nonceSz);
14893
    }
14894
14895
    return ret;
14896
}
14897
14898
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
14899
/* Initialize an AES GCM cipher for decryption.
14900
 *
14901
 * Must call wc_AesInit() before calling this function.
14902
 *
14903
 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
14904
 * instead.
14905
 *
14906
 * @param [in, out] aes   AES object.
14907
 * @param [in]      key   Buffer holding key.
14908
 * @param [in]      len   Length of key in bytes.
14909
 * @param [in]      iv    Buffer holding IV/nonce.
14910
 * @param [in]      ivSz  Length of IV/nonce in bytes.
14911
 * @return  0 on success.
14912
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
14913
 *          is NULL, or the IV is NULL and no previous IV has been set.
14914
 */
14915
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
14916
    word32 ivSz)
14917
{
14918
    /*
14919
     * There is no FIPS check on ivSz in decrypt mode -- SP
14920
     * 800-38D IV construction requirements bind encryption only; decryption
14921
     * must accept externally generated IVs of any supported length.
14922
     */
14923
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
14924
}
14925
14926
/* Update the AES GCM for decryption with data and/or authentication data. */
14927
int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
14928
    const byte* authIn, word32 authInSz)
14929
{
14930
    int ret = 0;
14931
14932
    /* Check validity of parameters. */
14933
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
14934
            ((out == NULL) || (in == NULL)))) {
14935
        ret = BAD_FUNC_ARG;
14936
    }
14937
14938
    /* Check key has been set. */
14939
    if ((ret == 0) && (!aes->gcmKeySet)) {
14940
        ret = MISSING_KEY;
14941
    }
14942
    /* Check IV has been set. */
14943
    if ((ret == 0) && (!aes->nonceSet)) {
14944
        ret = MISSING_IV;
14945
    }
14946
14947
    /* Prevent overflow of aes->cSz and ->aSz.  Per NIST SP 800-38D section
14948
     * 5.2.1.1, the maximum allowed ciphertext limit is 2^32 - 2 blocks, but we
14949
     * currently pass around the cumulative sizes in bytes as word32s, so we
14950
     * can't currently support the maximum allowed.
14951
     */
14952
    if ((ret == 0) &&
14953
        ((aes->cSz > WOLFSSL_MAX_32BIT - sz) ||
14954
         (aes->aSz > WOLFSSL_MAX_32BIT - authInSz)))
14955
    {
14956
        ret = AES_GCM_OVERFLOW_E;
14957
    }
14958
14959
    if (ret == 0) {
14960
        /* Decrypt with AAD and/or cipher text. */
14961
    #ifdef WOLFSSL_AESNI
14962
        if (aes->use_aesni) {
14963
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
14964
            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
14965
            RESTORE_VECTOR_REGISTERS();
14966
        }
14967
        else
14968
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
14969
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14970
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
14971
            ret = AesGcmDecryptUpdate_AARCH64(aes, out, in, sz, authIn,
14972
                authInSz);
14973
        }
14974
        else
14975
    #elif defined(WOLFSSL_RISCV_ASM)
14976
        ret = AesGcmDecryptUpdate_RISCV64(aes, out, in, sz, authIn, authInSz);
14977
        if (0)
14978
    #endif
14979
        {
14980
            /* Update the authentication tag with any authentication data and
14981
             * cipher text. */
14982
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
14983
            /* Decrypt the cipher text. */
14984
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
14985
        }
14986
    }
14987
14988
    return ret;
14989
}
14990
14991
/* Finalize the AES GCM for decryption and check the authentication tag.
14992
 *
14993
 * Must set key and IV before calling this function.
14994
 * Must call wc_AesGcmInit() before calling this function.
14995
 *
14996
 * @param [in, out] aes        AES object.
14997
 * @param [in]      authTag    Buffer holding authentication tag.
14998
 * @param [in]      authTagSz  Length of authentication tag in bytes.
14999
 * @return  0 on success.
15000
 */
15001
int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
15002
{
15003
    int ret = 0;
15004
15005
    /* Check validity of parameters. */
15006
    if ((aes == NULL) || (authTag == NULL)) {
15007
        ret = BAD_FUNC_ARG;
15008
    }
15009
15010
    if (ret == 0)
15011
        ret = wc_local_AesGcmCheckTagSz(authTagSz);
15012
15013
    /* Check key has been set. */
15014
    if ((ret == 0) && (!aes->gcmKeySet)) {
15015
        ret = MISSING_KEY;
15016
    }
15017
    /* Check IV has been set. */
15018
    if ((ret == 0) && (!aes->nonceSet)) {
15019
        ret = MISSING_IV;
15020
    }
15021
15022
    if (ret == 0) {
15023
        /* Calculate authentication tag and compare with one passed in.. */
15024
    #ifdef WOLFSSL_AESNI
15025
        if (aes->use_aesni) {
15026
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15027
            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
15028
            RESTORE_VECTOR_REGISTERS();
15029
        }
15030
        else
15031
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
15032
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15033
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
15034
            ret = AesGcmDecryptFinal_AARCH64(aes, authTag, authTagSz);
15035
        }
15036
        else
15037
    #elif defined(WOLFSSL_RISCV_ASM)
15038
        ret = AesGcmDecryptFinal_RISCV64(aes, authTag, authTagSz);
15039
        if (0)
15040
    #endif
15041
        {
15042
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
15043
            /* Calculate authentication tag. */
15044
            ret = AesGcmFinal_C(aes, calcTag, WC_AES_BLOCK_SIZE);
15045
            if (ret == 0) {
15046
                /* Check calculated tag matches the one passed in. */
15047
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
15048
                    ret = AES_GCM_AUTH_E;
15049
                }
15050
            }
15051
        }
15052
    }
15053
15054
    return ret;
15055
}
15056
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
15057
#endif /* WOLFSSL_AESGCM_STREAM */
15058
#endif /* WOLFSSL_XILINX_CRYPT */
15059
#endif /* end of block for AESGCM implementation selection */
15060
15061
15062
/* Common to all, abstract functions that build off of lower level AESGCM
15063
 * functions */
15064
#ifndef WC_NO_RNG
15065
15066
0
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
15067
0
    return (ivSz == GCM_NONCE_MIN_SZ ||
15068
0
            ivSz == GCM_NONCE_MID_SZ ||
15069
0
            ivSz == GCM_NONCE_MAX_SZ);
15070
0
}
15071
15072
15073
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
15074
0
{
15075
0
    int ret = 0;
15076
15077
0
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
15078
0
        ret = BAD_FUNC_ARG;
15079
0
    }
15080
15081
0
    if (ret == 0) {
15082
0
        XMEMCPY((byte*)aes->reg, iv, ivSz);
15083
15084
        /* If the IV is 96, allow for a 2^64 invocation counter.
15085
         * For any other size for the nonce, limit the invocation
15086
         * counter to 32-bits. (SP 800-38D 8.3) */
15087
0
        aes->invokeCtr[0] = 0;
15088
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
15089
    #ifdef WOLFSSL_AESGCM_STREAM
15090
        aes->ctrSet = 1;
15091
    #endif
15092
0
        aes->nonceSz = ivSz;
15093
0
    }
15094
15095
0
    return ret;
15096
0
}
15097
15098
15099
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
15100
                   const byte* ivFixed, word32 ivFixedSz,
15101
                   WC_RNG* rng)
15102
0
{
15103
0
    int ret = 0;
15104
15105
0
    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
15106
0
        (ivFixed == NULL && ivFixedSz != 0) ||
15107
0
        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
15108
15109
0
        ret = BAD_FUNC_ARG;
15110
0
    }
15111
15112
0
    if (ret == 0) {
15113
0
        byte* iv = (byte*)aes->reg;
15114
15115
0
        if (ivFixedSz)
15116
0
            XMEMCPY(iv, ivFixed, ivFixedSz);
15117
15118
0
        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
15119
0
    }
15120
15121
0
    if (ret == 0) {
15122
        /* If the IV is 96, allow for a 2^64 invocation counter.
15123
         * For any other size for the nonce, limit the invocation
15124
         * counter to 32-bits. (SP 800-38D 8.3) */
15125
0
        aes->invokeCtr[0] = 0;
15126
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
15127
    #ifdef WOLFSSL_AESGCM_STREAM
15128
        aes->ctrSet = 1;
15129
    #endif
15130
0
        aes->nonceSz = ivSz;
15131
0
    }
15132
15133
0
    return ret;
15134
0
}
15135
15136
15137
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
15138
                        byte* ivOut, word32 ivOutSz,
15139
                        byte* authTag, word32 authTagSz,
15140
                        const byte* authIn, word32 authInSz)
15141
0
{
15142
0
    int ret = 0;
15143
15144
0
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
15145
0
        ivOut == NULL || ivOutSz != aes->nonceSz ||
15146
0
        (authIn == NULL && authInSz != 0)) {
15147
15148
0
        ret = BAD_FUNC_ARG;
15149
0
    }
15150
15151
#if defined(HAVE_FIPS) && defined(WC_FIPS_AESGCM_NO_SHORT_NONCES)
15152
    if ((ret == 0) && (ivOutSz < GCM_NONCE_MID_SZ))
15153
        ret = FIPS_BAD_VALUE_E;
15154
#endif
15155
15156
0
    if (ret == 0) {
15157
0
        aes->invokeCtr[0]++;
15158
0
        if (aes->invokeCtr[0] == 0) {
15159
0
            aes->invokeCtr[1]++;
15160
0
            if (aes->invokeCtr[1] == 0)
15161
0
                ret = AES_GCM_OVERFLOW_E;
15162
0
        }
15163
0
    }
15164
15165
0
    if (ret == 0) {
15166
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
15167
0
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
15168
0
                               (byte*)aes->reg, ivOutSz,
15169
0
                               authTag, authTagSz,
15170
0
                               authIn, authInSz);
15171
0
        if (ret == 0)
15172
0
            IncCtr((byte*)aes->reg, ivOutSz);
15173
0
    }
15174
15175
0
    return ret;
15176
0
}
15177
15178
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
15179
            const byte* authIn, word32 authInSz,
15180
            byte* authTag, word32 authTagSz, WC_RNG* rng)
15181
0
{
15182
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
15183
0
    int ret;
15184
15185
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
15186
0
        authTag == NULL || authTagSz == 0 || rng == NULL) {
15187
15188
0
        return BAD_FUNC_ARG;
15189
0
    }
15190
15191
#ifdef WOLFSSL_SMALL_STACK
15192
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
15193
#else
15194
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15195
0
#endif
15196
0
    if (ret != 0)
15197
0
        return ret;
15198
15199
0
    ret = wc_AesGcmSetKey(aes, key, keySz);
15200
0
    if (ret == 0)
15201
0
        ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
15202
0
    if (ret == 0)
15203
0
        ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
15204
0
                                  authTag, authTagSz, authIn, authInSz);
15205
15206
#ifdef WOLFSSL_SMALL_STACK
15207
    wc_AesDelete(aes, NULL);
15208
#else
15209
0
    wc_AesFree(aes);
15210
0
#endif
15211
15212
0
    return ret;
15213
0
}
15214
15215
int wc_GmacVerify(const byte* key, word32 keySz,
15216
                  const byte* iv, word32 ivSz,
15217
                  const byte* authIn, word32 authInSz,
15218
                  const byte* authTag, word32 authTagSz)
15219
0
{
15220
0
    int ret;
15221
0
#ifdef HAVE_AES_DECRYPT
15222
0
    WC_DECLARE_VAR(aes, Aes, 1, 0);
15223
15224
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
15225
0
        authTag == NULL || authTagSz == 0 || authTagSz > WC_AES_BLOCK_SIZE) {
15226
15227
0
        return BAD_FUNC_ARG;
15228
0
    }
15229
15230
#ifdef WOLFSSL_SMALL_STACK
15231
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
15232
#else
15233
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15234
0
#endif
15235
0
    if (ret == 0) {
15236
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
15237
0
        if (ret == 0)
15238
0
            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
15239
0
                                  authTag, authTagSz, authIn, authInSz);
15240
15241
0
    }
15242
#ifdef WOLFSSL_SMALL_STACK
15243
    wc_AesDelete(aes, NULL);
15244
#else
15245
0
    wc_AesFree(aes);
15246
0
#endif
15247
#else
15248
    (void)key;
15249
    (void)keySz;
15250
    (void)iv;
15251
    (void)ivSz;
15252
    (void)authIn;
15253
    (void)authInSz;
15254
    (void)authTag;
15255
    (void)authTagSz;
15256
    ret = NOT_COMPILED_IN;
15257
#endif
15258
0
    return ret;
15259
0
}
15260
15261
#endif /* WC_NO_RNG */
15262
15263
15264
int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
15265
0
{
15266
0
    if (gmac == NULL || key == NULL) {
15267
0
        return BAD_FUNC_ARG;
15268
0
    }
15269
0
    return wc_AesGcmSetKey(&gmac->aes, key, len);
15270
0
}
15271
15272
15273
/* Note, wc_GmacUpdate() is not a streaming API, it's a one-shot calculation of
15274
 * the authTag.
15275
 */
15276
int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
15277
                              const byte* authIn, word32 authInSz,
15278
                              byte* authTag, word32 authTagSz)
15279
0
{
15280
0
    if (gmac == NULL) {
15281
0
        return BAD_FUNC_ARG;
15282
0
    }
15283
15284
0
    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
15285
0
                                         authTag, authTagSz, authIn, authInSz);
15286
0
}
15287
15288
#endif /* HAVE_AESGCM */
15289
15290
#ifdef HAVE_AESCCM
15291
15292
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
15293
{
15294
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
15295
        return BAD_FUNC_ARG;
15296
15297
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
15298
}
15299
15300
15301
/* Checks if the tag size is an accepted value based on RFC 3610 section 2
15302
 * returns 0 if tag size is ok
15303
 */
15304
int wc_AesCcmCheckTagSize(int sz)
15305
{
15306
    /* values here are from RFC 3610 section 2 */
15307
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
15308
            && sz != 16) {
15309
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
15310
        return BAD_FUNC_ARG;
15311
    }
15312
    return 0;
15313
}
15314
15315
#if defined(HAVE_COLDFIRE_SEC)
15316
    #error "Coldfire SEC doesn't currently support AES-CCM mode"
15317
15318
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
15319
        !defined(WOLFSSL_QNX_CAAM)
15320
    /* implemented in wolfcrypt/src/port/caam_aes.c */
15321
15322
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
15323
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
15324
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15325
                   const byte* nonce, word32 nonceSz,
15326
                   byte* authTag, word32 authTagSz,
15327
                   const byte* authIn, word32 authInSz)
15328
{
15329
    return wc_AesCcmEncrypt_silabs(
15330
        aes, out, in, inSz,
15331
        nonce, nonceSz,
15332
        authTag, authTagSz,
15333
        authIn, authInSz);
15334
}
15335
15336
#ifdef HAVE_AES_DECRYPT
15337
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15338
                   const byte* nonce, word32 nonceSz,
15339
                   const byte* authTag, word32 authTagSz,
15340
                   const byte* authIn, word32 authInSz)
15341
{
15342
    return wc_AesCcmDecrypt_silabs(
15343
        aes, out, in, inSz,
15344
        nonce, nonceSz,
15345
        authTag, authTagSz,
15346
        authIn, authInSz);
15347
}
15348
#endif
15349
#elif defined(FREESCALE_LTC)
15350
15351
/* return 0 on success */
15352
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15353
                   const byte* nonce, word32 nonceSz,
15354
                   byte* authTag, word32 authTagSz,
15355
                   const byte* authIn, word32 authInSz)
15356
{
15357
    byte *key;
15358
    word32 keySize;
15359
    status_t status;
15360
15361
    /* sanity check on arguments */
15362
    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
15363
     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
15364
     * don't allow it here either.
15365
     */
15366
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
15367
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
15368
        return BAD_FUNC_ARG;
15369
    }
15370
15371
    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
15372
        return BAD_FUNC_ARG;
15373
    }
15374
15375
    key = (byte*)aes->key;
15376
15377
    status = wc_AesGetKeySize(aes, &keySize);
15378
    if (status != 0) {
15379
        return status;
15380
    }
15381
15382
    {
15383
        word32 lenSz = (word32)WC_AES_BLOCK_SIZE - 1U - nonceSz;
15384
        /* With a large nonce, B[] runs out of room to represent inSz, and beyond
15385
         * that, the counter itself can wrap.
15386
         */
15387
        if ((lenSz < sizeof(inSz)) &&
15388
            (inSz >= ((word32)1 << (lenSz * 8))))
15389
        {
15390
            return AES_CCM_OVERFLOW_E;
15391
        }
15392
    }
15393
15394
    status = wolfSSL_CryptHwMutexLock();
15395
    if (status != 0)
15396
        return status;
15397
15398
    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
15399
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
15400
    wolfSSL_CryptHwMutexUnLock();
15401
15402
    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
15403
}
15404
15405
#ifdef HAVE_AES_DECRYPT
15406
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15407
                   const byte* nonce, word32 nonceSz,
15408
                   const byte* authTag, word32 authTagSz,
15409
                   const byte* authIn, word32 authInSz)
15410
{
15411
    byte *key;
15412
    word32 keySize;
15413
    status_t status;
15414
15415
    /* sanity check on arguments */
15416
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
15417
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
15418
        return BAD_FUNC_ARG;
15419
    }
15420
15421
    key = (byte*)aes->key;
15422
15423
    status = wc_AesGetKeySize(aes, &keySize);
15424
    if (status != 0) {
15425
        return status;
15426
    }
15427
15428
    {
15429
        word32 lenSz = (word32)WC_AES_BLOCK_SIZE - 1U - nonceSz;
15430
        /* With a large nonce, B[] runs out of room to represent inSz, and beyond
15431
         * that, the counter itself can wrap.
15432
         */
15433
        if ((lenSz < sizeof(inSz)) &&
15434
            (inSz >= ((word32)1 << (lenSz * 8))))
15435
        {
15436
            return AES_CCM_OVERFLOW_E;
15437
        }
15438
    }
15439
15440
    status = wolfSSL_CryptHwMutexLock();
15441
    if (status != 0)
15442
        return status;
15443
    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
15444
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
15445
    wolfSSL_CryptHwMutexUnLock();
15446
15447
    if (status != kStatus_Success) {
15448
        XMEMSET(out, 0, inSz);
15449
        return AES_CCM_AUTH_E;
15450
    }
15451
    return 0;
15452
}
15453
#endif /* HAVE_AES_DECRYPT */
15454
15455
#else
15456
15457
/* Software CCM */
15458
static WARN_UNUSED_RESULT int roll_x(
15459
    Aes* aes, const byte* in, word32 inSz, byte* out)
15460
{
15461
    int ret;
15462
15463
    /* process the bulk of the data */
15464
    while (inSz >= WC_AES_BLOCK_SIZE) {
15465
        xorbuf(out, in, WC_AES_BLOCK_SIZE);
15466
        in += WC_AES_BLOCK_SIZE;
15467
        inSz -= WC_AES_BLOCK_SIZE;
15468
15469
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
15470
         * roll_x() after the AES cache lines are already hot -- no need to
15471
         * absorb additional prefetch overhead here.
15472
         */
15473
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
15474
        if (ret != 0)
15475
            return ret;
15476
    }
15477
15478
    /* process remainder of the data */
15479
    if (inSz > 0) {
15480
        xorbuf(out, in, inSz);
15481
        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
15482
         * roll_x() after the AES cache lines are already hot -- no need to
15483
         * absorb additional prefetch overhead here.
15484
         */
15485
        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
15486
        if (ret != 0)
15487
            return ret;
15488
    }
15489
15490
    return 0;
15491
}
15492
15493
static WARN_UNUSED_RESULT int roll_auth(
15494
    Aes* aes, const byte* in, word32 inSz, byte* out)
15495
{
15496
    word32 authLenSz;
15497
    word32 remainder;
15498
    int ret;
15499
15500
    /* encode the length in */
15501
    if (inSz <= 0xFEFF) {
15502
        authLenSz = 2;
15503
        out[0] ^= (byte)(inSz >> 8);
15504
        out[1] ^= (byte)inSz;
15505
    }
15506
    else {
15507
        authLenSz = 6;
15508
        out[0] ^= 0xFF;
15509
        out[1] ^= 0xFE;
15510
        out[2] ^= (byte)(inSz >> 24);
15511
        out[3] ^= (byte)(inSz >> 16);
15512
        out[4] ^= (byte)(inSz >>  8);
15513
        out[5] ^= (byte)inSz;
15514
    }
15515
    /* Note, the protocol handles auth data up to 2^64, but we are
15516
     * using 32-bit sizes right now, so the bigger data isn't handled
15517
     * else {}
15518
     */
15519
15520
    /* start fill out the rest of the first block */
15521
    remainder = WC_AES_BLOCK_SIZE - authLenSz;
15522
    if (inSz >= remainder) {
15523
        /* plenty of bulk data to fill the remainder of this block */
15524
        xorbuf(out + authLenSz, in, remainder);
15525
        inSz -= remainder;
15526
        in += remainder;
15527
    }
15528
    else {
15529
        /* not enough bulk data, copy what is available, and pad zero */
15530
        xorbuf(out + authLenSz, in, inSz);
15531
        inSz = 0;
15532
    }
15533
    /* wc_AesCcmEncrypt() and wc_AesCcmDecrypt() only call roll_auth() after the
15534
     * AES cache lines are already hot -- no need to absorb additional prefetch
15535
     * overhead here.
15536
     */
15537
    ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
15538
15539
    if ((ret == 0) && (inSz > 0)) {
15540
        ret = roll_x(aes, in, inSz, out);
15541
    }
15542
15543
    return ret;
15544
}
15545
15546
15547
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
15548
{
15549
    word32 i;
15550
15551
    for (i = 0; i < lenSz; i++) {
15552
        if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
15553
    }
15554
}
15555
15556
#ifdef WOLFSSL_AESNI
15557
static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
15558
{
15559
    word32 i;
15560
15561
    /* B+1 = B */
15562
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 1, B, WC_AES_BLOCK_SIZE);
15563
    /* B+2,B+3 = B,B+1 */
15564
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 2, B, WC_AES_BLOCK_SIZE * 2);
15565
15566
    for (i = 0; i < lenSz; i++) {
15567
        if (++B[WC_AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
15568
    }
15569
    B[WC_AES_BLOCK_SIZE * 3 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 3 - 1] + 2U);
15570
    if (B[WC_AES_BLOCK_SIZE * 3 - 1] < 2U) {
15571
        for (i = 1; i < lenSz; i++) {
15572
            if (++B[WC_AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
15573
        }
15574
    }
15575
    B[WC_AES_BLOCK_SIZE * 4 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 4 - 1] + 3U);
15576
    if (B[WC_AES_BLOCK_SIZE * 4 - 1] < 3U) {
15577
        for (i = 1; i < lenSz; i++) {
15578
            if (++B[WC_AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
15579
        }
15580
    }
15581
}
15582
15583
static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
15584
{
15585
    word32 i;
15586
15587
    B[WC_AES_BLOCK_SIZE - 1] = (byte)(B[WC_AES_BLOCK_SIZE - 1] + 4U);
15588
    if (B[WC_AES_BLOCK_SIZE - 1] < 4U) {
15589
        for (i = 1; i < lenSz; i++) {
15590
            if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) break;
15591
        }
15592
    }
15593
}
15594
#endif
15595
15596
/* Software AES - CCM Encrypt */
15597
/* return 0 on success */
15598
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15599
                   const byte* nonce, word32 nonceSz,
15600
                   byte* authTag, word32 authTagSz,
15601
                   const byte* authIn, word32 authInSz)
15602
{
15603
#ifdef WOLFSSL_AESNI
15604
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
15605
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
15606
#else
15607
    byte A[WC_AES_BLOCK_SIZE];
15608
    byte B[WC_AES_BLOCK_SIZE];
15609
#endif
15610
    byte lenSz;
15611
    word32 i;
15612
    byte mask = 0xFF;
15613
    const word32 wordSz = (word32)sizeof(word32);
15614
    int ret;
15615
15616
    /* sanity check on arguments */
15617
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
15618
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
15619
            authTagSz > WC_AES_BLOCK_SIZE)
15620
        return BAD_FUNC_ARG;
15621
15622
    /* Sanity check on authIn to prevent segfault in xorbuf() where
15623
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
15624
    if (authIn == NULL && authInSz > 0)
15625
        return BAD_FUNC_ARG;
15626
15627
    /* sanity check on tag size */
15628
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
15629
        return BAD_FUNC_ARG;
15630
    }
15631
15632
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
15633
15634
    /* With a large nonce, B[] runs out of room to represent inSz, and beyond
15635
     * that, the counter itself can wrap.
15636
     */
15637
    if ((lenSz < sizeof(inSz)) &&
15638
        (inSz >= ((word32)1 << (lenSz * 8))))
15639
    {
15640
        return AES_CCM_OVERFLOW_E;
15641
    }
15642
15643
#ifdef WOLF_CRYPTO_CB
15644
    #ifndef WOLF_CRYPTO_CB_FIND
15645
    if (aes->devId != INVALID_DEVID)
15646
    #endif
15647
    {
15648
        int crypto_cb_ret =
15649
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
15650
                                      authTag, authTagSz, authIn, authInSz);
15651
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15652
            return crypto_cb_ret;
15653
        /* fall-through when unavailable */
15654
    }
15655
#endif
15656
15657
    /* Software/HW key schedule required from here on. */
15658
    if (!WC_AES_KEY_IS_SET(aes)) {
15659
        WOLFSSL_MSG("AES key not set");
15660
        return MISSING_KEY;
15661
    }
15662
15663
    XMEMSET(A, 0, sizeof(A));
15664
    XMEMCPY(B+1, nonce, nonceSz);
15665
15666
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
15667
                  + (8 * (((byte)authTagSz - 2) / 2))
15668
                  + (lenSz - 1));
15669
    for (i = 0; i < lenSz; i++) {
15670
        if (mask && i >= wordSz)
15671
            mask = 0x00;
15672
        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
15673
    }
15674
15675
#ifdef WOLFSSL_CHECK_MEM_ZERO
15676
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
15677
#endif
15678
15679
    VECTOR_REGISTERS_PUSH;
15680
    /* note this wc_AesEncrypt() will perform cache prefetches if needed, so
15681
     * that the later encrypt ops don't need to.
15682
     */
15683
    ret = wc_AesEncrypt(aes, B, A);
15684
#ifdef WOLFSSL_CHECK_MEM_ZERO
15685
    if (ret == 0)
15686
        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
15687
#endif
15688
15689
    if ((ret == 0) && (authInSz > 0))
15690
        ret = roll_auth(aes, authIn, authInSz, A);
15691
15692
    if ((ret == 0) && (inSz > 0))
15693
        ret = roll_x(aes, in, inSz, A);
15694
15695
    if (ret == 0) {
15696
        XMEMCPY(authTag, A, authTagSz);
15697
15698
        B[0] = (byte)(lenSz - 1U);
15699
        for (i = 0; i < lenSz; i++)
15700
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15701
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15702
    }
15703
15704
    if (ret == 0) {
15705
        xorbuf(authTag, A, authTagSz);
15706
        B[15] = 1;
15707
    }
15708
#ifdef WOLFSSL_AESNI
15709
    if ((ret == 0) && aes->use_aesni) {
15710
        while (inSz >= WC_AES_BLOCK_SIZE * 4) {
15711
            AesCcmCtrIncSet4(B, lenSz);
15712
15713
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
15714
                            (int)aes->rounds);
15715
15716
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
15717
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE * 4);
15718
15719
            inSz -= WC_AES_BLOCK_SIZE * 4;
15720
            in += WC_AES_BLOCK_SIZE * 4;
15721
            out += WC_AES_BLOCK_SIZE * 4;
15722
15723
            AesCcmCtrInc4(B, lenSz);
15724
        }
15725
    }
15726
#endif
15727
    if (ret == 0) {
15728
        while (inSz >= WC_AES_BLOCK_SIZE) {
15729
            ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15730
            if (ret != 0)
15731
                break;
15732
            xorbuf(A, in, WC_AES_BLOCK_SIZE);
15733
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
15734
15735
            AesCcmCtrInc(B, lenSz);
15736
            inSz -= WC_AES_BLOCK_SIZE;
15737
            in += WC_AES_BLOCK_SIZE;
15738
            out += WC_AES_BLOCK_SIZE;
15739
        }
15740
    }
15741
    if ((ret == 0) && (inSz > 0)) {
15742
        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
15743
    }
15744
    if ((ret == 0) && (inSz > 0)) {
15745
        xorbuf(A, in, inSz);
15746
        XMEMCPY(out, A, inSz);
15747
    }
15748
15749
    ForceZero(A, sizeof(A));
15750
    ForceZero(B, sizeof(B));
15751
15752
#ifdef WOLFSSL_CHECK_MEM_ZERO
15753
    wc_MemZero_Check(A, sizeof(A));
15754
    wc_MemZero_Check(B, sizeof(B));
15755
#endif
15756
15757
    VECTOR_REGISTERS_POP;
15758
15759
    return ret;
15760
}
15761
15762
#ifdef HAVE_AES_DECRYPT
15763
/* Software AES - CCM Decrypt */
15764
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
15765
                   const byte* nonce, word32 nonceSz,
15766
                   const byte* authTag, word32 authTagSz,
15767
                   const byte* authIn, word32 authInSz)
15768
{
15769
#ifdef WOLFSSL_AESNI
15770
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
15771
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
15772
#else
15773
    byte A[WC_AES_BLOCK_SIZE];
15774
    byte B[WC_AES_BLOCK_SIZE];
15775
#endif
15776
    byte* o;
15777
    byte lenSz;
15778
    word32 i, oSz;
15779
    byte mask = 0xFF;
15780
    const word32 wordSz = (word32)sizeof(word32);
15781
    int ret = 0;
15782
#ifdef WC_AES_HAVE_PREFETCH_ARG
15783
    int did_prefetches = 0;
15784
#endif
15785
15786
    /* sanity check on arguments */
15787
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
15788
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
15789
        authTagSz > WC_AES_BLOCK_SIZE)
15790
        return BAD_FUNC_ARG;
15791
15792
    /* Sanity check on authIn to prevent segfault in xorbuf() where
15793
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
15794
    if (authIn == NULL && authInSz > 0)
15795
        return BAD_FUNC_ARG;
15796
15797
    /* sanity check on tag size */
15798
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
15799
        return BAD_FUNC_ARG;
15800
    }
15801
15802
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
15803
15804
    /* With a large nonce, B[] runs out of room to represent inSz, and beyond
15805
     * that, the counter itself can wrap.
15806
     */
15807
    if ((lenSz < sizeof(inSz)) &&
15808
        (inSz >= ((word32)1 << (lenSz * 8))))
15809
    {
15810
        return AES_CCM_OVERFLOW_E;
15811
    }
15812
15813
#ifdef WOLF_CRYPTO_CB
15814
    #ifndef WOLF_CRYPTO_CB_FIND
15815
    if (aes->devId != INVALID_DEVID)
15816
    #endif
15817
    {
15818
        int crypto_cb_ret =
15819
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
15820
            authTag, authTagSz, authIn, authInSz);
15821
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
15822
            return crypto_cb_ret;
15823
        /* fall-through when unavailable */
15824
    }
15825
#endif
15826
15827
    /* Software/HW key schedule required from here on. */
15828
    if (!WC_AES_KEY_IS_SET(aes)) {
15829
        WOLFSSL_MSG("AES key not set");
15830
        return MISSING_KEY;
15831
    }
15832
15833
    o = out;
15834
    oSz = inSz;
15835
    XMEMSET(A, 0, sizeof A);
15836
    XMEMCPY(B+1, nonce, nonceSz);
15837
15838
    B[0] = (byte)(lenSz - 1U);
15839
    for (i = 0; i < lenSz; i++)
15840
        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15841
    B[15] = 1;
15842
15843
#ifdef WOLFSSL_CHECK_MEM_ZERO
15844
    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
15845
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
15846
#endif
15847
15848
    VECTOR_REGISTERS_PUSH;
15849
15850
#ifdef WOLFSSL_AESNI
15851
    if (aes->use_aesni) {
15852
        while (oSz >= WC_AES_BLOCK_SIZE * 4) {
15853
            AesCcmCtrIncSet4(B, lenSz);
15854
15855
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
15856
                            (int)aes->rounds);
15857
15858
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
15859
            XMEMCPY(o, A, WC_AES_BLOCK_SIZE * 4);
15860
15861
            oSz -= WC_AES_BLOCK_SIZE * 4;
15862
            in += WC_AES_BLOCK_SIZE * 4;
15863
            o += WC_AES_BLOCK_SIZE * 4;
15864
15865
            AesCcmCtrInc4(B, lenSz);
15866
        }
15867
    }
15868
#endif
15869
15870
    while (oSz >= WC_AES_BLOCK_SIZE) {
15871
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15872
        if (ret != 0)
15873
            break;
15874
        xorbuf(A, in, WC_AES_BLOCK_SIZE);
15875
        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
15876
        AesCcmCtrInc(B, lenSz);
15877
        oSz -= WC_AES_BLOCK_SIZE;
15878
        in += WC_AES_BLOCK_SIZE;
15879
        o += WC_AES_BLOCK_SIZE;
15880
    }
15881
15882
    /* oSz, not inSz, is the count of bytes left after the block loop above --
15883
     * inSz is kept pristine here for the CBC-MAC phase below. */
15884
    if ((ret == 0) && (oSz > 0))
15885
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15886
15887
    if ((ret == 0) && (oSz > 0)) {
15888
        xorbuf(A, in, oSz);
15889
        XMEMCPY(o, A, oSz);
15890
    }
15891
15892
    if (ret == 0) {
15893
        o = out;
15894
        oSz = inSz;
15895
15896
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
15897
                      + (8 * (((byte)authTagSz - 2) / 2))
15898
                      + (lenSz - 1));
15899
        for (i = 0; i < lenSz; i++) {
15900
            if (mask && i >= wordSz)
15901
                mask = 0x00;
15902
            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
15903
        }
15904
15905
        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
15906
    }
15907
15908
    if (ret == 0) {
15909
        if (authInSz > 0)
15910
            ret = roll_auth(aes, authIn, authInSz, A);
15911
    }
15912
    if ((ret == 0) && (inSz > 0))
15913
        ret = roll_x(aes, o, oSz, A);
15914
15915
    if (ret == 0) {
15916
        B[0] = (byte)(lenSz - 1U);
15917
        for (i = 0; i < lenSz; i++)
15918
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
15919
        ret = AesEncrypt_preFetchOpt(aes, B, B, &did_prefetches);
15920
    }
15921
15922
    if (ret == 0)
15923
        xorbuf(A, B, authTagSz);
15924
15925
    if (ret == 0) {
15926
        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
15927
            /* If the authTag check fails, don't keep the decrypted data.
15928
             * Unfortunately, you need the decrypted data to calculate the
15929
             * check value. */
15930
            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
15931
                        defined(ACVP_VECTOR_TESTING)
15932
            WOLFSSL_MSG("Preserve output for vector responses");
15933
            #else
15934
            if (inSz > 0)
15935
                XMEMSET(out, 0, inSz);
15936
            #endif
15937
            ret = AES_CCM_AUTH_E;
15938
        }
15939
    }
15940
15941
    ForceZero(A, sizeof(A));
15942
    ForceZero(B, sizeof(B));
15943
    o = NULL;
15944
15945
#ifdef WOLFSSL_CHECK_MEM_ZERO
15946
    wc_MemZero_Check(A, sizeof(A));
15947
    wc_MemZero_Check(B, sizeof(B));
15948
#endif
15949
15950
    VECTOR_REGISTERS_POP;
15951
15952
    return ret;
15953
}
15954
15955
#endif /* HAVE_AES_DECRYPT */
15956
#endif /* software CCM */
15957
15958
/* abstract functions that call lower level AESCCM functions */
15959
#ifndef WC_NO_RNG
15960
15961
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
15962
{
15963
    int ret = 0;
15964
15965
    if (aes == NULL || nonce == NULL ||
15966
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
15967
15968
        ret = BAD_FUNC_ARG;
15969
    }
15970
15971
    if (ret == 0) {
15972
        XMEMCPY(aes->reg, nonce, nonceSz);
15973
        aes->nonceSz = nonceSz;
15974
15975
        /* Invocation counter should be 2^61 */
15976
        aes->invokeCtr[0] = 0;
15977
        aes->invokeCtr[1] = 0xE0000000;
15978
    }
15979
15980
    return ret;
15981
}
15982
15983
15984
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
15985
                        byte* ivOut, word32 ivOutSz,
15986
                        byte* authTag, word32 authTagSz,
15987
                        const byte* authIn, word32 authInSz)
15988
{
15989
    int ret = 0;
15990
15991
    if (aes == NULL || out == NULL ||
15992
        (in == NULL && sz != 0) ||
15993
        ivOut == NULL ||
15994
        (authIn == NULL && authInSz != 0) ||
15995
        (ivOutSz != aes->nonceSz)) {
15996
15997
        ret = BAD_FUNC_ARG;
15998
    }
15999
16000
    if (ret == 0) {
16001
        aes->invokeCtr[0]++;
16002
        if (aes->invokeCtr[0] == 0) {
16003
            aes->invokeCtr[1]++;
16004
            if (aes->invokeCtr[1] == 0)
16005
                ret = AES_CCM_OVERFLOW_E;
16006
        }
16007
    }
16008
16009
    if (ret == 0) {
16010
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
16011
                               (byte*)aes->reg, aes->nonceSz,
16012
                               authTag, authTagSz,
16013
                               authIn, authInSz);
16014
        if (ret == 0) {
16015
            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
16016
            IncCtr((byte*)aes->reg, aes->nonceSz);
16017
        }
16018
    }
16019
16020
    return ret;
16021
}
16022
16023
#endif /* WC_NO_RNG */
16024
16025
#endif /* HAVE_AESCCM */
16026
16027
#ifndef WC_NO_CONSTRUCTORS
16028
16029
0
#define AES_NEW_INIT_PLAIN  0
16030
#ifdef WOLF_PRIVATE_KEY_ID
16031
#define AES_NEW_INIT_ID     1
16032
#define AES_NEW_INIT_LABEL  2
16033
#endif
16034
16035
static Aes* _AesNew_common(void* heap, int devId, int *result_code,
16036
                            int aesInitType, unsigned char* id,
16037
                            int idLen, const char* label)
16038
0
{
16039
0
    int ret;
16040
0
    Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
16041
0
    if (aes == NULL) {
16042
0
        ret = MEMORY_E;
16043
0
    }
16044
0
    else {
16045
0
        switch (aesInitType) {
16046
#ifdef WOLF_PRIVATE_KEY_ID
16047
        case AES_NEW_INIT_ID:
16048
            if (id == NULL || idLen == 0 || label != NULL) {
16049
                ret = BAD_FUNC_ARG;
16050
            }
16051
            else {
16052
                ret = wc_AesInit_Id(aes, id, idLen, heap, devId);
16053
            }
16054
            break;
16055
        case AES_NEW_INIT_LABEL:
16056
            if (label == NULL || id != NULL || idLen != 0) {
16057
                ret = BAD_FUNC_ARG;
16058
            }
16059
            else {
16060
                ret = wc_AesInit_Label(aes, label, heap, devId);
16061
            }
16062
            break;
16063
#endif
16064
0
        default:
16065
0
            if (id != NULL || idLen != 0 || label != NULL) {
16066
0
                ret = BAD_FUNC_ARG;
16067
0
            }
16068
0
            else {
16069
0
                ret = wc_AesInit(aes, heap, devId);
16070
0
            }
16071
0
            break;
16072
0
        }
16073
0
        if (ret != 0) {
16074
0
            XFREE(aes, heap, DYNAMIC_TYPE_AES);
16075
0
            aes = NULL;
16076
0
        }
16077
0
    }
16078
0
    (void)aesInitType;
16079
0
    (void)id;
16080
0
    (void)idLen;
16081
0
    (void)label;
16082
16083
0
    if (result_code != NULL) {
16084
0
        *result_code = ret;
16085
0
    }
16086
16087
0
    return aes;
16088
0
}
16089
16090
Aes* wc_AesNew(void* heap, int devId, int *result_code)
16091
0
{
16092
0
    return _AesNew_common(heap, devId, result_code,
16093
0
                          AES_NEW_INIT_PLAIN, NULL, 0, NULL);
16094
0
}
16095
16096
#ifdef WOLF_PRIVATE_KEY_ID
16097
Aes* wc_AesNew_Id(unsigned char* id, int len, void* heap, int devId,
16098
                   int *result_code)
16099
{
16100
    return _AesNew_common(heap, devId, result_code,
16101
                          AES_NEW_INIT_ID, id, len, NULL);
16102
}
16103
16104
Aes* wc_AesNew_Label(const char* label, void* heap, int devId,
16105
                      int *result_code)
16106
{
16107
    return _AesNew_common(heap, devId, result_code,
16108
                          AES_NEW_INIT_LABEL, NULL, 0, label);
16109
}
16110
#endif /* WOLF_PRIVATE_KEY_ID */
16111
16112
int wc_AesDelete(Aes *aes, Aes** aes_p)
16113
0
{
16114
0
    void* heap;
16115
0
    if (aes == NULL)
16116
0
        return BAD_FUNC_ARG;
16117
0
    heap = aes->heap;
16118
0
    wc_AesFree(aes);
16119
0
    XFREE(aes, heap, DYNAMIC_TYPE_AES);
16120
0
    if (aes_p != NULL)
16121
0
        *aes_p = NULL;
16122
0
    return 0;
16123
0
}
16124
#endif /* !WC_NO_CONSTRUCTORS */
16125
16126
/* Initialize Aes */
16127
int wc_AesInit(Aes* aes, void* heap, int devId)
16128
0
{
16129
0
    int ret = 0;
16130
16131
0
    if (aes == NULL)
16132
0
        return BAD_FUNC_ARG;
16133
16134
0
    XMEMSET(aes, 0, sizeof(*aes));
16135
16136
0
    aes->heap = heap;
16137
16138
#if defined(WOLF_CRYPTO_CB)
16139
    aes->devId = devId;
16140
    aes->devCtx = NULL;
16141
#else
16142
0
    (void)devId;
16143
0
#endif
16144
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
16145
    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
16146
                                                        aes->heap, devId);
16147
#endif /* WOLFSSL_ASYNC_CRYPT */
16148
16149
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
16150
    aes->alFd = WC_SOCK_NOTSET;
16151
    aes->rdFd = WC_SOCK_NOTSET;
16152
#endif
16153
#if defined(WOLFSSL_DEVCRYPTO) && \
16154
   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
16155
    aes->ctx.cfd    = -1;
16156
    aes->ctx.inited = 0;
16157
#endif
16158
#if defined(WOLFSSL_IMXRT_DCP)
16159
    DCPAesInit(aes);
16160
#endif
16161
16162
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
16163
    ret = wc_psa_aes_init(aes);
16164
#endif
16165
16166
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
16167
    if (ret == 0)
16168
        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
16169
#endif
16170
16171
0
    return ret;
16172
0
}
16173
16174
#ifdef WOLF_PRIVATE_KEY_ID
16175
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
16176
{
16177
    int ret = 0;
16178
16179
    if (aes == NULL)
16180
        ret = BAD_FUNC_ARG;
16181
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
16182
        ret = BUFFER_E;
16183
16184
    if (ret == 0)
16185
        ret = wc_AesInit(aes, heap, devId);
16186
    if (ret == 0) {
16187
        XMEMCPY(aes->id, id, (size_t)len);
16188
        aes->idLen = len;
16189
        aes->labelLen = 0;
16190
        /* keyInstalled stays 0: the key lives on the device, not in the
16191
         * software schedule. See the field comment in aes.h. */
16192
    }
16193
16194
    return ret;
16195
}
16196
16197
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
16198
{
16199
    int ret = 0;
16200
    size_t labelLen = 0;
16201
16202
    if (aes == NULL || label == NULL)
16203
        ret = BAD_FUNC_ARG;
16204
    if (ret == 0) {
16205
        labelLen = XSTRLEN(label);
16206
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
16207
            ret = BUFFER_E;
16208
    }
16209
16210
    if (ret == 0)
16211
        ret = wc_AesInit(aes, heap, devId);
16212
    if (ret == 0) {
16213
        XMEMCPY(aes->label, label, labelLen);
16214
        aes->labelLen = (int)labelLen;
16215
        aes->idLen = 0;
16216
        /* keyInstalled stays 0: see wc_AesInit_Id() above. */
16217
    }
16218
16219
    return ret;
16220
}
16221
#endif
16222
16223
/* Free Aes resources */
16224
void wc_AesFree(Aes* aes)
16225
0
{
16226
0
    if (aes == NULL) {
16227
0
        return;
16228
0
    }
16229
16230
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
16231
    #ifndef WOLF_CRYPTO_CB_FIND
16232
    if (aes->devId != INVALID_DEVID)
16233
    #endif
16234
    {
16235
        int ret = wc_CryptoCb_Free(aes->devId, WC_ALGO_TYPE_CIPHER,
16236
                                   WC_CIPHER_AES, 0, aes);
16237
    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
16238
        aes->devCtx = NULL;  /* Clear device context handle */
16239
    #endif
16240
        /* This path skips the ForceZero below, so clear the flag here or a
16241
         * reused context passes the key-set guard with a freed key. */
16242
        aes->keyInstalled = 0;
16243
        /* If callback wants standard free, it can set devId to INVALID_DEVID.
16244
         * Otherwise assume the callback handled cleanup. */
16245
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16246
            return;
16247
        /* fall-through when unavailable */
16248
    }
16249
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
16250
16251
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
16252
    {
16253
        int ret = wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
16254
        if (ret != 0)
16255
            WOLFSSL_DEBUG_PRINTF("ERROR: wc_AesFree(): wc_debug_CipherLifecycleFree() returned %d.\n", ret);
16256
    }
16257
#endif
16258
16259
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
16260
    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
16261
#endif /* WOLFSSL_ASYNC_CRYPT */
16262
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
16263
    if (aes->rdFd > 0) { /* negative is error case */
16264
        close(aes->rdFd);
16265
        aes->rdFd = WC_SOCK_NOTSET;
16266
    }
16267
    if (aes->alFd > 0) {
16268
        close(aes->alFd);
16269
        aes->alFd = WC_SOCK_NOTSET;
16270
    }
16271
#endif /* WOLFSSL_AFALG */
16272
#ifdef WOLFSSL_KCAPI_AES
16273
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
16274
    if (aes->init == 1) {
16275
        kcapi_cipher_destroy(aes->handle);
16276
    }
16277
    aes->init = 0;
16278
    aes->handle = NULL;
16279
#endif
16280
#if defined(WOLFSSL_DEVCRYPTO) && \
16281
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
16282
    wc_DevCryptoFree(&aes->ctx);
16283
#endif
16284
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
16285
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
16286
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
16287
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
16288
#endif
16289
#if defined(WOLFSSL_IMXRT_DCP)
16290
    DCPAesFree(aes);
16291
#endif
16292
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
16293
    !defined(WOLFSSL_AESNI)
16294
    if (aes->streamData != NULL) {
16295
        ForceZero(aes->streamData, aes->streamData_sz);
16296
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
16297
        aes->streamData = NULL;
16298
    }
16299
#endif
16300
16301
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
16302
    if (aes->useSWCrypt == 0) {
16303
        se050_aes_free(aes);
16304
    }
16305
#endif
16306
#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
16307
    wc_Microchip_aes_free(aes);
16308
#endif
16309
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
16310
    wc_psa_aes_free(aes);
16311
#endif
16312
16313
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
16314
    wc_MAXQ10XX_AesFree(aes);
16315
#endif
16316
16317
#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
16318
    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
16319
    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
16320
    wc_fspsm_Aesfree(aes);
16321
#endif
16322
16323
0
    ForceZero(aes, sizeof(Aes));
16324
16325
#ifdef WOLFSSL_CHECK_MEM_ZERO
16326
    wc_MemZero_Check(aes, sizeof(Aes));
16327
#endif
16328
0
}
16329
16330
int wc_AesGetKeySize(Aes* aes, word32* keySize)
16331
0
{
16332
0
    int ret = 0;
16333
16334
0
    if (aes == NULL || keySize == NULL) {
16335
0
        return BAD_FUNC_ARG;
16336
0
    }
16337
16338
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
16339
    return wc_psa_aes_get_key_size(aes, keySize);
16340
#endif
16341
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
16342
    *keySize = aes->ctx.key.keySize;
16343
    return ret;
16344
#endif
16345
0
    switch (aes->rounds) {
16346
0
#ifdef WOLFSSL_AES_128
16347
0
    case 10:
16348
0
        *keySize = 16;
16349
0
        break;
16350
0
#endif
16351
0
#ifdef WOLFSSL_AES_192
16352
0
    case 12:
16353
0
        *keySize = 24;
16354
0
        break;
16355
0
#endif
16356
0
#ifdef WOLFSSL_AES_256
16357
0
    case 14:
16358
0
        *keySize = 32;
16359
0
        break;
16360
0
#endif
16361
0
    default:
16362
0
        *keySize = 0;
16363
0
        ret = BAD_FUNC_ARG;
16364
0
    }
16365
16366
0
    return ret;
16367
0
}
16368
16369
#endif /* !WOLFSSL_TI_CRYPT */
16370
16371
/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
16372
 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
16373
 */
16374
#ifndef VECTOR_REGISTERS_PUSH
16375
    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
16376
#endif
16377
#ifndef VECTOR_REGISTERS_POP
16378
    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
16379
#endif
16380
16381
#ifdef HAVE_AES_ECB
16382
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
16383
        !defined(WOLFSSL_QNX_CAAM)
16384
    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
16385
16386
#elif defined(WOLFSSL_AFALG)
16387
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
16388
16389
#elif defined(WOLFSSL_DEVCRYPTO_AES)
16390
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
16391
16392
#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
16393
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
16394
16395
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
16396
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
16397
16398
#elif defined(MAX3266X_AES)
16399
16400
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16401
{
16402
    int status;
16403
    word32 keySize;
16404
16405
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16406
        return BAD_FUNC_ARG;
16407
16408
    status = wc_AesGetKeySize(aes, &keySize);
16409
    if (status != 0) {
16410
        return status;
16411
    }
16412
16413
    status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key,
16414
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
16415
16416
    return status;
16417
}
16418
16419
#ifdef HAVE_AES_DECRYPT
16420
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16421
{
16422
    int status;
16423
    word32 keySize;
16424
16425
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16426
        return BAD_FUNC_ARG;
16427
16428
    status = wc_AesGetKeySize(aes, &keySize);
16429
    if (status != 0) {
16430
        return status;
16431
    }
16432
16433
    status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key,
16434
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
16435
16436
    return status;
16437
}
16438
#endif /* HAVE_AES_DECRYPT */
16439
16440
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
16441
16442
/* Software AES - ECB */
16443
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16444
{
16445
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16446
        return BAD_FUNC_ARG;
16447
16448
    return AES_ECB_encrypt(aes, in, out, sz);
16449
}
16450
16451
16452
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16453
{
16454
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16455
        return BAD_FUNC_ARG;
16456
16457
    return AES_ECB_decrypt(aes, in, out, sz);
16458
}
16459
16460
#elif defined(WOLFSSL_PSOC6_CRYPTO)
16461
16462
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16463
{
16464
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16465
        return BAD_FUNC_ARG;
16466
    if (!WC_AES_KEY_IS_SET(aes)) {
16467
        WOLFSSL_MSG("AES key not set");
16468
        return MISSING_KEY;
16469
    }
16470
16471
    return wc_Psoc6_Aes_EcbEncrypt(aes, out, in, sz);
16472
}
16473
16474
#define _AesEcbEncrypt(aes, out, in, sz) wc_AesEcbEncrypt(aes, out, in, sz)
16475
16476
#ifdef HAVE_AES_DECRYPT
16477
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16478
{
16479
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16480
        return BAD_FUNC_ARG;
16481
    if (!WC_AES_KEY_IS_SET(aes)) {
16482
        WOLFSSL_MSG("AES key not set");
16483
        return MISSING_KEY;
16484
    }
16485
16486
    return wc_Psoc6_Aes_EcbDecrypt(aes, out, in, sz);
16487
}
16488
16489
#define _AesEcbDecrypt(aes, out, in, sz) wc_AesEcbDecrypt(aes, out, in, sz)
16490
#endif /* HAVE_AES_DECRYPT */
16491
16492
#else
16493
16494
/* Software AES - ECB */
16495
static WARN_UNUSED_RESULT int _AesEcbEncrypt(
16496
    Aes* aes, byte* out, const byte* in, word32 sz)
16497
{
16498
    int ret = 0;
16499
16500
#ifdef WOLF_CRYPTO_CB
16501
    #ifndef WOLF_CRYPTO_CB_FIND
16502
    if (aes->devId != INVALID_DEVID)
16503
    #endif
16504
    {
16505
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
16506
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16507
            return ret;
16508
        ret = 0;
16509
        /* fall-through when unavailable */
16510
    }
16511
#endif
16512
#ifdef WOLF_CRYPTO_CB_ONLY_AES
16513
    /* No software fallback: the per-block loop below would only re-invoke
16514
     * cryptocb ECB and propagate UNAVAILABLE; short-circuit instead. */
16515
    return NO_VALID_DEVID;
16516
#endif
16517
#ifdef WOLFSSL_IMXRT_DCP
16518
    if (aes->keylen == 16)
16519
        return DCPAesEcbEncrypt(aes, out, in, sz);
16520
#endif
16521
16522
    /* Software key schedule required from here on. */
16523
    if (!WC_AES_KEY_IS_SET(aes)) {
16524
        WOLFSSL_MSG("AES key not set");
16525
        return MISSING_KEY;
16526
    }
16527
16528
    VECTOR_REGISTERS_PUSH;
16529
16530
#if defined(WOLFSSL_RISCV_ASM)
16531
    AES_encrypt_blocks_RISCV64(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16532
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16533
#ifdef WOLFSSL_ARM32_AES_DISPATCH
16534
    if (aes->use_aes_hw_crypto) {
16535
        AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key,
16536
            (int)aes->rounds);
16537
    }
16538
    else {
16539
        AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key,
16540
            aes->rounds);
16541
    }
16542
#elif !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16543
    AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16544
#else
16545
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
16546
#endif
16547
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16548
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16549
    if (aes->use_aes_hw_crypto) {
16550
        AES_encrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
16551
            (int)aes->rounds);
16552
    }
16553
    else
16554
#endif
16555
#if !defined(WOLFSSL_ARMASM_NO_NEON)
16556
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16557
    if (sz >= 32)
16558
#endif
16559
    {
16560
        AES_ECB_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
16561
            aes->rounds);
16562
    }
16563
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16564
    else
16565
#endif
16566
#endif
16567
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16568
    {
16569
        AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key,
16570
            aes->rounds);
16571
    }
16572
#endif
16573
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
16574
    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
16575
    ret = 0;
16576
#else
16577
#ifdef WOLFSSL_AESNI
16578
    if (aes->use_aesni) {
16579
    #ifdef WOLFSSL_X86_64_BUILD
16580
        AesEcbEncryptBlocks(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16581
    #else
16582
        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16583
    #endif
16584
    }
16585
    else
16586
#endif
16587
    {
16588
#if defined(NEED_AES_TABLES)
16589
        AesEncryptBlocks_C(aes, in, out, sz);
16590
#else
16591
        word32 i;
16592
#ifdef WC_AES_HAVE_PREFETCH_ARG
16593
        int did_prefetches = 0;
16594
#endif
16595
16596
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
16597
            ret = AesEncrypt_preFetchOpt(aes, in, out, &did_prefetches);
16598
            if (ret != 0)
16599
                break;
16600
            in += WC_AES_BLOCK_SIZE;
16601
            out += WC_AES_BLOCK_SIZE;
16602
        }
16603
#endif
16604
    }
16605
#endif
16606
16607
    VECTOR_REGISTERS_POP;
16608
16609
    return ret;
16610
}
16611
16612
#ifdef HAVE_AES_DECRYPT
16613
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
16614
    Aes* aes, byte* out, const byte* in, word32 sz)
16615
{
16616
    int ret = 0;
16617
16618
#ifdef WOLF_CRYPTO_CB
16619
    #ifndef WOLF_CRYPTO_CB_FIND
16620
    if (aes->devId != INVALID_DEVID)
16621
    #endif
16622
    {
16623
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
16624
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
16625
            return ret;
16626
        ret = 0;
16627
        /* fall-through when unavailable */
16628
    }
16629
#endif
16630
#ifdef WOLF_CRYPTO_CB_ONLY_AES
16631
    return NO_VALID_DEVID;
16632
#endif
16633
#ifdef WOLFSSL_IMXRT_DCP
16634
    if (aes->keylen == 16)
16635
        return DCPAesEcbDecrypt(aes, out, in, sz);
16636
#endif
16637
16638
    /* Software key schedule required from here on. */
16639
    if (!WC_AES_KEY_IS_SET(aes)) {
16640
        WOLFSSL_MSG("AES key not set");
16641
        return MISSING_KEY;
16642
    }
16643
16644
    VECTOR_REGISTERS_PUSH;
16645
16646
#if defined(WOLFSSL_RISCV_ASM)
16647
    AES_decrypt_blocks_RISCV64(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16648
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16649
#ifdef WOLFSSL_ARM32_AES_DISPATCH
16650
    if (aes->use_aes_hw_crypto) {
16651
        AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key,
16652
            (int)aes->rounds);
16653
    }
16654
    else {
16655
        AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key,
16656
            aes->rounds);
16657
    }
16658
#elif !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16659
    AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16660
#else
16661
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
16662
#endif
16663
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16664
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16665
    if (aes->use_aes_hw_crypto) {
16666
        AES_decrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
16667
            (int)aes->rounds);
16668
    }
16669
    else
16670
#endif
16671
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
16672
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16673
    if (sz >= 64)
16674
#endif
16675
    {
16676
        AES_ECB_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
16677
            aes->rounds);
16678
    }
16679
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16680
    else
16681
#endif
16682
#endif
16683
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16684
    {
16685
        AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key,
16686
            aes->rounds);
16687
    }
16688
#endif
16689
#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))
16690
    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
16691
    ret = 0;
16692
#else
16693
#ifdef WOLFSSL_AESNI
16694
    if (aes->use_aesni) {
16695
    #ifdef WOLFSSL_X86_64_BUILD
16696
        AesEcbDecryptBlocks(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16697
    #else
16698
        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
16699
    #endif
16700
    }
16701
    else
16702
#endif
16703
    {
16704
#if defined(NEED_AES_TABLES)
16705
        AesDecryptBlocks_C(aes, in, out, sz);
16706
#else
16707
        word32 i;
16708
16709
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
16710
            ret = wc_AesDecryptDirect(aes, out, in);
16711
            if (ret != 0)
16712
                break;
16713
            in += WC_AES_BLOCK_SIZE;
16714
            out += WC_AES_BLOCK_SIZE;
16715
        }
16716
#endif
16717
    }
16718
#endif
16719
16720
    VECTOR_REGISTERS_POP;
16721
16722
    return ret;
16723
}
16724
#endif
16725
16726
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16727
{
16728
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16729
      return BAD_FUNC_ARG;
16730
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
16731
        return BAD_LENGTH_E;
16732
    }
16733
16734
    return _AesEcbEncrypt(aes, out, in, sz);
16735
}
16736
16737
#ifdef HAVE_AES_DECRYPT
16738
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16739
{
16740
    if ((in == NULL) || (out == NULL) || (aes == NULL))
16741
      return BAD_FUNC_ARG;
16742
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
16743
        return BAD_LENGTH_E;
16744
    }
16745
16746
    return _AesEcbDecrypt(aes, out, in, sz);
16747
}
16748
#endif /* HAVE_AES_DECRYPT */
16749
#endif
16750
#endif /* HAVE_AES_ECB */
16751
16752
#if defined(WOLFSSL_AES_CFB)
16753
16754
#if defined(WOLFSSL_NXP_HASHCRYPT_AES)
16755
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
16756
16757
#elif defined(WOLFSSL_PSOC6_CRYPTO)
16758
16759
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16760
{
16761
    if (aes == NULL)
16762
        return BAD_FUNC_ARG;
16763
    if (!WC_AES_KEY_IS_SET(aes)) {
16764
        WOLFSSL_MSG("AES key not set");
16765
        return MISSING_KEY;
16766
    }
16767
    return wc_Psoc6_Aes_CfbEncrypt(aes, out, in, sz);
16768
}
16769
16770
#ifdef HAVE_AES_DECRYPT
16771
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
16772
{
16773
    if (aes == NULL)
16774
        return BAD_FUNC_ARG;
16775
    if (!WC_AES_KEY_IS_SET(aes)) {
16776
        WOLFSSL_MSG("AES key not set");
16777
        return MISSING_KEY;
16778
    }
16779
    return wc_Psoc6_Aes_CfbDecrypt(aes, out, in, sz);
16780
}
16781
#endif /* HAVE_AES_DECRYPT */
16782
16783
#else
16784
/* Feedback AES mode
16785
 *
16786
 * aes structure holding key to use for encryption
16787
 * out buffer to hold result of encryption (must be at least as large as input
16788
 *     buffer)
16789
 * in  buffer to encrypt
16790
 * sz  size of input buffer
16791
 * mode flag to specify AES mode
16792
 *
16793
 * returns 0 on success and negative error values on failure
16794
 */
16795
/* Software AES - CFB Encrypt */
16796
static WARN_UNUSED_RESULT int AesCfbEncrypt_C(Aes* aes, byte* out,
16797
    const byte* in, word32 sz)
16798
{
16799
    int ret = 0;
16800
    word32 processed;
16801
#ifdef WC_AES_HAVE_PREFETCH_ARG
16802
    int did_prefetches = 0;
16803
#endif
16804
16805
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16806
        return BAD_FUNC_ARG;
16807
    }
16808
    if (!WC_AES_KEY_IS_SET(aes)) {
16809
        WOLFSSL_MSG("AES key not set");
16810
        return MISSING_KEY;
16811
    }
16812
    if (sz == 0) {
16813
        return 0;
16814
    }
16815
16816
    if (aes->left > 0) {
16817
        /* consume any unused bytes left in aes->tmp */
16818
        processed = min(aes->left, sz);
16819
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16820
            processed);
16821
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out,
16822
            processed);
16823
        aes->left -= processed;
16824
        out += processed;
16825
        in += processed;
16826
        sz -= processed;
16827
    }
16828
16829
    VECTOR_REGISTERS_PUSH;
16830
16831
    while (sz >= WC_AES_BLOCK_SIZE) {
16832
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
16833
                                        &did_prefetches);
16834
        if (ret != 0) {
16835
            break;
16836
        }
16837
        xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
16838
        XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
16839
        out += WC_AES_BLOCK_SIZE;
16840
        in  += WC_AES_BLOCK_SIZE;
16841
        sz  -= WC_AES_BLOCK_SIZE;
16842
    }
16843
16844
    /* encrypt left over data */
16845
    if ((ret == 0) && sz) {
16846
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16847
                                     &did_prefetches);
16848
        if (ret == 0) {
16849
            xorbufout(out, in, aes->tmp, sz);
16850
            XMEMCPY(aes->reg, out, sz);
16851
            aes->left = WC_AES_BLOCK_SIZE - sz;
16852
        }
16853
    }
16854
16855
    VECTOR_REGISTERS_POP;
16856
16857
    return ret;
16858
}
16859
16860
16861
#if defined(HAVE_AES_DECRYPT)
16862
/* CFB 128
16863
 *
16864
 * aes structure holding key to use for decryption
16865
 * out buffer to hold result of decryption (must be at least as large as input
16866
 *     buffer)
16867
 * in  buffer to decrypt
16868
 * sz  size of input buffer
16869
 *
16870
 * returns 0 on success and negative error values on failure
16871
 */
16872
/* Software AES - CFB Decrypt */
16873
static WARN_UNUSED_RESULT int AesCfbDecrypt_C(Aes* aes, byte* out,
16874
    const byte* in, word32 sz, byte mode)
16875
{
16876
    int ret = 0;
16877
    word32 processed;
16878
#ifdef WC_AES_HAVE_PREFETCH_ARG
16879
    int did_prefetches = 0;
16880
#endif
16881
#ifndef WC_AES_CFB_DEC_BUF_BLOCKS
16882
    #define WC_AES_CFB_DEC_BUF_BLOCKS 32
16883
#elif WC_AES_CFB_DEC_BUF_BLOCKS < 2
16884
    #error Invalid WC_AES_CFB_DEC_BUF_BLOCKS
16885
#endif
16886
#ifdef WOLFSSL_SMALL_STACK
16887
    byte *tmp = NULL;
16888
#endif
16889
16890
    (void)mode;
16891
16892
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
16893
        return BAD_FUNC_ARG;
16894
    }
16895
    if (!WC_AES_KEY_IS_SET(aes)) {
16896
        WOLFSSL_MSG("AES key not set");
16897
        return MISSING_KEY;
16898
    }
16899
    if (sz == 0) {
16900
        return 0;
16901
    }
16902
16903
    if (aes->left > 0) {
16904
        /* consume any unused bytes left in aes->tmp */
16905
        processed = min(aes->left, sz);
16906
        /* copy input over to aes->reg */
16907
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, processed);
16908
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
16909
            processed);
16910
        aes->left -= processed;
16911
        out += processed;
16912
        in += processed;
16913
        sz -= processed;
16914
    }
16915
16916
#if defined(WOLFSSL_SMALL_STACK) && defined(HAVE_AES_ECB) &&    \
16917
    !defined(WOLFSSL_PIC32MZ_CRYPT) &&                          \
16918
    (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
16919
    /* Only suffer the heap overhead if sz is enough to warrant it.
16920
     *
16921
     * Allocate the working buffer before suspending interrupts, so that we can
16922
     * allocate with regular GFP_KERNEL.
16923
     */
16924
    if (sz >= WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE)
16925
        tmp = (byte *)XMALLOC(WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_AES);
16926
16927
    VECTOR_REGISTERS_PUSH2(XFREE(tmp, NULL, DYNAMIC_TYPE_AES););
16928
#else
16929
    VECTOR_REGISTERS_PUSH;
16930
#endif
16931
16932
    #if defined(HAVE_AES_ECB) && \
16933
        !defined(WOLFSSL_PIC32MZ_CRYPT) && \
16934
        (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
16935
#ifdef WOLFSSL_SMALL_STACK
16936
    if (tmp != NULL)
16937
#endif
16938
    {
16939
#ifndef WOLFSSL_SMALL_STACK
16940
        ALIGN16 byte tmp[WC_AES_CFB_DEC_BUF_BLOCKS * WC_AES_BLOCK_SIZE];
16941
#endif
16942
        if (sz >= 2 * WC_AES_BLOCK_SIZE) {
16943
            /* CFB-decrypt keystream block i is E(C_{i-1}): block 0 uses the
16944
             * feedback register, block i>=1 uses the previous cipher block.  So
16945
             * ECB the ciphertext straight out of 'in' (no shift-copy) to get
16946
             * E(C_0..C_{n-1}), XOR block i with the (i-1)th ECB output, and
16947
             * carry E(C_{n-1}) as the next chunk's block-0 keystream - E(reg)
16948
             * is computed only once here. */
16949
            ALIGN16 byte ks[WC_AES_BLOCK_SIZE];
16950
            ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, ks,
16951
                                         &did_prefetches);
16952
            while ((ret == 0) && (sz >= 2 * WC_AES_BLOCK_SIZE)) {
16953
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
16954
                word32 nbytes;
16955
                if (blocks > WC_AES_CFB_DEC_BUF_BLOCKS)
16956
                    blocks = WC_AES_CFB_DEC_BUF_BLOCKS;
16957
                nbytes = blocks * WC_AES_BLOCK_SIZE;
16958
                /* tmp[i] = E(C_i), read directly from the input. Already inside
16959
                 * VECTOR_REGISTERS_PUSH, so use the inner ECB (no nested
16960
                 * save/restore or re-dispatch) where available. */
16961
            #if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
16962
                if (aes->use_aesni) {
16963
                    AesEcbEncryptBlocks(in, tmp, nbytes, (byte*)aes->key,
16964
                                        (int)aes->rounds);
16965
                }
16966
                else
16967
            #endif
16968
                {
16969
                    ret = wc_AesEcbEncrypt(aes, tmp, in, nbytes);
16970
                    if (ret != 0)
16971
                        break;
16972
                }
16973
                /* Feedback for the tail = last cipher block; save it before the
16974
                 * XOR can overwrite 'in' (in == out case). */
16975
                XMEMCPY((byte*)aes->reg, in + nbytes - WC_AES_BLOCK_SIZE,
16976
                        WC_AES_BLOCK_SIZE);
16977
                /* P_0 = C_0 ^ E(feedback); P_i = C_i ^ E(C_{i-1}) =
16978
                 *       C_i ^ tmp[i-1]. */
16979
                xorbufout(out, in, ks, WC_AES_BLOCK_SIZE);
16980
                xorbufout(out + WC_AES_BLOCK_SIZE, in + WC_AES_BLOCK_SIZE, tmp,
16981
                          nbytes - WC_AES_BLOCK_SIZE);
16982
                /* Carry E(last cipher block) as the next chunk's block-0 KS. */
16983
                XMEMCPY(ks, tmp + nbytes - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
16984
                out += nbytes;
16985
                in  += nbytes;
16986
                sz  -= nbytes;
16987
            }
16988
        }
16989
    }
16990
    #endif
16991
    while (sz >= WC_AES_BLOCK_SIZE) {
16992
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
16993
                                        &did_prefetches);
16994
        if (ret != 0) {
16995
            break;
16996
        }
16997
        XMEMCPY((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
16998
        xorbufout(out, in, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
16999
        out += WC_AES_BLOCK_SIZE;
17000
        in  += WC_AES_BLOCK_SIZE;
17001
        sz  -= WC_AES_BLOCK_SIZE;
17002
    }
17003
17004
    /* decrypt left over data */
17005
    if ((ret == 0) && sz) {
17006
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17007
                                        &did_prefetches);
17008
        if (ret == 0) {
17009
            XMEMCPY(aes->reg, in, sz);
17010
            xorbufout(out, in, aes->tmp, sz);
17011
            aes->left = WC_AES_BLOCK_SIZE - sz;
17012
        }
17013
    }
17014
17015
    VECTOR_REGISTERS_POP;
17016
17017
#ifdef WOLFSSL_SMALL_STACK
17018
    /* Free tmp after restoring interrupts, so that GFP_KERNEL is usable. */
17019
    XFREE(tmp, NULL, DYNAMIC_TYPE_AES);
17020
#endif
17021
17022
    return ret;
17023
}
17024
#endif /* HAVE_AES_DECRYPT */
17025
17026
/* CFB 128
17027
 *
17028
 * aes structure holding key to use for encryption
17029
 * out buffer to hold result of encryption (must be at least as large as input
17030
 *     buffer)
17031
 * in  buffer to encrypt
17032
 * sz  size of input buffer
17033
 *
17034
 * returns 0 on success and negative error values on failure
17035
 */
17036
/* Software AES - CFB Encrypt */
17037
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17038
{
17039
#ifdef WOLF_CRYPTO_CB
17040
    if (aes == NULL)
17041
        return BAD_FUNC_ARG;
17042
    #ifndef WOLF_CRYPTO_CB_FIND
17043
    if (aes->devId != INVALID_DEVID)
17044
    #endif
17045
    {
17046
        int crypto_cb_ret = wc_CryptoCb_AesCfbEncrypt(aes, out, in, sz);
17047
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17048
            return crypto_cb_ret;
17049
        /* fall-through when unavailable */
17050
    }
17051
#endif
17052
    return AesCfbEncrypt_C(aes, out, in, sz);
17053
}
17054
17055
17056
#ifdef HAVE_AES_DECRYPT
17057
/* CFB 128
17058
 *
17059
 * aes structure holding key to use for decryption
17060
 * out buffer to hold result of decryption (must be at least as large as input
17061
 *     buffer)
17062
 * in  buffer to decrypt
17063
 * sz  size of input buffer
17064
 *
17065
 * returns 0 on success and negative error values on failure
17066
 */
17067
/* Software AES - CFB Decrypt */
17068
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17069
{
17070
#ifdef WOLF_CRYPTO_CB
17071
    if (aes == NULL)
17072
        return BAD_FUNC_ARG;
17073
    #ifndef WOLF_CRYPTO_CB_FIND
17074
    if (aes->devId != INVALID_DEVID)
17075
    #endif
17076
    {
17077
        int crypto_cb_ret = wc_CryptoCb_AesCfbDecrypt(aes, out, in, sz);
17078
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17079
            return crypto_cb_ret;
17080
        /* fall-through when unavailable */
17081
    }
17082
#endif
17083
    return AesCfbDecrypt_C(aes, out, in, sz, AES_CFB_MODE);
17084
}
17085
#endif /* HAVE_AES_DECRYPT */
17086
#endif /* WOLFSSL_PSOC6_CRYPTO */
17087
17088
#ifndef WOLFSSL_NO_AES_CFB_1_8
17089
/* shift the whole WC_AES_BLOCK_SIZE array left by 8 or 1 bits */
17090
static void shiftLeftArray(byte* ary, byte shift)
17091
{
17092
    int i;
17093
17094
    if (shift == WOLFSSL_BIT_SIZE) {
17095
        /* shifting over by 8 bits */
17096
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
17097
            ary[i] = ary[i+1];
17098
        }
17099
        ary[i] = 0;
17100
    }
17101
    else {
17102
        /* shifting over by 7 or less bits */
17103
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
17104
            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
17105
            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
17106
            ary[i] = (byte)((ary[i] << shift) + carry);
17107
        }
17108
        ary[i] = (byte)(ary[i] << shift);
17109
    }
17110
}
17111
17112
17113
/* returns 0 on success and negative values on failure */
17114
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
17115
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
17116
{
17117
    byte *pt;
17118
    int ret = 0;
17119
#ifdef WC_AES_HAVE_PREFETCH_ARG
17120
    int did_prefetches = 0;
17121
#endif
17122
17123
    if (aes == NULL || out == NULL || in == NULL) {
17124
        return BAD_FUNC_ARG;
17125
    }
17126
17127
    if (!WC_AES_KEY_IS_SET(aes)) {
17128
        WOLFSSL_MSG("AES key not set");
17129
        return MISSING_KEY;
17130
    }
17131
    if (sz == 0) {
17132
        return 0;
17133
    }
17134
17135
    VECTOR_REGISTERS_PUSH;
17136
17137
    while (sz > 0) {
17138
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17139
                                        &did_prefetches);
17140
        if (ret != 0)
17141
            break;
17142
        if (dir == AES_DECRYPTION) {
17143
            pt = (byte*)aes->reg;
17144
17145
            /* LSB + CAT */
17146
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
17147
            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
17148
        }
17149
17150
        /* MSB + XOR */
17151
    #ifdef BIG_ENDIAN_ORDER
17152
        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
17153
    #endif
17154
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
17155
        if (dir == AES_ENCRYPTION) {
17156
            pt = (byte*)aes->reg;
17157
17158
            /* LSB + CAT */
17159
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
17160
            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
17161
        }
17162
17163
        out += 1;
17164
        in  += 1;
17165
        sz  -= 1;
17166
    }
17167
17168
    VECTOR_REGISTERS_POP;
17169
17170
    return ret;
17171
}
17172
17173
17174
/* returns 0 on success and negative values on failure */
17175
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
17176
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
17177
{
17178
    byte tmp;
17179
    byte cur = 0; /* hold current work in order to handle inline in=out */
17180
    byte* pt;
17181
    int bit = 7;
17182
    int ret = 0;
17183
#ifdef WC_AES_HAVE_PREFETCH_ARG
17184
    int did_prefetches = 0;
17185
#endif
17186
17187
    if (aes == NULL || out == NULL || in == NULL) {
17188
        return BAD_FUNC_ARG;
17189
    }
17190
17191
    if (!WC_AES_KEY_IS_SET(aes)) {
17192
        WOLFSSL_MSG("AES key not set");
17193
        return MISSING_KEY;
17194
    }
17195
    if (sz == 0) {
17196
        return 0;
17197
    }
17198
17199
    VECTOR_REGISTERS_PUSH;
17200
17201
    while (sz > 0) {
17202
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17203
                                        &did_prefetches);
17204
        if (ret != 0)
17205
            break;
17206
        if (dir == AES_DECRYPTION) {
17207
            pt = (byte*)aes->reg;
17208
17209
            /* LSB + CAT */
17210
            tmp = (byte)((0X01U << bit) & in[0]);
17211
            tmp = (byte)(tmp >> bit);
17212
            tmp &= 0x01;
17213
            shiftLeftArray((byte*)aes->reg, 1);
17214
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
17215
        }
17216
17217
        /* MSB  + XOR */
17218
        tmp = (byte)((0X01U << bit) & in[0]);
17219
        pt = (byte*)aes->tmp;
17220
        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
17221
        tmp &= 0x01;
17222
        cur = (byte)(cur | (tmp << bit));
17223
17224
17225
        if (dir == AES_ENCRYPTION) {
17226
            pt = (byte*)aes->reg;
17227
17228
            /* LSB + CAT */
17229
            shiftLeftArray((byte*)aes->reg, 1);
17230
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
17231
        }
17232
17233
        bit--;
17234
        if (bit < 0) {
17235
            out[0] = cur;
17236
            out += 1;
17237
            in  += 1;
17238
            sz  -= 1;
17239
            bit = 7U;
17240
            cur = 0;
17241
        }
17242
        else {
17243
            sz -= 1;
17244
        }
17245
    }
17246
17247
    if (ret == 0) {
17248
        if (bit < 7) {
17249
            out[0] = cur;
17250
        }
17251
    }
17252
17253
    VECTOR_REGISTERS_POP;
17254
17255
    return ret;
17256
}
17257
17258
17259
/* CFB 1
17260
 *
17261
 * aes structure holding key to use for encryption
17262
 * out buffer to hold result of encryption (must be at least as large as input
17263
 *     buffer)
17264
 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
17265
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
17266
 *
17267
 * returns 0 on success and negative values on failure
17268
 */
17269
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17270
{
17271
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
17272
}
17273
17274
17275
/* CFB 8
17276
 *
17277
 * aes structure holding key to use for encryption
17278
 * out buffer to hold result of encryption (must be at least as large as input
17279
 *     buffer)
17280
 * in  buffer to encrypt
17281
 * sz  size of input buffer
17282
 *
17283
 * returns 0 on success and negative values on failure
17284
 */
17285
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17286
{
17287
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
17288
}
17289
#ifdef HAVE_AES_DECRYPT
17290
17291
/* CFB 1
17292
 *
17293
 * aes structure holding key to use for encryption
17294
 * out buffer to hold result of encryption (must be at least as large as input
17295
 *     buffer)
17296
 * in  buffer to encrypt
17297
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
17298
 *
17299
 * returns 0 on success and negative values on failure
17300
 */
17301
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17302
{
17303
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
17304
}
17305
17306
17307
/* CFB 8
17308
 *
17309
 * aes structure holding key to use for encryption
17310
 * out buffer to hold result of encryption (must be at least as large as input
17311
 *     buffer)
17312
 * in  buffer to encrypt
17313
 * sz  size of input buffer
17314
 *
17315
 * returns 0 on success and negative values on failure
17316
 */
17317
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17318
{
17319
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
17320
}
17321
#endif /* HAVE_AES_DECRYPT */
17322
#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
17323
#endif /* WOLFSSL_AES_CFB */
17324
17325
#ifdef WOLFSSL_AES_OFB
17326
#ifdef WOLFSSL_NXP_HASHCRYPT_AES
17327
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
17328
17329
#else /* software */
17330
/* OFB AES mode
17331
 *
17332
 * aes structure holding key to use for encryption
17333
 * out buffer to hold result of encryption (must be at least as large as input
17334
 *     buffer)
17335
 * in  buffer to encrypt
17336
 * sz  size of input buffer
17337
 *
17338
 * returns 0 on success and negative error values on failure
17339
 */
17340
/* Software AES - OFB Encrypt/Decrypt */
17341
static WARN_UNUSED_RESULT int AesOfbCrypt_C(Aes* aes, byte* out, const byte* in,
17342
    word32 sz)
17343
{
17344
    int ret = 0;
17345
    word32 processed;
17346
#ifdef WC_AES_HAVE_PREFETCH_ARG
17347
    int did_prefetches = 0;
17348
#endif
17349
17350
    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
17351
        return BAD_FUNC_ARG;
17352
    }
17353
    if (!WC_AES_KEY_IS_SET(aes)) {
17354
        WOLFSSL_MSG("AES key not set");
17355
        return MISSING_KEY;
17356
    }
17357
    if (sz == 0) {
17358
        return 0;
17359
    }
17360
17361
    if (aes->left > 0) {
17362
        /* consume any unused bytes left in aes->tmp */
17363
        processed = min(aes->left, sz);
17364
        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
17365
            processed);
17366
        aes->left -= processed;
17367
        out += processed;
17368
        in += processed;
17369
        sz -= processed;
17370
    }
17371
17372
    VECTOR_REGISTERS_PUSH;
17373
17374
    while (sz >= WC_AES_BLOCK_SIZE) {
17375
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
17376
                                        &did_prefetches);
17377
        if (ret != 0) {
17378
            break;
17379
        }
17380
        xorbufout(out, in, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
17381
        out += WC_AES_BLOCK_SIZE;
17382
        in  += WC_AES_BLOCK_SIZE;
17383
        sz  -= WC_AES_BLOCK_SIZE;
17384
    }
17385
17386
    /* encrypt left over data */
17387
    if ((ret == 0) && sz) {
17388
        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
17389
                                        &did_prefetches);
17390
        if (ret == 0) {
17391
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
17392
            xorbufout(out, in, aes->tmp, sz);
17393
            aes->left = WC_AES_BLOCK_SIZE - sz;
17394
        }
17395
    }
17396
17397
    VECTOR_REGISTERS_POP;
17398
17399
    return ret;
17400
}
17401
17402
/* OFB
17403
 *
17404
 * aes structure holding key to use for encryption
17405
 * out buffer to hold result of encryption (must be at least as large as input
17406
 *     buffer)
17407
 * in  buffer to encrypt
17408
 * sz  size of input buffer
17409
 *
17410
 * returns 0 on success and negative error values on failure
17411
 */
17412
/* Software AES - OFB Encrypt */
17413
int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17414
{
17415
#ifdef WOLF_CRYPTO_CB
17416
    if (aes == NULL)
17417
        return BAD_FUNC_ARG;
17418
    #ifndef WOLF_CRYPTO_CB_FIND
17419
    if (aes->devId != INVALID_DEVID)
17420
    #endif
17421
    {
17422
        int crypto_cb_ret = wc_CryptoCb_AesOfbEncrypt(aes, out, in, sz);
17423
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17424
            return crypto_cb_ret;
17425
        /* fall-through when unavailable */
17426
    }
17427
#endif
17428
    return AesOfbCrypt_C(aes, out, in, sz);
17429
}
17430
17431
17432
#ifdef HAVE_AES_DECRYPT
17433
/* OFB
17434
 *
17435
 * aes structure holding key to use for decryption
17436
 * out buffer to hold result of decryption (must be at least as large as input
17437
 *     buffer)
17438
 * in  buffer to decrypt
17439
 * sz  size of input buffer
17440
 *
17441
 * returns 0 on success and negative error values on failure
17442
 */
17443
/* Software AES - OFB Decrypt */
17444
int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
17445
{
17446
#ifdef WOLF_CRYPTO_CB
17447
    if (aes == NULL)
17448
        return BAD_FUNC_ARG;
17449
    #ifndef WOLF_CRYPTO_CB_FIND
17450
    if (aes->devId != INVALID_DEVID)
17451
    #endif
17452
    {
17453
        int crypto_cb_ret = wc_CryptoCb_AesOfbDecrypt(aes, out, in, sz);
17454
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
17455
            return crypto_cb_ret;
17456
        /* fall-through when unavailable */
17457
    }
17458
#endif
17459
    return AesOfbCrypt_C(aes, out, in, sz);
17460
}
17461
#endif /* HAVE_AES_DECRYPT */
17462
#endif /* software */
17463
#endif /* WOLFSSL_AES_OFB */
17464
17465
17466
#ifdef HAVE_AES_KEYWRAP
17467
17468
/* Initialize key wrap counter with value */
17469
static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
17470
{
17471
    word32 i;
17472
    word32 bytes;
17473
17474
    bytes = sizeof(word32);
17475
    for (i = 0; i < sizeof(word32); i++) {
17476
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
17477
        bytes--;
17478
    }
17479
}
17480
17481
/* Increment key wrap counter */
17482
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
17483
{
17484
    int i;
17485
17486
    /* in network byte order so start at end and work back */
17487
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
17488
        if (++inOutCtr[i])  /* we're done unless we overflow */
17489
            return;
17490
    }
17491
}
17492
17493
/* Decrement key wrap counter */
17494
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
17495
{
17496
    int i;
17497
17498
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
17499
        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
17500
            return;
17501
    }
17502
}
17503
17504
/* Core RFC 3394 wrapping loop: plaintext at out+8, initial A in aiv; writes
17505
 * C[0]=A and wrapped R[i] in place.  Caller owns output-buffer sizing. */
17506
static int AesKeyWrapRaw(Aes* aes, word32 inSz, byte* out, const byte* aiv)
17507
{
17508
    word32 i;
17509
    byte* r;
17510
    int j;
17511
    int ret = 0;
17512
17513
    byte t[KEYWRAP_BLOCK_SIZE];
17514
    byte tmp[WC_AES_BLOCK_SIZE];
17515
17516
    /* at least two 64-bit blocks, on a 64-bit boundary */
17517
    if (aes == NULL || out == NULL || aiv == NULL ||
17518
        inSz < 2 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0) {
17519
        return BAD_FUNC_ARG;
17520
    }
17521
17522
#ifndef HAVE_AES_ECB
17523
    /* The block loop below uses the wc_AesEncryptDirect macro, which bypasses
17524
     * the public function's guard. With HAVE_AES_ECB the loop calls
17525
     * wc_AesEcbEncrypt instead, whose own guard sits after the crypto
17526
     * callback dispatch, so a device-held key still reaches the device. */
17527
    if (!WC_AES_KEY_IS_SET(aes)) {
17528
        WOLFSSL_MSG("AES key not set");
17529
        return MISSING_KEY;
17530
    }
17531
#endif
17532
17533
    r = out + KEYWRAP_BLOCK_SIZE;
17534
    XMEMSET(t, 0, sizeof(t));
17535
17536
    /* A = initial value */
17537
    XMEMCPY(tmp, aiv, KEYWRAP_BLOCK_SIZE);
17538
17539
#ifndef HAVE_AES_ECB
17540
    /* Direct block access must save vector registers across the loop; with
17541
     * HAVE_AES_ECB wc_AesEcbEncrypt saves them and can route to an ECB cb. */
17542
    VECTOR_REGISTERS_PUSH;
17543
#endif
17544
17545
    for (j = 0; j <= 5; j++) {
17546
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
17547
            /* load R[i] */
17548
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
17549
17550
#ifdef HAVE_AES_ECB
17551
            ret = wc_AesEcbEncrypt(aes, tmp, tmp, WC_AES_BLOCK_SIZE);
17552
#else
17553
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
17554
#endif
17555
            if (ret != 0)
17556
                break;
17557
17558
            /* calculate new A */
17559
            IncrementKeyWrapCounter(t);
17560
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
17561
17562
            /* save R[i] */
17563
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
17564
            r += KEYWRAP_BLOCK_SIZE;
17565
        }
17566
        if (ret != 0)
17567
            break;
17568
        r = out + KEYWRAP_BLOCK_SIZE;
17569
    }
17570
17571
#ifndef HAVE_AES_ECB
17572
    VECTOR_REGISTERS_POP;
17573
#endif
17574
17575
    if (ret != 0)
17576
        return ret;
17577
17578
    /* C[0] = A */
17579
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
17580
17581
    return 0;
17582
}
17583
17584
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
17585
        word32 outSz, const byte* iv)
17586
{
17587
    int ret;
17588
    byte aiv[KEYWRAP_BLOCK_SIZE];
17589
17590
    /* >= two 64-bit blocks on a 64-bit boundary, output fits outSz; inSz
17591
     * capped at INT_MAX-8 so the returned inSz+8 stays a non-negative int. */
17592
    if (aes == NULL || in == NULL || out == NULL ||
17593
        inSz < 2 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0 ||
17594
        inSz > 0x7FFFFFFFU - KEYWRAP_BLOCK_SIZE ||
17595
        outSz < inSz + KEYWRAP_BLOCK_SIZE)
17596
        return BAD_FUNC_ARG;
17597
17598
#ifdef WOLF_CRYPTO_CB
17599
    #ifndef WOLF_CRYPTO_CB_FIND
17600
    if (aes->devId != INVALID_DEVID)
17601
    #endif
17602
    {
17603
        ret = wc_CryptoCb_AesKeyWrap(aes, in, inSz, out, outSz, iv, 0);
17604
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
17605
            return ret;
17606
        }
17607
        /* fall through to software when unavailable */
17608
    }
17609
#endif
17610
17611
    /* user IV is optional */
17612
    if (iv == NULL) {
17613
        XMEMSET(aiv, 0xA6, KEYWRAP_BLOCK_SIZE);
17614
    }
17615
    else {
17616
        XMEMCPY(aiv, iv, KEYWRAP_BLOCK_SIZE);
17617
    }
17618
17619
    /* stage plaintext at out+8; XMEMMOVE so in-place wrap (in == out) is safe */
17620
    XMEMMOVE(out + KEYWRAP_BLOCK_SIZE, in, inSz);
17621
17622
    ret = AesKeyWrapRaw(aes, inSz, out, aiv);
17623
    if (ret != 0) {
17624
        /* wipe the plaintext staged at out+8 (and any partial cipher state
17625
         * left there) so it is not leaked to the caller on failure */
17626
        ForceZero(out + KEYWRAP_BLOCK_SIZE, inSz);
17627
        return ret;
17628
    }
17629
17630
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
17631
}
17632
17633
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
17634
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
17635
                  byte* out, word32 outSz, const byte* iv)
17636
{
17637
    WC_DECLARE_VAR(aes, Aes, 1, 0);
17638
    int ret;
17639
17640
    if (key == NULL)
17641
        return BAD_FUNC_ARG;
17642
17643
#ifdef WOLFSSL_SMALL_STACK
17644
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
17645
                              DYNAMIC_TYPE_AES)) == NULL)
17646
        return MEMORY_E;
17647
#endif
17648
17649
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17650
    if (ret != 0)
17651
        goto out;
17652
17653
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
17654
    if (ret != 0) {
17655
        wc_AesFree(aes);
17656
        goto out;
17657
    }
17658
17659
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
17660
17661
    wc_AesFree(aes);
17662
17663
  out:
17664
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
17665
17666
    return ret;
17667
}
17668
17669
/* Core RFC 3394 unwrapping loop: decrypts (n+1) blocks in `in` to n blocks in
17670
 * out and recovered A in aOut.  No integrity check; caller verifies A. */
17671
static int AesKeyUnWrapRaw(Aes* aes, const byte* in, word32 inSz, byte* out,
17672
        byte* aOut)
17673
{
17674
    byte* r;
17675
    word32 i, n;
17676
    int j;
17677
    int ret = 0;
17678
17679
    byte t[KEYWRAP_BLOCK_SIZE];
17680
    byte tmp[WC_AES_BLOCK_SIZE];
17681
17682
    /* (n+1) blocks in, n >= 2 recovered blocks out, on a 64-bit boundary */
17683
    if (aes == NULL || in == NULL || out == NULL || aOut == NULL ||
17684
        inSz < 3 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0) {
17685
        return BAD_FUNC_ARG;
17686
    }
17687
17688
#ifndef HAVE_AES_ECB
17689
    /* The block loop below uses the wc_AesDecryptDirect macro, which bypasses
17690
     * the public function's guard. With HAVE_AES_ECB the loop calls
17691
     * wc_AesEcbDecrypt instead, whose own guard sits after the crypto
17692
     * callback dispatch, so a device-held key still reaches the device. */
17693
    if (!WC_AES_KEY_IS_SET(aes)) {
17694
        WOLFSSL_MSG("AES key not set");
17695
        return MISSING_KEY;
17696
    }
17697
#endif
17698
17699
    /* A = C[0], R[i] = C[i]; XMEMMOVE so in-place unwrap (in == out) is safe */
17700
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
17701
    XMEMMOVE(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
17702
    XMEMSET(t, 0, sizeof(t));
17703
17704
#ifndef HAVE_AES_ECB
17705
    /* Like AesKeyWrapRaw: HAVE_AES_ECB routes each block through wc_AesEcbDecrypt
17706
     * (saves registers + ECB cb); otherwise save vector registers here. */
17707
    VECTOR_REGISTERS_PUSH;
17708
#endif
17709
17710
    /* initialize counter to 6n */
17711
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
17712
    InitKeyWrapCounter(t, 6 * n);
17713
17714
    for (j = 5; j >= 0; j--) {
17715
        for (i = n; i >= 1; i--) {
17716
17717
            /* calculate A */
17718
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
17719
            DecrementKeyWrapCounter(t);
17720
17721
            /* load R[i], starting at end of R */
17722
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
17723
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
17724
#ifdef HAVE_AES_ECB
17725
            ret = wc_AesEcbDecrypt(aes, tmp, tmp, WC_AES_BLOCK_SIZE);
17726
#else
17727
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
17728
#endif
17729
            if (ret != 0)
17730
                break;
17731
17732
            /* save R[i] */
17733
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
17734
        }
17735
        if (ret != 0)
17736
            break;
17737
    }
17738
17739
#ifndef HAVE_AES_ECB
17740
    VECTOR_REGISTERS_POP;
17741
#endif
17742
17743
    if (ret != 0)
17744
        return ret;
17745
17746
    /* return recovered A */
17747
    XMEMCPY(aOut, tmp, KEYWRAP_BLOCK_SIZE);
17748
17749
    return 0;
17750
}
17751
17752
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
17753
        word32 outSz, const byte* iv)
17754
{
17755
    int ret;
17756
    byte a[KEYWRAP_BLOCK_SIZE];
17757
17758
    const byte* expIv;
17759
    const byte defaultIV[] = {
17760
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
17761
    };
17762
17763
    /* (n+1) >= 3 blocks on a 64-bit boundary, n blocks fit outSz; inSz capped
17764
     * at INT_MAX so the returned inSz-8 stays a non-negative int. */
17765
    if (aes == NULL || in == NULL || out == NULL ||
17766
        inSz < 3 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0 ||
17767
        inSz > 0x7FFFFFFFU || outSz < inSz - KEYWRAP_BLOCK_SIZE)
17768
        return BAD_FUNC_ARG;
17769
17770
#ifdef WOLF_CRYPTO_CB
17771
    #ifndef WOLF_CRYPTO_CB_FIND
17772
    if (aes->devId != INVALID_DEVID)
17773
    #endif
17774
    {
17775
        ret = wc_CryptoCb_AesKeyUnWrap(aes, in, inSz, out, outSz, iv, 0);
17776
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
17777
            return ret;
17778
        }
17779
        /* fall through to software when unavailable */
17780
    }
17781
#endif
17782
17783
    /* user IV optional */
17784
    if (iv != NULL) {
17785
        expIv = iv;
17786
    }
17787
    else {
17788
        expIv = defaultIV;
17789
    }
17790
17791
    ret = AesKeyUnWrapRaw(aes, in, inSz, out, a);
17792
    if (ret != 0) {
17793
        return ret;
17794
    }
17795
17796
    /* verify IV */
17797
    if (ConstantCompare(a, expIv, KEYWRAP_BLOCK_SIZE) != 0) {
17798
        /* IV check failed: wipe the recovered plaintext key material left in
17799
         * out before returning so it is not leaked to the caller */
17800
        ForceZero(out, inSz - KEYWRAP_BLOCK_SIZE);
17801
        return BAD_KEYWRAP_IV_E;
17802
    }
17803
17804
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
17805
}
17806
17807
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
17808
                    byte* out, word32 outSz, const byte* iv)
17809
{
17810
    WC_DECLARE_VAR(aes, Aes, 1, 0);
17811
    int ret;
17812
17813
    (void)iv;
17814
17815
    if (key == NULL)
17816
        return BAD_FUNC_ARG;
17817
17818
#ifdef WOLFSSL_SMALL_STACK
17819
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
17820
                              DYNAMIC_TYPE_AES)) == NULL)
17821
        return MEMORY_E;
17822
#endif
17823
17824
17825
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17826
    if (ret != 0)
17827
        goto out;
17828
17829
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
17830
    if (ret != 0) {
17831
        wc_AesFree(aes);
17832
        goto out;
17833
    }
17834
17835
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
17836
17837
    wc_AesFree(aes);
17838
17839
  out:
17840
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
17841
17842
    return ret;
17843
}
17844
17845
#ifdef WOLFSSL_AES_KEYWRAP_PADDING
17846
17847
/* RFC 5649 AIV high-half constant; the low half carries the 32-bit MLI. */
17848
static const byte kwpAivConst[] = { 0xA6, 0x59, 0x59, 0xA6 };
17849
17850
/* Build the RFC 5649 AIV: 4-byte constant (iv override or default) | 4-byte
17851
 * big-endian MLI m. */
17852
static void BuildKwpAiv(byte* aiv, const byte* iv, word32 m)
17853
{
17854
    if (iv == NULL) {
17855
        XMEMCPY(aiv, kwpAivConst, sizeof(kwpAivConst));
17856
    }
17857
    else {
17858
        XMEMCPY(aiv, iv, sizeof(kwpAivConst));
17859
    }
17860
17861
    aiv[4] = (byte)(m >> 24);
17862
    aiv[5] = (byte)(m >> 16);
17863
    aiv[6] = (byte)(m >>  8);
17864
    aiv[7] = (byte)(m);
17865
}
17866
17867
int wc_AesKeyWrap_Pad_ex(Aes* aes, const byte* in, word32 inSz, byte* out,
17868
        word32 outSz, const byte* iv)
17869
{
17870
    int ret;
17871
    word32 n;
17872
    word32 padSz;
17873
    byte aiv[KEYWRAP_BLOCK_SIZE];
17874
17875
    /* inSz capped at INT_MAX-(2*8-1) so rounding up to whole blocks plus the
17876
     * AIV block can't overflow padSz+8; too-small output -> BAD_FUNC_ARG. */
17877
    if (aes == NULL || in == NULL || inSz == 0 || out == NULL ||
17878
        inSz > 0x7FFFFFFFU - (2 * KEYWRAP_BLOCK_SIZE - 1))
17879
        return BAD_FUNC_ARG;
17880
17881
    /* n = ceil(m/8) padded blocks; output is (n+1) blocks */
17882
    n = (inSz + KEYWRAP_BLOCK_SIZE - 1) / KEYWRAP_BLOCK_SIZE;
17883
    padSz = n * KEYWRAP_BLOCK_SIZE;
17884
    if (outSz < padSz + KEYWRAP_BLOCK_SIZE)
17885
        return BAD_FUNC_ARG;
17886
17887
#ifdef WOLF_CRYPTO_CB
17888
    #ifndef WOLF_CRYPTO_CB_FIND
17889
    if (aes->devId != INVALID_DEVID)
17890
    #endif
17891
    {
17892
        ret = wc_CryptoCb_AesKeyWrap(aes, in, inSz, out, outSz, iv, 1);
17893
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
17894
            return ret;
17895
        }
17896
        /* fall through to software when unavailable */
17897
    }
17898
#endif
17899
17900
    /* AIV = const | MLI(inSz) */
17901
    BuildKwpAiv(aiv, iv, inSz);
17902
17903
    /* stage plaintext at out+8 (XMEMMOVE for in-place), zeroing the pad octets */
17904
    XMEMMOVE(out + KEYWRAP_BLOCK_SIZE, in, inSz);
17905
    if (padSz > inSz) {
17906
        XMEMSET(out + KEYWRAP_BLOCK_SIZE + inSz, 0, padSz - inSz);
17907
    }
17908
17909
    if (n == 1) {
17910
        /* single block: C[0]|C[1] = ENC(K, AIV | P[1]) */
17911
        byte tmp[WC_AES_BLOCK_SIZE];
17912
        XMEMCPY(tmp, aiv, KEYWRAP_BLOCK_SIZE);
17913
        XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, out + KEYWRAP_BLOCK_SIZE,
17914
                KEYWRAP_BLOCK_SIZE);
17915
#ifdef HAVE_AES_ECB
17916
        /* Route through wc_AesEcbEncrypt so an ECB crypto callback can service
17917
         * the block; it saves its own registers. */
17918
        ret = wc_AesEcbEncrypt(aes, out, tmp, WC_AES_BLOCK_SIZE);
17919
#else
17920
        VECTOR_REGISTERS_PUSH;
17921
        ret = wc_AesEncryptDirect(aes, out, tmp);
17922
        VECTOR_REGISTERS_POP;
17923
#endif
17924
        /* tmp held AIV | plaintext key material */
17925
        ForceZero(tmp, sizeof(tmp));
17926
    }
17927
    else {
17928
        /* run the RFC 3394 loop with the AIV as the initial value */
17929
        ret = AesKeyWrapRaw(aes, padSz, out, aiv);
17930
    }
17931
    if (ret != 0) {
17932
        /* wipe the plaintext staged at out+8 (and any partial cipher state)
17933
         * so it is not leaked to the caller on failure */
17934
        ForceZero(out + KEYWRAP_BLOCK_SIZE, padSz);
17935
        return ret;
17936
    }
17937
17938
    return (int)(padSz + KEYWRAP_BLOCK_SIZE);
17939
}
17940
17941
int wc_AesKeyWrap_Pad(const byte* key, word32 keySz, const byte* in,
17942
        word32 inSz, byte* out, word32 outSz, const byte* iv)
17943
{
17944
    WC_DECLARE_VAR(aes, Aes, 1, NULL);
17945
    int ret;
17946
17947
    if (key == NULL) {
17948
        return BAD_FUNC_ARG;
17949
    }
17950
17951
    WC_ALLOC_VAR_EX(aes, Aes, 1, NULL, DYNAMIC_TYPE_AES, return MEMORY_E);
17952
17953
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17954
    if (ret != 0) {
17955
        goto out;
17956
    }
17957
17958
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
17959
    if (ret != 0) {
17960
        wc_AesFree(aes);
17961
        goto out;
17962
    }
17963
17964
    ret = wc_AesKeyWrap_Pad_ex(aes, in, inSz, out, outSz, iv);
17965
17966
    wc_AesFree(aes);
17967
17968
  out:
17969
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
17970
17971
    return ret;
17972
}
17973
17974
int wc_AesKeyUnWrap_Pad_ex(Aes* aes, const byte* in, word32 inSz, byte* out,
17975
        word32 outSz, const byte* iv)
17976
{
17977
    int ret;
17978
    word32 n;
17979
    word32 mli;
17980
    byte a[KEYWRAP_BLOCK_SIZE];
17981
    byte expConst[sizeof(kwpAivConst)];
17982
17983
    /* (n+1) >= 2 blocks on a 64-bit boundary; inSz capped at INT_MAX so the
17984
     * returned MLI stays a non-negative int; too-small output -> BAD_FUNC_ARG. */
17985
    if (aes == NULL || in == NULL || out == NULL ||
17986
        inSz < 2 * KEYWRAP_BLOCK_SIZE || (inSz % KEYWRAP_BLOCK_SIZE) != 0 ||
17987
        inSz > 0x7FFFFFFFU || outSz < inSz - KEYWRAP_BLOCK_SIZE)
17988
        return BAD_FUNC_ARG;
17989
17990
#ifdef WOLF_CRYPTO_CB
17991
    #ifndef WOLF_CRYPTO_CB_FIND
17992
    if (aes->devId != INVALID_DEVID)
17993
    #endif
17994
    {
17995
        ret = wc_CryptoCb_AesKeyUnWrap(aes, in, inSz, out, outSz, iv, 1);
17996
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
17997
            return ret;
17998
        }
17999
        /* fall through to software when unavailable */
18000
    }
18001
#endif
18002
18003
    /* number of padded 64-bit plaintext blocks */
18004
    n = (inSz / KEYWRAP_BLOCK_SIZE) - 1;
18005
18006
    if (n == 1) {
18007
        /* single block: AIV|P[1] = DEC(K, C[0]|C[1]) */
18008
        byte tmp[WC_AES_BLOCK_SIZE];
18009
#ifdef HAVE_AES_ECB
18010
        /* Route through wc_AesEcbDecrypt so an ECB crypto callback can service
18011
         * the block; it saves its own registers. */
18012
        ret = wc_AesEcbDecrypt(aes, tmp, in, WC_AES_BLOCK_SIZE);
18013
#else
18014
        VECTOR_REGISTERS_PUSH;
18015
        ret = wc_AesDecryptDirect(aes, tmp, in);
18016
        VECTOR_REGISTERS_POP;
18017
#endif
18018
        if (ret == 0) {
18019
            XMEMCPY(a, tmp, KEYWRAP_BLOCK_SIZE);
18020
            XMEMCPY(out, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
18021
        }
18022
        /* tmp held AIV | plaintext key material */
18023
        ForceZero(tmp, sizeof(tmp));
18024
    }
18025
    else {
18026
        /* recover A and padded plaintext via the RFC 3394 loop (no check) */
18027
        ret = AesKeyUnWrapRaw(aes, in, inSz, out, a);
18028
    }
18029
    if (ret != 0) {
18030
        return ret;
18031
    }
18032
18033
    /* expected high-half constant (iv override or default) */
18034
    if (iv == NULL) {
18035
        XMEMCPY(expConst, kwpAivConst, sizeof(kwpAivConst));
18036
    }
18037
    else {
18038
        XMEMCPY(expConst, iv, sizeof(kwpAivConst));
18039
    }
18040
18041
    /* MLI = LSB(32,A) in network order */
18042
    mli = ((word32)a[4] << 24) | ((word32)a[5] << 16) |
18043
          ((word32)a[6] <<  8) |  (word32)a[7];
18044
18045
    /* Validate the three RFC 5649 checks in constant time: fold failures into
18046
     * one mask and branch once, so timing does not reveal which check failed. */
18047
    {
18048
        word32 dataSz  = inSz - KEYWRAP_BLOCK_SIZE;   /* 8*n plaintext octets */
18049
        word32 lastBlk = dataSz - KEYWRAP_BLOCK_SIZE; /* offset 8*(n-1)       */
18050
        word32 fail;
18051
        word32 j;
18052
#ifndef WORD64_AVAILABLE
18053
        byte   lowMask = (byte)~(byte)(0u - ((mli >> 31) & 1u));
18054
        int    mliInt  = (int)(mli & 0x7FFFFFFFu);
18055
#endif
18056
18057
        /* check 1: MSB(32,A) == constant */
18058
        fail = (word32)ctMaskNotEq(ConstantCompare(a, expConst,
18059
                                           (int)sizeof(kwpAivConst)), 0);
18060
18061
#ifdef WORD64_AVAILABLE
18062
        /* check 2: 8*(n-1) < MLI <= 8*n */
18063
        fail |= ~(ctMaskWord32GTE(mli, lastBlk + 1)    /* MLI >= 8*(n-1)+1 */
18064
                & ctMaskWord32GTE(dataSz, mli));       /* 8*n >= MLI       */
18065
18066
        /* check 3: octets in [MLI, 8*n) are zero.  A valid MLI is in the final
18067
         * block, so scan it at fixed offsets, requiring zero where off >= MLI. */
18068
        for (j = 0; j < KEYWRAP_BLOCK_SIZE; j++) {
18069
            word32 off = lastBlk + j;
18070
            fail |= ctMaskWord32GTE(off, mli)          /* off >= MLI */
18071
                    & (word32)ctMaskNotEq((int)out[off], 0);
18072
        }
18073
#else
18074
        /* No word64: compare in int range.  MLI with its high bit set (>= 2^31
18075
         * > 8*n) is forced to fail so the int compares see valid values. */
18076
18077
        /* check 2: 8*(n-1) < MLI <= 8*n */
18078
        fail |= (word32)(byte)~(byte)(ctMaskGT(mliInt, (int)lastBlk)
18079
                                    & ctMaskLTE(mliInt, (int)dataSz)
18080
                                    & lowMask);
18081
18082
        /* check 3: octets in [MLI, 8*n) are zero (see note above). */
18083
        for (j = 0; j < KEYWRAP_BLOCK_SIZE; j++) {
18084
            int  off   = (int)(lastBlk + j);
18085
            byte isPad = (byte)(ctMaskGTE(off, mliInt) & lowMask);
18086
            fail |= (word32)(byte)(isPad &
18087
                                   ctMaskNotEq((int)out[lastBlk + j], 0));
18088
        }
18089
#endif
18090
18091
        if (fail != 0) {
18092
            goto badIv;
18093
        }
18094
    }
18095
18096
    return (int)mli;
18097
18098
badIv:
18099
    /* integrity check failed: wipe the recovered plaintext in out so it is
18100
     * not leaked to the caller */
18101
    ForceZero(out, inSz - KEYWRAP_BLOCK_SIZE);
18102
    return BAD_KEYWRAP_IV_E;
18103
}
18104
18105
int wc_AesKeyUnWrap_Pad(const byte* key, word32 keySz, const byte* in,
18106
        word32 inSz, byte* out, word32 outSz, const byte* iv)
18107
{
18108
    WC_DECLARE_VAR(aes, Aes, 1, NULL);
18109
    int ret;
18110
18111
    if (key == NULL) {
18112
        return BAD_FUNC_ARG;
18113
    }
18114
18115
    WC_ALLOC_VAR_EX(aes, Aes, 1, NULL, DYNAMIC_TYPE_AES, return MEMORY_E);
18116
18117
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
18118
    if (ret != 0) {
18119
        goto out;
18120
    }
18121
18122
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
18123
    if (ret != 0) {
18124
        wc_AesFree(aes);
18125
        goto out;
18126
    }
18127
18128
    ret = wc_AesKeyUnWrap_Pad_ex(aes, in, inSz, out, outSz, iv);
18129
18130
    wc_AesFree(aes);
18131
18132
  out:
18133
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
18134
18135
    return ret;
18136
}
18137
18138
#endif /* WOLFSSL_AES_KEYWRAP_PADDING */
18139
18140
#endif /* HAVE_AES_KEYWRAP */
18141
18142
#ifdef WOLFSSL_AES_XTS
18143
18144
/* Galois Field to use */
18145
#define GF_XTS 0x87
18146
18147
/* Set up keys for encryption and/or decryption.
18148
 *
18149
 * aes   buffer holding aes subkeys
18150
 * heap  heap hint to use for memory. Can be NULL
18151
 * devId id to use with async crypto. Can be 0
18152
 *
18153
 * return 0 on success
18154
 */
18155
int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
18156
{
18157
    int    ret = 0;
18158
18159
    if (aes == NULL) {
18160
        return BAD_FUNC_ARG;
18161
    }
18162
18163
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
18164
        return ret;
18165
    }
18166
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
18167
        (void)wc_AesFree(&aes->tweak);
18168
        return ret;
18169
    }
18170
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18171
    if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) {
18172
        (void)wc_AesFree(&aes->tweak);
18173
        (void)wc_AesFree(&aes->aes);
18174
        return ret;
18175
    }
18176
#endif
18177
18178
    return 0;
18179
}
18180
18181
/* Set up keys for encryption and/or decryption.
18182
 *
18183
 * aes   buffer holding aes subkeys
18184
 * key   AES key for encrypt/decrypt and tweak process (concatenated)
18185
 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
18186
 *       32 for a 16 byte key.
18187
 * dir   direction: AES_ENCRYPTION, AES_DECRYPTION, or
18188
 *       AES_ENCRYPTION_AND_DECRYPTION
18189
 *
18190
 * return 0 on success
18191
 */
18192
int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
18193
{
18194
    word32 keySz;
18195
    int    ret = 0;
18196
18197
    if (aes == NULL || key == NULL) {
18198
        return BAD_FUNC_ARG;
18199
    }
18200
18201
    if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION)
18202
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18203
        && (dir != AES_ENCRYPTION_AND_DECRYPTION)
18204
#endif
18205
        )
18206
    {
18207
        return BAD_FUNC_ARG;
18208
    }
18209
18210
    if ((len != (AES_128_KEY_SIZE*2)) &&
18211
#ifndef HAVE_FIPS
18212
        /* XTS-384 not allowed by FIPS and can not be treated like
18213
         * RSA-4096 bit keys back in the day, can not vendor affirm
18214
         * the use of 2 concatenated 192-bit keys (XTS-384) */
18215
        (len != (AES_192_KEY_SIZE*2)) &&
18216
#endif
18217
        (len != (AES_256_KEY_SIZE*2)))
18218
    {
18219
        WOLFSSL_MSG("Unsupported key size");
18220
        return WC_KEY_SIZE_E;
18221
    }
18222
18223
    keySz = len/2;
18224
18225
#if defined(HAVE_FIPS) || !defined(WC_AES_XTS_ALLOW_DUPLICATE_KEYS)
18226
    if (XMEMCMP(key, key + keySz, keySz) == 0) {
18227
        WOLFSSL_MSG("AES-XTS main and tweak keys must differ");
18228
        return BAD_FUNC_ARG;
18229
    }
18230
#endif
18231
18232
    if (dir == AES_ENCRYPTION
18233
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18234
        || dir == AES_ENCRYPTION_AND_DECRYPTION
18235
#endif
18236
        )
18237
    {
18238
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
18239
    }
18240
18241
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18242
    if ((ret == 0) && ((dir == AES_DECRYPTION)
18243
                       || (dir == AES_ENCRYPTION_AND_DECRYPTION)))
18244
        ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION);
18245
#else
18246
    if (dir == AES_DECRYPTION)
18247
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
18248
#endif
18249
18250
    if (ret == 0)
18251
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
18252
                AES_ENCRYPTION);
18253
18254
#ifdef WOLFSSL_AESNI
18255
    if (ret == 0) {
18256
        /* With WC_C_DYNAMIC_FALLBACK, the main and tweak keys could have
18257
         * conflicting _aesni status, but the AES-XTS asm implementations need
18258
         * them to all be AESNI.  If any aren't, disable AESNI on all.
18259
         */
18260
    #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18261
        if ((((dir == AES_ENCRYPTION) ||
18262
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
18263
             && (aes->aes.use_aesni != aes->tweak.use_aesni))
18264
            ||
18265
            (((dir == AES_DECRYPTION) ||
18266
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
18267
             && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)))
18268
        {
18269
        #ifdef WC_C_DYNAMIC_FALLBACK
18270
            aes->aes.use_aesni = 0;
18271
            aes->aes_decrypt.use_aesni = 0;
18272
            aes->tweak.use_aesni = 0;
18273
        #else
18274
            ret = SYSLIB_FAILED_E;
18275
        #endif
18276
        }
18277
    #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
18278
        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
18279
        #ifdef WC_C_DYNAMIC_FALLBACK
18280
            aes->aes.use_aesni = 0;
18281
            aes->tweak.use_aesni = 0;
18282
        #else
18283
            ret = SYSLIB_FAILED_E;
18284
        #endif
18285
        }
18286
    #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
18287
    }
18288
#endif /* WOLFSSL_AESNI */
18289
18290
    return ret;
18291
}
18292
18293
/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
18294
 *
18295
 * Note: is up to user to call wc_AesXtsFree when done.
18296
 *
18297
 * return 0 on success
18298
 */
18299
int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
18300
        void* heap, int devId)
18301
{
18302
    int    ret = 0;
18303
18304
    if (aes == NULL || key == NULL) {
18305
        return BAD_FUNC_ARG;
18306
    }
18307
18308
    ret = wc_AesXtsInit(aes, heap, devId);
18309
    if (ret != 0)
18310
        return ret;
18311
18312
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
18313
18314
    if (ret != 0)
18315
        wc_AesXtsFree(aes);
18316
18317
    return ret;
18318
}
18319
18320
18321
/* This is used to free up resources used by Aes structs
18322
 *
18323
 * aes AES keys to free
18324
 *
18325
 * return 0 on success
18326
 */
18327
int wc_AesXtsFree(XtsAes* aes)
18328
{
18329
    if (aes != NULL) {
18330
        wc_AesFree(&aes->aes);
18331
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
18332
        wc_AesFree(&aes->aes_decrypt);
18333
#endif
18334
        wc_AesFree(&aes->tweak);
18335
    }
18336
18337
    return 0;
18338
}
18339
18340
18341
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
18342
 * instead of a byte array. This just converts the word64 to a byte array and
18343
 * calls wc_AesXtsEncrypt.
18344
 *
18345
 * aes    AES keys to use for block encrypt/decrypt
18346
 * out    output buffer to hold cipher text
18347
 * in     input plain text buffer to encrypt
18348
 * sz     size of both out and in buffers
18349
 * sector value to use for tweak
18350
 *
18351
 * returns 0 on success
18352
 */
18353
int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
18354
        word32 sz, word64 sector)
18355
{
18356
    byte* pt;
18357
    byte  i[WC_AES_BLOCK_SIZE];
18358
18359
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
18360
#ifdef BIG_ENDIAN_ORDER
18361
    sector = ByteReverseWord64(sector);
18362
#endif
18363
    pt = (byte*)&sector;
18364
    XMEMCPY(i, pt, sizeof(word64));
18365
18366
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
18367
}
18368
18369
#ifdef HAVE_AES_DECRYPT
18370
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
18371
 * instead of a byte array. This just converts the word64 to a byte array.
18372
 *
18373
 * aes    AES keys to use for block encrypt/decrypt
18374
 * out    output buffer to hold plain text
18375
 * in     input cipher text buffer to encrypt
18376
 * sz     size of both out and in buffers
18377
 * sector value to use for tweak
18378
 *
18379
 * returns 0 on success
18380
 */
18381
int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
18382
        word64 sector)
18383
{
18384
    byte* pt;
18385
    byte  i[WC_AES_BLOCK_SIZE];
18386
18387
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
18388
#ifdef BIG_ENDIAN_ORDER
18389
    sector = ByteReverseWord64(sector);
18390
#endif
18391
    pt = (byte*)&sector;
18392
    XMEMCPY(i, pt, sizeof(word64));
18393
18394
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
18395
}
18396
#endif
18397
18398
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18399
18400
#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
18401
    #define USE_INTEL_SPEEDUP
18402
#endif
18403
18404
#if defined(USE_INTEL_SPEEDUP)
18405
    #define HAVE_INTEL_AVX1
18406
    #define HAVE_INTEL_AVX2
18407
#endif /* USE_INTEL_SPEEDUP */
18408
18409
void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
18410
                     const unsigned char* i, const unsigned char* key,
18411
                     const unsigned char* key2, int nr)
18412
                     XASM_LINK("AES_XTS_encrypt_aesni");
18413
#ifdef WOLFSSL_AESXTS_STREAM
18414
void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
18415
                     int tweak_nr)
18416
                     XASM_LINK("AES_XTS_init_aesni");
18417
void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
18418
                     const unsigned char* key, unsigned char *i, int nr)
18419
                     XASM_LINK("AES_XTS_encrypt_update_aesni");
18420
#endif
18421
#ifdef HAVE_INTEL_AVX1
18422
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
18423
                     word32 sz, const unsigned char* i,
18424
                     const unsigned char* key, const unsigned char* key2,
18425
                     int nr)
18426
                     XASM_LINK("AES_XTS_encrypt_avx1");
18427
#ifdef WOLFSSL_AESXTS_STREAM
18428
void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
18429
                     int tweak_nr)
18430
                     XASM_LINK("AES_XTS_init_avx1");
18431
void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
18432
                     const unsigned char* key, unsigned char *i, int nr)
18433
                     XASM_LINK("AES_XTS_encrypt_update_avx1");
18434
#endif
18435
#endif /* HAVE_INTEL_AVX1 */
18436
#ifdef HAVE_INTEL_VAES
18437
void AES_XTS_encrypt_vaes(const unsigned char *in, unsigned char *out,
18438
                     word32 sz, const unsigned char* i,
18439
                     const unsigned char* key, const unsigned char* key2,
18440
                     int nr)
18441
                     XASM_LINK("AES_XTS_encrypt_vaes");
18442
#ifdef WOLFSSL_AESXTS_STREAM
18443
void AES_XTS_init_vaes(unsigned char* i, const unsigned char* tweak_key,
18444
                     int tweak_nr)
18445
                     XASM_LINK("AES_XTS_init_vaes");
18446
void AES_XTS_encrypt_update_vaes(const unsigned char *in, unsigned char *out, word32 sz,
18447
                     const unsigned char* key, unsigned char *i, int nr)
18448
                     XASM_LINK("AES_XTS_encrypt_update_vaes");
18449
#endif
18450
#endif /* HAVE_INTEL_VAES */
18451
#ifdef HAVE_INTEL_AVX512
18452
void AES_XTS_encrypt_avx512(const unsigned char *in, unsigned char *out,
18453
                     word32 sz, const unsigned char* i,
18454
                     const unsigned char* key, const unsigned char* key2,
18455
                     int nr)
18456
                     XASM_LINK("AES_XTS_encrypt_avx512");
18457
#ifdef WOLFSSL_AESXTS_STREAM
18458
void AES_XTS_init_avx512(unsigned char* i, const unsigned char* tweak_key,
18459
                     int tweak_nr)
18460
                     XASM_LINK("AES_XTS_init_avx512");
18461
void AES_XTS_encrypt_update_avx512(const unsigned char *in, unsigned char *out, word32 sz,
18462
                     const unsigned char* key, unsigned char *i, int nr)
18463
                     XASM_LINK("AES_XTS_encrypt_update_avx512");
18464
#endif
18465
#endif /* HAVE_INTEL_AVX512 */
18466
18467
18468
#ifdef HAVE_AES_DECRYPT
18469
void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
18470
                     const unsigned char* i, const unsigned char* key,
18471
                     const unsigned char* key2, int nr)
18472
                     XASM_LINK("AES_XTS_decrypt_aesni");
18473
#ifdef WOLFSSL_AESXTS_STREAM
18474
void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
18475
                     const unsigned char* key, unsigned char *i, int nr)
18476
                     XASM_LINK("AES_XTS_decrypt_update_aesni");
18477
#endif
18478
#ifdef HAVE_INTEL_AVX1
18479
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
18480
                     word32 sz, const unsigned char* i,
18481
                     const unsigned char* key, const unsigned char* key2,
18482
                     int nr)
18483
                     XASM_LINK("AES_XTS_decrypt_avx1");
18484
#ifdef WOLFSSL_AESXTS_STREAM
18485
void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
18486
                     const unsigned char* key, unsigned char *i, int nr)
18487
                     XASM_LINK("AES_XTS_decrypt_update_avx1");
18488
#endif
18489
#endif /* HAVE_INTEL_AVX1 */
18490
#ifdef HAVE_INTEL_VAES
18491
void AES_XTS_decrypt_vaes(const unsigned char *in, unsigned char *out,
18492
                     word32 sz, const unsigned char* i,
18493
                     const unsigned char* key, const unsigned char* key2,
18494
                     int nr)
18495
                     XASM_LINK("AES_XTS_decrypt_vaes");
18496
#ifdef WOLFSSL_AESXTS_STREAM
18497
void AES_XTS_decrypt_update_vaes(const unsigned char *in, unsigned char *out, word32 sz,
18498
                     const unsigned char* key, unsigned char *i, int nr)
18499
                     XASM_LINK("AES_XTS_decrypt_update_vaes");
18500
#endif
18501
#endif /* HAVE_INTEL_VAES */
18502
#ifdef HAVE_INTEL_AVX512
18503
void AES_XTS_decrypt_avx512(const unsigned char *in, unsigned char *out,
18504
                     word32 sz, const unsigned char* i,
18505
                     const unsigned char* key, const unsigned char* key2,
18506
                     int nr)
18507
                     XASM_LINK("AES_XTS_decrypt_avx512");
18508
#ifdef WOLFSSL_AESXTS_STREAM
18509
void AES_XTS_decrypt_update_avx512(const unsigned char *in, unsigned char *out, word32 sz,
18510
                     const unsigned char* key, unsigned char *i, int nr)
18511
                     XASM_LINK("AES_XTS_decrypt_update_avx512");
18512
#endif
18513
#endif /* HAVE_INTEL_AVX512 */
18514
#endif /* HAVE_AES_DECRYPT */
18515
18516
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
18517
18518
#ifdef HAVE_AES_ECB
18519
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
18520
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
18521
    defined(WOLFSSL_ARM32_AES_DISPATCH)) || defined(WOLFSSL_AESXTS_STREAM)
18522
/* helper function for encrypting / decrypting full buffer at once */
18523
static WARN_UNUSED_RESULT int _AesXtsHelper(
18524
    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
18525
{
18526
    word32 outSz   = sz;
18527
    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
18528
    byte*  pt      = out;
18529
18530
    outSz -= WC_AES_BLOCK_SIZE;
18531
18532
    while (outSz > 0) {
18533
        word32 j;
18534
        byte carry = 0;
18535
18536
        /* multiply by shift left and propagate carry */
18537
        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
18538
            byte tmpC;
18539
18540
            tmpC   = (pt[j] >> 7) & 0x01;
18541
            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
18542
            carry  = tmpC;
18543
        }
18544
        if (carry) {
18545
            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
18546
        }
18547
18548
        pt += WC_AES_BLOCK_SIZE;
18549
    }
18550
18551
    xorbuf(out, in, totalSz);
18552
#ifndef WOLFSSL_RISCV_ASM
18553
    if (dir == AES_ENCRYPTION) {
18554
        return _AesEcbEncrypt(aes, out, out, totalSz);
18555
    }
18556
    else {
18557
        return _AesEcbDecrypt(aes, out, out, totalSz);
18558
    }
18559
#else
18560
    if (dir == AES_ENCRYPTION) {
18561
        return wc_AesEcbEncrypt(aes, out, out, totalSz);
18562
    }
18563
    else {
18564
        return wc_AesEcbDecrypt(aes, out, out, totalSz);
18565
    }
18566
#endif
18567
}
18568
#endif
18569
#endif /* HAVE_AES_ECB */
18570
18571
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
18572
 *
18573
 * xaes  AES keys to use for block encrypt/decrypt
18574
 * out   output buffer to hold cipher text
18575
 * in    input plain text buffer to encrypt
18576
 * sz    size of both out and in buffers
18577
 * i     value to use for tweak
18578
 *
18579
 * returns 0 on success
18580
 */
18581
/* Software AES - XTS Encrypt  */
18582
18583
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
18584
     defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
18585
     defined(WOLFSSL_ARM32_AES_DISPATCH)) && !defined(WOLFSSL_PPC64_ASM)
18586
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
18587
                                  word32 sz,
18588
                                  byte *i);
18589
#if !defined(WOLFSSL_RISCV_ASM)
18590
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
18591
        const byte* i)
18592
{
18593
    int ret;
18594
    byte tweak_block[WC_AES_BLOCK_SIZE];
18595
18596
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
18597
    if (ret != 0)
18598
        return ret;
18599
18600
    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
18601
}
18602
#endif /* !WOLFSSL_RISCV_ASM */
18603
#endif
18604
18605
#ifdef WOLFSSL_AESXTS_STREAM
18606
18607
/* Block-streaming AES-XTS tweak setup.
18608
 *
18609
 * xaes  AES keys to use for block encrypt/decrypt
18610
 * i     readwrite value to use for tweak
18611
 *
18612
 * returns 0 on success
18613
 */
18614
static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
18615
    return wc_AesEncryptDirect(&xaes->tweak, i, i);
18616
}
18617
18618
#endif /* WOLFSSL_AESXTS_STREAM */
18619
18620
#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
18621
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
18622
    defined(WOLFSSL_ARM32_AES_DISPATCH) || defined(WOLFSSL_AESXTS_STREAM)
18623
/* Block-streaming AES-XTS.
18624
 *
18625
 * Supply block-aligned input data with successive calls.  Final call need not
18626
 * be block aligned.
18627
 *
18628
 * xaes  AES keys to use for block encrypt/decrypt
18629
 * out   output buffer to hold cipher text
18630
 * in    input plain text buffer to encrypt
18631
 * sz    size of both out and in buffers
18632
 *
18633
 * returns 0 on success
18634
 */
18635
/* Software AES - XTS Encrypt  */
18636
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
18637
                                  word32 sz,
18638
                                  byte *i)
18639
{
18640
    int ret = 0;
18641
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
18642
    Aes *aes = &xaes->aes;
18643
18644
#ifdef HAVE_AES_ECB
18645
    /* encrypt all of buffer at once when possible */
18646
    if (in != out) { /* can not handle inline */
18647
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
18648
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
18649
            return ret;
18650
    }
18651
#endif
18652
18653
    while (blocks > 0) {
18654
        word32 j;
18655
        byte carry = 0;
18656
18657
#ifdef HAVE_AES_ECB
18658
        if (in == out)
18659
#endif
18660
        { /* check for if inline */
18661
            byte buf[WC_AES_BLOCK_SIZE];
18662
18663
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
18664
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
18665
            ret = wc_AesEncryptDirect(aes, out, buf);
18666
            if (ret != 0)
18667
                return ret;
18668
        }
18669
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
18670
18671
        /* multiply by shift left and propagate carry */
18672
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
18673
            byte tmpC;
18674
18675
            tmpC   = (i[j] >> 7) & 0x01;
18676
            i[j] = (byte)(((i[j] << 1) + carry) & 0xFF);
18677
            carry  = tmpC;
18678
        }
18679
        if (carry) {
18680
            i[0] ^= GF_XTS;
18681
        }
18682
18683
        in  += WC_AES_BLOCK_SIZE;
18684
        out += WC_AES_BLOCK_SIZE;
18685
        sz  -= WC_AES_BLOCK_SIZE;
18686
        blocks--;
18687
    }
18688
18689
    /* stealing operation of XTS to handle left overs */
18690
    if (sz > 0) {
18691
        byte buf[WC_AES_BLOCK_SIZE];
18692
18693
        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
18694
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
18695
            return BUFFER_E;
18696
        }
18697
        if (in != out) {
18698
            XMEMCPY(out, buf, sz);
18699
            XMEMCPY(buf, in, sz);
18700
        }
18701
        else {
18702
            byte buf2[WC_AES_BLOCK_SIZE];
18703
18704
            XMEMCPY(buf2, buf, sz);
18705
            XMEMCPY(buf, in, sz);
18706
            XMEMCPY(out, buf2, sz);
18707
        }
18708
18709
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
18710
        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
18711
        if (ret == 0)
18712
            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
18713
    }
18714
18715
    return ret;
18716
}
18717
#endif
18718
18719
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
18720
 *
18721
 * xaes  AES keys to use for block encrypt/decrypt
18722
 * out   output buffer to hold cipher text
18723
 * in    input plain text buffer to encrypt
18724
 * sz    size of both out and in buffers
18725
 * i     value to use for tweak
18726
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
18727
 *       adds a sanity check on how the user calls the function.
18728
 *
18729
 * returns 0 on success
18730
 */
18731
int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
18732
        const byte* i, word32 iSz)
18733
{
18734
    int ret;
18735
18736
    Aes *aes;
18737
18738
    if (xaes == NULL || out == NULL || in == NULL) {
18739
        return BAD_FUNC_ARG;
18740
    }
18741
18742
#if FIPS_VERSION3_GE(6,0,0)
18743
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
18744
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
18745
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
18746
     */
18747
    if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
18748
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
18749
        return BAD_FUNC_ARG;
18750
    }
18751
#endif
18752
18753
    aes = &xaes->aes;
18754
18755
    /* rounds == 0 means no software key schedule: XTS has no crypto
18756
     * callback dispatch, so a device-owned key is unusable here. */
18757
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
18758
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
18759
        return BAD_FUNC_ARG;
18760
    }
18761
18762
    if (iSz < WC_AES_BLOCK_SIZE) {
18763
        return BAD_FUNC_ARG;
18764
    }
18765
18766
    if (sz < WC_AES_BLOCK_SIZE) {
18767
        WOLFSSL_MSG("Plain text input too small for encryption");
18768
        return BAD_FUNC_ARG;
18769
    }
18770
18771
#if defined(WOLFSSL_RISCV_ASM)
18772
    AES_XTS_encrypt_RISCV64(in, out, sz, i, (byte*)xaes->aes.key,
18773
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, (int)xaes->aes.rounds);
18774
    ret = 0;
18775
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
18776
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
18777
    /* The base 32-bit AES assembly has no XTS variant, so the run-time
18778
     * fallback is the software XTS (which dispatches per-block via
18779
     * wc_AesEncrypt). */
18780
#ifdef WOLFSSL_ARM32_AES_DISPATCH
18781
    if (xaes->aes.use_aes_hw_crypto) {
18782
        AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
18783
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18784
        ret = 0;
18785
    }
18786
    else {
18787
        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
18788
    }
18789
#else
18790
    AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
18791
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18792
    ret = 0;
18793
#endif
18794
#elif defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18795
    if (aes->use_aesni) {
18796
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
18797
#if defined(HAVE_INTEL_AVX512)
18798
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18799
            AES_XTS_encrypt_avx512(in, out, sz, i,
18800
                                   (const byte*)aes->key,
18801
                                   (const byte*)xaes->tweak.key,
18802
                                   (int)aes->rounds);
18803
            ret = 0;
18804
        }
18805
        else
18806
#endif
18807
#if defined(HAVE_INTEL_VAES)
18808
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18809
            AES_XTS_encrypt_vaes(in, out, sz, i,
18810
                                 (const byte*)aes->key,
18811
                                 (const byte*)xaes->tweak.key,
18812
                                 (int)aes->rounds);
18813
            ret = 0;
18814
        }
18815
        else
18816
#endif
18817
#if defined(HAVE_INTEL_AVX1)
18818
        if (IS_INTEL_AVX1(intel_flags)) {
18819
            AES_XTS_encrypt_avx1(in, out, sz, i,
18820
                                 (const byte*)aes->key,
18821
                                 (const byte*)xaes->tweak.key,
18822
                                 (int)aes->rounds);
18823
            ret = 0;
18824
        }
18825
        else
18826
#endif
18827
        {
18828
            AES_XTS_encrypt_aesni(in, out, sz, i,
18829
                                  (const byte*)aes->key,
18830
                                  (const byte*)xaes->tweak.key,
18831
                                  (int)aes->rounds);
18832
            ret = 0;
18833
        }
18834
        RESTORE_VECTOR_REGISTERS();
18835
    }
18836
    else {
18837
        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
18838
    }
18839
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
18840
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
18841
    if (aes->use_aes_hw_crypto) {
18842
        AES_XTS_encrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
18843
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18844
        ret = 0;
18845
    }
18846
    else
18847
#endif
18848
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
18849
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18850
    if (sz >= 32)
18851
#endif
18852
    {
18853
        AES_XTS_encrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
18854
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18855
        ret = 0;
18856
    }
18857
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18858
    else
18859
#endif
18860
#endif
18861
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
18862
    {
18863
        AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
18864
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18865
        ret = 0;
18866
    }
18867
#endif
18868
#elif defined(WOLFSSL_PPC64_ASM)
18869
    AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
18870
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
18871
    ret = 0;
18872
#else
18873
    ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
18874
#endif
18875
18876
    return ret;
18877
}
18878
18879
#ifdef WOLFSSL_AESXTS_STREAM
18880
18881
/* Block-streaming AES-XTS.
18882
 *
18883
 * xaes  AES keys to use for block encrypt/decrypt
18884
 * i     readwrite value to use for tweak
18885
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
18886
 *       adds a sanity check on how the user calls the function.
18887
 *
18888
 * returns 0 on success
18889
 */
18890
int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
18891
                         struct XtsAesStreamData *stream)
18892
{
18893
    int ret;
18894
18895
    Aes *aes;
18896
18897
    if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
18898
        return BAD_FUNC_ARG;
18899
    }
18900
18901
    if (iSz < WC_AES_BLOCK_SIZE) {
18902
        return BAD_FUNC_ARG;
18903
    }
18904
18905
    aes = &xaes->aes;
18906
18907
    /* rounds == 0 means no software key schedule: XTS has no crypto
18908
     * callback dispatch, so a device-owned key is unusable here. */
18909
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
18910
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
18911
        return BAD_FUNC_ARG;
18912
    }
18913
18914
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
18915
    stream->bytes_crypted_with_this_tweak = 0;
18916
18917
    {
18918
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18919
        if (aes->use_aesni) {
18920
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
18921
#if defined(HAVE_INTEL_AVX512)
18922
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18923
                AES_XTS_init_avx512(stream->tweak_block,
18924
                                    (const byte*)xaes->tweak.key,
18925
                                    (int)xaes->tweak.rounds);
18926
                ret = 0;
18927
            }
18928
            else
18929
#endif
18930
#if defined(HAVE_INTEL_VAES)
18931
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
18932
                AES_XTS_init_vaes(stream->tweak_block,
18933
                                  (const byte*)xaes->tweak.key,
18934
                                  (int)xaes->tweak.rounds);
18935
                ret = 0;
18936
            }
18937
            else
18938
#endif
18939
#if defined(HAVE_INTEL_AVX1)
18940
            if (IS_INTEL_AVX1(intel_flags)) {
18941
                AES_XTS_init_avx1(stream->tweak_block,
18942
                                  (const byte*)xaes->tweak.key,
18943
                                  (int)xaes->tweak.rounds);
18944
                ret = 0;
18945
            }
18946
            else
18947
#endif
18948
            {
18949
                AES_XTS_init_aesni(stream->tweak_block,
18950
                                   (const byte*)xaes->tweak.key,
18951
                                   (int)xaes->tweak.rounds);
18952
                ret = 0;
18953
            }
18954
            RESTORE_VECTOR_REGISTERS();
18955
        }
18956
        else
18957
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
18958
        {
18959
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
18960
        }
18961
    }
18962
18963
    return ret;
18964
}
18965
18966
/* Block-streaming AES-XTS
18967
 *
18968
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
18969
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsEncryptUpdate().
18970
 * wc_AesXtsEncryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
18971
 *
18972
 * xaes  AES keys to use for block encrypt/decrypt
18973
 * out   output buffer to hold cipher text
18974
 * in    input plain text buffer to encrypt
18975
 * sz    size of both out and in buffers -- must be >= WC_AES_BLOCK_SIZE.
18976
 * i     value to use for tweak
18977
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
18978
 *       adds a sanity check on how the user calls the function.
18979
 *
18980
 * returns 0 on success
18981
 */
18982
static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
18983
                           struct XtsAesStreamData *stream)
18984
{
18985
    int ret;
18986
18987
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18988
    Aes *aes;
18989
#endif
18990
18991
    if (xaes == NULL || out == NULL || in == NULL) {
18992
        return BAD_FUNC_ARG;
18993
    }
18994
18995
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
18996
    aes = &xaes->aes;
18997
#endif
18998
18999
    if (sz < WC_AES_BLOCK_SIZE) {
19000
        WOLFSSL_MSG("Plain text input too small for encryption");
19001
        return BAD_FUNC_ARG;
19002
    }
19003
19004
    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
19005
    {
19006
        WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
19007
        return BAD_FUNC_ARG;
19008
    }
19009
19010
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
19011
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
19012
                             stream->bytes_crypted_with_this_tweak))
19013
    {
19014
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
19015
                    "in AesXtsEncryptUpdate().");
19016
    }
19017
#endif
19018
#if FIPS_VERSION3_GE(6,0,0)
19019
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
19020
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
19021
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
19022
     */
19023
    if (stream->bytes_crypted_with_this_tweak >
19024
        FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
19025
    {
19026
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
19027
        return BAD_FUNC_ARG;
19028
    }
19029
#endif
19030
    {
19031
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
19032
        if (aes->use_aesni) {
19033
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
19034
#if defined(HAVE_INTEL_AVX512)
19035
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19036
                AES_XTS_encrypt_update_avx512(in, out, sz,
19037
                                              (const byte*)aes->key,
19038
                                              stream->tweak_block,
19039
                                              (int)aes->rounds);
19040
                ret = 0;
19041
            }
19042
            else
19043
#endif
19044
#if defined(HAVE_INTEL_VAES)
19045
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19046
                AES_XTS_encrypt_update_vaes(in, out, sz,
19047
                                            (const byte*)aes->key,
19048
                                            stream->tweak_block,
19049
                                            (int)aes->rounds);
19050
                ret = 0;
19051
            }
19052
            else
19053
#endif
19054
#if defined(HAVE_INTEL_AVX1)
19055
            if (IS_INTEL_AVX1(intel_flags)) {
19056
                AES_XTS_encrypt_update_avx1(in, out, sz,
19057
                                            (const byte*)aes->key,
19058
                                            stream->tweak_block,
19059
                                            (int)aes->rounds);
19060
                ret = 0;
19061
            }
19062
            else
19063
#endif
19064
            {
19065
                AES_XTS_encrypt_update_aesni(in, out, sz,
19066
                                            (const byte*)aes->key,
19067
                                            stream->tweak_block,
19068
                                            (int)aes->rounds);
19069
                ret = 0;
19070
            }
19071
            RESTORE_VECTOR_REGISTERS();
19072
        }
19073
        else
19074
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
19075
        {
19076
            ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
19077
        }
19078
    }
19079
19080
    return ret;
19081
}
19082
19083
int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19084
                           struct XtsAesStreamData *stream)
19085
{
19086
    if (stream == NULL)
19087
        return BAD_FUNC_ARG;
19088
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
19089
        return BAD_FUNC_ARG;
19090
    return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
19091
}
19092
19093
int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19094
                           struct XtsAesStreamData *stream)
19095
{
19096
    int ret;
19097
    if (stream == NULL)
19098
        return BAD_FUNC_ARG;
19099
    if (sz > 0)
19100
        ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
19101
    else
19102
        ret = 0;
19103
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
19104
     * after finalization.
19105
     */
19106
    stream->bytes_crypted_with_this_tweak |= 1U;
19107
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
19108
#ifdef WOLFSSL_CHECK_MEM_ZERO
19109
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
19110
#endif
19111
    return ret;
19112
}
19113
19114
#endif /* WOLFSSL_AESXTS_STREAM */
19115
19116
#ifdef HAVE_AES_DECRYPT
19117
19118
/* Same process as encryption but use aes_decrypt key.
19119
 *
19120
 * xaes  AES keys to use for block encrypt/decrypt
19121
 * out   output buffer to hold plain text
19122
 * in    input cipher text buffer to decrypt
19123
 * sz    size of both out and in buffers
19124
 * i     value to use for tweak
19125
 *
19126
 * returns 0 on success
19127
 */
19128
/* Software AES - XTS Decrypt */
19129
19130
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
19131
     defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
19132
     defined(WOLFSSL_ARM32_AES_DISPATCH)) && !defined(WOLFSSL_PPC64_ASM)
19133
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
19134
                                  word32 sz, byte *i);
19135
19136
#if !defined(WOLFSSL_RISCV_ASM)
19137
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19138
        const byte* i)
19139
{
19140
    int ret;
19141
    byte tweak_block[WC_AES_BLOCK_SIZE];
19142
19143
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
19144
    if (ret != 0)
19145
        return ret;
19146
19147
    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
19148
}
19149
#endif /* !WOLFSSL_RISCV_ASM */
19150
#endif
19151
19152
#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
19153
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \
19154
    defined(WOLFSSL_ARM32_AES_DISPATCH)) || defined(WOLFSSL_AESXTS_STREAM)
19155
/* Block-streaming AES-XTS.
19156
 *
19157
 * Same process as encryption but use decrypt key.
19158
 *
19159
 * Supply block-aligned input data with successive calls.  Final call need not
19160
 * be block aligned.
19161
 *
19162
 * xaes  AES keys to use for block encrypt/decrypt
19163
 * out   output buffer to hold plain text
19164
 * in    input cipher text buffer to decrypt
19165
 * sz    size of both out and in buffers
19166
 * i     value to use for tweak
19167
 *
19168
 * returns 0 on success
19169
 */
19170
/* Software AES - XTS Decrypt */
19171
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
19172
                                  word32 sz, byte *i)
19173
{
19174
    int ret = 0;
19175
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
19176
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
19177
    Aes *aes = &xaes->aes_decrypt;
19178
#else
19179
    Aes *aes = &xaes->aes;
19180
#endif
19181
    word32 j;
19182
    byte carry = 0;
19183
    byte stl = (sz % WC_AES_BLOCK_SIZE);
19184
19185
    /* if Stealing then break out of loop one block early to handle special
19186
     * case */
19187
    if (stl > 0) {
19188
        blocks--;
19189
    }
19190
19191
#ifdef HAVE_AES_ECB
19192
    /* decrypt all of buffer at once when possible */
19193
    if (in != out) { /* can not handle inline */
19194
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
19195
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
19196
            return ret;
19197
    }
19198
#endif
19199
19200
    while (blocks > 0) {
19201
#ifdef HAVE_AES_ECB
19202
        if (in == out)
19203
#endif
19204
        { /* check for if inline */
19205
            byte buf[WC_AES_BLOCK_SIZE];
19206
19207
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
19208
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
19209
            ret = wc_AesDecryptDirect(aes, out, buf);
19210
            if (ret != 0)
19211
                return ret;
19212
        }
19213
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
19214
19215
        /* multiply by shift left and propagate carry */
19216
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
19217
            byte tmpC;
19218
19219
            tmpC   = (i[j] >> 7) & 0x01;
19220
            i[j] = (byte)(((i[j] << 1) + carry) & 0xFF);
19221
            carry  = tmpC;
19222
        }
19223
        if (carry) {
19224
            i[0] ^= GF_XTS;
19225
        }
19226
        carry = 0;
19227
19228
        in  += WC_AES_BLOCK_SIZE;
19229
        out += WC_AES_BLOCK_SIZE;
19230
        sz  -= WC_AES_BLOCK_SIZE;
19231
        blocks--;
19232
    }
19233
19234
    /* stealing operation of XTS to handle left overs */
19235
    if (sz >= WC_AES_BLOCK_SIZE) {
19236
        byte buf[WC_AES_BLOCK_SIZE];
19237
        byte tmp2[WC_AES_BLOCK_SIZE];
19238
19239
        /* multiply by shift left and propagate carry */
19240
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
19241
            byte tmpC;
19242
19243
            tmpC   = (i[j] >> 7) & 0x01;
19244
            tmp2[j] = (byte)((i[j] << 1) + carry);
19245
            carry  = tmpC;
19246
        }
19247
        if (carry) {
19248
            tmp2[0] ^= GF_XTS;
19249
        }
19250
19251
        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
19252
        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
19253
        ret = wc_AesDecryptDirect(aes, out, buf);
19254
        if (ret != 0)
19255
            return ret;
19256
        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
19257
19258
        /* tmp2 holds partial | last */
19259
        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
19260
        in  += WC_AES_BLOCK_SIZE;
19261
        out += WC_AES_BLOCK_SIZE;
19262
        sz  -= WC_AES_BLOCK_SIZE;
19263
19264
        /* Make buffer with end of cipher text | last */
19265
        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
19266
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
19267
            return BUFFER_E;
19268
        }
19269
        XMEMCPY(buf, in,   sz);
19270
        XMEMCPY(out, tmp2, sz);
19271
19272
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
19273
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
19274
        if (ret != 0)
19275
            return ret;
19276
        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
19277
        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
19278
    }
19279
19280
    return ret;
19281
}
19282
#endif
19283
19284
/* Same process as encryption but Aes key is AES_DECRYPTION type.
19285
 *
19286
 * xaes  AES keys to use for block encrypt/decrypt
19287
 * out   output buffer to hold plain text
19288
 * in    input cipher text buffer to decrypt
19289
 * sz    size of both out and in buffers
19290
 * i     value to use for tweak
19291
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
19292
 *       adds a sanity check on how the user calls the function.
19293
 *
19294
 * returns 0 on success
19295
 */
19296
int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19297
        const byte* i, word32 iSz)
19298
{
19299
    int ret;
19300
    Aes *aes;
19301
19302
    if (xaes == NULL || out == NULL || in == NULL) {
19303
        return BAD_FUNC_ARG;
19304
    }
19305
19306
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
19307
    aes = &xaes->aes_decrypt;
19308
#else
19309
    aes = &xaes->aes;
19310
#endif
19311
19312
/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
19313
 * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
19314
 * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes or
19315
 * 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
19316
 * return whenever sz / WC_AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
19317
 * not a sequence of complete blocks.
19318
 */
19319
19320
    /* rounds == 0 means no software key schedule: XTS has no crypto
19321
     * callback dispatch, so a device-owned key is unusable here. */
19322
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
19323
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
19324
        return BAD_FUNC_ARG;
19325
    }
19326
19327
    if (iSz < WC_AES_BLOCK_SIZE) {
19328
        return BAD_FUNC_ARG;
19329
    }
19330
19331
    if (sz < WC_AES_BLOCK_SIZE) {
19332
        WOLFSSL_MSG("Cipher text input too small for decryption");
19333
        return BAD_FUNC_ARG;
19334
    }
19335
19336
#if defined(WOLFSSL_RISCV_ASM)
19337
    /* Use the selected decrypt schedule (aes), not xaes->aes - under
19338
     * WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS xaes->aes holds the
19339
     * ENCRYPT schedule; matches the AESNI branch below. */
19340
    AES_XTS_decrypt_RISCV64(in, out, sz, i, (byte*)aes->key,
19341
        (byte*)xaes->tweak.key, (byte*)aes->tmp, (int)aes->rounds);
19342
    ret = 0;
19343
#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
19344
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
19345
    /* The base 32-bit AES assembly has no XTS variant, so the run-time
19346
     * fallback is the software XTS (which dispatches per-block via
19347
     * wc_AesDecrypt). */
19348
#ifdef WOLFSSL_ARM32_AES_DISPATCH
19349
    if (xaes->aes.use_aes_hw_crypto) {
19350
        AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
19351
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
19352
        ret = 0;
19353
    }
19354
    else {
19355
        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
19356
    }
19357
#else
19358
    AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
19359
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
19360
    ret = 0;
19361
#endif
19362
#elif defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
19363
    if (aes->use_aesni) {
19364
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
19365
#if defined(HAVE_INTEL_AVX512)
19366
        if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19367
            AES_XTS_decrypt_avx512(in, out, sz, i,
19368
                                   (const byte*)aes->key,
19369
                                   (const byte*)xaes->tweak.key,
19370
                                   (int)aes->rounds);
19371
            ret = 0;
19372
        }
19373
        else
19374
#endif
19375
#if defined(HAVE_INTEL_VAES)
19376
        if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19377
            AES_XTS_decrypt_vaes(in, out, sz, i,
19378
                                 (const byte*)aes->key,
19379
                                 (const byte*)xaes->tweak.key,
19380
                                 (int)aes->rounds);
19381
            ret = 0;
19382
        }
19383
        else
19384
#endif
19385
#if defined(HAVE_INTEL_AVX1)
19386
        if (IS_INTEL_AVX1(intel_flags)) {
19387
            AES_XTS_decrypt_avx1(in, out, sz, i,
19388
                                 (const byte*)aes->key,
19389
                                 (const byte*)xaes->tweak.key,
19390
                                 (int)aes->rounds);
19391
            ret = 0;
19392
        }
19393
        else
19394
#endif
19395
        {
19396
            AES_XTS_decrypt_aesni(in, out, sz, i,
19397
                                  (const byte*)aes->key,
19398
                                  (const byte*)xaes->tweak.key,
19399
                                  (int)aes->rounds);
19400
            ret = 0;
19401
        }
19402
        RESTORE_VECTOR_REGISTERS();
19403
    }
19404
    else {
19405
        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
19406
    }
19407
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
19408
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
19409
    if (aes->use_aes_hw_crypto) {
19410
        AES_XTS_decrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
19411
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
19412
        ret = 0;
19413
    }
19414
    else
19415
#endif
19416
#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
19417
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
19418
    if (sz >= 64)
19419
#endif
19420
    {
19421
        AES_XTS_decrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
19422
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
19423
        ret = 0;
19424
    }
19425
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
19426
    else
19427
#endif
19428
#endif
19429
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
19430
    {
19431
        AES_XTS_decrypt(in, out, sz, i, (byte*)xaes->aes.key,
19432
            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
19433
        ret = 0;
19434
    }
19435
#endif
19436
#elif defined(WOLFSSL_PPC64_ASM)
19437
    AES_XTS_decrypt(in, out, sz, i, (byte*)xaes->aes.key,
19438
        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
19439
    ret = 0;
19440
#else
19441
    ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
19442
#endif
19443
19444
    return ret;
19445
}
19446
19447
#ifdef WOLFSSL_AESXTS_STREAM
19448
19449
/* Same process as encryption but Aes key is AES_DECRYPTION type.
19450
 *
19451
 * xaes  AES keys to use for block encrypt/decrypt
19452
 * i     readwrite value to use for tweak
19453
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
19454
 *       adds a sanity check on how the user calls the function.
19455
 *
19456
 * returns 0 on success
19457
 */
19458
int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
19459
                         struct XtsAesStreamData *stream)
19460
{
19461
    int ret;
19462
    Aes *aes;
19463
19464
    if (xaes == NULL) {
19465
        return BAD_FUNC_ARG;
19466
    }
19467
19468
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
19469
    aes = &xaes->aes_decrypt;
19470
#else
19471
    aes = &xaes->aes;
19472
#endif
19473
19474
    /* rounds == 0 means no software key schedule: XTS has no crypto
19475
     * callback dispatch, so a device-owned key is unusable here. */
19476
    if ((aes->keylen == 0) || (aes->rounds == 0)) {
19477
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
19478
        return BAD_FUNC_ARG;
19479
    }
19480
19481
    if (iSz < WC_AES_BLOCK_SIZE) {
19482
        return BAD_FUNC_ARG;
19483
    }
19484
19485
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
19486
    stream->bytes_crypted_with_this_tweak = 0;
19487
19488
    {
19489
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
19490
        if (aes->use_aesni) {
19491
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
19492
#if defined(HAVE_INTEL_AVX512)
19493
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19494
                AES_XTS_init_avx512(stream->tweak_block,
19495
                                    (const byte*)xaes->tweak.key,
19496
                                    (int)xaes->tweak.rounds);
19497
                ret = 0;
19498
            }
19499
            else
19500
#endif
19501
#if defined(HAVE_INTEL_VAES)
19502
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19503
                AES_XTS_init_vaes(stream->tweak_block,
19504
                                  (const byte*)xaes->tweak.key,
19505
                                  (int)xaes->tweak.rounds);
19506
                ret = 0;
19507
            }
19508
            else
19509
#endif
19510
#if defined(HAVE_INTEL_AVX1)
19511
            if (IS_INTEL_AVX1(intel_flags)) {
19512
                AES_XTS_init_avx1(stream->tweak_block,
19513
                                  (const byte*)xaes->tweak.key,
19514
                                  (int)xaes->tweak.rounds);
19515
                ret = 0;
19516
            }
19517
            else
19518
#endif
19519
            {
19520
                AES_XTS_init_aesni(stream->tweak_block,
19521
                                   (const byte*)xaes->tweak.key,
19522
                                   (int)xaes->tweak.rounds);
19523
                ret = 0;
19524
            }
19525
            RESTORE_VECTOR_REGISTERS();
19526
        }
19527
        else
19528
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
19529
        {
19530
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
19531
        }
19532
19533
    }
19534
19535
    return ret;
19536
}
19537
19538
/* Block-streaming AES-XTS
19539
 *
19540
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
19541
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsDecryptUpdate().
19542
 * wc_AesXtsDecryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
19543
 *
19544
 * xaes  AES keys to use for block encrypt/decrypt
19545
 * out   output buffer to hold plain text
19546
 * in    input cipher text buffer to decrypt
19547
 * sz    size of both out and in buffers
19548
 * i     tweak buffer of size WC_AES_BLOCK_SIZE.
19549
 *
19550
 * returns 0 on success
19551
 */
19552
static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19553
                           struct XtsAesStreamData *stream)
19554
{
19555
    int ret;
19556
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
19557
    Aes *aes;
19558
#endif
19559
19560
    if (xaes == NULL || out == NULL || in == NULL) {
19561
        return BAD_FUNC_ARG;
19562
    }
19563
19564
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
19565
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
19566
    aes = &xaes->aes_decrypt;
19567
#else
19568
    aes = &xaes->aes;
19569
#endif
19570
#endif
19571
19572
    if (sz < WC_AES_BLOCK_SIZE) {
19573
        WOLFSSL_MSG("Cipher text input too small for decryption");
19574
        return BAD_FUNC_ARG;
19575
    }
19576
19577
    if (stream->bytes_crypted_with_this_tweak &
19578
        ((word32)WC_AES_BLOCK_SIZE - 1U))
19579
    {
19580
        WOLFSSL_MSG("AesXtsDecryptUpdate after previous finalizing call");
19581
        return BAD_FUNC_ARG;
19582
    }
19583
19584
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
19585
    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
19586
                             stream->bytes_crypted_with_this_tweak))
19587
    {
19588
        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
19589
                    "in AesXtsDecryptUpdate().");
19590
    }
19591
#endif
19592
19593
    {
19594
#if defined(WOLFSSL_AESNI) && !defined(WOLFSSL_X86_BUILD)
19595
        if (aes->use_aesni) {
19596
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
19597
#if defined(HAVE_INTEL_AVX512)
19598
            if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19599
                AES_XTS_decrypt_update_avx512(in, out, sz,
19600
                                              (const byte*)aes->key,
19601
                                              stream->tweak_block,
19602
                                              (int)aes->rounds);
19603
                ret = 0;
19604
            }
19605
            else
19606
#endif
19607
#if defined(HAVE_INTEL_VAES)
19608
            if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_VAES(intel_flags)) {
19609
                AES_XTS_decrypt_update_vaes(in, out, sz,
19610
                                            (const byte*)aes->key,
19611
                                            stream->tweak_block,
19612
                                            (int)aes->rounds);
19613
                ret = 0;
19614
            }
19615
            else
19616
#endif
19617
#if defined(HAVE_INTEL_AVX1)
19618
            if (IS_INTEL_AVX1(intel_flags)) {
19619
                AES_XTS_decrypt_update_avx1(in, out, sz,
19620
                                            (const byte*)aes->key,
19621
                                            stream->tweak_block,
19622
                                            (int)aes->rounds);
19623
                ret = 0;
19624
            }
19625
            else
19626
#endif
19627
            {
19628
                AES_XTS_decrypt_update_aesni(in, out, sz,
19629
                                             (const byte*)aes->key,
19630
                                             stream->tweak_block,
19631
                                             (int)aes->rounds);
19632
                ret = 0;
19633
            }
19634
            RESTORE_VECTOR_REGISTERS();
19635
        }
19636
        else
19637
#endif /* WOLFSSL_AESNI && !WOLFSSL_X86_BUILD */
19638
        {
19639
            ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
19640
                                         stream->tweak_block);
19641
        }
19642
    }
19643
19644
    return ret;
19645
}
19646
19647
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19648
                           struct XtsAesStreamData *stream)
19649
{
19650
    if (stream == NULL)
19651
        return BAD_FUNC_ARG;
19652
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
19653
        return BAD_FUNC_ARG;
19654
    return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
19655
}
19656
19657
int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
19658
                           struct XtsAesStreamData *stream)
19659
{
19660
    int ret;
19661
    if (stream == NULL)
19662
        return BAD_FUNC_ARG;
19663
    if (sz > 0)
19664
        ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
19665
    else
19666
        ret = 0;
19667
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
19668
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
19669
     * after finalization.
19670
     */
19671
    stream->bytes_crypted_with_this_tweak |= 1U;
19672
#ifdef WOLFSSL_CHECK_MEM_ZERO
19673
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
19674
#endif
19675
    return ret;
19676
}
19677
19678
#endif /* WOLFSSL_AESXTS_STREAM */
19679
#endif /* HAVE_AES_DECRYPT */
19680
19681
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
19682
 * sectorSz bytes
19683
 *
19684
 * xaes     AES keys to use for block encrypt
19685
 * out      output buffer to hold cipher text
19686
 * in       input plain text buffer to encrypt
19687
 * sz       size of both out and in buffers
19688
 * sector   value to use for tweak
19689
 * sectorSz size of the sector
19690
 *
19691
 * returns 0 on success
19692
 */
19693
int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
19694
        word32 sz, word64 sector, word32 sectorSz)
19695
{
19696
    int ret  = 0;
19697
    word32 iter = 0;
19698
    word32 sectorCount;
19699
    word32 remainder;
19700
19701
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
19702
        return BAD_FUNC_ARG;
19703
    }
19704
19705
    if (sz < WC_AES_BLOCK_SIZE) {
19706
        WOLFSSL_MSG("Cipher text input too small for encryption");
19707
        return BAD_FUNC_ARG;
19708
    }
19709
19710
    sectorCount  = sz / sectorSz;
19711
    remainder = sz % sectorSz;
19712
19713
    while (sectorCount) {
19714
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
19715
                in + (iter * sectorSz), sectorSz, sector);
19716
        if (ret != 0)
19717
            break;
19718
19719
        sectorCount--;
19720
        iter++;
19721
        sector++;
19722
    }
19723
19724
    if (remainder && ret == 0)
19725
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
19726
                in + (iter * sectorSz), remainder, sector);
19727
19728
    return ret;
19729
}
19730
19731
#ifdef HAVE_AES_DECRYPT
19732
19733
/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
19734
 *
19735
 * xaes     AES keys to use for block decrypt
19736
 * out      output buffer to hold cipher text
19737
 * in       input plain text buffer to encrypt
19738
 * sz       size of both out and in buffers
19739
 * sector   value to use for tweak
19740
 * sectorSz size of the sector
19741
 *
19742
 * returns 0 on success
19743
 */
19744
int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
19745
        word32 sz, word64 sector, word32 sectorSz)
19746
{
19747
    int ret  = 0;
19748
    word32 iter = 0;
19749
    word32 sectorCount;
19750
    word32 remainder;
19751
19752
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
19753
        return BAD_FUNC_ARG;
19754
    }
19755
19756
    if (sz < WC_AES_BLOCK_SIZE) {
19757
        WOLFSSL_MSG("Cipher text input too small for decryption");
19758
        return BAD_FUNC_ARG;
19759
    }
19760
19761
    sectorCount  = sz / sectorSz;
19762
    remainder = sz % sectorSz;
19763
19764
    while (sectorCount) {
19765
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
19766
                in + (iter * sectorSz), sectorSz, sector);
19767
        if (ret != 0)
19768
            break;
19769
19770
        sectorCount--;
19771
        iter++;
19772
        sector++;
19773
    }
19774
19775
    if (remainder && ret == 0)
19776
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
19777
                in + (iter * sectorSz), remainder, sector);
19778
19779
    return ret;
19780
}
19781
#endif /* HAVE_AES_DECRYPT */
19782
#endif /* WOLFSSL_AES_XTS */
19783
19784
#ifdef WOLFSSL_CMAC
19785
19786
int wc_local_CmacUpdateAes(struct Cmac *cmac, const byte* in, word32 inSz) {
19787
    int ret = 0;
19788
    Aes *aes = &cmac->aes;
19789
#ifdef WC_AES_HAVE_PREFETCH_ARG
19790
    int did_prefetches = 0;
19791
#endif
19792
19793
    VECTOR_REGISTERS_PUSH;
19794
19795
    while ((ret == 0) && (inSz != 0)) {
19796
        word32 add = min(inSz, WC_AES_BLOCK_SIZE - cmac->bufferSz);
19797
        XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
19798
19799
        cmac->bufferSz += add;
19800
        inSz -= add;
19801
        in += add;
19802
19803
        if (cmac->bufferSz == WC_AES_BLOCK_SIZE && inSz != 0) {
19804
            xorbuf(cmac->buffer, cmac->digest, WC_AES_BLOCK_SIZE);
19805
            ret = AesEncrypt_preFetchOpt(aes, cmac->buffer,
19806
                                            cmac->digest, &did_prefetches);
19807
            if (ret == 0) {
19808
                cmac->totalSz += WC_AES_BLOCK_SIZE;
19809
                cmac->bufferSz = 0;
19810
            }
19811
        }
19812
    }
19813
19814
    VECTOR_REGISTERS_POP;
19815
19816
    return ret;
19817
}
19818
19819
#endif /* WOLFSSL_CMAC */
19820
19821
#ifdef WOLFSSL_AES_SIV
19822
19823
/*
19824
 * See RFC 5297 Section 2.4.
19825
 */
19826
static WARN_UNUSED_RESULT int S2V(
19827
    const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc,
19828
    const byte* nonce, word32 nonceSz, const byte* data,
19829
    word32 dataSz, byte* out)
19830
{
19831
#ifdef WOLFSSL_SMALL_STACK
19832
    byte* tmp[3] = {NULL, NULL, NULL};
19833
    int i;
19834
    Cmac* cmac;
19835
#else
19836
    byte tmp[3][WC_AES_BLOCK_SIZE];
19837
    Cmac cmac[1];
19838
#endif
19839
    word32 macSz = WC_AES_BLOCK_SIZE;
19840
    int ret = 0;
19841
    byte tmpi = 0;
19842
    word32 ai;
19843
    word32 zeroBytes;
19844
19845
#ifdef WOLFSSL_SMALL_STACK
19846
    for (i = 0; i < 3; ++i) {
19847
        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19848
        if (tmp[i] == NULL) {
19849
            ret = MEMORY_E;
19850
            break;
19851
        }
19852
    }
19853
    if (ret == 0)
19854
#endif
19855
19856
    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
19857
        /* See RFC 5297 Section 7. */
19858
        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
19859
                    " 126.");
19860
        ret = BAD_FUNC_ARG;
19861
    }
19862
19863
    if (ret == 0) {
19864
        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
19865
        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
19866
19867
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
19868
                                 key, keySz);
19869
    }
19870
19871
    if (ret == 0) {
19872
        /* Loop over authenticated associated data AD1..ADn */
19873
        for (ai = 0; ai < numAssoc; ++ai) {
19874
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
19875
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
19876
                                     assoc[ai].assocSz, key, keySz);
19877
            if (ret != 0)
19878
                break;
19879
            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
19880
            tmpi = (byte)(1 - tmpi);
19881
        }
19882
19883
        /* Add nonce as final AD. See RFC 5297 Section 3. */
19884
        if ((ret == 0) && (nonceSz > 0)) {
19885
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
19886
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
19887
                                     nonceSz, key, keySz);
19888
            if (ret == 0) {
19889
                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
19890
            }
19891
            tmpi = (byte)(1U - tmpi);
19892
        }
19893
19894
        /* For simplicity of the remaining code, make sure the "final" result
19895
           is always in tmp[0]. */
19896
        if (tmpi == 1) {
19897
            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
19898
        }
19899
    }
19900
19901
    if (ret == 0) {
19902
        if (dataSz >= WC_AES_BLOCK_SIZE) {
19903
19904
            WC_ALLOC_VAR_EX(cmac, Cmac, 1, NULL, DYNAMIC_TYPE_CMAC,
19905
                ret=MEMORY_E);
19906
            if (WC_VAR_OK(cmac))
19907
            {
19908
            #ifdef WOLFSSL_CHECK_MEM_ZERO
19909
                /* Aes part is checked by wc_AesFree. */
19910
                wc_MemZero_Add("wc_AesCmacGenerate cmac",
19911
                    ((unsigned char *)cmac) + sizeof(Aes),
19912
                    sizeof(Cmac) - sizeof(Aes));
19913
            #endif
19914
                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
19915
                       WC_AES_BLOCK_SIZE);
19916
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
19917
                if (ret == 0) {
19918
                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
19919
                }
19920
                if (ret == 0) {
19921
                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
19922
                }
19923
                if (ret == 0) {
19924
                    ret = wc_CmacFinal(cmac, out, &macSz);
19925
                }
19926
            }
19927
        #ifdef WOLFSSL_SMALL_STACK
19928
            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
19929
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
19930
            wc_MemZero_Check(cmac, sizeof(Cmac));
19931
        #endif
19932
        }
19933
        else {
19934
            XMEMCPY(tmp[2], data, dataSz);
19935
            tmp[2][dataSz] |= 0x80;
19936
            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
19937
            if (zeroBytes != 0) {
19938
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
19939
            }
19940
            ShiftAndXorRb(tmp[1], tmp[0]);
19941
            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
19942
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
19943
                                     keySz);
19944
        }
19945
    }
19946
19947
#ifdef WOLFSSL_SMALL_STACK
19948
    for (i = 0; i < 3; ++i) {
19949
        if (tmp[i] != NULL) {
19950
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
19951
        }
19952
    }
19953
#endif
19954
19955
    return ret;
19956
}
19957
19958
static WARN_UNUSED_RESULT int AesSivCipher(
19959
    const byte* key, word32 keySz, const AesSivAssoc* assoc,
19960
    word32 numAssoc, const byte* nonce, word32 nonceSz,
19961
    const byte* data, word32 dataSz, byte* siv, byte* out,
19962
    int enc)
19963
{
19964
    int ret = 0;
19965
    WC_DECLARE_VAR(aes, Aes, 1, 0);
19966
    byte sivTmp[WC_AES_BLOCK_SIZE];
19967
19968
#ifdef WOLFSSL_CHECK_MEM_ZERO
19969
    /* Poison before the (conditional) fill so error paths that never write
19970
     * sivTmp still leave it defined; the used paths overwrite it. Register
19971
     * here (the highest point from which every exit funnels to the single
19972
     * ForceZero+Check below). */
19973
    XMEMSET(sivTmp, 0xff, sizeof(sivTmp));
19974
    wc_MemZero_Add("AesSivCipher sivTmp", sivTmp, sizeof(sivTmp));
19975
#endif
19976
19977
    if (key == NULL || siv == NULL || out == NULL) {
19978
        WOLFSSL_MSG("Bad parameter");
19979
        ret = BAD_FUNC_ARG;
19980
    }
19981
19982
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
19983
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
19984
        ret = BAD_FUNC_ARG;
19985
    }
19986
19987
    if (ret == 0) {
19988
        if (enc == 1) {
19989
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
19990
                      dataSz, sivTmp);
19991
            if (ret != 0) {
19992
                WOLFSSL_MSG("S2V failed.");
19993
            }
19994
            else {
19995
                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
19996
            }
19997
        }
19998
        else {
19999
            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
20000
        }
20001
    }
20002
20003
    if (ret == 0) {
20004
#ifdef WOLFSSL_SMALL_STACK
20005
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
20006
#else
20007
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
20008
#endif
20009
        if (ret != 0) {
20010
            WOLFSSL_MSG("Failed to initialized AES object.");
20011
        }
20012
    }
20013
20014
    if (ret == 0) {
20015
        if (dataSz > 0) {
20016
            sivTmp[12] &= 0x7f;
20017
            sivTmp[8] &= 0x7f;
20018
            ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
20019
                               AES_ENCRYPTION);
20020
            if (ret != 0) {
20021
                WOLFSSL_MSG("Failed to set key for AES-CTR.");
20022
            }
20023
            else {
20024
                ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
20025
                if (ret != 0) {
20026
                    WOLFSSL_MSG("AES-CTR encryption failed.");
20027
                }
20028
            }
20029
        }
20030
20031
        if (ret == 0 && enc == 0) {
20032
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out,
20033
                      dataSz, sivTmp);
20034
            if (ret != 0) {
20035
                WOLFSSL_MSG("S2V failed.");
20036
            }
20037
20038
            if (ret == 0 && ConstantCompare(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
20039
                WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
20040
                ret = AES_SIV_AUTH_E;
20041
            }
20042
        }
20043
20044
        if (ret != 0) {
20045
            ForceZero(out, dataSz);
20046
        }
20047
20048
    #ifdef WOLFSSL_SMALL_STACK
20049
        wc_AesDelete(aes, NULL);
20050
    #else
20051
        wc_AesFree(aes);
20052
    #endif
20053
    }
20054
20055
    ForceZero(sivTmp, sizeof(sivTmp));
20056
#ifdef WOLFSSL_CHECK_MEM_ZERO
20057
    wc_MemZero_Check(sivTmp, sizeof(sivTmp));
20058
#endif
20059
20060
    return ret;
20061
}
20062
20063
/*
20064
 * See RFC 5297 Section 2.6.
20065
 */
20066
int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
20067
                     word32 assocSz, const byte* nonce, word32 nonceSz,
20068
                     const byte* in, word32 inSz, byte* siv, byte* out)
20069
{
20070
    AesSivAssoc ad;
20071
    ad.assoc = assoc;
20072
    ad.assocSz = assocSz;
20073
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
20074
                        siv, out, 1);
20075
}
20076
20077
/*
20078
 * See RFC 5297 Section 2.7.
20079
 */
20080
int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
20081
                     word32 assocSz, const byte* nonce, word32 nonceSz,
20082
                     const byte* in, word32 inSz, byte* siv, byte* out)
20083
{
20084
    AesSivAssoc ad;
20085
    ad.assoc = assoc;
20086
    ad.assocSz = assocSz;
20087
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
20088
                        siv, out, 0);
20089
}
20090
20091
/*
20092
 * See RFC 5297 Section 2.6.
20093
 */
20094
int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
20095
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
20096
                        const byte* in, word32 inSz, byte* siv, byte* out)
20097
{
20098
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
20099
                        siv, out, 1);
20100
}
20101
20102
/*
20103
 * See RFC 5297 Section 2.7.
20104
 */
20105
int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
20106
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
20107
                        const byte* in, word32 inSz, byte* siv, byte* out)
20108
{
20109
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
20110
                        siv, out, 0);
20111
}
20112
20113
#endif /* WOLFSSL_AES_SIV */
20114
20115
#ifdef WOLFSSL_AESGCM_SIV
20116
20117
/* AES-GCM-SIV - a nonce misuse-resistant AEAD. See RFC 8452.
20118
 *
20119
 * The implementation here is portable C.  AES block operations reuse the
20120
 * internal wc_AesEncrypt(), so HAVE_AESGCM is required for that to be built.
20121
 */
20122
#ifndef HAVE_AESGCM
20123
    #error "WOLFSSL_AESGCM_SIV requires HAVE_AESGCM"
20124
#endif
20125
20126
#define AES_GCM_SIV_NONCE_SZ  12
20127
#define AES_GCM_SIV_TAG_SZ    WC_AES_BLOCK_SIZE
20128
20129
#ifndef GCM_SMALL
20130
/* GF(2^128) reduction table used by the table-based software multiplies; not
20131
 * needed by the table-free GCM_SMALL variant. R[a] is the contribution, to the
20132
 * top two bytes, of reducing a nibble 'a' shifted out past x^127 (the GHASH
20133
 * polynomial x^128+x^7+x^2+x+1). Same table wolfSSL uses for table GHASH. */
20134
static const byte AES_GCM_SIV_R[16][2] = {
20135
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
20136
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
20137
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
20138
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
20139
};
20140
#endif
20141
20142
/* Reverse the order of the 16 bytes of a block. in and out must not alias. */
20143
static WC_INLINE void AesGcmSivByteReverse(byte* out, const byte* in)
20144
{
20145
#if !defined(WOLFSSL_USE_ALIGN) && defined(WORD64_AVAILABLE)
20146
    /* Unaligned word access is permitted: reverse eight bytes at a time with a
20147
     * hardware byte-swap rather than one byte at a time. Endian independent -
20148
     * load native, reverse the value's bytes, store native: that reverses the
20149
     * bytes in memory on both little- and big-endian. */
20150
    word64 lo, hi;
20151
    XMEMCPY(&lo, in,     sizeof(lo));
20152
    XMEMCPY(&hi, in + 8, sizeof(hi));
20153
    lo = ByteReverseWord64(lo);
20154
    hi = ByteReverseWord64(hi);
20155
    XMEMCPY(out,     &hi, sizeof(hi));
20156
    XMEMCPY(out + 8, &lo, sizeof(lo));
20157
#else
20158
    int i;
20159
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
20160
        out[i] = in[WC_AES_BLOCK_SIZE - 1 - i];
20161
    }
20162
#endif
20163
}
20164
20165
/* POLYVAL state (RFC 8452 Section 3). POLYVAL is GHASH on byte-reversed inputs,
20166
 * so the field is the GHASH field with the most-significant bit of byte 0 the
20167
 * x^0 coefficient (see RFC 8452 Appendix A). The key is one of:
20168
 *  - GCM_SMALL: the 16-byte key (table-free, smallest footprint).
20169
 *  - word64:    a Shoup 4-bit table (256 bytes), word64 multiply - used when a
20170
 *               64-bit type is available and GCM_WORD32 is not requested.
20171
 *  - word32:    the same 4-bit table, word32 multiply - used for GCM_WORD32 or
20172
 *               when no 64-bit type is available.
20173
 *
20174
 * Every variant reads the message, key and running sum a byte at a time and
20175
 * (the word64/word32 variants) load/store their words with explicit shifts or
20176
 * a byte-swap rather than casting buffers, so all are independent of platform
20177
 * endianness; the word loads also respect WOLFSSL_USE_ALIGN, so input, key and
20178
 * output buffers may be little- or big-endian and aligned or unaligned.
20179
 */
20180
/* When the generated x86_64 AES-NI/PCLMUL POLYVAL multiply is available
20181
 * (aes_gcm_asm.S), the per-block multiply can be offloaded to it at runtime.
20182
 * This is the generated external assembly - no assembly lives in this file. */
20183
#if defined(WOLFSSL_AESNI) && defined(WOLFSSL_X86_64_BUILD)
20184
    #define WC_POLYVAL_ASM
20185
#ifdef __cplusplus
20186
    extern "C" {
20187
#endif
20188
    /* s += POLYVAL of 'blocks' 16-byte blocks of data, hash key h prepared as
20189
     * the byte-reversed mulX_GHASH(ByteReverse(authKey)); s is POLYVAL byte
20190
     * order. */
20191
    void AES_GCMSIV_polyval_aesni(unsigned char* s, const unsigned char* h,
20192
        const unsigned char* data, word32 blocks)
20193
        XASM_LINK("AES_GCMSIV_polyval_aesni");
20194
#ifdef HAVE_INTEL_AVX1
20195
    void AES_GCMSIV_polyval_avx1(unsigned char* s, const unsigned char* h,
20196
        const unsigned char* data, word32 blocks)
20197
        XASM_LINK("AES_GCMSIV_polyval_avx1");
20198
#endif
20199
#ifdef HAVE_INTEL_VAES
20200
    /* Aggregated 2-blocks-per-ymm POLYVAL (VPCLMULQDQ). */
20201
    void AES_GCMSIV_polyval_vaes(unsigned char* s, const unsigned char* h,
20202
        const unsigned char* data, word32 blocks)
20203
        XASM_LINK("AES_GCMSIV_polyval_vaes");
20204
#endif
20205
#ifdef HAVE_INTEL_AVX512
20206
    /* Aggregated 4-blocks-per-zmm POLYVAL (VPCLMULQDQ). */
20207
    void AES_GCMSIV_polyval_avx512(unsigned char* s, const unsigned char* h,
20208
        const unsigned char* data, word32 blocks)
20209
        XASM_LINK("AES_GCMSIV_polyval_avx512");
20210
#endif
20211
    /* AES-GCM-SIV CTR keystream (RFC 8452): a 32-bit little-endian counter in
20212
     * the first 4 bytes of the block (mod 2^32, no carry), block used directly
20213
     * as the AES input. Encrypts the full-16-byte-block portion of 'length'
20214
     * bytes (pipelined), advancing and writing 'ctr' back. */
20215
    #define WC_GCMSIV_CTR_ASM
20216
    void AES_GCMSIV_ctr_aesni(const unsigned char* in, unsigned char* out,
20217
        unsigned long length, const unsigned char* KS, int nr,
20218
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_aesni");
20219
#ifdef HAVE_INTEL_AVX1
20220
    void AES_GCMSIV_ctr_avx1(const unsigned char* in, unsigned char* out,
20221
        unsigned long length, const unsigned char* KS, int nr,
20222
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_avx1");
20223
#endif
20224
#ifdef HAVE_INTEL_VAES
20225
    void AES_GCMSIV_ctr_vaes(const unsigned char* in, unsigned char* out,
20226
        unsigned long length, const unsigned char* KS, int nr,
20227
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_vaes");
20228
#endif
20229
#ifdef HAVE_INTEL_AVX512
20230
    void AES_GCMSIV_ctr_avx512(const unsigned char* in, unsigned char* out,
20231
        unsigned long length, const unsigned char* KS, int nr,
20232
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_avx512");
20233
#endif
20234
#ifdef __cplusplus
20235
    }
20236
#endif
20237
#elif defined(WOLFSSL_ARMASM) && defined(__aarch64__)
20238
    /* The generated AArch64 POLYVAL multiplies (armv8-aes-asm.S) offload the
20239
     * per-block multiply: PMULL when the CPU has the crypto extension, else the
20240
     * 8-bit-pmul NEON variant, else the scalar (base) variant. This is the
20241
     * generated external assembly - no assembly lives here. */
20242
    #define WC_POLYVAL_ASM
20243
    #define WC_POLYVAL_ASM_AARCH64
20244
    /* The base (scalar) variant multiplies through the word64 software table
20245
     * poly->m, so it is only available when that table is built. */
20246
    #if defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) && \
20247
        !defined(GCM_SMALL) && !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
20248
        #define WC_POLYVAL_ASM_AARCH64_BASE
20249
    #endif
20250
#ifdef __cplusplus
20251
    extern "C" {
20252
#endif
20253
    /* s += POLYVAL of 'blocks' 16-byte blocks of data. For the PMULL and NEON
20254
     * variants h is the prepared key (byte-reversed mulX_GHASH(ByteReverse(
20255
     * authKey))); for the base variant h is the word64 table poly->m. s is in
20256
     * POLYVAL byte order in every case. */
20257
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20258
    void AES_GCMSIV_polyval_pmull(unsigned char* s, const unsigned char* h,
20259
        const unsigned char* data, word32 blocks)
20260
        XASM_LINK("AES_GCMSIV_polyval_pmull");
20261
#endif
20262
#ifndef WOLFSSL_ARMASM_NO_NEON
20263
    void AES_GCMSIV_polyval_neon(unsigned char* s, const unsigned char* h,
20264
        const unsigned char* data, word32 blocks)
20265
        XASM_LINK("AES_GCMSIV_polyval_neon");
20266
#endif
20267
#ifdef WC_POLYVAL_ASM_AARCH64_BASE
20268
    void AES_GCMSIV_polyval_base(unsigned char* s, const unsigned char* h,
20269
        const unsigned char* data, word32 blocks)
20270
        XASM_LINK("AES_GCMSIV_polyval_base");
20271
#endif
20272
    /* AES-GCM-SIV CTR keystream (RFC 8452): 32-bit little-endian counter in the
20273
     * first 4 bytes of the block, mod 2^32, block used directly. Full-block
20274
     * portion only (the C tail finishes any partial block). The crypto variant
20275
     * pipelines aese; the NEON/base variants pipeline software table AES. KS is
20276
     * the AES key schedule in every case. */
20277
    #define WC_GCMSIV_CTR_ASM
20278
    #define WC_GCMSIV_CTR_ASM_AARCH64
20279
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20280
    void AES_GCMSIV_ctr_aarch64(const unsigned char* in, unsigned char* out,
20281
        unsigned long length, const unsigned char* KS, int nr,
20282
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_aarch64");
20283
#endif
20284
#ifndef WOLFSSL_ARMASM_NO_NEON
20285
    void AES_GCMSIV_ctr_neon(const unsigned char* in, unsigned char* out,
20286
        unsigned long length, const unsigned char* KS, int nr,
20287
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_neon");
20288
#endif
20289
#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
20290
    void AES_GCMSIV_ctr_base(const unsigned char* in, unsigned char* out,
20291
        unsigned long length, const unsigned char* KS, int nr,
20292
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_base");
20293
#endif
20294
#ifdef __cplusplus
20295
    }
20296
#endif
20297
#elif defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
20298
      !defined(WOLFSSL_ARMASM_THUMB2)
20299
    /* AArch32 (32-bit ARM). The generated armv8-32-aes-asm.S provides POLYVAL
20300
     * and CTR for the crypto (vmull.p64 / aese) and base (table) variants. In a
20301
     * run-time dispatch build both are compiled in and the selectors below pick
20302
     * one per CPU (WOLFSSL_ARM32_AES_DISPATCH); otherwise the choice is fixed
20303
     * at compile time by WOLFSSL_ARMASM_NO_HW_CRYPTO - matching the rest of the
20304
     * AArch32 AES. */
20305
    #define WC_POLYVAL_ASM
20306
    #define WC_POLYVAL_ASM_AARCH32
20307
    #define WC_GCMSIV_CTR_ASM
20308
    #define WC_GCMSIV_CTR_ASM_AARCH32
20309
    /* The base POLYVAL multiplies through the word64 software table poly->m,
20310
     * compiled when the crypto extension can be absent at run time (no-crypto
20311
     * build or the run-time dispatch build) and the table is available. */
20312
    #if (defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || \
20313
         defined(WOLFSSL_ARM32_AES_DISPATCH)) && defined(WORD64_AVAILABLE) && \
20314
        !defined(GCM_WORD32) && !defined(GCM_SMALL)
20315
        #define WC_POLYVAL_ASM_AARCH32_BASE
20316
    #endif
20317
#ifdef __cplusplus
20318
    extern "C" {
20319
#endif
20320
    /* Crypto and base variants both exist in a dispatch build; the selectors
20321
     * below pick one per CPU at run time. */
20322
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20323
    void AES_GCMSIV_polyval_crypto(unsigned char* s, const unsigned char* h,
20324
        const unsigned char* data, word32 blocks)
20325
        XASM_LINK("AES_GCMSIV_polyval_crypto");
20326
    void AES_GCMSIV_ctr_crypto(const unsigned char* in, unsigned char* out,
20327
        unsigned long length, const unsigned char* KS, int nr,
20328
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_crypto");
20329
#endif
20330
#if defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) || defined(WOLFSSL_ARM32_AES_DISPATCH)
20331
#ifdef WC_POLYVAL_ASM_AARCH32_BASE
20332
    void AES_GCMSIV_polyval_base(unsigned char* s, const unsigned char* h,
20333
        const unsigned char* data, word32 blocks)
20334
        XASM_LINK("AES_GCMSIV_polyval_base");
20335
#endif
20336
    void AES_GCMSIV_ctr_base(const unsigned char* in, unsigned char* out,
20337
        unsigned long length, const unsigned char* KS, int nr,
20338
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_base");
20339
#endif
20340
#ifdef __cplusplus
20341
    }
20342
#endif
20343
#elif defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_THUMB2)
20344
    /* Thumb-2 (32-bit ARM, Thumb-2 encoding). A single table-based variant
20345
     * (ported from the AArch32 base): POLYVAL multiplies through the word64
20346
     * software table poly->m; CTR is the table AES with the SIV counter. */
20347
    #define WC_GCMSIV_CTR_ASM
20348
    #define WC_GCMSIV_CTR_ASM_THUMB2
20349
    #if defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) && !defined(GCM_SMALL)
20350
        #define WC_POLYVAL_ASM
20351
        #define WC_POLYVAL_ASM_THUMB2
20352
    #endif
20353
#ifdef __cplusplus
20354
    extern "C" {
20355
#endif
20356
#ifdef WC_POLYVAL_ASM_THUMB2
20357
    void AES_GCMSIV_polyval_thumb2(unsigned char* s, const unsigned char* h,
20358
        const unsigned char* data, word32 blocks)
20359
        XASM_LINK("AES_GCMSIV_polyval_thumb2");
20360
#endif
20361
    void AES_GCMSIV_ctr_thumb2(const unsigned char* in, unsigned char* out,
20362
        unsigned long length, const unsigned char* KS, int nr,
20363
        unsigned char* ctr) XASM_LINK("AES_GCMSIV_ctr_thumb2");
20364
#ifdef __cplusplus
20365
    }
20366
#endif
20367
#endif
20368
20369
#ifdef WC_POLYVAL_ASM
20370
    typedef void (*AesGcmSivPolyvalFn)(unsigned char* s, const unsigned char* h,
20371
        const unsigned char* data, word32 blocks);
20372
#endif
20373
#ifdef WC_GCMSIV_CTR_ASM
20374
    typedef void (*AesGcmSivCtrFn)(const unsigned char* in, unsigned char* out,
20375
        unsigned long length, const unsigned char* KS, int nr,
20376
        unsigned char* ctr);
20377
#endif
20378
20379
typedef struct AesGcmSivPolyval {
20380
#ifdef WC_POLYVAL_ASM
20381
    byte hHw[WC_AES_BLOCK_SIZE]; /* prepared key for the asm multiply */
20382
    const byte* asmKey;          /* key passed to fn: hHw, or the table below */
20383
    AesGcmSivPolyvalFn fn;       /* asm multiply, or NULL for software */
20384
#endif
20385
#if defined(GCM_SMALL)
20386
    byte   h[WC_AES_BLOCK_SIZE]; /* hash key = mulX_GHASH(ByteReverse(H)) */
20387
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
20388
    word64 m[16][2];             /* m[i] = i * mulX_GHASH(ByteReverse(H)) */
20389
#else
20390
    word32 m[16][4];             /* m[i] = i * mulX_GHASH(ByteReverse(H)) */
20391
#endif
20392
    byte s[WC_AES_BLOCK_SIZE];   /* running sum, GHASH representation */
20393
} AesGcmSivPolyval;
20394
20395
/* Multiply a GF(2^128) element (GHASH bit order: the most-significant bit of
20396
 * byte 0 is the x^0 coefficient) by x: shift the 128-bit value right by one
20397
 * and reduce with the GHASH polynomial. Branch free, so constant time. Used by
20398
 * the GCM_SMALL multiply and to derive the carry-less-multiply asm hash key
20399
 * (mulX_GHASH); the word64/word32 table variants use AesGcmSivMulX64/32, so this
20400
 * is only compiled when one of those two callers is. Placed after the
20401
 * WC_POLYVAL_ASM #defines above so that guard is resolved here. */
20402
#if defined(GCM_SMALL) || defined(WC_POLYVAL_ASM)
20403
static WC_INLINE void AesGcmSivMulX(byte* x)
20404
{
20405
    int i;
20406
    byte carryIn = 0;
20407
    byte borrow = (byte)((0x00U - (x[WC_AES_BLOCK_SIZE - 1] & 0x01U)) & 0xE1U);
20408
20409
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
20410
        byte carryOut = (byte)((x[i] & 0x01) << 7);
20411
        x[i] = (byte)((x[i] >> 1) | carryIn);
20412
        carryIn = carryOut;
20413
    }
20414
    x[0] ^= borrow;
20415
}
20416
#endif /* GCM_SMALL || WC_POLYVAL_ASM */
20417
20418
#if defined(GCM_SMALL)
20419
20420
/* s = s * h with no precomputed table: decompose h bit-by-bit and accumulate
20421
 * shifted copies of s. Mirrors wolfSSL's GCM_SMALL GMULT. */
20422
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
20423
{
20424
    byte Z[WC_AES_BLOCK_SIZE];
20425
    byte V[WC_AES_BLOCK_SIZE];
20426
    int i, j;
20427
20428
    XMEMSET(Z, 0, sizeof(Z));
20429
    XMEMCPY(V, poly->s, WC_AES_BLOCK_SIZE);
20430
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
20431
        byte y = poly->h[i];
20432
        for (j = 0; j < 8; j++) {
20433
            if (y & 0x80) {
20434
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
20435
            }
20436
            AesGcmSivMulX(V);
20437
            y = (byte)(y << 1);
20438
        }
20439
    }
20440
    XMEMCPY(poly->s, Z, WC_AES_BLOCK_SIZE);
20441
}
20442
20443
/* Store the hash key mulX_GHASH(ByteReverse(h)); no table to build. */
20444
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
20445
{
20446
    AesGcmSivByteReverse(poly->h, h);
20447
    AesGcmSivMulX(poly->h);
20448
    XMEMSET(poly->s, 0, sizeof(poly->s));
20449
}
20450
20451
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
20452
20453
/* Load/store a big-endian word64 - the high word is bytes 0..7 of the block,
20454
 * so byte 0 (the x^0..x^7 coefficients) is the most-significant byte.
20455
 *
20456
 * Where unaligned word access is permitted (!WOLFSSL_USE_ALIGN) this is a
20457
 * single word64 load/store plus a hardware byte-swap on little-endian; where
20458
 * alignment is required it is assembled a byte at a time. Both forms are
20459
 * endian independent. */
20460
#ifndef WOLFSSL_USE_ALIGN
20461
static WC_INLINE word64 AesGcmSivLoad64(const byte* b)
20462
{
20463
    word64 v;
20464
    XMEMCPY(&v, b, sizeof(v));
20465
#ifdef LITTLE_ENDIAN_ORDER
20466
    v = ByteReverseWord64(v);
20467
#endif
20468
    return v;
20469
}
20470
static WC_INLINE void AesGcmSivStore64(byte* b, word64 v)
20471
{
20472
#ifdef LITTLE_ENDIAN_ORDER
20473
    v = ByteReverseWord64(v);
20474
#endif
20475
    XMEMCPY(b, &v, sizeof(v));
20476
}
20477
#else
20478
static WC_INLINE word64 AesGcmSivLoad64(const byte* b)
20479
{
20480
    return ((word64)b[0] << 56) | ((word64)b[1] << 48) |
20481
           ((word64)b[2] << 40) | ((word64)b[3] << 32) |
20482
           ((word64)b[4] << 24) | ((word64)b[5] << 16) |
20483
           ((word64)b[6] <<  8) | ((word64)b[7]);
20484
}
20485
static WC_INLINE void AesGcmSivStore64(byte* b, word64 v)
20486
{
20487
    b[0] = (byte)(v >> 56); b[1] = (byte)(v >> 48);
20488
    b[2] = (byte)(v >> 40); b[3] = (byte)(v >> 32);
20489
    b[4] = (byte)(v >> 24); b[5] = (byte)(v >> 16);
20490
    b[6] = (byte)(v >>  8); b[7] = (byte)(v);
20491
}
20492
#endif
20493
20494
/* Multiply the 128-bit value (hi,lo) by x and reduce: a right shift by one of
20495
 * the whole value, XOR-ing the reduction polynomial (0xe1 into byte 0) when a
20496
 * one is shifted out past x^127 (the low bit of lo). */
20497
static WC_INLINE void AesGcmSivMulX64(word64* hi, word64* lo)
20498
{
20499
    word64 carry = *lo & 1;
20500
    *lo = (*lo >> 1) | (*hi << 63);
20501
    *hi = (*hi >> 1) ^ (W64LIT(0xe100000000000000) & (word64)(0 - carry));
20502
}
20503
20504
/* s = s * H. The accumulator is shifted right a nibble at a time; the nibble
20505
 * that falls off is reduced through AES_GCM_SIV_R into the top two bytes. */
20506
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
20507
{
20508
    byte* x = poly->s;
20509
    word64 (*m)[2] = poly->m;
20510
    word64 zHi = 0, zLo = 0;
20511
    int i;
20512
20513
    for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
20514
        byte xi = x[i];
20515
        byte a;
20516
20517
        /* low nibble */
20518
        zHi ^= m[xi & 0xf][0];
20519
        zLo ^= m[xi & 0xf][1];
20520
        a = (byte)(zLo & 0xf);
20521
        zLo = (zLo >> 4) | (zHi << 60);
20522
        zHi = zHi >> 4;
20523
        zHi ^= ((word64)AES_GCM_SIV_R[a][0] << 56) |
20524
               ((word64)AES_GCM_SIV_R[a][1] << 48);
20525
20526
        /* high nibble */
20527
        zHi ^= m[xi >> 4][0];
20528
        zLo ^= m[xi >> 4][1];
20529
        if (i == 0) {
20530
            break;
20531
        }
20532
        a = (byte)(zLo & 0xf);
20533
        zLo = (zLo >> 4) | (zHi << 60);
20534
        zHi = zHi >> 4;
20535
        zHi ^= ((word64)AES_GCM_SIV_R[a][0] << 56) |
20536
               ((word64)AES_GCM_SIV_R[a][1] << 48);
20537
    }
20538
20539
    AesGcmSivStore64(x,     zHi);
20540
    AesGcmSivStore64(x + 8, zLo);
20541
}
20542
20543
/* Build the 4-bit table for mulX_GHASH(ByteReverse(h)). */
20544
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
20545
{
20546
    byte hrev[WC_AES_BLOCK_SIZE];
20547
    word64 (*m)[2] = poly->m;
20548
    int i;
20549
20550
#ifdef WOLFSSL_CHECK_MEM_ZERO
20551
    /* hrev will hold ByteReverse(H), the per-message hash key; register from
20552
     * the top (baseline keeps it defined) so every exit reaches the
20553
     * ForceZero+Check below. */
20554
    XMEMSET(hrev, 0, sizeof(hrev));
20555
    wc_MemZero_Add("AesGcmSivPolyvalInitSw hrev", hrev, sizeof(hrev));
20556
#endif
20557
20558
    /* m[8] = 1 * H = mulX_GHASH(ByteReverse(h)); successive halvings give the
20559
     * power-of-two nibble entries. */
20560
    AesGcmSivByteReverse(hrev, h);
20561
    m[0x8][0] = AesGcmSivLoad64(hrev);
20562
    m[0x8][1] = AesGcmSivLoad64(hrev + 8);
20563
    AesGcmSivMulX64(&m[0x8][0], &m[0x8][1]);
20564
    m[0x4][0] = m[0x8][0]; m[0x4][1] = m[0x8][1]; AesGcmSivMulX64(&m[0x4][0], &m[0x4][1]);
20565
    m[0x2][0] = m[0x4][0]; m[0x2][1] = m[0x4][1]; AesGcmSivMulX64(&m[0x2][0], &m[0x2][1]);
20566
    m[0x1][0] = m[0x2][0]; m[0x1][1] = m[0x2][1]; AesGcmSivMulX64(&m[0x1][0], &m[0x1][1]);
20567
20568
    /* The rest are sums of those basis entries (i = high bit + remainder). */
20569
    m[0x0][0] = 0; m[0x0][1] = 0;
20570
    for (i = 0; i < 16; i++) {
20571
        static const byte hibit[16] =
20572
            { 0, 0, 0, 2, 0, 4, 4, 4, 0, 8, 8, 8, 8, 8, 8, 8 };
20573
        int top = hibit[i];
20574
        if (top != 0) {
20575
            m[i][0] = m[top][0] ^ m[i - top][0];
20576
            m[i][1] = m[top][1] ^ m[i - top][1];
20577
        }
20578
    }
20579
20580
    XMEMSET(poly->s, 0, sizeof(poly->s));
20581
    /* hrev held ByteReverse(H), the per-message hash key; wipe it. */
20582
    ForceZero(hrev, sizeof(hrev));
20583
#ifdef WOLFSSL_CHECK_MEM_ZERO
20584
    wc_MemZero_Check(hrev, sizeof(hrev));
20585
#endif
20586
}
20587
20588
#else /* word32: GCM_WORD32 or no 64-bit type */
20589
20590
/* Load/store a big-endian word32 - byte 0 is the most-significant byte. Same
20591
 * aligned/unaligned split as AesGcmSivLoad64/Store64; both forms are endian
20592
 * independent. */
20593
#ifndef WOLFSSL_USE_ALIGN
20594
static WC_INLINE word32 AesGcmSivLoad32(const byte* b)
20595
{
20596
    word32 v;
20597
    XMEMCPY(&v, b, sizeof(v));
20598
#ifdef LITTLE_ENDIAN_ORDER
20599
    v = ByteReverseWord32(v);
20600
#endif
20601
    return v;
20602
}
20603
static WC_INLINE void AesGcmSivStore32(byte* b, word32 v)
20604
{
20605
#ifdef LITTLE_ENDIAN_ORDER
20606
    v = ByteReverseWord32(v);
20607
#endif
20608
    XMEMCPY(b, &v, sizeof(v));
20609
}
20610
#else
20611
static WC_INLINE word32 AesGcmSivLoad32(const byte* b)
20612
{
20613
    return ((word32)b[0] << 24) | ((word32)b[1] << 16) |
20614
           ((word32)b[2] <<  8) | ((word32)b[3]);
20615
}
20616
static WC_INLINE void AesGcmSivStore32(byte* b, word32 v)
20617
{
20618
    b[0] = (byte)(v >> 24); b[1] = (byte)(v >> 16);
20619
    b[2] = (byte)(v >>  8); b[3] = (byte)(v);
20620
}
20621
#endif
20622
20623
/* Multiply the 128-bit value (z[0] most significant) by x and reduce: shift
20624
 * the whole value right by one, XOR-ing 0xe1 into byte 0 when a one is shifted
20625
 * out past x^127 (the low bit of z[3]). */
20626
static WC_INLINE void AesGcmSivMulX32(word32* z)
20627
{
20628
    word32 carry = z[3] & 1;
20629
    z[3] = (z[3] >> 1) | (z[2] << 31);
20630
    z[2] = (z[2] >> 1) | (z[1] << 31);
20631
    z[1] = (z[1] >> 1) | (z[0] << 31);
20632
    z[0] = (z[0] >> 1) ^ (0xe1000000U & (word32)(0 - carry));
20633
}
20634
20635
/* s = s * H. The accumulator is shifted right a nibble at a time; the nibble
20636
 * that falls off is reduced through AES_GCM_SIV_R into the top two bytes. */
20637
static void AesGcmSivGMult(AesGcmSivPolyval* poly)
20638
{
20639
    byte* x = poly->s;
20640
    word32 (*m)[4] = poly->m;
20641
    word32 z0 = 0, z1 = 0, z2 = 0, z3 = 0;
20642
    int i;
20643
20644
    for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
20645
        word32* mr;
20646
        byte xi = x[i];
20647
        byte a;
20648
20649
        /* low nibble */
20650
        mr = m[xi & 0xf];
20651
        z0 ^= mr[0]; z1 ^= mr[1]; z2 ^= mr[2]; z3 ^= mr[3];
20652
        a = (byte)(z3 & 0xf);
20653
        z3 = (z3 >> 4) | (z2 << 28);
20654
        z2 = (z2 >> 4) | (z1 << 28);
20655
        z1 = (z1 >> 4) | (z0 << 28);
20656
        z0 = z0 >> 4;
20657
        z0 ^= ((word32)AES_GCM_SIV_R[a][0] << 24) |
20658
              ((word32)AES_GCM_SIV_R[a][1] << 16);
20659
20660
        /* high nibble */
20661
        mr = m[xi >> 4];
20662
        z0 ^= mr[0]; z1 ^= mr[1]; z2 ^= mr[2]; z3 ^= mr[3];
20663
        if (i == 0) {
20664
            break;
20665
        }
20666
        a = (byte)(z3 & 0xf);
20667
        z3 = (z3 >> 4) | (z2 << 28);
20668
        z2 = (z2 >> 4) | (z1 << 28);
20669
        z1 = (z1 >> 4) | (z0 << 28);
20670
        z0 = z0 >> 4;
20671
        z0 ^= ((word32)AES_GCM_SIV_R[a][0] << 24) |
20672
              ((word32)AES_GCM_SIV_R[a][1] << 16);
20673
    }
20674
20675
    AesGcmSivStore32(x,      z0);
20676
    AesGcmSivStore32(x + 4,  z1);
20677
    AesGcmSivStore32(x + 8,  z2);
20678
    AesGcmSivStore32(x + 12, z3);
20679
}
20680
20681
/* Build the 4-bit table for mulX_GHASH(ByteReverse(h)). */
20682
static void AesGcmSivPolyvalInitSw(AesGcmSivPolyval* poly, const byte* h)
20683
{
20684
    byte hrev[WC_AES_BLOCK_SIZE];
20685
    word32 (*m)[4] = poly->m;
20686
    int i;
20687
20688
#ifdef WOLFSSL_CHECK_MEM_ZERO
20689
    /* hrev will hold ByteReverse(H), the per-message hash key; register from
20690
     * the top (baseline keeps it defined) so every exit reaches the
20691
     * ForceZero+Check below. */
20692
    XMEMSET(hrev, 0, sizeof(hrev));
20693
    wc_MemZero_Add("AesGcmSivPolyvalInitSw hrev", hrev, sizeof(hrev));
20694
#endif
20695
20696
    /* m[8] = 1 * H = mulX_GHASH(ByteReverse(h)); successive halvings give the
20697
     * power-of-two nibble entries. */
20698
    AesGcmSivByteReverse(hrev, h);
20699
    m[0x8][0] = AesGcmSivLoad32(hrev);
20700
    m[0x8][1] = AesGcmSivLoad32(hrev + 4);
20701
    m[0x8][2] = AesGcmSivLoad32(hrev + 8);
20702
    m[0x8][3] = AesGcmSivLoad32(hrev + 12);
20703
    AesGcmSivMulX32(m[0x8]);
20704
    XMEMCPY(m[0x4], m[0x8], sizeof(m[0x4])); AesGcmSivMulX32(m[0x4]);
20705
    XMEMCPY(m[0x2], m[0x4], sizeof(m[0x2])); AesGcmSivMulX32(m[0x2]);
20706
    XMEMCPY(m[0x1], m[0x2], sizeof(m[0x1])); AesGcmSivMulX32(m[0x1]);
20707
20708
    /* The rest are sums of those basis entries (i = high bit + remainder). */
20709
    m[0x0][0] = 0; m[0x0][1] = 0; m[0x0][2] = 0; m[0x0][3] = 0;
20710
    for (i = 0; i < 16; i++) {
20711
        static const byte hibit[16] =
20712
            { 0, 0, 0, 2, 0, 4, 4, 4, 0, 8, 8, 8, 8, 8, 8, 8 };
20713
        int top = hibit[i];
20714
        if (top != 0) {
20715
            m[i][0] = m[top][0] ^ m[i - top][0];
20716
            m[i][1] = m[top][1] ^ m[i - top][1];
20717
            m[i][2] = m[top][2] ^ m[i - top][2];
20718
            m[i][3] = m[top][3] ^ m[i - top][3];
20719
        }
20720
    }
20721
20722
    XMEMSET(poly->s, 0, sizeof(poly->s));
20723
    /* hrev held ByteReverse(H), the per-message hash key; wipe it. */
20724
    ForceZero(hrev, sizeof(hrev));
20725
#ifdef WOLFSSL_CHECK_MEM_ZERO
20726
    wc_MemZero_Check(hrev, sizeof(hrev));
20727
#endif
20728
}
20729
20730
#endif /* POLYVAL multiply variant */
20731
20732
#ifdef WC_POLYVAL_ASM_THUMB2
20733
/* Thumb-2: the single table POLYVAL variant. */
20734
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
20735
{
20736
    return &AES_GCMSIV_polyval_thumb2;
20737
}
20738
#elif defined(WC_POLYVAL_ASM_AARCH32)
20739
/* AArch32: crypto (vmull.p64) POLYVAL when the CPU implements PMULL, else the
20740
 * base (table) variant.  In a run-time dispatch build the choice is made per
20741
 * CPU - matching the flags Check_CPU_support_HwCrypto set on the Aes object,
20742
 * which AES-GCM-SIV keys through wc_AesSetKey; otherwise it is fixed at compile
20743
 * time. */
20744
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
20745
{
20746
#ifdef WOLFSSL_ARM32_AES_DISPATCH
20747
    cpuid_get_flags_ex(&cpuid_flags);
20748
    if (IS_ARM32_PMULL(cpuid_flags)) {
20749
        return &AES_GCMSIV_polyval_crypto;
20750
    }
20751
    /* The base multiply needs the word64 table (poly->m), which is not built
20752
     * for GCM_SMALL / GCM_WORD32; fall back to the C multiply there. */
20753
#ifdef WC_POLYVAL_ASM_AARCH32_BASE
20754
    return &AES_GCMSIV_polyval_base;
20755
#else
20756
    return NULL;
20757
#endif
20758
#elif !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
20759
    return &AES_GCMSIV_polyval_crypto;
20760
#elif defined(WC_POLYVAL_ASM_AARCH32_BASE)
20761
    return &AES_GCMSIV_polyval_base;
20762
#else
20763
    return NULL;
20764
#endif
20765
}
20766
#elif defined(WC_POLYVAL_ASM_AARCH64)
20767
/* Select the best available generated POLYVAL multiply: PMULL when the CPU has
20768
 * the crypto extension, else the 8-bit-pmul NEON variant, else the scalar base
20769
 * variant, else NULL to fall back to software. */
20770
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
20771
{
20772
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20773
    cpuid_get_flags_ex(&cpuid_flags);
20774
    if (IS_AARCH64_PMULL(cpuid_flags)) {
20775
        return &AES_GCMSIV_polyval_pmull;
20776
    }
20777
#endif
20778
#ifndef WOLFSSL_ARMASM_NO_NEON
20779
    return &AES_GCMSIV_polyval_neon;
20780
#elif defined(WC_POLYVAL_ASM_AARCH64_BASE)
20781
    return &AES_GCMSIV_polyval_base;
20782
#else
20783
    return NULL;
20784
#endif
20785
}
20786
#elif defined(WC_POLYVAL_ASM)
20787
/* Select the best available generated POLYVAL multiply for this CPU, or NULL
20788
 * to fall back to software. PCLMUL is present on every AES-NI capable CPU, so
20789
 * AES-NI gates the base path (matching wolfSSL's AES-GCM). */
20790
static AesGcmSivPolyvalFn AesGcmSivPolyvalAsm(void)
20791
{
20792
    cpuid_get_flags_ex(&intel_flags);
20793
    if (!IS_INTEL_AESNI(intel_flags)) {
20794
        return NULL;
20795
    }
20796
#ifdef HAVE_INTEL_AVX512
20797
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
20798
        return &AES_GCMSIV_polyval_avx512;
20799
    }
20800
#endif
20801
#ifdef HAVE_INTEL_VAES
20802
    if (IS_INTEL_VAES(intel_flags) && IS_INTEL_AVX2(intel_flags)) {
20803
        return &AES_GCMSIV_polyval_vaes;
20804
    }
20805
#endif
20806
#ifdef HAVE_INTEL_AVX1
20807
    if (IS_INTEL_AVX1(intel_flags)) {
20808
        return &AES_GCMSIV_polyval_avx1;
20809
    }
20810
#endif
20811
    return &AES_GCMSIV_polyval_aesni;
20812
}
20813
#endif
20814
20815
#ifdef WC_GCMSIV_CTR_ASM_THUMB2
20816
/* Thumb-2: the single table CTR variant. */
20817
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
20818
{
20819
    return &AES_GCMSIV_ctr_thumb2;
20820
}
20821
#elif defined(WC_GCMSIV_CTR_ASM_AARCH32)
20822
/* AArch32: crypto (aese) CTR when the CPU implements AES, else the base (table)
20823
 * variant.  The CTR keystream runs through the AES key schedule, so the variant
20824
 * must match how the key was expanded (Check_CPU_support_HwCrypto): the crypto
20825
 * schedule is taken only when both AES and PMULL are present. */
20826
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
20827
{
20828
#ifdef WOLFSSL_ARM32_AES_DISPATCH
20829
    cpuid_get_flags_ex(&cpuid_flags);
20830
    if (IS_ARM32_AES(cpuid_flags) && IS_ARM32_PMULL(cpuid_flags)) {
20831
        return &AES_GCMSIV_ctr_crypto;
20832
    }
20833
    return &AES_GCMSIV_ctr_base;
20834
#elif !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
20835
    return &AES_GCMSIV_ctr_crypto;
20836
#else
20837
    return &AES_GCMSIV_ctr_base;
20838
#endif
20839
}
20840
#elif defined(WC_GCMSIV_CTR_ASM_AARCH64)
20841
/* Select the best generated CTR keystream: pipelined aese when the CPU has the
20842
 * AES extension, else the NEON or base software-table variant, else NULL. */
20843
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
20844
{
20845
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
20846
    cpuid_get_flags_ex(&cpuid_flags);
20847
    if (IS_AARCH64_AES(cpuid_flags)) {
20848
        return &AES_GCMSIV_ctr_aarch64;
20849
    }
20850
#endif
20851
#ifndef WOLFSSL_ARMASM_NO_NEON
20852
    return &AES_GCMSIV_ctr_neon;
20853
#elif !defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
20854
    return &AES_GCMSIV_ctr_base;
20855
#else
20856
    return NULL;
20857
#endif
20858
}
20859
#elif defined(WC_GCMSIV_CTR_ASM)
20860
/* Select the best generated AES-GCM-SIV CTR keystream for this CPU. AES-NI is
20861
 * the base; AVX1/VAES/AVX512 are progressively wider pipelines. */
20862
static AesGcmSivCtrFn AesGcmSivCtrAsm(void)
20863
{
20864
    cpuid_get_flags_ex(&intel_flags);
20865
    if (!IS_INTEL_AESNI(intel_flags)) {
20866
        return NULL;
20867
    }
20868
#ifdef HAVE_INTEL_AVX512
20869
    if (IS_INTEL_AVX512(intel_flags) && IS_INTEL_VAES(intel_flags)) {
20870
        return &AES_GCMSIV_ctr_avx512;
20871
    }
20872
#endif
20873
#ifdef HAVE_INTEL_VAES
20874
    if (IS_INTEL_VAES(intel_flags) && IS_INTEL_AVX2(intel_flags)) {
20875
        return &AES_GCMSIV_ctr_vaes;
20876
    }
20877
#endif
20878
#ifdef HAVE_INTEL_AVX1
20879
    if (IS_INTEL_AVX1(intel_flags)) {
20880
        return &AES_GCMSIV_ctr_avx1;
20881
    }
20882
#endif
20883
    return &AES_GCMSIV_ctr_aesni;
20884
}
20885
#endif
20886
20887
/* Initialize POLYVAL with the 16-byte hash key h, using the generated assembly
20888
 * multiply when the CPU supports it and a software variant otherwise. */
20889
static void AesGcmSivPolyvalInit(AesGcmSivPolyval* poly, const byte* h)
20890
{
20891
#ifdef WC_POLYVAL_ASM
20892
    AesGcmSivPolyvalFn fn = AesGcmSivPolyvalAsm();
20893
    if (fn != NULL) {
20894
#if defined(WC_POLYVAL_ASM_AARCH64_BASE) || defined(WC_POLYVAL_ASM_AARCH32_BASE)
20895
        if (fn == &AES_GCMSIV_polyval_base) {
20896
            /* The scalar variant multiplies through the word64 software table,
20897
             * so build it and point the asm at it. */
20898
            AesGcmSivPolyvalInitSw(poly, h);
20899
            poly->asmKey = (const byte*)poly->m;
20900
            poly->fn = fn;
20901
            return;
20902
        }
20903
#endif
20904
#ifdef WC_POLYVAL_ASM_THUMB2
20905
        if (fn == &AES_GCMSIV_polyval_thumb2) {
20906
            /* Table variant: build the word64 software table and point at it. */
20907
            AesGcmSivPolyvalInitSw(poly, h);
20908
            poly->asmKey = (const byte*)poly->m;
20909
            poly->fn = fn;
20910
            return;
20911
        }
20912
#endif
20913
        {
20914
            byte t[WC_AES_BLOCK_SIZE];
20915
        #ifdef WOLFSSL_CHECK_MEM_ZERO
20916
            /* t will hold the prepared hash key; register from the top
20917
             * (baseline keeps it defined) so every exit of this block reaches
20918
             * the ForceZero+Check below. */
20919
            XMEMSET(t, 0, sizeof(t));
20920
            wc_MemZero_Add("AesGcmSivPolyvalInit t", t, sizeof(t));
20921
        #endif
20922
            /* Prepare the hash key for the asm: byte-reversed
20923
             * mulX_GHASH(ByteReverse(h)). */
20924
            AesGcmSivByteReverse(t, h);
20925
            AesGcmSivMulX(t);
20926
            AesGcmSivByteReverse(poly->hHw, t);
20927
            XMEMSET(poly->s, 0, sizeof(poly->s));
20928
            poly->asmKey = poly->hHw;
20929
            poly->fn = fn;
20930
            /* t held the prepared hash key; wipe the stack copy. */
20931
            ForceZero(t, sizeof(t));
20932
        #ifdef WOLFSSL_CHECK_MEM_ZERO
20933
            wc_MemZero_Check(t, sizeof(t));
20934
        #endif
20935
        }
20936
        return;
20937
    }
20938
    poly->fn = NULL;
20939
#endif
20940
    AesGcmSivPolyvalInitSw(poly, h);
20941
}
20942
20943
/* Add data to the POLYVAL sum. A trailing partial block is zero-padded to a
20944
 * full block, which is exactly the padding RFC 8452 applies to the AAD and
20945
 * the plaintext independently. */
20946
static void AesGcmSivPolyvalUpdate(AesGcmSivPolyval* poly, const byte* data,
20947
    word32 sz)
20948
{
20949
    byte block[WC_AES_BLOCK_SIZE];
20950
    byte rev[WC_AES_BLOCK_SIZE];
20951
    int k;
20952
20953
#ifdef WOLFSSL_CHECK_MEM_ZERO
20954
    /* block holds a padded AAD/plaintext block/tail in both the asm and the
20955
     * scalar path; register from the top (baseline keeps it defined) so every
20956
     * exit reaches a ForceZero+Check. */
20957
    XMEMSET(block, 0, sizeof(block));
20958
    wc_MemZero_Add("AesGcmSivPolyvalUpdate block", block, sizeof(block));
20959
#endif
20960
20961
#ifdef WC_POLYVAL_ASM
20962
    if (poly->fn != NULL) {
20963
        word32 blocks = sz / WC_AES_BLOCK_SIZE;
20964
        word32 partial = sz % WC_AES_BLOCK_SIZE;
20965
        if (blocks > 0) {
20966
            poly->fn(poly->s, poly->asmKey, data, blocks);
20967
            data += blocks * WC_AES_BLOCK_SIZE;
20968
        }
20969
        if (partial > 0) {
20970
            XMEMSET(block, 0, sizeof(block));
20971
            XMEMCPY(block, data, partial);
20972
            poly->fn(poly->s, poly->asmKey, block, 1);
20973
        }
20974
        /* block may have held a padded AAD/plaintext tail; wipe it. */
20975
        ForceZero(block, sizeof(block));
20976
    #ifdef WOLFSSL_CHECK_MEM_ZERO
20977
        wc_MemZero_Check(block, sizeof(block));
20978
    #endif
20979
        return;
20980
    }
20981
#endif
20982
#ifdef WOLFSSL_CHECK_MEM_ZERO
20983
    /* rev holds a byte-reversed AAD/plaintext block; only the scalar path uses
20984
     * it, so register it here (baseline covers the sz == 0 case). */
20985
    XMEMSET(rev, 0, sizeof(rev));
20986
    wc_MemZero_Add("AesGcmSivPolyvalUpdate rev", rev, sizeof(rev));
20987
#endif
20988
    while (sz >= WC_AES_BLOCK_SIZE) {
20989
        AesGcmSivByteReverse(rev, data);
20990
        for (k = 0; k < WC_AES_BLOCK_SIZE; k++) {
20991
            poly->s[k] ^= rev[k];
20992
        }
20993
        AesGcmSivGMult(poly);
20994
        data += WC_AES_BLOCK_SIZE;
20995
        sz   -= WC_AES_BLOCK_SIZE;
20996
    }
20997
    if (sz > 0) {
20998
        XMEMSET(block, 0, sizeof(block));
20999
        XMEMCPY(block, data, sz);
21000
        AesGcmSivByteReverse(rev, block);
21001
        for (k = 0; k < WC_AES_BLOCK_SIZE; k++) {
21002
            poly->s[k] ^= rev[k];
21003
        }
21004
        AesGcmSivGMult(poly);
21005
    }
21006
    /* block/rev held byte-reversed AAD/plaintext blocks; wipe them. */
21007
    ForceZero(block, sizeof(block));
21008
    ForceZero(rev, sizeof(rev));
21009
#ifdef WOLFSSL_CHECK_MEM_ZERO
21010
    wc_MemZero_Check(block, sizeof(block));
21011
    wc_MemZero_Check(rev, sizeof(rev));
21012
#endif
21013
}
21014
21015
/* Output the 16-byte POLYVAL result and wipe the key material and state. */
21016
static void AesGcmSivPolyvalFinal(AesGcmSivPolyval* poly, byte* out)
21017
{
21018
    AesGcmSivByteReverse(out, poly->s);
21019
    ForceZero(poly, sizeof(*poly));
21020
}
21021
21022
/* Derive the message-authentication-key and message-encryption-key from the
21023
 * key-generating-key (loaded into kgk) and the nonce. See RFC 8452 Section 4.
21024
 *
21025
 * authKey is 16 bytes; encKey is keySz bytes (16 or 32). */
21026
static WARN_UNUSED_RESULT int AesGcmSivDeriveKeys(Aes* kgk, const byte* nonce,
21027
    word32 keySz, byte* authKey, byte* encKey)
21028
{
21029
    byte block[WC_AES_BLOCK_SIZE];
21030
    byte out[WC_AES_BLOCK_SIZE];
21031
    word32 ctr;
21032
    word32 encBlocks = keySz / 8; /* 2 for AES-128, 4 for AES-256 */
21033
    int ret = 0;
21034
21035
    /* Each derivation block is: LE32(counter) || nonce(12 bytes). The low 8
21036
     * bytes of each AES output are concatenated to form the derived keys. */
21037
    XMEMCPY(block + 4, nonce, AES_GCM_SIV_NONCE_SZ);
21038
21039
#ifdef WOLFSSL_CHECK_MEM_ZERO
21040
    /* out receives the derived auth/enc key bytes from each AES block. */
21041
    XMEMSET(out, 0xff, sizeof(out));
21042
    wc_MemZero_Add("AesGcmSivDeriveKeys out", out, sizeof(out));
21043
#endif
21044
21045
    for (ctr = 0; ctr < 2; ctr++) {
21046
        block[0] = (byte)ctr;
21047
        block[1] = 0; block[2] = 0; block[3] = 0;
21048
        ret = wc_AesEncrypt(kgk, block, out);
21049
        if (ret != 0)
21050
            break;
21051
        XMEMCPY(authKey + ctr * 8, out, 8);
21052
    }
21053
21054
    for (ctr = 0; (ret == 0) && (ctr < encBlocks); ctr++) {
21055
        block[0] = (byte)(ctr + 2);
21056
        block[1] = 0; block[2] = 0; block[3] = 0;
21057
        ret = wc_AesEncrypt(kgk, block, out);
21058
        if (ret != 0)
21059
            break;
21060
        XMEMCPY(encKey + ctr * 8, out, 8);
21061
    }
21062
21063
    ForceZero(block, sizeof(block));
21064
    ForceZero(out, sizeof(out));
21065
#ifdef WOLFSSL_CHECK_MEM_ZERO
21066
    wc_MemZero_Check(out, sizeof(out));
21067
#endif
21068
21069
    return ret;
21070
}
21071
21072
/* Compute the AES-GCM-SIV tag over the AAD and plaintext. enc holds the
21073
 * message-encryption-key. See RFC 8452 Section 4. */
21074
static WARN_UNUSED_RESULT int AesGcmSivCalcTag(Aes* enc, const byte* authKey,
21075
    const byte* nonce, const byte* aad, word32 aadSz, const byte* plain,
21076
    word32 plainSz, byte* tag)
21077
{
21078
    AesGcmSivPolyval poly;
21079
    byte lenBlock[WC_AES_BLOCK_SIZE];
21080
    byte s[WC_AES_BLOCK_SIZE];
21081
    /* Bit lengths (sz * 8) as 64-bit values, computed without needing a
21082
     * 64-bit type: low 32 bits and the 3 bits that carry into the next word. */
21083
    word32 aadLo = aadSz << 3, aadHi = aadSz >> 29;
21084
    word32 ptLo  = plainSz << 3, ptHi = plainSz >> 29;
21085
    int i;
21086
    int ret;
21087
21088
#ifdef WOLFSSL_CHECK_MEM_ZERO
21089
    /* s holds the POLYVAL result then the pre-encryption tag input. Register
21090
     * from the top (single exit funnels to the ForceZero+Check below);
21091
     * baseline keeps it defined for the checker. */
21092
    XMEMSET(s, 0, sizeof(s));
21093
    wc_MemZero_Add("AesGcmSivCalcTag s", s, sizeof(s));
21094
#endif
21095
21096
    AesGcmSivPolyvalInit(&poly, authKey);
21097
    AesGcmSivPolyvalUpdate(&poly, aad, aadSz);
21098
    AesGcmSivPolyvalUpdate(&poly, plain, plainSz);
21099
21100
    /* Length block: LE64(aad_bits) || LE64(plaintext_bits). */
21101
    lenBlock[0]  = (byte)aadLo; lenBlock[1] = (byte)(aadLo >> 8);
21102
    lenBlock[2]  = (byte)(aadLo >> 16); lenBlock[3] = (byte)(aadLo >> 24);
21103
    lenBlock[4]  = (byte)aadHi; lenBlock[5] = (byte)(aadHi >> 8);
21104
    lenBlock[6]  = (byte)(aadHi >> 16); lenBlock[7] = (byte)(aadHi >> 24);
21105
    lenBlock[8]  = (byte)ptLo; lenBlock[9] = (byte)(ptLo >> 8);
21106
    lenBlock[10] = (byte)(ptLo >> 16); lenBlock[11] = (byte)(ptLo >> 24);
21107
    lenBlock[12] = (byte)ptHi; lenBlock[13] = (byte)(ptHi >> 8);
21108
    lenBlock[14] = (byte)(ptHi >> 16); lenBlock[15] = (byte)(ptHi >> 24);
21109
    AesGcmSivPolyvalUpdate(&poly, lenBlock, WC_AES_BLOCK_SIZE);
21110
21111
    AesGcmSivPolyvalFinal(&poly, s);
21112
21113
    /* XOR the nonce into the first 12 bytes and clear the top bit of the
21114
     * last byte, then encrypt to produce the tag. */
21115
    for (i = 0; i < AES_GCM_SIV_NONCE_SZ; i++) {
21116
        s[i] ^= nonce[i];
21117
    }
21118
    s[WC_AES_BLOCK_SIZE - 1] &= 0x7f;
21119
21120
    ret = wc_AesEncrypt(enc, s, tag);
21121
21122
    ForceZero(s, sizeof(s));
21123
#ifdef WOLFSSL_CHECK_MEM_ZERO
21124
    wc_MemZero_Check(s, sizeof(s));
21125
#endif
21126
    return ret;
21127
}
21128
21129
/* Apply AES-GCM-SIV's counter mode to in, producing out. enc holds the
21130
 * message-encryption-key, tag is the 16-byte authentication tag. The counter
21131
 * is the tag with the top bit of the last byte set; only the first 4 bytes
21132
 * are incremented, as a little-endian 32-bit value, wrapping modulo 2^32.
21133
 * See RFC 8452 Section 4. */
21134
static WARN_UNUSED_RESULT int AesGcmSivCtr(Aes* enc, const byte* tag,
21135
    const byte* in, word32 sz, byte* out)
21136
{
21137
    byte ctrBlock[WC_AES_BLOCK_SIZE];
21138
    byte ks[WC_AES_BLOCK_SIZE];
21139
    word32 c;
21140
    int ret = 0;
21141
21142
#ifdef WOLFSSL_CHECK_MEM_ZERO
21143
    /* ks holds the AES-CTR keystream block; register from the top (single
21144
     * exit funnels to the ForceZero+Check below). */
21145
    XMEMSET(ks, 0, sizeof(ks));
21146
    wc_MemZero_Add("AesGcmSivCtr ks", ks, sizeof(ks));
21147
#endif
21148
21149
    XMEMCPY(ctrBlock, tag, WC_AES_BLOCK_SIZE);
21150
    ctrBlock[WC_AES_BLOCK_SIZE - 1] |= 0x80;
21151
21152
#ifdef WC_GCMSIV_CTR_ASM
21153
    /* Offload the full-block keystream to the pipelined assembly; it advances
21154
     * and writes ctrBlock back. The final partial block (if any) is finished by
21155
     * the scalar loop below. */
21156
    {
21157
        AesGcmSivCtrFn fn = AesGcmSivCtrAsm();
21158
        if (fn != NULL) {
21159
            word32 full = sz & ~(word32)(WC_AES_BLOCK_SIZE - 1);
21160
            if (full > 0) {
21161
                fn(in, out, (unsigned long)full, (const byte*)enc->key,
21162
                    (int)enc->rounds, ctrBlock);
21163
                in  += full;
21164
                out += full;
21165
                sz  -= full;
21166
            }
21167
        }
21168
    }
21169
#endif
21170
21171
    c = (word32)ctrBlock[0]        | ((word32)ctrBlock[1] << 8) |
21172
        ((word32)ctrBlock[2] << 16) | ((word32)ctrBlock[3] << 24);
21173
21174
    while (sz > 0) {
21175
        word32 n = (sz < WC_AES_BLOCK_SIZE) ? sz : (word32)WC_AES_BLOCK_SIZE;
21176
        word32 i;
21177
21178
        ret = wc_AesEncrypt(enc, ctrBlock, ks);
21179
        if (ret != 0)
21180
            break;
21181
        for (i = 0; i < n; i++) {
21182
            out[i] = (byte)(in[i] ^ ks[i]);
21183
        }
21184
21185
        in  += n;
21186
        out += n;
21187
        sz  -= n;
21188
21189
        c++;
21190
        ctrBlock[0] = (byte)c;         ctrBlock[1] = (byte)(c >> 8);
21191
        ctrBlock[2] = (byte)(c >> 16); ctrBlock[3] = (byte)(c >> 24);
21192
    }
21193
21194
    ForceZero(ks, sizeof(ks));
21195
    ForceZero(ctrBlock, sizeof(ctrBlock));
21196
#ifdef WOLFSSL_CHECK_MEM_ZERO
21197
    wc_MemZero_Check(ks, sizeof(ks));
21198
#endif
21199
    return ret;
21200
}
21201
21202
/* Common validation for the encrypt/decrypt entry points. */
21203
static WARN_UNUSED_RESULT int AesGcmSivCheckArgs(const byte* key, word32 keySz,
21204
    const byte* nonce, word32 nonceSz, const byte* aad, word32 aadSz,
21205
    const byte* in, word32 inSz, const byte* out, const byte* tag,
21206
    word32 tagSz)
21207
{
21208
    if (key == NULL || nonce == NULL || tag == NULL) {
21209
        return BAD_FUNC_ARG;
21210
    }
21211
    if ((inSz != 0) && ((in == NULL) || (out == NULL))) {
21212
        return BAD_FUNC_ARG;
21213
    }
21214
    if ((aadSz != 0) && (aad == NULL)) {
21215
        return BAD_FUNC_ARG;
21216
    }
21217
    if ((keySz != 16) && (keySz != 32)) {
21218
        return BAD_FUNC_ARG;
21219
    }
21220
    if (nonceSz != AES_GCM_SIV_NONCE_SZ) {
21221
        return BAD_FUNC_ARG;
21222
    }
21223
    if (tagSz != AES_GCM_SIV_TAG_SZ) {
21224
        return BAD_FUNC_ARG;
21225
    }
21226
    return 0;
21227
}
21228
21229
/*
21230
 * Encrypt with AES-GCM-SIV. See RFC 8452 Section 4.
21231
 *
21232
 * out receives inSz bytes of ciphertext; tag receives the 16-byte tag.
21233
 */
21234
int wc_AesGcmSivEncrypt(const byte* key, word32 keySz, const byte* nonce,
21235
    word32 nonceSz, const byte* aad, word32 aadSz, const byte* in,
21236
    word32 inSz, byte* out, byte* tag, word32 tagSz)
21237
{
21238
    WC_DECLARE_VAR(aes, Aes, 1, 0);
21239
    byte authKey[WC_AES_BLOCK_SIZE];
21240
    byte encKey[32];
21241
    byte tagTmp[AES_GCM_SIV_TAG_SZ];
21242
    int ret;
21243
21244
#ifdef WOLFSSL_CHECK_MEM_ZERO
21245
    /* Derived per-message MAC key, encryption key, and tag. Register from the
21246
     * top; every exit funnels to the shared ForceZero+Check block below. */
21247
    XMEMSET(authKey, 0, sizeof(authKey));
21248
    XMEMSET(encKey, 0, sizeof(encKey));
21249
    XMEMSET(tagTmp, 0, sizeof(tagTmp));
21250
    wc_MemZero_Add("wc_AesGcmSivEncrypt authKey", authKey, sizeof(authKey));
21251
    wc_MemZero_Add("wc_AesGcmSivEncrypt encKey", encKey, sizeof(encKey));
21252
    wc_MemZero_Add("wc_AesGcmSivEncrypt tagTmp", tagTmp, sizeof(tagTmp));
21253
#endif
21254
21255
    ret = AesGcmSivCheckArgs(key, keySz, nonce, nonceSz, aad, aadSz, in, inSz,
21256
                             out, tag, tagSz);
21257
21258
    if (ret == 0) {
21259
    #ifdef WOLFSSL_SMALL_STACK
21260
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
21261
    #else
21262
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
21263
    #endif
21264
    }
21265
21266
    if (ret == 0) {
21267
        /* Load the key-generating-key and derive the per-message keys. */
21268
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
21269
        if (ret == 0) {
21270
            ret = AesGcmSivDeriveKeys(aes, nonce, keySz, authKey, encKey);
21271
        }
21272
        /* Switch the AES object to the message-encryption-key. */
21273
        if (ret == 0) {
21274
            ret = wc_AesSetKey(aes, encKey, keySz, NULL, AES_ENCRYPTION);
21275
        }
21276
        /* Tag is computed over the plaintext, then the plaintext is
21277
         * encrypted with the tag-derived counter. */
21278
        if (ret == 0) {
21279
            ret = AesGcmSivCalcTag(aes, authKey, nonce, aad, aadSz, in, inSz,
21280
                                   tagTmp);
21281
        }
21282
        if (ret == 0) {
21283
            ret = AesGcmSivCtr(aes, tagTmp, in, inSz, out);
21284
        }
21285
        if (ret == 0) {
21286
            XMEMCPY(tag, tagTmp, AES_GCM_SIV_TAG_SZ);
21287
        }
21288
21289
    #ifdef WOLFSSL_SMALL_STACK
21290
        wc_AesDelete(aes, NULL);
21291
    #else
21292
        wc_AesFree(aes);
21293
    #endif
21294
    }
21295
21296
    ForceZero(authKey, sizeof(authKey));
21297
    ForceZero(encKey, sizeof(encKey));
21298
    ForceZero(tagTmp, sizeof(tagTmp));
21299
#ifdef WOLFSSL_CHECK_MEM_ZERO
21300
    wc_MemZero_Check(authKey, sizeof(authKey));
21301
    wc_MemZero_Check(encKey, sizeof(encKey));
21302
    wc_MemZero_Check(tagTmp, sizeof(tagTmp));
21303
#endif
21304
21305
    return ret;
21306
}
21307
21308
/*
21309
 * Decrypt with AES-GCM-SIV. See RFC 8452 Section 4.
21310
 *
21311
 * in is inSz bytes of ciphertext, tag is the received 16-byte tag. On a
21312
 * successful authentication out receives inSz bytes of plaintext; on failure
21313
 * out is zeroed and AES_GCM_AUTH_E is returned.
21314
 */
21315
int wc_AesGcmSivDecrypt(const byte* key, word32 keySz, const byte* nonce,
21316
    word32 nonceSz, const byte* aad, word32 aadSz, const byte* in,
21317
    word32 inSz, byte* out, const byte* tag, word32 tagSz)
21318
{
21319
    WC_DECLARE_VAR(aes, Aes, 1, 0);
21320
    byte authKey[WC_AES_BLOCK_SIZE];
21321
    byte encKey[32];
21322
    byte expTag[AES_GCM_SIV_TAG_SZ];
21323
    int ret;
21324
21325
#ifdef WOLFSSL_CHECK_MEM_ZERO
21326
    /* Derived per-message MAC key, encryption key, and recomputed tag.
21327
     * Register from the top; every exit funnels to the shared ForceZero+Check
21328
     * block below. */
21329
    XMEMSET(authKey, 0, sizeof(authKey));
21330
    XMEMSET(encKey, 0, sizeof(encKey));
21331
    XMEMSET(expTag, 0, sizeof(expTag));
21332
    wc_MemZero_Add("wc_AesGcmSivDecrypt authKey", authKey, sizeof(authKey));
21333
    wc_MemZero_Add("wc_AesGcmSivDecrypt encKey", encKey, sizeof(encKey));
21334
    wc_MemZero_Add("wc_AesGcmSivDecrypt expTag", expTag, sizeof(expTag));
21335
#endif
21336
21337
    ret = AesGcmSivCheckArgs(key, keySz, nonce, nonceSz, aad, aadSz, in, inSz,
21338
                             out, tag, tagSz);
21339
21340
    if (ret == 0) {
21341
    #ifdef WOLFSSL_SMALL_STACK
21342
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
21343
    #else
21344
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
21345
    #endif
21346
    }
21347
21348
    if (ret == 0) {
21349
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
21350
        if (ret == 0) {
21351
            ret = AesGcmSivDeriveKeys(aes, nonce, keySz, authKey, encKey);
21352
        }
21353
        if (ret == 0) {
21354
            ret = wc_AesSetKey(aes, encKey, keySz, NULL, AES_ENCRYPTION);
21355
        }
21356
        /* Recover the plaintext, then recompute and verify the tag over it. */
21357
        if (ret == 0) {
21358
            ret = AesGcmSivCtr(aes, tag, in, inSz, out);
21359
        }
21360
        if (ret == 0) {
21361
            ret = AesGcmSivCalcTag(aes, authKey, nonce, aad, aadSz, out, inSz,
21362
                                   expTag);
21363
        }
21364
        if (ret == 0) {
21365
            if (ConstantCompare(expTag, tag, AES_GCM_SIV_TAG_SZ) != 0) {
21366
                ret = AES_GCM_AUTH_E;
21367
            }
21368
        }
21369
        if (ret != 0) {
21370
            ForceZero(out, inSz);
21371
        }
21372
21373
    #ifdef WOLFSSL_SMALL_STACK
21374
        wc_AesDelete(aes, NULL);
21375
    #else
21376
        wc_AesFree(aes);
21377
    #endif
21378
    }
21379
21380
    ForceZero(authKey, sizeof(authKey));
21381
    ForceZero(encKey, sizeof(encKey));
21382
    ForceZero(expTag, sizeof(expTag));
21383
#ifdef WOLFSSL_CHECK_MEM_ZERO
21384
    wc_MemZero_Check(authKey, sizeof(authKey));
21385
    wc_MemZero_Check(encKey, sizeof(encKey));
21386
    wc_MemZero_Check(expTag, sizeof(expTag));
21387
#endif
21388
21389
    return ret;
21390
}
21391
21392
#endif /* WOLFSSL_AESGCM_SIV */
21393
21394
#if defined(WOLFSSL_AES_EAX)
21395
21396
/*
21397
 * AES EAX one-shot API
21398
 * Encrypts input data and computes an auth tag over the input
21399
 * auth data and ciphertext
21400
 *
21401
 * Returns 0 on success
21402
 * Returns error code on failure
21403
 */
21404
int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
21405
                          const byte* in, word32 inSz,
21406
                          const byte* nonce, word32 nonceSz,
21407
                          /* output computed auth tag */
21408
                          byte* authTag, word32 authTagSz,
21409
                          /* input data to authenticate */
21410
                          const byte* authIn, word32 authInSz)
21411
{
21412
#if defined(WOLFSSL_SMALL_STACK)
21413
    AesEax *eax;
21414
#else
21415
    AesEax eax_mem;
21416
    AesEax *eax = &eax_mem;
21417
#endif
21418
    int ret;
21419
    int eaxInited = 0;
21420
21421
    if (key == NULL || nonce == NULL || authTag == NULL
21422
            || (inSz > 0 && (out == NULL || in == NULL))
21423
            || (authInSz > 0 && authIn == NULL)) {
21424
        return BAD_FUNC_ARG;
21425
    }
21426
21427
#if defined(WOLFSSL_SMALL_STACK)
21428
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
21429
                                 NULL,
21430
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
21431
        return MEMORY_E;
21432
    }
21433
#endif
21434
21435
    if ((ret = wc_AesEaxInit(eax,
21436
                             key, keySz,
21437
                             nonce, nonceSz,
21438
                             authIn, authInSz)) != 0) {
21439
        goto cleanup;
21440
    }
21441
    eaxInited = 1;
21442
21443
    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
21444
        goto cleanup;
21445
    }
21446
21447
    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
21448
        goto cleanup;
21449
    }
21450
21451
cleanup:
21452
    if (eaxInited)
21453
        wc_AesEaxFree(eax);
21454
#if defined(WOLFSSL_SMALL_STACK)
21455
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
21456
#endif
21457
    return ret;
21458
}
21459
21460
21461
/*
21462
 * AES EAX one-shot API
21463
 * Decrypts and authenticates data against a supplied auth tag
21464
 *
21465
 * Returns 0 on success
21466
 * Returns error code on failure
21467
 */
21468
int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
21469
                          const byte* in, word32 inSz,
21470
                          const byte* nonce, word32 nonceSz,
21471
                          /* auth tag to verify against */
21472
                          const byte* authTag, word32 authTagSz,
21473
                          /* input data to authenticate */
21474
                          const byte* authIn, word32 authInSz)
21475
{
21476
#if defined(WOLFSSL_SMALL_STACK)
21477
    AesEax *eax;
21478
#else
21479
    AesEax eax_mem;
21480
    AesEax *eax = &eax_mem;
21481
#endif
21482
    int ret;
21483
    int eaxInited = 0;
21484
21485
    if (key == NULL || nonce == NULL || authTag == NULL
21486
            || (inSz > 0 && (out == NULL || in == NULL))
21487
            || (authInSz > 0 && authIn == NULL)) {
21488
        return BAD_FUNC_ARG;
21489
    }
21490
21491
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ
21492
            || authTagSz > WC_AES_BLOCK_SIZE) {
21493
        return BAD_FUNC_ARG;
21494
    }
21495
21496
#if defined(WOLFSSL_SMALL_STACK)
21497
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
21498
                                 NULL,
21499
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
21500
        return MEMORY_E;
21501
    }
21502
#endif
21503
21504
    if ((ret = wc_AesEaxInit(eax,
21505
                             key, keySz,
21506
                             nonce, nonceSz,
21507
                             authIn, authInSz)) != 0) {
21508
21509
        goto cleanup;
21510
    }
21511
    eaxInited = 1;
21512
21513
    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
21514
        goto cleanup;
21515
    }
21516
21517
    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
21518
        goto cleanup;
21519
    }
21520
21521
cleanup:
21522
    if (eaxInited)
21523
        wc_AesEaxFree(eax);
21524
#if defined(WOLFSSL_SMALL_STACK)
21525
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
21526
#endif
21527
    return ret;
21528
}
21529
21530
21531
/*
21532
 * AES EAX Incremental API:
21533
 * Initializes an AES EAX encryption or decryption operation. This must be
21534
 * called before any other EAX APIs are used on the AesEax struct
21535
 *
21536
 * Returns 0 on success
21537
 * Returns error code on failure
21538
 */
21539
int  wc_AesEaxInit(AesEax* eax,
21540
                   const byte* key, word32 keySz,
21541
                   const byte* nonce, word32 nonceSz,
21542
                   const byte* authIn, word32 authInSz)
21543
{
21544
    int ret = 0;
21545
    word32 cmacSize;
21546
    int aesInited = 0;
21547
    int nonceCmacInited = 0;
21548
    int aadCmacInited = 0;
21549
21550
    if (eax == NULL || key == NULL ||  nonce == NULL) {
21551
        return BAD_FUNC_ARG;
21552
    }
21553
21554
    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
21555
21556
    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
21557
        goto out;
21558
    }
21559
    aesInited = 1;
21560
21561
    if ((ret = wc_AesSetKey(&eax->aes,
21562
                            key,
21563
                            keySz,
21564
                            NULL,
21565
                            AES_ENCRYPTION)) != 0) {
21566
        goto out;
21567
    }
21568
21569
    /*
21570
    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
21571
    *   N' = OMAC^0_K(N)
21572
    */
21573
    if ((ret = wc_InitCmac(&eax->nonceCmac,
21574
                           key,
21575
                           keySz,
21576
                           WC_CMAC_AES,
21577
                           NULL)) != 0) {
21578
        return ret;
21579
    }
21580
    nonceCmacInited = 1;
21581
21582
    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
21583
                             eax->prefixBuf,
21584
                             sizeof(eax->prefixBuf))) != 0) {
21585
        goto out;
21586
    }
21587
21588
    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
21589
        goto out;
21590
    }
21591
21592
    cmacSize = WC_AES_BLOCK_SIZE;
21593
    if ((ret = wc_CmacFinal(&eax->nonceCmac,
21594
                            eax->nonceCmacFinal,
21595
                            &cmacSize)) != 0) {
21596
        goto out;
21597
    }
21598
21599
    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
21600
        goto out;
21601
    }
21602
21603
    /*
21604
     * start the OMAC used to build the auth tag chunk for the AD .
21605
     * This CMAC is continued in subsequent update calls when more auth data is
21606
     * provided
21607
     *   H' = OMAC^1_K(H)
21608
     */
21609
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 1;
21610
    if ((ret = wc_InitCmac(&eax->aadCmac,
21611
                           key,
21612
                           keySz,
21613
                           WC_CMAC_AES,
21614
                           NULL)) != 0) {
21615
        goto out;
21616
    }
21617
    aadCmacInited = 1;
21618
21619
    if ((ret = wc_CmacUpdate(&eax->aadCmac,
21620
                             eax->prefixBuf,
21621
                             sizeof(eax->prefixBuf))) != 0) {
21622
        goto out;
21623
    }
21624
21625
    if (authIn != NULL) {
21626
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
21627
            goto out;
21628
        }
21629
    }
21630
21631
    /*
21632
     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
21633
     * updated in subsequent calls to encrypt/decrypt
21634
     *  C' = OMAC^2_K(C)
21635
     */
21636
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 2;
21637
    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
21638
                           key,
21639
                           keySz,
21640
                           WC_CMAC_AES,
21641
                           NULL)) != 0) {
21642
        goto out;
21643
    }
21644
21645
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
21646
                             eax->prefixBuf,
21647
                             sizeof(eax->prefixBuf))) != 0) {
21648
        goto out;
21649
    }
21650
21651
out:
21652
21653
    if (ret != 0) {
21654
        if (aesInited)
21655
            wc_AesFree(&eax->aes);
21656
        if (nonceCmacInited)
21657
            wc_CmacFree(&eax->nonceCmac);
21658
        if (aadCmacInited)
21659
            wc_CmacFree(&eax->aadCmac);
21660
    }
21661
21662
    return ret;
21663
}
21664
21665
21666
/*
21667
 * AES EAX Incremental API:
21668
 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
21669
 * the authentication stream
21670
 *
21671
 * Returns 0 on success
21672
 * Returns error code on failure
21673
 */
21674
int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
21675
                            const byte* in, word32 inSz,
21676
                            const byte* authIn, word32 authInSz)
21677
{
21678
    int ret;
21679
21680
    if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))
21681
            || (authInSz > 0 && authIn == NULL)) {
21682
        return BAD_FUNC_ARG;
21683
    }
21684
21685
    if (inSz > 0) {
21686
        /*
21687
         * Encrypt the plaintext using AES CTR
21688
         *  C = CTR(M)
21689
         */
21690
        if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
21691
            return ret;
21692
        }
21693
21694
        /*
21695
         * update OMAC with new ciphertext
21696
         *  C' = OMAC^2_K(C)
21697
         */
21698
        if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
21699
            return ret;
21700
        }
21701
    }
21702
21703
    /* If there exists new auth data, update the OMAC for that as well */
21704
    if (authIn != NULL) {
21705
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
21706
            return ret;
21707
        }
21708
    }
21709
21710
    return 0;
21711
}
21712
21713
21714
/*
21715
 * AES EAX Incremental API:
21716
 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
21717
 * the authentication stream
21718
 *
21719
 * Returns 0 on success
21720
 * Returns error code on failure
21721
 */
21722
int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
21723
                            const byte* in, word32 inSz,
21724
                            const byte* authIn, word32 authInSz)
21725
{
21726
    int ret;
21727
21728
    if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))
21729
            || (authInSz > 0 && authIn == NULL)) {
21730
        return BAD_FUNC_ARG;
21731
    }
21732
21733
    if (inSz > 0) {
21734
        /*
21735
         * Decrypt the plaintext using AES CTR
21736
         *  C = CTR(M)
21737
         */
21738
        if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
21739
            return ret;
21740
        }
21741
21742
        /*
21743
         * update OMAC with new ciphertext
21744
         *  C' = OMAC^2_K(C)
21745
         */
21746
        if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
21747
            return ret;
21748
        }
21749
    }
21750
21751
    /* If there exists new auth data, update the OMAC for that as well */
21752
    if (authIn != NULL) {
21753
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
21754
            return ret;
21755
        }
21756
    }
21757
21758
    return 0;
21759
}
21760
21761
21762
/*
21763
 * AES EAX Incremental API:
21764
 * Provides additional auth data information to the authentication
21765
 * stream for an authenticated encryption or decryption operation
21766
 *
21767
 * Returns 0 on success
21768
 * Returns error code on failure
21769
 */
21770
int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
21771
{
21772
    if (eax == NULL) {
21773
        return BAD_FUNC_ARG;
21774
    }
21775
    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
21776
}
21777
21778
21779
/*
21780
 * AES EAX Incremental API:
21781
 * Finalizes the authenticated encryption operation, computing the auth tag
21782
 * over previously supplied auth data and computed ciphertext
21783
 *
21784
 * Returns 0 on success
21785
 * Returns error code on failure
21786
 */
21787
int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
21788
{
21789
    word32 cmacSize;
21790
    int ret;
21791
    word32 i;
21792
21793
    if (eax == NULL || authTag == NULL || authTagSz == 0 ||
21794
            authTagSz > WC_AES_BLOCK_SIZE || authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
21795
        return BAD_FUNC_ARG;
21796
    }
21797
21798
    /* Complete the OMAC for the ciphertext */
21799
    cmacSize = WC_AES_BLOCK_SIZE;
21800
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
21801
                                  eax->ciphertextCmacFinal,
21802
                                  &cmacSize)) != 0) {
21803
        return ret;
21804
    }
21805
21806
    /* Complete the OMAC for auth data */
21807
    cmacSize = WC_AES_BLOCK_SIZE;
21808
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
21809
                                  eax->aadCmacFinal,
21810
                                  &cmacSize)) != 0) {
21811
        return ret;
21812
    }
21813
21814
    /*
21815
     * Concatenate all three auth tag chunks into the final tag, truncating
21816
     * at the specified tag length
21817
     *   T = Tag [first authTagSz bytes]
21818
     */
21819
    for (i = 0; i < authTagSz; i++) {
21820
        authTag[i] = eax->nonceCmacFinal[i]
21821
                    ^ eax->aadCmacFinal[i]
21822
                    ^ eax->ciphertextCmacFinal[i];
21823
    }
21824
21825
    return 0;
21826
}
21827
21828
21829
/*
21830
 * AES EAX Incremental API:
21831
 * Finalizes the authenticated decryption operation, computing the auth tag
21832
 * for the previously supplied auth data and cipher text and validating it
21833
 * against a provided auth tag
21834
 *
21835
 * Returns 0 on success
21836
 * Return error code for failure
21837
 */
21838
int wc_AesEaxDecryptFinal(AesEax* eax,
21839
                          const byte* authIn, word32 authInSz)
21840
{
21841
    int ret;
21842
    word32 i;
21843
    word32 cmacSize;
21844
21845
#if defined(WOLFSSL_SMALL_STACK)
21846
    byte *authTag;
21847
#else
21848
    byte authTag[WC_AES_BLOCK_SIZE];
21849
#endif
21850
21851
    if (eax == NULL || authIn == NULL || authInSz > WC_AES_BLOCK_SIZE
21852
            || authInSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
21853
        return BAD_FUNC_ARG;
21854
    }
21855
21856
    /* Complete the OMAC for the ciphertext */
21857
    cmacSize = WC_AES_BLOCK_SIZE;
21858
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
21859
                                  eax->ciphertextCmacFinal,
21860
                                  &cmacSize)) != 0) {
21861
        return ret;
21862
    }
21863
21864
    /* Complete the OMAC for auth data */
21865
    cmacSize = WC_AES_BLOCK_SIZE;
21866
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
21867
                                  eax->aadCmacFinal,
21868
                                  &cmacSize)) != 0) {
21869
        return ret;
21870
    }
21871
21872
#if defined(WOLFSSL_SMALL_STACK)
21873
    authTag = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21874
    if (authTag == NULL) {
21875
        return MEMORY_E;
21876
    }
21877
#endif
21878
21879
    /*
21880
     * Concatenate all three auth tag chunks into the final tag, truncating
21881
     * at the specified tag length
21882
     *   T = Tag [first authInSz bytes]
21883
     */
21884
    for (i = 0; i < authInSz; i++) {
21885
        authTag[i] = eax->nonceCmacFinal[i]
21886
                    ^ eax->aadCmacFinal[i]
21887
                    ^ eax->ciphertextCmacFinal[i];
21888
    }
21889
21890
    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
21891
        ret = AES_EAX_AUTH_E;
21892
    }
21893
    else {
21894
        ret = 0;
21895
    }
21896
21897
#if defined(WOLFSSL_SMALL_STACK)
21898
    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
21899
#endif
21900
21901
    return ret;
21902
}
21903
21904
/*
21905
 * Frees the underlying CMAC and AES contexts. Must be called when done using
21906
 * the AES EAX context structure.
21907
 *
21908
 * Returns 0 on success
21909
 * Returns error code on failure
21910
 */
21911
int wc_AesEaxFree(AesEax* eax)
21912
{
21913
    if (eax == NULL) {
21914
        return BAD_FUNC_ARG;
21915
    }
21916
21917
    (void)wc_CmacFree(&eax->ciphertextCmac);
21918
    (void)wc_CmacFree(&eax->aadCmac);
21919
    wc_AesFree(&eax->aes);
21920
21921
    return 0;
21922
}
21923
21924
#endif /* WOLFSSL_AES_EAX */
21925
21926
#ifdef WOLFSSL_AES_CTS
21927
21928
21929
/* One-shot API */
21930
int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out,
21931
                     const byte* in, word32 inSz,
21932
                     const byte* iv)
21933
{
21934
    WC_DECLARE_VAR(aes, Aes, 1, 0);
21935
    int ret = 0;
21936
    word32 outSz = inSz;
21937
21938
    if (key == NULL || out == NULL || in == NULL || iv == NULL)
21939
        return BAD_FUNC_ARG;
21940
21941
#ifdef WOLFSSL_SMALL_STACK
21942
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
21943
#else
21944
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
21945
#endif
21946
    if (ret == 0)
21947
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
21948
    if (ret == 0)
21949
        ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz);
21950
    if (ret == 0) {
21951
        out += outSz;
21952
        outSz = inSz - outSz;
21953
        ret = wc_AesCtsEncryptFinal(aes, out, &outSz);
21954
    }
21955
21956
#ifdef WOLFSSL_SMALL_STACK
21957
    wc_AesDelete(aes, NULL);
21958
#else
21959
    wc_AesFree(aes);
21960
#endif
21961
    return ret;
21962
}
21963
21964
int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out,
21965
                     const byte* in, word32 inSz,
21966
                     const byte* iv)
21967
{
21968
    WC_DECLARE_VAR(aes, Aes, 1, 0);
21969
    int ret = 0;
21970
    word32 outSz = inSz;
21971
21972
    if (key == NULL || out == NULL || in == NULL || iv == NULL) {
21973
        return BAD_FUNC_ARG;
21974
    }
21975
21976
#ifdef WOLFSSL_SMALL_STACK
21977
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
21978
#else
21979
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
21980
#endif
21981
    if (ret == 0)
21982
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
21983
    if (ret == 0)
21984
        ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz);
21985
    if (ret == 0) {
21986
        out += outSz;
21987
        outSz = inSz - outSz;
21988
        ret = wc_AesCtsDecryptFinal(aes, out, &outSz);
21989
    }
21990
21991
#ifdef WOLFSSL_SMALL_STACK
21992
    wc_AesDelete(aes, NULL);
21993
#else
21994
    wc_AesFree(aes);
21995
#endif
21996
    return ret;
21997
}
21998
21999
static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz,
22000
                        const byte* in, word32 inSz, int enc)
22001
{
22002
    word32 blocks = 0;
22003
    int ret = 0;
22004
    word32 writtenSz = 0;
22005
    word32 tmpOutSz;
22006
22007
    if (aes == NULL || out == NULL || in == NULL || outSz == NULL)
22008
        return BAD_FUNC_ARG;
22009
22010
    /* Error out early for easy sanity check */
22011
    if (*outSz < inSz)
22012
        return BUFFER_E;
22013
    tmpOutSz = *outSz;
22014
22015
    /* We need to store last two blocks of plaintext */
22016
    if (aes->left > 0) {
22017
        word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left);
22018
        XMEMCPY(aes->ctsBlock + aes->left, in, copySz);
22019
        aes->left += copySz;
22020
        in += copySz;
22021
        inSz -= copySz;
22022
22023
        if (aes->left == WC_AES_BLOCK_SIZE * 2) {
22024
            if (inSz > WC_AES_BLOCK_SIZE) {
22025
                if (tmpOutSz < WC_AES_BLOCK_SIZE * 2)
22026
                    return BUFFER_E;
22027
                if (enc) {
22028
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
22029
                                           WC_AES_BLOCK_SIZE * 2);
22030
                }
22031
                else {
22032
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
22033
                                           WC_AES_BLOCK_SIZE * 2);
22034
                }
22035
                if (ret != 0)
22036
                    return ret;
22037
                out += WC_AES_BLOCK_SIZE * 2;
22038
                writtenSz += WC_AES_BLOCK_SIZE * 2;
22039
                tmpOutSz -= WC_AES_BLOCK_SIZE * 2;
22040
                aes->left = 0;
22041
            }
22042
            else if (inSz > 0) {
22043
                if (tmpOutSz < WC_AES_BLOCK_SIZE)
22044
                    return BUFFER_E;
22045
                if (enc) {
22046
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
22047
                                           WC_AES_BLOCK_SIZE);
22048
                }
22049
                else {
22050
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
22051
                                           WC_AES_BLOCK_SIZE);
22052
                }
22053
                if (ret != 0)
22054
                    return ret;
22055
                out += WC_AES_BLOCK_SIZE;
22056
                writtenSz += WC_AES_BLOCK_SIZE;
22057
                tmpOutSz -= WC_AES_BLOCK_SIZE;
22058
                /* Move the last block in ctsBlock to the beginning for
22059
                 * next operation */
22060
                XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE,
22061
                        WC_AES_BLOCK_SIZE);
22062
                XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz);
22063
                aes->left = WC_AES_BLOCK_SIZE + inSz;
22064
                *outSz = writtenSz;
22065
                return ret; /* Return the result of encryption */
22066
            }
22067
            else {
22068
                /* Can't output data as we need > 1 block for Final call */
22069
                *outSz = writtenSz;
22070
                return 0;
22071
            }
22072
        }
22073
        else {
22074
            /* All input has been absorbed into aes->ctsBlock */
22075
            *outSz = 0;
22076
            return 0;
22077
        }
22078
    }
22079
    if (inSz > WC_AES_BLOCK_SIZE) {
22080
        /* We need to store the last two full or partial blocks */
22081
        blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE;
22082
        blocks -= 2;
22083
    }
22084
    if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE)
22085
        return BUFFER_E;
22086
    if (enc)
22087
        ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
22088
    else
22089
        ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
22090
    in += blocks * WC_AES_BLOCK_SIZE;
22091
    inSz -= blocks * WC_AES_BLOCK_SIZE;
22092
    XMEMCPY(aes->ctsBlock, in, inSz);
22093
    aes->left = inSz;
22094
    writtenSz += blocks * WC_AES_BLOCK_SIZE;
22095
    *outSz = writtenSz;
22096
    return ret;
22097
}
22098
22099
/* Incremental API */
22100
int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz,
22101
                           const byte* in, word32 inSz)
22102
{
22103
    return AesCtsUpdate(aes, out, outSz, in, inSz, 1);
22104
}
22105
22106
int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz)
22107
{
22108
    int ret = 0;
22109
22110
    if (aes == NULL || out == NULL || outSz == NULL)
22111
        return BAD_FUNC_ARG;
22112
    if (*outSz < aes->left)
22113
        return BUFFER_E;
22114
22115
    /* Input must be at least two complete or partial blocks */
22116
    if (aes->left <= WC_AES_BLOCK_SIZE)
22117
        return BAD_FUNC_ARG;
22118
22119
    /* Zero padding */
22120
    XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left);
22121
22122
    ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock,
22123
                           WC_AES_BLOCK_SIZE * 2);
22124
    if (ret != 0)
22125
        return ret;
22126
22127
    XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
22128
    XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock,
22129
            aes->left - WC_AES_BLOCK_SIZE);
22130
    *outSz = aes->left;
22131
    return ret;
22132
}
22133
22134
int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz,
22135
                           const byte* in, word32 inSz)
22136
{
22137
    return AesCtsUpdate(aes, out, outSz, in, inSz, 0);
22138
}
22139
22140
int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz)
22141
{
22142
    int ret = 0;
22143
    byte iv[WC_AES_BLOCK_SIZE];
22144
    byte tmp[WC_AES_BLOCK_SIZE];
22145
    word32 partialSz;
22146
    word32 padSz;
22147
22148
    if (aes == NULL || out == NULL || outSz == NULL)
22149
        return BAD_FUNC_ARG;
22150
    if (*outSz < aes->left)
22151
        return BUFFER_E;
22152
22153
    /* Input must be at least two complete or partial blocks */
22154
    if (aes->left <= WC_AES_BLOCK_SIZE)
22155
        return BAD_FUNC_ARG;
22156
22157
    partialSz = aes->left - WC_AES_BLOCK_SIZE;
22158
    padSz = 2 * WC_AES_BLOCK_SIZE - aes->left;
22159
    /* Zero pad */
22160
    XMEMSET(aes->ctsBlock + aes->left, 0, padSz);
22161
22162
    /* Store IV */
22163
    XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE);
22164
    /* Load IV */
22165
    XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
22166
22167
    ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE);
22168
    if (ret != 0)
22169
        return ret;
22170
22171
    /* Write out partial block */
22172
    XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz);
22173
    /* Retrieve the padding */
22174
    XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz);
22175
    /* Restore IV */
22176
    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
22177
22178
    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE,
22179
                           WC_AES_BLOCK_SIZE);
22180
    if (ret != 0)
22181
        return ret;
22182
22183
    *outSz = aes->left;
22184
    return ret;
22185
}
22186
22187
#endif /* WOLFSSL_AES_CTS */
22188
22189
#endif /* !NO_AES */