Coverage Report

Created: 2025-06-23 06:10

/src/wolfssl/wolfcrypt/src/aes.c
Line
Count
Source (jump to first uncovered line)
1
/* aes.c
2
 *
3
 * Copyright (C) 2006-2025 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 2 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
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
33
34
#if !defined(NO_AES)
35
36
/* Tip: Locate the software cipher modes by searching for "Software AES" */
37
38
#if FIPS_VERSION3_GE(2,0,0)
39
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
40
    #define FIPS_NO_WRAPPERS
41
42
    #ifdef USE_WINDOWS_API
43
        #pragma code_seg(".fipsA$b")
44
        #pragma const_seg(".fipsB$b")
45
    #endif
46
#endif
47
48
#include <wolfssl/wolfcrypt/aes.h>
49
50
#ifdef WOLFSSL_AESNI
51
#include <wmmintrin.h>
52
#include <emmintrin.h>
53
#include <smmintrin.h>
54
#endif /* WOLFSSL_AESNI */
55
56
#include <wolfssl/wolfcrypt/cpuid.h>
57
58
#ifdef WOLF_CRYPTO_CB
59
    #include <wolfssl/wolfcrypt/cryptocb.h>
60
#endif
61
62
#ifdef WOLFSSL_SECO_CAAM
63
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
64
#endif
65
66
#ifdef WOLFSSL_IMXRT_DCP
67
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
68
#endif
69
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
70
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
71
#endif
72
73
#if defined(WOLFSSL_AES_SIV)
74
    #include <wolfssl/wolfcrypt/cmac.h>
75
#endif /* WOLFSSL_AES_SIV */
76
77
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
78
    #include <wolfssl/wolfcrypt/port/psa/psa.h>
79
#endif
80
81
#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
82
    #include <wolfssl/wolfcrypt/port/maxim/max3266x.h>
83
#ifdef MAX3266X_CB
84
    /* Revert back to SW so HW CB works */
85
    /* HW only works for AES: ECB, CBC, and partial via ECB for other modes */
86
    #include <wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h>
87
    /* Turn off MAX3266X_AES in the context of this file when using CB */
88
    #undef MAX3266X_AES
89
#endif
90
#endif
91
92
#if defined(WOLFSSL_TI_CRYPT)
93
    #include <wolfcrypt/src/port/ti/ti-aes.c>
94
#else
95
96
#ifdef NO_INLINE
97
    #include <wolfssl/wolfcrypt/misc.h>
98
#else
99
    #define WOLFSSL_MISC_INCLUDED
100
    #include <wolfcrypt/src/misc.c>
101
#endif
102
103
#if (!defined(WOLFSSL_ARMASM) || defined(__aarch64__)) && \
104
    !defined(WOLFSSL_RISCV_ASM)
105
106
#ifdef WOLFSSL_IMX6_CAAM_BLOB
107
    /* case of possibly not using hardware acceleration for AES but using key
108
       blobs */
109
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
110
#endif
111
112
#ifdef DEBUG_AESNI
113
    #include <stdio.h>
114
#endif
115
116
#ifdef _MSC_VER
117
    /* 4127 warning constant while(1)  */
118
    #pragma warning(disable: 4127)
119
#endif
120
121
#if !defined(WOLFSSL_ARMASM) && FIPS_VERSION3_GE(6,0,0)
122
    const unsigned int wolfCrypt_FIPS_aes_ro_sanity[2] =
123
                                                     { 0x1a2b3c4d, 0x00000002 };
124
    int wolfCrypt_FIPS_AES_sanity(void)
125
    {
126
        return 0;
127
    }
128
#endif
129
130
/* Define AES implementation includes and functions */
131
#if defined(STM32_CRYPTO)
132
     /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
133
134
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
135
136
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
137
        Aes* aes, const byte* inBlock, byte* outBlock)
138
    {
139
        int ret = 0;
140
    #ifdef WOLFSSL_STM32_CUBEMX
141
        CRYP_HandleTypeDef hcryp;
142
    #else
143
        CRYP_InitTypeDef cryptInit;
144
        CRYP_KeyInitTypeDef keyInit;
145
    #endif
146
147
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
148
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
149
        if (ret < 0)
150
            return ret;
151
#endif
152
153
    #ifdef WOLFSSL_STM32_CUBEMX
154
        ret = wc_Stm32_Aes_Init(aes, &hcryp);
155
        if (ret != 0)
156
            return ret;
157
158
        ret = wolfSSL_CryptHwMutexLock();
159
        if (ret != 0)
160
            return ret;
161
162
    #if defined(STM32_HAL_V2)
163
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
164
    #elif defined(STM32_CRYPTO_AES_ONLY)
165
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
166
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
167
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
168
    #endif
169
        HAL_CRYP_Init(&hcryp);
170
171
    #if defined(STM32_HAL_V2)
172
        ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
173
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
174
    #elif defined(STM32_CRYPTO_AES_ONLY)
175
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
176
            outBlock, STM32_HAL_TIMEOUT);
177
    #else
178
        ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
179
            outBlock, STM32_HAL_TIMEOUT);
180
    #endif
181
        if (ret != HAL_OK) {
182
            ret = WC_TIMEOUT_E;
183
        }
184
        HAL_CRYP_DeInit(&hcryp);
185
186
    #else /* Standard Peripheral Library */
187
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
188
        if (ret != 0)
189
            return ret;
190
191
        ret = wolfSSL_CryptHwMutexLock();
192
        if (ret != 0)
193
            return ret;
194
195
        /* reset registers to their default values */
196
        CRYP_DeInit();
197
198
        /* setup key */
199
        CRYP_KeyInit(&keyInit);
200
201
        /* set direction and mode */
202
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
203
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
204
        CRYP_Init(&cryptInit);
205
206
        /* enable crypto processor */
207
        CRYP_Cmd(ENABLE);
208
209
        /* flush IN/OUT FIFOs */
210
        CRYP_FIFOFlush();
211
212
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
213
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
214
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
215
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
216
217
        /* wait until the complete message has been processed */
218
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
219
220
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
221
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
222
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
223
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
224
225
        /* disable crypto processor */
226
        CRYP_Cmd(DISABLE);
227
    #endif /* WOLFSSL_STM32_CUBEMX */
228
        wolfSSL_CryptHwMutexUnLock();
229
        wc_Stm32_Aes_Cleanup();
230
231
        return ret;
232
    }
233
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
234
235
#ifdef HAVE_AES_DECRYPT
236
    #if defined(WOLFSSL_AES_DIRECT)
237
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
238
        Aes* aes, const byte* inBlock, byte* outBlock)
239
    {
240
        int ret = 0;
241
    #ifdef WOLFSSL_STM32_CUBEMX
242
        CRYP_HandleTypeDef hcryp;
243
    #else
244
        CRYP_InitTypeDef cryptInit;
245
        CRYP_KeyInitTypeDef keyInit;
246
    #endif
247
248
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
249
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
250
        if (ret < 0)
251
            return ret;
252
#endif
253
254
    #ifdef WOLFSSL_STM32_CUBEMX
255
        ret = wc_Stm32_Aes_Init(aes, &hcryp);
256
        if (ret != 0)
257
            return ret;
258
259
        ret = wolfSSL_CryptHwMutexLock();
260
        if (ret != 0)
261
            return ret;
262
263
    #if defined(STM32_HAL_V2)
264
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
265
    #elif defined(STM32_CRYPTO_AES_ONLY)
266
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
267
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
268
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
269
    #endif
270
        HAL_CRYP_Init(&hcryp);
271
272
    #if defined(STM32_HAL_V2)
273
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
274
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
275
    #elif defined(STM32_CRYPTO_AES_ONLY)
276
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
277
            outBlock, STM32_HAL_TIMEOUT);
278
    #else
279
        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
280
            outBlock, STM32_HAL_TIMEOUT);
281
    #endif
282
        if (ret != HAL_OK) {
283
            ret = WC_TIMEOUT_E;
284
        }
285
        HAL_CRYP_DeInit(&hcryp);
286
287
    #else /* Standard Peripheral Library */
288
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
289
        if (ret != 0)
290
            return ret;
291
292
        ret = wolfSSL_CryptHwMutexLock();
293
        if (ret != 0)
294
            return ret;
295
296
        /* reset registers to their default values */
297
        CRYP_DeInit();
298
299
        /* set direction and key */
300
        CRYP_KeyInit(&keyInit);
301
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
302
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
303
        CRYP_Init(&cryptInit);
304
305
        /* enable crypto processor */
306
        CRYP_Cmd(ENABLE);
307
308
        /* wait until decrypt key has been initialized */
309
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
310
311
        /* set direction and mode */
312
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
313
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
314
        CRYP_Init(&cryptInit);
315
316
        /* enable crypto processor */
317
        CRYP_Cmd(ENABLE);
318
319
        /* flush IN/OUT FIFOs */
320
        CRYP_FIFOFlush();
321
322
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
323
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
324
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
325
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
326
327
        /* wait until the complete message has been processed */
328
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
329
330
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
331
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
332
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
333
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
334
335
        /* disable crypto processor */
336
        CRYP_Cmd(DISABLE);
337
    #endif /* WOLFSSL_STM32_CUBEMX */
338
        wolfSSL_CryptHwMutexUnLock();
339
        wc_Stm32_Aes_Cleanup();
340
341
        return ret;
342
    }
343
    #endif /* WOLFSSL_AES_DIRECT */
344
#endif /* HAVE_AES_DECRYPT */
345
346
#elif defined(HAVE_COLDFIRE_SEC)
347
    /* Freescale Coldfire SEC support for CBC mode.
348
     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
349
    #include "sec.h"
350
    #include "mcf5475_sec.h"
351
    #include "mcf5475_siu.h"
352
#elif defined(FREESCALE_LTC)
353
    #include "fsl_ltc.h"
354
    #if defined(FREESCALE_LTC_AES_GCM)
355
        #undef NEED_AES_TABLES
356
        #undef GCM_TABLE
357
    #endif
358
359
        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
360
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
361
            Aes* aes, const byte* inBlock, byte* outBlock)
362
        {
363
            word32 keySize = 0;
364
            byte* key = (byte*)aes->key;
365
            int ret = wc_AesGetKeySize(aes, &keySize);
366
            if (ret != 0)
367
                return ret;
368
369
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
370
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
371
            if (ret < 0)
372
                return ret;
373
#endif
374
375
            if (wolfSSL_CryptHwMutexLock() == 0) {
376
                LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
377
                    key, keySize);
378
                wolfSSL_CryptHwMutexUnLock();
379
            }
380
            return 0;
381
        }
382
        #ifdef HAVE_AES_DECRYPT
383
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
384
            Aes* aes, const byte* inBlock, byte* outBlock)
385
        {
386
            word32 keySize = 0;
387
            byte* key = (byte*)aes->key;
388
            int ret = wc_AesGetKeySize(aes, &keySize);
389
            if (ret != 0)
390
                return ret;
391
392
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
393
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
394
            if (ret < 0)
395
                return ret;
396
#endif
397
398
            if (wolfSSL_CryptHwMutexLock() == 0) {
399
                LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
400
                    key, keySize, kLTC_EncryptKey);
401
                wolfSSL_CryptHwMutexUnLock();
402
            }
403
            return 0;
404
        }
405
        #endif
406
407
#elif defined(FREESCALE_MMCAU)
408
    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
409
     * through the CAU/mmCAU library. Documentation located in
410
     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
411
     * Guide (See note in README). */
412
    #ifdef FREESCALE_MMCAU_CLASSIC
413
        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
414
        #include "cau_api.h"
415
    #else
416
        #include "fsl_mmcau.h"
417
    #endif
418
419
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
420
        Aes* aes, const byte* inBlock, byte* outBlock)
421
    {
422
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
423
        {
424
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
425
            if (ret < 0)
426
                return ret;
427
        }
428
#endif
429
430
        if (wolfSSL_CryptHwMutexLock() == 0) {
431
        #ifdef FREESCALE_MMCAU_CLASSIC
432
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
433
                WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
434
                return BAD_ALIGN_E;
435
            }
436
            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
437
        #else
438
            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
439
                                 outBlock);
440
        #endif
441
            wolfSSL_CryptHwMutexUnLock();
442
        }
443
        return 0;
444
    }
445
    #ifdef HAVE_AES_DECRYPT
446
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
447
        Aes* aes, const byte* inBlock, byte* outBlock)
448
    {
449
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
450
        {
451
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
452
            if (ret < 0)
453
                return ret;
454
        }
455
#endif
456
        if (wolfSSL_CryptHwMutexLock() == 0) {
457
        #ifdef FREESCALE_MMCAU_CLASSIC
458
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
459
                WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
460
                return BAD_ALIGN_E;
461
            }
462
            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
463
        #else
464
            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
465
                                 outBlock);
466
        #endif
467
            wolfSSL_CryptHwMutexUnLock();
468
        }
469
        return 0;
470
    }
471
    #endif /* HAVE_AES_DECRYPT */
472
473
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
474
475
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
476
477
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
478
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
479
        Aes* aes, const byte* inBlock, byte* outBlock)
480
    {
481
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
482
        {
483
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
484
            if (ret < 0)
485
                return ret;
486
        }
487
#endif
488
        /* Thread mutex protection handled in Pic32Crypto */
489
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
490
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
491
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
492
    }
493
    #endif
494
495
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
496
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
497
        Aes* aes, const byte* inBlock, byte* outBlock)
498
    {
499
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
500
        {
501
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
502
            if (ret < 0)
503
                return ret;
504
        }
505
#endif
506
        /* Thread mutex protection handled in Pic32Crypto */
507
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
508
            outBlock, inBlock, WC_AES_BLOCK_SIZE,
509
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
510
    }
511
    #endif
512
513
#elif defined(WOLFSSL_NRF51_AES)
514
    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
515
    #include "wolfssl/wolfcrypt/port/nrf51.h"
516
517
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
518
        Aes* aes, const byte* inBlock, byte* outBlock)
519
    {
520
        int ret;
521
522
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
523
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
524
        if (ret < 0)
525
            return ret;
526
#endif
527
528
        ret = wolfSSL_CryptHwMutexLock();
529
        if (ret == 0) {
530
            ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds,
531
                                    outBlock);
532
            wolfSSL_CryptHwMutexUnLock();
533
        }
534
        return ret;
535
    }
536
537
    #ifdef HAVE_AES_DECRYPT
538
        #error nRF51 AES Hardware does not support decrypt
539
    #endif /* HAVE_AES_DECRYPT */
540
541
#elif defined(WOLFSSL_ESP32_CRYPT) && \
542
     !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
543
    #include <esp_log.h>
544
    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
545
    #define TAG "aes"
546
547
    /* We'll use SW for fallback:
548
     *   unsupported key lengths. (e.g. ESP32-S3)
549
     *   chipsets not implemented.
550
     *   hardware busy. */
551
    #define NEED_AES_TABLES
552
    #define NEED_AES_HW_FALLBACK
553
    #define NEED_SOFTWARE_AES_SETKEY
554
    #undef  WOLFSSL_AES_DIRECT
555
    #define WOLFSSL_AES_DIRECT
556
557
    /* Encrypt: If we choose to never have a fallback to SW: */
558
    #if !defined(NEED_AES_HW_FALLBACK) && (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
559
    static WARN_UNUSED_RESULT int wc_AesEncrypt( /* calling this one when NO_AES_192 is defined */
560
        Aes* aes, const byte* inBlock, byte* outBlock)
561
    {
562
        int ret;
563
564
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
565
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
566
        if (ret < 0)
567
            return ret;
568
#endif
569
570
        /* Thread mutex protection handled in esp_aes_hw_InUse */
571
    #ifdef NEED_AES_HW_FALLBACK
572
        if (wc_esp32AesSupportedKeyLen(aes)) {
573
            ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
574
        }
575
    #else
576
        ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
577
    #endif
578
        return ret;
579
    }
580
    #endif
581
582
    /* Decrypt: If we choose to never have a fallback to SW: */
583
    #if !defined(NEED_AES_HW_FALLBACK) && (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
584
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
585
        Aes* aes, const byte* inBlock, byte* outBlock)
586
    {
587
        int ret = 0;
588
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
589
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
590
        if (ret < 0)
591
            return ret;
592
#endif
593
        /* Thread mutex protection handled in esp_aes_hw_InUse */
594
    #ifdef NEED_AES_HW_FALLBACK
595
        if (wc_esp32AesSupportedKeyLen(aes)) {
596
            ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
597
        }
598
        else {
599
            ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
600
        }
601
    #else
602
        /* if we don't need fallback, always use HW */
603
        ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
604
    #endif
605
        return ret;
606
    }
607
    #endif
608
609
#elif defined(WOLFSSL_AESNI)
610
611
    #define NEED_AES_TABLES
612
613
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
614
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
615
     */
616
617
    #ifndef AESNI_ALIGN
618
        #define AESNI_ALIGN 16
619
    #endif
620
621
    /* note that all write access to these static variables must be idempotent,
622
     * as arranged by Check_CPU_support_AES(), else they will be susceptible to
623
     * data races.
624
     */
625
    static int checkedAESNI = 0;
626
    static int haveAESNI  = 0;
627
    static word32 intel_flags = 0;
628
629
    static WARN_UNUSED_RESULT int Check_CPU_support_AES(void)
630
    {
631
        intel_flags = cpuid_get_flags();
632
633
        return IS_INTEL_AESNI(intel_flags) != 0;
634
    }
635
636
637
    /* tell C compiler these are asm functions in case any mix up of ABI underscore
638
       prefix between clang/gcc/llvm etc */
639
    #ifdef HAVE_AES_CBC
640
        void AES_CBC_encrypt_AESNI(const unsigned char* in, unsigned char* out,
641
                             unsigned char* ivec, unsigned long length,
642
                             const unsigned char* KS, int nr)
643
                             XASM_LINK("AES_CBC_encrypt_AESNI");
644
645
        #ifdef HAVE_AES_DECRYPT
646
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
647
                void AES_CBC_decrypt_AESNI_by4(const unsigned char* in, unsigned char* out,
648
                                         unsigned char* ivec, unsigned long length,
649
                                         const unsigned char* KS, int nr)
650
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by4");
651
            #elif defined(WOLFSSL_AESNI_BY6)
652
                void AES_CBC_decrypt_AESNI_by6(const unsigned char* in, unsigned char* out,
653
                                         unsigned char* ivec, unsigned long length,
654
                                         const unsigned char* KS, int nr)
655
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by6");
656
            #else /* WOLFSSL_AESNI_BYx */
657
                void AES_CBC_decrypt_AESNI_by8(const unsigned char* in, unsigned char* out,
658
                                         unsigned char* ivec, unsigned long length,
659
                                         const unsigned char* KS, int nr)
660
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by8");
661
            #endif /* WOLFSSL_AESNI_BYx */
662
        #endif /* HAVE_AES_DECRYPT */
663
    #endif /* HAVE_AES_CBC */
664
665
    void AES_ECB_encrypt_AESNI(const unsigned char* in, unsigned char* out,
666
                         unsigned long length, const unsigned char* KS, int nr)
667
                         XASM_LINK("AES_ECB_encrypt_AESNI");
668
669
    #ifdef HAVE_AES_DECRYPT
670
        void AES_ECB_decrypt_AESNI(const unsigned char* in, unsigned char* out,
671
                             unsigned long length, const unsigned char* KS, int nr)
672
                             XASM_LINK("AES_ECB_decrypt_AESNI");
673
    #endif
674
675
    void AES_128_Key_Expansion_AESNI(const unsigned char* userkey,
676
                               unsigned char* key_schedule)
677
                               XASM_LINK("AES_128_Key_Expansion_AESNI");
678
679
    void AES_192_Key_Expansion_AESNI(const unsigned char* userkey,
680
                               unsigned char* key_schedule)
681
                               XASM_LINK("AES_192_Key_Expansion_AESNI");
682
683
    void AES_256_Key_Expansion_AESNI(const unsigned char* userkey,
684
                               unsigned char* key_schedule)
685
                               XASM_LINK("AES_256_Key_Expansion_AESNI");
686
687
688
    static WARN_UNUSED_RESULT int AES_set_encrypt_key_AESNI(
689
        const unsigned char *userKey, const int bits, Aes* aes)
690
    {
691
        int ret;
692
693
        ASSERT_SAVED_VECTOR_REGISTERS();
694
695
        if (!userKey || !aes)
696
            return BAD_FUNC_ARG;
697
698
        switch (bits) {
699
            case 128:
700
               AES_128_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 10;
701
               return 0;
702
            case 192:
703
               AES_192_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 12;
704
               return 0;
705
            case 256:
706
               AES_256_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 14;
707
               return 0;
708
            default:
709
                ret = BAD_FUNC_ARG;
710
        }
711
712
        return ret;
713
    }
714
715
    #ifdef HAVE_AES_DECRYPT
716
        static WARN_UNUSED_RESULT int AES_set_decrypt_key_AESNI(
717
            const unsigned char* userKey, const int bits, Aes* aes)
718
        {
719
            word32 nr;
720
#ifdef WOLFSSL_SMALL_STACK
721
            Aes *temp_key;
722
#else
723
            Aes temp_key[1];
724
#endif
725
            __m128i *Key_Schedule;
726
            __m128i *Temp_Key_Schedule;
727
728
            ASSERT_SAVED_VECTOR_REGISTERS();
729
730
            if (!userKey || !aes)
731
                return BAD_FUNC_ARG;
732
733
#ifdef WOLFSSL_SMALL_STACK
734
            if ((temp_key = (Aes *)XMALLOC(sizeof *aes, aes->heap,
735
                                           DYNAMIC_TYPE_AES)) == NULL)
736
                return MEMORY_E;
737
#endif
738
739
            if (AES_set_encrypt_key_AESNI(userKey,bits,temp_key)
740
                == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
741
#ifdef WOLFSSL_SMALL_STACK
742
                XFREE(temp_key, aes->heap, DYNAMIC_TYPE_AES);
743
#endif
744
                return BAD_FUNC_ARG;
745
            }
746
747
            Key_Schedule = (__m128i*)aes->key;
748
            Temp_Key_Schedule = (__m128i*)temp_key->key;
749
750
            nr = temp_key->rounds;
751
            aes->rounds = nr;
752
753
            Key_Schedule[nr] = Temp_Key_Schedule[0];
754
            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
755
            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
756
            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
757
            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
758
            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
759
            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
760
            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
761
            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
762
            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
763
764
            if (nr>10) {
765
                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
766
                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
767
            }
768
769
            if (nr>12) {
770
                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
771
                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
772
            }
773
774
            Key_Schedule[0] = Temp_Key_Schedule[nr];
775
776
#ifdef WOLFSSL_SMALL_STACK
777
            XFREE(temp_key, aes->heap, DYNAMIC_TYPE_AES);
778
#endif
779
780
            return 0;
781
        }
782
    #endif /* HAVE_AES_DECRYPT */
783
784
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
785
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
786
787
    #define NEED_AES_TABLES
788
789
    static int checkedCpuIdFlags = 0;
790
    static word32 cpuid_flags = 0;
791
792
    static void Check_CPU_support_HwCrypto(Aes* aes)
793
    {
794
        if (checkedCpuIdFlags == 0) {
795
            cpuid_flags = cpuid_get_flags();
796
            checkedCpuIdFlags = 1;
797
        }
798
        aes->use_aes_hw_crypto = IS_AARCH64_AES(cpuid_flags);
799
    #ifdef HAVE_AESGCM
800
        aes->use_pmull_hw_crypto = IS_AARCH64_PMULL(cpuid_flags);
801
        aes->use_sha3_hw_crypto = IS_AARCH64_SHA3(cpuid_flags);
802
    #endif
803
    }
804
805
#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
806
        && !defined(WOLFSSL_QNX_CAAM)) || \
807
      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
808
        defined(HAVE_AESCCM))
809
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
810
            Aes* aes, const byte* inBlock, byte* outBlock)
811
        {
812
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
813
            {
814
                int ret =
815
                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
816
                if (ret < 0)
817
                    return ret;
818
            }
819
#endif
820
            return wc_AesEncryptDirect(aes, outBlock, inBlock);
821
        }
822
823
#elif defined(WOLFSSL_AFALG)
824
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
825
826
#elif defined(WOLFSSL_DEVCRYPTO_AES)
827
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
828
829
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
830
    #include "hal_data.h"
831
832
    #ifndef WOLFSSL_SCE_AES256_HANDLE
833
        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
834
    #endif
835
836
    #ifndef WOLFSSL_SCE_AES192_HANDLE
837
        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
838
    #endif
839
840
    #ifndef WOLFSSL_SCE_AES128_HANDLE
841
        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
842
    #endif
843
844
    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
845
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
846
    {
847
        word32 ret;
848
849
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
850
                CRYPTO_WORD_ENDIAN_BIG) {
851
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
852
        }
853
854
        switch (aes->keylen) {
855
        #ifdef WOLFSSL_AES_128
856
            case AES_128_KEY_SIZE:
857
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
858
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
859
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
860
                        (word32*)outBlock);
861
                break;
862
        #endif
863
        #ifdef WOLFSSL_AES_192
864
            case AES_192_KEY_SIZE:
865
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
866
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
867
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
868
                        (word32*)outBlock);
869
                break;
870
        #endif
871
        #ifdef WOLFSSL_AES_256
872
            case AES_256_KEY_SIZE:
873
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
874
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
875
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
876
                        (word32*)outBlock);
877
                break;
878
        #endif
879
            default:
880
                WOLFSSL_MSG("Unknown key size");
881
                return BAD_FUNC_ARG;
882
        }
883
884
        if (ret != SSP_SUCCESS) {
885
            /* revert input */
886
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
887
            return WC_HW_E;
888
        }
889
890
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
891
                CRYPTO_WORD_ENDIAN_BIG) {
892
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
893
            if (inBlock != outBlock) {
894
                /* revert input */
895
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
896
            }
897
        }
898
        return 0;
899
    }
900
901
    #if defined(HAVE_AES_DECRYPT)
902
    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
903
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
904
    {
905
        word32 ret;
906
907
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
908
                CRYPTO_WORD_ENDIAN_BIG) {
909
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
910
        }
911
912
        switch (aes->keylen) {
913
        #ifdef WOLFSSL_AES_128
914
            case AES_128_KEY_SIZE:
915
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
916
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
917
                        (sz / sizeof(word32)), (word32*)inBlock,
918
                        (word32*)outBlock);
919
                break;
920
        #endif
921
        #ifdef WOLFSSL_AES_192
922
            case AES_192_KEY_SIZE:
923
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
924
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
925
                        (sz / sizeof(word32)), (word32*)inBlock,
926
                        (word32*)outBlock);
927
                break;
928
        #endif
929
        #ifdef WOLFSSL_AES_256
930
            case AES_256_KEY_SIZE:
931
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
932
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
933
                        (sz / sizeof(word32)), (word32*)inBlock,
934
                        (word32*)outBlock);
935
                break;
936
        #endif
937
            default:
938
                WOLFSSL_MSG("Unknown key size");
939
                return BAD_FUNC_ARG;
940
        }
941
        if (ret != SSP_SUCCESS) {
942
            return WC_HW_E;
943
        }
944
945
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
946
                CRYPTO_WORD_ENDIAN_BIG) {
947
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
948
            if (inBlock != outBlock) {
949
                /* revert input */
950
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
951
            }
952
        }
953
954
        return 0;
955
    }
956
    #endif /* HAVE_AES_DECRYPT */
957
958
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
959
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
960
        Aes* aes, const byte* inBlock, byte* outBlock)
961
    {
962
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
963
        {
964
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
965
            if (ret < 0)
966
                return ret;
967
        }
968
#endif
969
        return AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
970
    }
971
    #endif
972
973
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
974
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
975
        Aes* aes, const byte* inBlock, byte* outBlock)
976
    {
977
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
978
        {
979
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
980
            if (ret < 0)
981
                return ret;
982
        }
983
#endif
984
        return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
985
    }
986
    #endif
987
988
#elif defined(WOLFSSL_KCAPI_AES)
989
    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
990
    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
991
        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
992
        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
993
        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
994
        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
995
996
        #define NEED_AES_TABLES
997
    #endif
998
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
999
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
1000
1001
#elif defined(WOLFSSL_RISCV_ASM)
1002
/* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
1003
1004
#else
1005
1006
    /* using wolfCrypt software implementation */
1007
    #define NEED_AES_TABLES
1008
#endif
1009
1010
1011
1012
#if defined(WC_AES_BITSLICED) && !defined(HAVE_AES_ECB)
1013
    #error "When WC_AES_BITSLICED is defined, HAVE_AES_ECB is needed."
1014
#endif
1015
1016
#ifdef NEED_AES_TABLES
1017
1018
#ifndef WC_AES_BITSLICED
1019
#if !defined(WOLFSSL_SILABS_SE_ACCEL) ||  \
1020
     defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
1021
     defined(NEED_AES_HW_FALLBACK)
1022
static const FLASH_QUALIFIER word32 rcon[] = {
1023
    0x01000000, 0x02000000, 0x04000000, 0x08000000,
1024
    0x10000000, 0x20000000, 0x40000000, 0x80000000,
1025
    0x1B000000, 0x36000000,
1026
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1027
};
1028
#endif
1029
1030
#ifndef WOLFSSL_AES_SMALL_TABLES
1031
static const FLASH_QUALIFIER word32 Te[4][256] = {
1032
{
1033
    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1034
    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1035
    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1036
    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1037
    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1038
    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1039
    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1040
    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1041
    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1042
    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1043
    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1044
    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1045
    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1046
    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1047
    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1048
    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1049
    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1050
    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1051
    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1052
    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1053
    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1054
    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1055
    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1056
    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1057
    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1058
    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1059
    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1060
    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1061
    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1062
    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1063
    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1064
    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1065
    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1066
    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1067
    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1068
    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1069
    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1070
    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1071
    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1072
    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1073
    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1074
    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1075
    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1076
    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1077
    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1078
    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1079
    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1080
    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1081
    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1082
    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1083
    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1084
    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1085
    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1086
    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1087
    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1088
    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1089
    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1090
    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1091
    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1092
    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1093
    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1094
    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1095
    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1096
    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1097
},
1098
{
1099
    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1100
    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1101
    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1102
    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1103
    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1104
    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1105
    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1106
    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1107
    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1108
    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1109
    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1110
    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1111
    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1112
    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1113
    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1114
    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1115
    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1116
    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1117
    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1118
    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1119
    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1120
    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1121
    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1122
    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1123
    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1124
    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1125
    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1126
    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1127
    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1128
    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1129
    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1130
    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1131
    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1132
    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1133
    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1134
    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1135
    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1136
    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1137
    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1138
    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1139
    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1140
    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1141
    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1142
    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1143
    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1144
    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1145
    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1146
    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1147
    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1148
    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1149
    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1150
    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1151
    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1152
    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1153
    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1154
    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1155
    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1156
    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1157
    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1158
    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1159
    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1160
    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1161
    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1162
    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1163
},
1164
{
1165
    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1166
    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1167
    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1168
    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1169
    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1170
    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1171
    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1172
    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1173
    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1174
    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1175
    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1176
    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1177
    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1178
    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1179
    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1180
    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1181
    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1182
    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1183
    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1184
    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1185
    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1186
    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1187
    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1188
    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1189
    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1190
    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1191
    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1192
    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1193
    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1194
    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1195
    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1196
    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1197
    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1198
    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1199
    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1200
    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1201
    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1202
    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1203
    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1204
    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1205
    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1206
    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1207
    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1208
    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1209
    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1210
    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1211
    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1212
    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1213
    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1214
    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1215
    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1216
    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1217
    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1218
    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1219
    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1220
    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1221
    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1222
    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1223
    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1224
    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1225
    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1226
    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1227
    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1228
    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1229
},
1230
{
1231
    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1232
    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1233
    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1234
    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1235
    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1236
    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1237
    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1238
    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1239
    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1240
    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1241
    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1242
    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1243
    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1244
    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1245
    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1246
    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1247
    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1248
    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1249
    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1250
    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1251
    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1252
    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1253
    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1254
    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1255
    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1256
    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1257
    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1258
    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1259
    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1260
    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1261
    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1262
    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1263
    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1264
    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1265
    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1266
    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1267
    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1268
    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1269
    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1270
    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1271
    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1272
    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1273
    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1274
    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1275
    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1276
    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1277
    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1278
    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1279
    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1280
    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1281
    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1282
    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1283
    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1284
    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1285
    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1286
    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1287
    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1288
    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1289
    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1290
    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1291
    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1292
    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1293
    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1294
    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1295
}
1296
};
1297
1298
#if defined(HAVE_AES_DECRYPT) && !defined(WOLFSSL_SILABS_SE_ACCEL)
1299
static const FLASH_QUALIFIER word32 Td[4][256] = {
1300
{
1301
    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1302
    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1303
    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1304
    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1305
    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1306
    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1307
    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1308
    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1309
    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1310
    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1311
    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1312
    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1313
    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1314
    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1315
    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1316
    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1317
    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1318
    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1319
    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1320
    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1321
    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1322
    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1323
    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1324
    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1325
    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1326
    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1327
    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1328
    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1329
    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1330
    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1331
    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1332
    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1333
    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1334
    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1335
    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1336
    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1337
    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1338
    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1339
    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1340
    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1341
    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1342
    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1343
    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1344
    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1345
    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1346
    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1347
    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1348
    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1349
    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1350
    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1351
    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1352
    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1353
    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1354
    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1355
    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1356
    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1357
    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1358
    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1359
    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1360
    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1361
    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1362
    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1363
    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1364
    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1365
},
1366
{
1367
    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
1368
    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
1369
    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
1370
    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
1371
    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
1372
    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
1373
    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
1374
    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
1375
    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
1376
    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
1377
    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
1378
    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
1379
    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
1380
    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
1381
    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
1382
    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
1383
    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
1384
    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
1385
    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
1386
    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
1387
    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
1388
    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
1389
    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
1390
    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
1391
    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
1392
    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
1393
    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
1394
    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
1395
    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
1396
    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
1397
    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
1398
    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
1399
    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
1400
    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
1401
    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
1402
    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
1403
    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
1404
    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
1405
    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
1406
    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
1407
    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
1408
    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
1409
    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
1410
    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
1411
    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
1412
    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
1413
    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
1414
    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
1415
    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
1416
    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
1417
    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
1418
    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
1419
    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
1420
    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
1421
    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
1422
    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
1423
    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
1424
    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
1425
    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
1426
    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
1427
    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
1428
    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
1429
    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
1430
    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
1431
},
1432
{
1433
    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
1434
    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
1435
    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
1436
    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
1437
    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
1438
    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
1439
    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
1440
    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
1441
    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
1442
    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
1443
    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
1444
    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
1445
    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
1446
    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
1447
    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
1448
    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
1449
    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
1450
    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
1451
    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
1452
    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
1453
1454
    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
1455
    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
1456
    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
1457
    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
1458
    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
1459
    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
1460
    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
1461
    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
1462
    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
1463
    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
1464
    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
1465
    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
1466
    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
1467
    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
1468
    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
1469
    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
1470
    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
1471
    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
1472
    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
1473
    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
1474
    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
1475
    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
1476
    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
1477
    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
1478
    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
1479
    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
1480
    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
1481
    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
1482
    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
1483
    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
1484
    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
1485
    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
1486
    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
1487
    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
1488
    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
1489
    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
1490
    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
1491
    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
1492
    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
1493
    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
1494
    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
1495
    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
1496
    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
1497
    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
1498
},
1499
{
1500
    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
1501
    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
1502
    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
1503
    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
1504
    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
1505
    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
1506
    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
1507
    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
1508
    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
1509
    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
1510
    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
1511
    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
1512
    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
1513
    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
1514
    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
1515
    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
1516
    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
1517
    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
1518
    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
1519
    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
1520
    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
1521
    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
1522
    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
1523
    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
1524
    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
1525
    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
1526
    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
1527
    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
1528
    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
1529
    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
1530
    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
1531
    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
1532
    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
1533
    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
1534
    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
1535
    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
1536
    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
1537
    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
1538
    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
1539
    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
1540
    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
1541
    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
1542
    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
1543
    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
1544
    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
1545
    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
1546
    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
1547
    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
1548
    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
1549
    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
1550
    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
1551
    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
1552
    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
1553
    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
1554
    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
1555
    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
1556
    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
1557
    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
1558
    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
1559
    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
1560
    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
1561
    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
1562
    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
1563
    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
1564
}
1565
};
1566
#endif /* HAVE_AES_DECRYPT */
1567
#endif /* WOLFSSL_AES_SMALL_TABLES */
1568
1569
#ifdef HAVE_AES_DECRYPT
1570
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC) && \
1571
                              !defined(WOLFSSL_SILABS_SE_ACCEL)) || \
1572
    defined(WOLFSSL_AES_DIRECT)
1573
static const FLASH_QUALIFIER byte Td4[256] =
1574
{
1575
    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
1576
    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
1577
    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
1578
    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
1579
    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
1580
    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
1581
    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
1582
    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
1583
    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
1584
    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
1585
    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
1586
    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
1587
    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
1588
    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
1589
    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
1590
    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
1591
    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
1592
    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
1593
    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
1594
    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
1595
    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
1596
    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
1597
    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
1598
    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
1599
    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
1600
    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
1601
    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
1602
    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
1603
    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
1604
    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
1605
    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
1606
    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
1607
};
1608
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1609
#endif /* HAVE_AES_DECRYPT */
1610
1611
#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
1612
1613
#ifdef WOLFSSL_AES_SMALL_TABLES
1614
static const byte Tsbox[256] = {
1615
    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
1616
    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
1617
    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
1618
    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
1619
    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
1620
    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
1621
    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
1622
    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
1623
    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
1624
    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
1625
    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
1626
    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
1627
    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
1628
    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
1629
    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
1630
    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
1631
    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
1632
    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
1633
    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
1634
    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
1635
    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
1636
    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
1637
    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
1638
    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
1639
    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
1640
    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
1641
    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
1642
    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
1643
    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
1644
    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
1645
    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
1646
    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
1647
};
1648
1649
#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
1650
1651
static WARN_UNUSED_RESULT word32 col_mul(
1652
    word32 t, int i2, int i3, int ia, int ib)
1653
{
1654
    byte t3 = GETBYTE(t, i3);
1655
    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
1656
1657
    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
1658
}
1659
1660
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
1661
static WARN_UNUSED_RESULT word32 inv_col_mul(
1662
    word32 t, int i9, int ib, int id, int ie)
1663
{
1664
    byte t9 = GETBYTE(t, i9);
1665
    byte tb = GETBYTE(t, ib);
1666
    byte td = GETBYTE(t, id);
1667
    byte te = GETBYTE(t, ie);
1668
    byte t0 = t9 ^ tb ^ td;
1669
    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
1670
}
1671
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1672
#endif /* WOLFSSL_AES_SMALL_TABLES */
1673
#endif
1674
1675
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
1676
                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
1677
1678
#ifndef WC_AES_BITSLICED
1679
1680
#ifndef WC_CACHE_LINE_SZ
1681
    #if defined(__x86_64__) || defined(_M_X64) || \
1682
       (defined(__ILP32__) && (__ILP32__ >= 1))
1683
0
        #define WC_CACHE_LINE_SZ 64
1684
    #else
1685
        /* default cache line size */
1686
        #define WC_CACHE_LINE_SZ 32
1687
    #endif
1688
#endif
1689
1690
#ifndef WC_NO_CACHE_RESISTANT
1691
1692
#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
1693
    #define WOLFSSL_AES_TOUCH_LINES
1694
#endif
1695
1696
#ifndef WOLFSSL_AES_SMALL_TABLES
1697
/* load 4 Te Tables into cache by cache line stride */
1698
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
1699
0
{
1700
0
#ifndef WOLFSSL_AES_TOUCH_LINES
1701
0
    word32 x = 0;
1702
0
    int i,j;
1703
1704
0
    for (i = 0; i < 4; i++) {
1705
        /* 256 elements, each one is 4 bytes */
1706
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
1707
0
            x &= Te[i][j];
1708
0
        }
1709
0
    }
1710
0
    return x;
1711
#else
1712
    return 0;
1713
#endif
1714
0
}
1715
#else
1716
/* load sbox into cache by cache line stride */
1717
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
1718
{
1719
#ifndef WOLFSSL_AES_TOUCH_LINES
1720
    word32 x = 0;
1721
    int i;
1722
1723
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
1724
        x &= Tsbox[i];
1725
    }
1726
    return x;
1727
#else
1728
    return 0;
1729
#endif
1730
}
1731
#endif
1732
#endif
1733
1734
#ifdef WOLFSSL_AES_TOUCH_LINES
1735
#if WC_CACHE_LINE_SZ == 128
1736
    #define WC_CACHE_LINE_BITS      5
1737
    #define WC_CACHE_LINE_MASK_HI   0xe0
1738
    #define WC_CACHE_LINE_MASK_LO   0x1f
1739
    #define WC_CACHE_LINE_ADD       0x20
1740
#elif WC_CACHE_LINE_SZ == 64
1741
    #define WC_CACHE_LINE_BITS      4
1742
    #define WC_CACHE_LINE_MASK_HI   0xf0
1743
    #define WC_CACHE_LINE_MASK_LO   0x0f
1744
    #define WC_CACHE_LINE_ADD       0x10
1745
#elif WC_CACHE_LINE_SZ == 32
1746
    #define WC_CACHE_LINE_BITS      3
1747
    #define WC_CACHE_LINE_MASK_HI   0xf8
1748
    #define WC_CACHE_LINE_MASK_LO   0x07
1749
    #define WC_CACHE_LINE_ADD       0x08
1750
#elif WC_CACHE_LINE_SZ == 16
1751
    #define WC_CACHE_LINE_BITS      2
1752
    #define WC_CACHE_LINE_MASK_HI   0xfc
1753
    #define WC_CACHE_LINE_MASK_LO   0x03
1754
    #define WC_CACHE_LINE_ADD       0x04
1755
#else
1756
    #error Cache line size not supported
1757
#endif
1758
1759
#ifndef WOLFSSL_AES_SMALL_TABLES
1760
static word32 GetTable(const word32* t, byte o)
1761
{
1762
#if WC_CACHE_LINE_SZ == 64
1763
    word32 e;
1764
    byte hi = o & 0xf0;
1765
    byte lo = o & 0x0f;
1766
1767
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1768
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1769
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1770
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1771
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1772
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1773
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1774
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1775
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1776
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1777
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1778
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1779
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1780
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1781
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1782
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1783
1784
    return e;
1785
#else
1786
    word32 e = 0;
1787
    int i;
1788
    byte hi = o & WC_CACHE_LINE_MASK_HI;
1789
    byte lo = o & WC_CACHE_LINE_MASK_LO;
1790
1791
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1792
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1793
        hi -= WC_CACHE_LINE_ADD;
1794
    }
1795
1796
    return e;
1797
#endif
1798
}
1799
#endif
1800
1801
#ifdef WOLFSSL_AES_SMALL_TABLES
1802
static byte GetTable8(const byte* t, byte o)
1803
{
1804
#if WC_CACHE_LINE_SZ == 64
1805
    byte e;
1806
    byte hi = o & 0xf0;
1807
    byte lo = o & 0x0f;
1808
1809
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1810
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1811
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1812
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1813
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1814
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1815
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1816
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1817
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1818
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1819
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1820
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1821
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1822
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1823
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1824
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1825
1826
    return e;
1827
#else
1828
    byte e = 0;
1829
    int i;
1830
    byte hi = o & WC_CACHE_LINE_MASK_HI;
1831
    byte lo = o & WC_CACHE_LINE_MASK_LO;
1832
1833
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1834
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1835
        hi -= WC_CACHE_LINE_ADD;
1836
    }
1837
1838
    return e;
1839
#endif
1840
}
1841
#endif
1842
1843
#ifndef WOLFSSL_AES_SMALL_TABLES
1844
static void GetTable_Multi(const word32* t, word32* t0, byte o0,
1845
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
1846
{
1847
    word32 e0 = 0;
1848
    word32 e1 = 0;
1849
    word32 e2 = 0;
1850
    word32 e3 = 0;
1851
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
1852
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
1853
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
1854
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
1855
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
1856
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
1857
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
1858
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
1859
    int i;
1860
1861
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1862
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
1863
        hi0 -= WC_CACHE_LINE_ADD;
1864
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
1865
        hi1 -= WC_CACHE_LINE_ADD;
1866
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
1867
        hi2 -= WC_CACHE_LINE_ADD;
1868
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
1869
        hi3 -= WC_CACHE_LINE_ADD;
1870
    }
1871
    *t0 = e0;
1872
    *t1 = e1;
1873
    *t2 = e2;
1874
    *t3 = e3;
1875
}
1876
static void XorTable_Multi(const word32* t, word32* t0, byte o0,
1877
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
1878
{
1879
    word32 e0 = 0;
1880
    word32 e1 = 0;
1881
    word32 e2 = 0;
1882
    word32 e3 = 0;
1883
    byte hi0 = o0 & 0xf0;
1884
    byte lo0 = o0 & 0x0f;
1885
    byte hi1 = o1 & 0xf0;
1886
    byte lo1 = o1 & 0x0f;
1887
    byte hi2 = o2 & 0xf0;
1888
    byte lo2 = o2 & 0x0f;
1889
    byte hi3 = o3 & 0xf0;
1890
    byte lo3 = o3 & 0x0f;
1891
    int i;
1892
1893
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1894
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
1895
        hi0 -= WC_CACHE_LINE_ADD;
1896
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
1897
        hi1 -= WC_CACHE_LINE_ADD;
1898
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
1899
        hi2 -= WC_CACHE_LINE_ADD;
1900
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
1901
        hi3 -= WC_CACHE_LINE_ADD;
1902
    }
1903
    *t0 ^= e0;
1904
    *t1 ^= e1;
1905
    *t2 ^= e2;
1906
    *t3 ^= e3;
1907
}
1908
static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
1909
{
1910
    word32 e = 0;
1911
    int i;
1912
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
1913
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
1914
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
1915
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
1916
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
1917
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
1918
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
1919
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
1920
1921
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1922
        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
1923
             << 24;
1924
        hi0 -= WC_CACHE_LINE_ADD;
1925
        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
1926
             << 16;
1927
        hi1 -= WC_CACHE_LINE_ADD;
1928
        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
1929
             <<  8;
1930
        hi2 -= WC_CACHE_LINE_ADD;
1931
        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
1932
             <<  0;
1933
        hi3 -= WC_CACHE_LINE_ADD;
1934
    }
1935
1936
    return e;
1937
}
1938
#endif
1939
#else
1940
1941
0
#define GetTable(t, o)  t[o]
1942
#define GetTable8(t, o) t[o]
1943
#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
1944
    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
1945
#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
1946
    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
1947
#define GetTable8_4(t, o0, o1, o2, o3) \
1948
0
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
1949
0
     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
1950
#endif
1951
1952
#ifndef HAVE_CUDA
1953
/* Encrypt a block using AES.
1954
 *
1955
 * @param [in]  aes       AES object.
1956
 * @param [in]  inBlock   Block to encrypt.
1957
 * @param [out] outBlock  Encrypted block.
1958
 * @param [in]  r         Rounds divided by 2.
1959
 */
1960
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
1961
        word32 r)
1962
0
{
1963
0
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
1964
0
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
1965
0
    const word32* rk;
1966
1967
#ifdef WC_C_DYNAMIC_FALLBACK
1968
    rk = aes->key_C_fallback;
1969
#else
1970
0
    rk = aes->key;
1971
0
#endif
1972
1973
    /*
1974
     * map byte array block to cipher state
1975
     * and add initial round key:
1976
     */
1977
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
1978
0
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
1979
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
1980
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
1981
1982
0
#ifdef LITTLE_ENDIAN_ORDER
1983
0
    s0 = ByteReverseWord32(s0);
1984
0
    s1 = ByteReverseWord32(s1);
1985
0
    s2 = ByteReverseWord32(s2);
1986
0
    s3 = ByteReverseWord32(s3);
1987
0
#endif
1988
1989
    /* AddRoundKey */
1990
0
    s0 ^= rk[0];
1991
0
    s1 ^= rk[1];
1992
0
    s2 ^= rk[2];
1993
0
    s3 ^= rk[3];
1994
1995
0
#ifndef WOLFSSL_AES_SMALL_TABLES
1996
0
#ifndef WC_NO_CACHE_RESISTANT
1997
0
    s0 |= PreFetchTe();
1998
0
#endif
1999
2000
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2001
0
#define ENC_ROUND_T_S(o)                                                       \
2002
0
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
2003
0
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
2004
0
         rk[(o)+4];                                                            \
2005
0
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
2006
0
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
2007
0
         rk[(o)+5];                                                            \
2008
0
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
2009
0
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
2010
0
         rk[(o)+6];                                                            \
2011
0
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
2012
0
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
2013
0
         rk[(o)+7]
2014
0
#define ENC_ROUND_S_T(o)                                                       \
2015
0
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
2016
0
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
2017
0
         rk[(o)+0];                                                            \
2018
0
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
2019
0
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
2020
0
         rk[(o)+1];                                                            \
2021
0
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
2022
0
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
2023
0
         rk[(o)+2];                                                            \
2024
0
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
2025
0
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
2026
0
         rk[(o)+3]
2027
#else
2028
#define ENC_ROUND_T_S(o)                                                       \
2029
    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
2030
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
2031
    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
2032
                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
2033
    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
2034
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
2035
    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
2036
                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
2037
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
2038
2039
#define ENC_ROUND_S_T(o)                                                       \
2040
    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
2041
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
2042
    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
2043
                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
2044
    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
2045
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2046
    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
2047
                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
2048
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2049
#endif
2050
2051
0
#ifndef WOLFSSL_AES_NO_UNROLL
2052
/* Unroll the loop. */
2053
0
                       ENC_ROUND_T_S( 0);
2054
0
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2055
0
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2056
0
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2057
0
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2058
0
    if (r > 5) {
2059
0
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2060
0
        if (r > 6) {
2061
0
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2062
0
        }
2063
0
    }
2064
0
    rk += r * 8;
2065
#else
2066
    /*
2067
     * Nr - 1 full rounds:
2068
     */
2069
2070
    for (;;) {
2071
        ENC_ROUND_T_S(0);
2072
2073
        rk += 8;
2074
        if (--r == 0) {
2075
            break;
2076
        }
2077
2078
        ENC_ROUND_S_T(0);
2079
    }
2080
#endif
2081
2082
    /*
2083
     * apply last round and
2084
     * map cipher state to byte array block:
2085
     */
2086
2087
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2088
0
    s0 =
2089
0
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2090
0
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2091
0
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2092
0
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2093
0
        rk[0];
2094
0
    s1 =
2095
0
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2096
0
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2097
0
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2098
0
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2099
0
        rk[1];
2100
0
    s2 =
2101
0
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2102
0
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2103
0
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2104
0
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2105
0
        rk[2];
2106
0
    s3 =
2107
0
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2108
0
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2109
0
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2110
0
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2111
0
        rk[3];
2112
#else
2113
{
2114
    word32 u0;
2115
    word32 u1;
2116
    word32 u2;
2117
    word32 u3;
2118
2119
    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
2120
    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
2121
                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
2122
    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
2123
    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
2124
    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
2125
                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
2126
    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
2127
    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
2128
    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
2129
                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
2130
    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
2131
    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
2132
    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
2133
                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
2134
    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
2135
    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
2136
}
2137
#endif
2138
#else
2139
#ifndef WC_NO_CACHE_RESISTANT
2140
    s0 |= PreFetchSBox();
2141
#endif
2142
2143
    r *= 2;
2144
    /* Two rounds at a time */
2145
    for (rk += 4; r > 1; r--, rk += 4) {
2146
        t0 =
2147
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2148
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2149
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2150
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2151
        t1 =
2152
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2153
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2154
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2155
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2156
        t2 =
2157
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2158
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2159
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2160
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2161
        t3 =
2162
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2163
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2164
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2165
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2166
2167
        s0 =
2168
            (col_mul(t0, 3, 2, 0, 1) << 24) ^
2169
            (col_mul(t0, 2, 1, 0, 3) << 16) ^
2170
            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
2171
            (col_mul(t0, 0, 3, 2, 1)      ) ^
2172
            rk[0];
2173
        s1 =
2174
            (col_mul(t1, 3, 2, 0, 1) << 24) ^
2175
            (col_mul(t1, 2, 1, 0, 3) << 16) ^
2176
            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
2177
            (col_mul(t1, 0, 3, 2, 1)      ) ^
2178
            rk[1];
2179
        s2 =
2180
            (col_mul(t2, 3, 2, 0, 1) << 24) ^
2181
            (col_mul(t2, 2, 1, 0, 3) << 16) ^
2182
            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
2183
            (col_mul(t2, 0, 3, 2, 1)      ) ^
2184
            rk[2];
2185
        s3 =
2186
            (col_mul(t3, 3, 2, 0, 1) << 24) ^
2187
            (col_mul(t3, 2, 1, 0, 3) << 16) ^
2188
            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
2189
            (col_mul(t3, 0, 3, 2, 1)      ) ^
2190
            rk[3];
2191
    }
2192
2193
    t0 =
2194
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2195
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2196
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2197
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2198
    t1 =
2199
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2200
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2201
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2202
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2203
    t2 =
2204
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2205
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2206
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2207
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2208
    t3 =
2209
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2210
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2211
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2212
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2213
    s0 = t0 ^ rk[0];
2214
    s1 = t1 ^ rk[1];
2215
    s2 = t2 ^ rk[2];
2216
    s3 = t3 ^ rk[3];
2217
#endif
2218
2219
    /* write out */
2220
0
#ifdef LITTLE_ENDIAN_ORDER
2221
0
    s0 = ByteReverseWord32(s0);
2222
0
    s1 = ByteReverseWord32(s1);
2223
0
    s2 = ByteReverseWord32(s2);
2224
0
    s3 = ByteReverseWord32(s3);
2225
0
#endif
2226
2227
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2228
0
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2229
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2230
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2231
0
}
2232
2233
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2234
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
2235
    !defined(MAX3266X_AES)
2236
/* Encrypt a number of blocks using AES.
2237
 *
2238
 * @param [in]  aes  AES object.
2239
 * @param [in]  in   Block to encrypt.
2240
 * @param [out] out  Encrypted block.
2241
 * @param [in]  sz   Number of blocks to encrypt.
2242
 */
2243
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2244
{
2245
    word32 i;
2246
2247
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
2248
        AesEncrypt_C(aes, in, out, aes->rounds >> 1);
2249
        in += WC_AES_BLOCK_SIZE;
2250
        out += WC_AES_BLOCK_SIZE;
2251
    }
2252
}
2253
#endif
2254
#else
2255
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2256
        word32 r);
2257
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2258
#endif /* HAVE_CUDA */
2259
2260
#else
2261
2262
/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
2263
 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
2264
 */
2265
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
2266
static void bs_sub_bytes(bs_word u[8])
2267
{
2268
    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
2269
    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
2270
    bs_word y20, y21;
2271
    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
2272
    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
2273
    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
2274
    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
2275
    bs_word t40, t41, t42, t43, t44, t45;
2276
    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
2277
    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
2278
    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
2279
    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
2280
    bs_word tc20, tc21, tc26;
2281
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
2282
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
2283
2284
    U0 = u[7];
2285
    U1 = u[6];
2286
    U2 = u[5];
2287
    U3 = u[4];
2288
    U4 = u[3];
2289
    U5 = u[2];
2290
    U6 = u[1];
2291
    U7 = u[0];
2292
2293
    y14 = U3 ^ U5;
2294
    y13 = U0 ^ U6;
2295
    y9 = U0 ^ U3;
2296
    y8 = U0 ^ U5;
2297
    t0 = U1 ^ U2;
2298
    y1 = t0 ^ U7;
2299
    y4 = y1 ^ U3;
2300
    y12 = y13 ^ y14;
2301
    y2 = y1 ^ U0;
2302
    y5 = y1 ^ U6;
2303
    y3 = y5 ^ y8;
2304
    t1 = U4 ^ y12;
2305
    y15 = t1 ^ U5;
2306
    y20 = t1 ^ U1;
2307
    y6 = y15 ^ U7;
2308
    y10 = y15 ^ t0;
2309
    y11 = y20 ^ y9;
2310
    y7 = U7 ^ y11;
2311
    y17 = y10 ^ y11;
2312
    y19 = y10 ^ y8;
2313
    y16 = t0 ^ y11;
2314
    y21 = y13 ^ y16;
2315
    y18 = U0 ^ y16;
2316
    t2 = y12 & y15;
2317
    t3 = y3 & y6;
2318
    t4 = t3 ^ t2;
2319
    t5 = y4 & U7;
2320
    t6 = t5 ^ t2;
2321
    t7 = y13 & y16;
2322
    t8 = y5 & y1;
2323
    t9 = t8 ^ t7;
2324
    t10 = y2 & y7;
2325
    t11 = t10 ^ t7;
2326
    t12 = y9 & y11;
2327
    t13 = y14 & y17;
2328
    t14 = t13 ^ t12;
2329
    t15 = y8 & y10;
2330
    t16 = t15 ^ t12;
2331
    t17 = t4 ^ y20;
2332
    t18 = t6 ^ t16;
2333
    t19 = t9 ^ t14;
2334
    t20 = t11 ^ t16;
2335
    t21 = t17 ^ t14;
2336
    t22 = t18 ^ y19;
2337
    t23 = t19 ^ y21;
2338
    t24 = t20 ^ y18;
2339
    t25 = t21 ^ t22;
2340
    t26 = t21 & t23;
2341
    t27 = t24 ^ t26;
2342
    t28 = t25 & t27;
2343
    t29 = t28 ^ t22;
2344
    t30 = t23 ^ t24;
2345
    t31 = t22 ^ t26;
2346
    t32 = t31 & t30;
2347
    t33 = t32 ^ t24;
2348
    t34 = t23 ^ t33;
2349
    t35 = t27 ^ t33;
2350
    t36 = t24 & t35;
2351
    t37 = t36 ^ t34;
2352
    t38 = t27 ^ t36;
2353
    t39 = t29 & t38;
2354
    t40 = t25 ^ t39;
2355
    t41 = t40 ^ t37;
2356
    t42 = t29 ^ t33;
2357
    t43 = t29 ^ t40;
2358
    t44 = t33 ^ t37;
2359
    t45 = t42 ^ t41;
2360
    z0 = t44 & y15;
2361
    z1 = t37 & y6;
2362
    z2 = t33 & U7;
2363
    z3 = t43 & y16;
2364
    z4 = t40 & y1;
2365
    z5 = t29 & y7;
2366
    z6 = t42 & y11;
2367
    z7 = t45 & y17;
2368
    z8 = t41 & y10;
2369
    z9 = t44 & y12;
2370
    z10 = t37 & y3;
2371
    z11 = t33 & y4;
2372
    z12 = t43 & y13;
2373
    z13 = t40 & y5;
2374
    z14 = t29 & y2;
2375
    z15 = t42 & y9;
2376
    z16 = t45 & y14;
2377
    z17 = t41 & y8;
2378
    tc1 = z15 ^ z16;
2379
    tc2 = z10 ^ tc1;
2380
    tc3 = z9 ^ tc2;
2381
    tc4 = z0 ^ z2;
2382
    tc5 = z1 ^ z0;
2383
    tc6 = z3 ^ z4;
2384
    tc7 = z12 ^ tc4;
2385
    tc8 = z7 ^ tc6;
2386
    tc9 = z8 ^ tc7;
2387
    tc10 = tc8 ^ tc9;
2388
    tc11 = tc6 ^ tc5;
2389
    tc12 = z3 ^ z5;
2390
    tc13 = z13 ^ tc1;
2391
    tc14 = tc4 ^ tc12;
2392
    S3 = tc3 ^ tc11;
2393
    tc16 = z6 ^ tc8;
2394
    tc17 = z14 ^ tc10;
2395
    tc18 = tc13 ^ tc14;
2396
    S7 = ~(z12 ^ tc18);
2397
    tc20 = z15 ^ tc16;
2398
    tc21 = tc2 ^ z11;
2399
    S0 = tc3 ^ tc16;
2400
    S6 = ~(tc10 ^ tc18);
2401
    S4 = tc14 ^ S3;
2402
    S1 = ~(S3 ^ tc16);
2403
    tc26 = tc17 ^ tc20;
2404
    S2 = ~(tc26 ^ z17);
2405
    S5 = tc21 ^ tc17;
2406
2407
    u[0] = S7;
2408
    u[1] = S6;
2409
    u[2] = S5;
2410
    u[3] = S4;
2411
    u[4] = S3;
2412
    u[5] = S2;
2413
    u[6] = S1;
2414
    u[7] = S0;
2415
}
2416
2417
#define BS_MASK_BIT_SET(w, j, bmask) \
2418
    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
2419
2420
#define BS_TRANS_8(t, o, w, bmask, s)                   \
2421
    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
2422
    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
2423
    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
2424
    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
2425
    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
2426
    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
2427
    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
2428
    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2429
2430
static void bs_transpose(bs_word* t, bs_word* blocks)
2431
{
2432
    bs_word bmask = 1;
2433
    int i;
2434
2435
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2436
2437
    for (i = 0; i < BS_WORD_SIZE; i++) {
2438
        int j;
2439
        int o = 0;
2440
        for (j = 0; j < BS_BLOCK_WORDS; j++) {
2441
        #ifdef LITTLE_ENDIAN_ORDER
2442
            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
2443
        #else
2444
            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
2445
        #endif
2446
    #ifdef WOLFSSL_AES_NO_UNROLL
2447
            int k;
2448
            for (k = 0; k < BS_WORD_SIZE; k++) {
2449
                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
2450
            }
2451
    #else
2452
            BS_TRANS_8(t, o, w, bmask,  0);
2453
        #if BS_WORD_SIZE >= 16
2454
            BS_TRANS_8(t, o, w, bmask,  8);
2455
        #endif
2456
        #if BS_WORD_SIZE >= 32
2457
            BS_TRANS_8(t, o, w, bmask, 16);
2458
            BS_TRANS_8(t, o, w, bmask, 24);
2459
        #endif
2460
        #if BS_WORD_SIZE >= 64
2461
            BS_TRANS_8(t, o, w, bmask, 32);
2462
            BS_TRANS_8(t, o, w, bmask, 40);
2463
            BS_TRANS_8(t, o, w, bmask, 48);
2464
            BS_TRANS_8(t, o, w, bmask, 56);
2465
        #endif
2466
    #endif
2467
            o += BS_WORD_SIZE;
2468
        }
2469
        bmask <<= 1;
2470
    }
2471
}
2472
2473
#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
2474
    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
2475
    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
2476
    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
2477
    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
2478
    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
2479
    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
2480
    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
2481
    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2482
2483
static void bs_inv_transpose(bs_word* t, bs_word* blocks)
2484
{
2485
    int o;
2486
2487
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2488
2489
    for (o = 0; o < BS_BLOCK_WORDS; o++) {
2490
        int i;
2491
        for (i = 0; i < BS_WORD_SIZE; i++) {
2492
        #ifdef LITTLE_ENDIAN_ORDER
2493
            bs_word bmask = (bs_word)1 << i;
2494
        #else
2495
            bs_word bmask = bs_bswap((bs_word)1 << i);
2496
        #endif
2497
            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
2498
    #ifdef WOLFSSL_AES_NO_UNROLL
2499
            int j;
2500
            for (j = 0; j < BS_WORD_SIZE; j++) {
2501
                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
2502
            }
2503
    #else
2504
            BS_INV_TRANS_8(t, o, w, bmask, 0);
2505
        #if BS_WORD_SIZE >= 16
2506
            BS_INV_TRANS_8(t, o, w, bmask, 8);
2507
        #endif
2508
        #if BS_WORD_SIZE >= 32
2509
            BS_INV_TRANS_8(t, o, w, bmask, 16);
2510
            BS_INV_TRANS_8(t, o, w, bmask, 24);
2511
        #endif
2512
        #if BS_WORD_SIZE >= 64
2513
            BS_INV_TRANS_8(t, o, w, bmask, 32);
2514
            BS_INV_TRANS_8(t, o, w, bmask, 40);
2515
            BS_INV_TRANS_8(t, o, w, bmask, 48);
2516
            BS_INV_TRANS_8(t, o, w, bmask, 56);
2517
        #endif
2518
    #endif
2519
        }
2520
    }
2521
}
2522
2523
#define BS_ROW_OFF_0    0
2524
#define BS_ROW_OFF_1    32
2525
#define BS_ROW_OFF_2    64
2526
#define BS_ROW_OFF_3    96
2527
2528
#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
2529
#define BS_IDX_MASK     0x7f
2530
2531
#define BS_ASSIGN_8(d, od, s, os)   \
2532
    d[(od) + 0] = s[(os) + 0];      \
2533
    d[(od) + 1] = s[(os) + 1];      \
2534
    d[(od) + 2] = s[(os) + 2];      \
2535
    d[(od) + 3] = s[(os) + 3];      \
2536
    d[(od) + 4] = s[(os) + 4];      \
2537
    d[(od) + 5] = s[(os) + 5];      \
2538
    d[(od) + 6] = s[(os) + 6];      \
2539
    d[(od) + 7] = s[(os) + 7]
2540
2541
static void bs_shift_rows(bs_word* t, bs_word* b)
2542
{
2543
    int i;
2544
2545
    for (i = 0; i < 128; i += 32) {
2546
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
2547
        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
2548
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
2549
        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
2550
    }
2551
}
2552
2553
#define BS_SHIFT_OFF_0  0
2554
#define BS_SHIFT_OFF_1  8
2555
#define BS_SHIFT_OFF_2  16
2556
#define BS_SHIFT_OFF_3  24
2557
2558
/* Shift rows and mix columns.
2559
 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
2560
 */
2561
2562
#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
2563
        of      = br0[7] ^ br1[7];                                  \
2564
        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
2565
        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
2566
        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
2567
        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
2568
        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
2569
        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
2570
        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
2571
        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
2572
2573
static void bs_shift_mix(bs_word* t, bs_word* b)
2574
{
2575
    int i;
2576
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
2577
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
2578
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
2579
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
2580
2581
    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
2582
        bs_word* br0 = b + or0;
2583
        bs_word* br1 = b + or1;
2584
        bs_word* br2 = b + or2;
2585
        bs_word* br3 = b + or3;
2586
        bs_word of;
2587
2588
        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
2589
        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
2590
        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
2591
        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
2592
2593
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2594
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2595
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2596
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2597
    }
2598
}
2599
2600
static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
2601
{
2602
    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
2603
}
2604
2605
static void bs_sub_bytes_blocks(bs_word* b)
2606
{
2607
    int i;
2608
2609
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
2610
        bs_sub_bytes(b + i);
2611
    }
2612
}
2613
2614
static const FLASH_QUALIFIER byte bs_rcon[] = {
2615
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
2616
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
2617
};
2618
2619
static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
2620
    bs_word block[AES_BLOCK_BITS];
2621
    bs_word trans[AES_BLOCK_BITS];
2622
2623
    XMEMSET(block, 0, sizeof(block));
2624
    XMEMCPY(block, in, 4);
2625
2626
    bs_transpose(trans, block);
2627
    bs_sub_bytes_blocks(trans);
2628
    bs_inv_transpose(block, trans);
2629
2630
    XMEMCPY(out, block, 4);
2631
}
2632
2633
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
2634
    /* Rotate the input 8 bits to the left */
2635
#ifdef LITTLE_ENDIAN_ORDER
2636
    *(word32*)out = rotrFixed(*(word32*)in, 8);
2637
#else
2638
    *(word32*)out = rotlFixed(*(word32*)in, 8);
2639
#endif
2640
    bs_ke_sub_bytes(out, out);
2641
    /* On just the first byte, add 2^i to the byte */
2642
    out[0] ^= bs_rcon[i];
2643
}
2644
2645
static void bs_expand_key(unsigned char *in, word32 sz) {
2646
    unsigned char t[4];
2647
    word32 o;
2648
    word8 i = 0;
2649
2650
    if (sz == 176) {
2651
        /* Total of 11 rounds - AES-128. */
2652
        for (o = 16; o < sz; o += 16) {
2653
            bs_ke_transform(t, in + o - 4, i);
2654
            i++;
2655
            *(word32*)(in + o +  0) = *(word32*)(in + o - 16) ^
2656
                                      *(word32*) t;
2657
            *(word32*)(in + o +  4) = *(word32*)(in + o - 12) ^
2658
                                      *(word32*)(in + o +  0);
2659
            *(word32*)(in + o +  8) = *(word32*)(in + o -  8) ^
2660
                                      *(word32*)(in + o +  4);
2661
            *(word32*)(in + o + 12) = *(word32*)(in + o -  4) ^
2662
                                      *(word32*)(in + o +  8);
2663
        }
2664
    }
2665
    else if (sz == 208) {
2666
        /* Total of 13 rounds - AES-192. */
2667
        for (o = 24; o < sz; o += 24) {
2668
            bs_ke_transform(t, in + o - 4, i);
2669
            i++;
2670
            *(word32*)(in + o +  0) = *(word32*)(in + o - 24) ^
2671
                                      *(word32*) t;
2672
            *(word32*)(in + o +  4) = *(word32*)(in + o - 20) ^
2673
                                      *(word32*)(in + o +  0);
2674
            *(word32*)(in + o +  8) = *(word32*)(in + o - 16) ^
2675
                                      *(word32*)(in + o +  4);
2676
            *(word32*)(in + o + 12) = *(word32*)(in + o - 12) ^
2677
                                      *(word32*)(in + o +  8);
2678
            *(word32*)(in + o + 16) = *(word32*)(in + o -  8) ^
2679
                                      *(word32*)(in + o + 12);
2680
            *(word32*)(in + o + 20) = *(word32*)(in + o -  4) ^
2681
                                      *(word32*)(in + o + 16);
2682
        }
2683
    }
2684
    else if (sz == 240) {
2685
        /* Total of 15 rounds - AES-256. */
2686
        for (o = 32; o < sz; o += 16) {
2687
            if ((o & 0x1f) == 0) {
2688
                bs_ke_transform(t, in + o - 4, i);
2689
                i++;
2690
            }
2691
            else {
2692
                bs_ke_sub_bytes(t, in + o - 4);
2693
            }
2694
            *(word32*)(in + o +  0) = *(word32*)(in + o - 32) ^
2695
                                      *(word32*) t;
2696
            *(word32*)(in + o +  4) = *(word32*)(in + o - 28) ^
2697
                                      *(word32*)(in + o +  0);
2698
            *(word32*)(in + o +  8) = *(word32*)(in + o - 24) ^
2699
                                      *(word32*)(in + o +  4);
2700
            *(word32*)(in + o + 12) = *(word32*)(in + o - 20) ^
2701
                                      *(word32*)(in + o +  8);
2702
        }
2703
    }
2704
}
2705
2706
static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
2707
    word32 rounds)
2708
{
2709
    int i;
2710
    byte bs_key[15 * WC_AES_BLOCK_SIZE];
2711
    int ksSz = (rounds + 1) * WC_AES_BLOCK_SIZE;
2712
    bs_word block[AES_BLOCK_BITS];
2713
2714
    /* Fist round. */
2715
    XMEMCPY(bs_key, key, keyLen);
2716
    bs_expand_key(bs_key, ksSz);
2717
2718
    for (i = 0; i < ksSz; i += WC_AES_BLOCK_SIZE) {
2719
        int k;
2720
2721
        XMEMCPY(block, bs_key + i, WC_AES_BLOCK_SIZE);
2722
        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
2723
            int l;
2724
            for (l = 0; l < BS_BLOCK_WORDS; l++) {
2725
                block[k + l] = block[l];
2726
            }
2727
        }
2728
        bs_transpose(rk, block);
2729
        rk += AES_BLOCK_BITS;
2730
    }
2731
}
2732
2733
static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
2734
{
2735
    word32 i;
2736
    bs_word trans[AES_BLOCK_BITS];
2737
2738
    bs_transpose(trans, state);
2739
2740
    bs_add_round_key(trans, trans, rk);
2741
    for (i = 1; i < r; i++) {
2742
        bs_sub_bytes_blocks(trans);
2743
        bs_shift_mix(state, trans);
2744
        rk += AES_BLOCK_BITS;
2745
        bs_add_round_key(trans, state, rk);
2746
    }
2747
    bs_sub_bytes_blocks(trans);
2748
    bs_shift_rows(state, trans);
2749
    rk += AES_BLOCK_BITS;
2750
    bs_add_round_key(trans, state, rk);
2751
    bs_inv_transpose(state, trans);
2752
}
2753
2754
#ifndef HAVE_CUDA
2755
/* Encrypt a block using AES.
2756
 *
2757
 * @param [in]  aes       AES object.
2758
 * @param [in]  inBlock   Block to encrypt.
2759
 * @param [out] outBlock  Encrypted block.
2760
 * @param [in]  r         Rounds divided by 2.
2761
 */
2762
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2763
        word32 r)
2764
{
2765
    bs_word state[AES_BLOCK_BITS];
2766
2767
    (void)r;
2768
2769
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
2770
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
2771
2772
    bs_encrypt(state, aes->bs_key, aes->rounds);
2773
2774
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
2775
}
2776
2777
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2778
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
2779
/* Encrypt a number of blocks using AES.
2780
 *
2781
 * @param [in]  aes  AES object.
2782
 * @param [in]  in   Block to encrypt.
2783
 * @param [out] out  Encrypted block.
2784
 * @param [in]  sz   Number of blocks to encrypt.
2785
 */
2786
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2787
{
2788
    bs_word state[AES_BLOCK_BITS];
2789
2790
    while (sz >= BS_BLOCK_SIZE) {
2791
        XMEMCPY(state, in, BS_BLOCK_SIZE);
2792
        bs_encrypt(state, aes->bs_key, aes->rounds);
2793
        XMEMCPY(out, state, BS_BLOCK_SIZE);
2794
        sz  -= BS_BLOCK_SIZE;
2795
        in  += BS_BLOCK_SIZE;
2796
        out += BS_BLOCK_SIZE;
2797
    }
2798
    if (sz > 0) {
2799
        XMEMCPY(state, in, sz);
2800
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
2801
        bs_encrypt(state, aes->bs_key, aes->rounds);
2802
        XMEMCPY(out, state, sz);
2803
    }
2804
}
2805
#endif
2806
#else
2807
extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2808
        word32 r);
2809
extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
2810
#endif /* HAVE_CUDA */
2811
2812
#endif /* !WC_AES_BITSLICED */
2813
2814
/* this section disabled with NO_AES_192 */
2815
/* calling this one when missing NO_AES_192  */
2816
static WARN_UNUSED_RESULT int wc_AesEncrypt(
2817
    Aes* aes, const byte* inBlock, byte* outBlock)
2818
0
{
2819
#if defined(MAX3266X_AES)
2820
    word32 keySize;
2821
#endif
2822
#if defined(MAX3266X_CB)
2823
    int ret_cb;
2824
#endif
2825
0
    word32 r;
2826
2827
0
    if (aes == NULL) {
2828
0
        return BAD_FUNC_ARG;
2829
0
    }
2830
2831
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
2832
    {
2833
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
2834
        if (ret < 0)
2835
            return ret;
2836
    }
2837
#endif
2838
2839
0
    r = aes->rounds >> 1;
2840
2841
0
    if (r > 7 || r == 0) {
2842
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
2843
0
        return KEYUSAGE_E;
2844
0
    }
2845
2846
#ifdef WOLFSSL_AESNI
2847
    if (aes->use_aesni) {
2848
        ASSERT_SAVED_VECTOR_REGISTERS();
2849
2850
        #ifdef DEBUG_AESNI
2851
            printf("about to aes encrypt\n");
2852
            printf("in  = %p\n", inBlock);
2853
            printf("out = %p\n", outBlock);
2854
            printf("aes->key = %p\n", aes->key);
2855
            printf("aes->rounds = %d\n", aes->rounds);
2856
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
2857
        #endif
2858
2859
        /* check alignment, decrypt doesn't need alignment */
2860
        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
2861
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
2862
            byte* tmp = (byte*)XMALLOC(WC_AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
2863
                                                      DYNAMIC_TYPE_TMP_BUFFER);
2864
            byte* tmp_align;
2865
            if (tmp == NULL)
2866
                return MEMORY_E;
2867
2868
            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
2869
2870
            XMEMCPY(tmp_align, inBlock, WC_AES_BLOCK_SIZE);
2871
            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, WC_AES_BLOCK_SIZE,
2872
                    (byte*)aes->key, (int)aes->rounds);
2873
            XMEMCPY(outBlock, tmp_align, WC_AES_BLOCK_SIZE);
2874
            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
2875
            return 0;
2876
        #else
2877
            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
2878
            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
2879
            return BAD_ALIGN_E;
2880
        #endif
2881
        }
2882
2883
        AES_ECB_encrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
2884
                        (int)aes->rounds);
2885
2886
        return 0;
2887
    }
2888
    else {
2889
        #ifdef DEBUG_AESNI
2890
            printf("Skipping AES-NI\n");
2891
        #endif
2892
    }
2893
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
2894
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
2895
    if (aes->use_aes_hw_crypto) {
2896
        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
2897
            (int)aes->rounds);
2898
        return 0;
2899
    }
2900
#endif /* WOLFSSL_AESNI */
2901
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
2902
    AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
2903
    return 0;
2904
#endif
2905
2906
#if defined(WOLFSSL_IMXRT_DCP)
2907
    if (aes->keylen == 16) {
2908
        DCPAesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
2909
        return 0;
2910
    }
2911
#endif
2912
2913
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
2914
    if (aes->useSWCrypt == 0) {
2915
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
2916
                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
2917
    }
2918
#endif
2919
2920
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
2921
    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
2922
    if (wc_esp32AesSupportedKeyLen(aes)) {
2923
        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
2924
    }
2925
    else {
2926
        /* For example, the ESP32-S3 does not support HW for len = 24,
2927
         * so fall back to SW */
2928
    #ifdef DEBUG_WOLFSSL
2929
        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
2930
                      aes->keylen);
2931
    #endif
2932
    }
2933
#endif
2934
2935
#if defined(MAX3266X_AES)
2936
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
2937
        return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
2938
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
2939
                                    outBlock, (unsigned int)keySize);
2940
    }
2941
#endif
2942
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
2943
    #ifndef WOLF_CRYPTO_CB_FIND
2944
    if (aes->devId != INVALID_DEVID)
2945
    #endif
2946
    {
2947
        ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock,
2948
                                            WC_AES_BLOCK_SIZE);
2949
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2950
            return ret_cb;
2951
        /* fall-through when unavailable */
2952
    }
2953
#endif
2954
2955
0
    AesEncrypt_C(aes, inBlock, outBlock, r);
2956
2957
0
    return 0;
2958
0
} /* wc_AesEncrypt */
2959
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
2960
2961
#if defined(HAVE_AES_DECRYPT)
2962
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC) && \
2963
                              !defined(WOLFSSL_SILABS_SE_ACCEL)) || \
2964
    defined(WOLFSSL_AES_DIRECT)
2965
2966
#ifndef WC_AES_BITSLICED
2967
#ifndef WC_NO_CACHE_RESISTANT
2968
#ifndef WOLFSSL_AES_SMALL_TABLES
2969
/* load 4 Td Tables into cache by cache line stride */
2970
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
2971
0
{
2972
0
    word32 x = 0;
2973
0
    int i,j;
2974
2975
0
    for (i = 0; i < 4; i++) {
2976
        /* 256 elements, each one is 4 bytes */
2977
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
2978
0
            x &= Td[i][j];
2979
0
        }
2980
0
    }
2981
0
    return x;
2982
0
}
2983
#endif /* !WOLFSSL_AES_SMALL_TABLES */
2984
2985
/* load Td Table4 into cache by cache line stride */
2986
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
2987
0
{
2988
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2989
0
    word32 x = 0;
2990
0
    int i;
2991
2992
0
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
2993
0
        x &= (word32)Td4[i];
2994
0
    }
2995
0
    return x;
2996
#else
2997
    return 0;
2998
#endif
2999
0
}
3000
#endif /* !WC_NO_CACHE_RESISTANT */
3001
3002
/* Decrypt a block using AES.
3003
 *
3004
 * @param [in]  aes       AES object.
3005
 * @param [in]  inBlock   Block to encrypt.
3006
 * @param [out] outBlock  Encrypted block.
3007
 * @param [in]  r         Rounds divided by 2.
3008
 */
3009
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3010
    word32 r)
3011
0
{
3012
0
    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
3013
0
    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
3014
0
    const word32* rk;
3015
3016
#ifdef WC_C_DYNAMIC_FALLBACK
3017
    rk = aes->key_C_fallback;
3018
#else
3019
0
    rk = aes->key;
3020
0
#endif
3021
3022
    /*
3023
     * map byte array block to cipher state
3024
     * and add initial round key:
3025
     */
3026
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
3027
0
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
3028
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
3029
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
3030
3031
0
#ifdef LITTLE_ENDIAN_ORDER
3032
0
    s0 = ByteReverseWord32(s0);
3033
0
    s1 = ByteReverseWord32(s1);
3034
0
    s2 = ByteReverseWord32(s2);
3035
0
    s3 = ByteReverseWord32(s3);
3036
0
#endif
3037
3038
0
    s0 ^= rk[0];
3039
0
    s1 ^= rk[1];
3040
0
    s2 ^= rk[2];
3041
0
    s3 ^= rk[3];
3042
3043
0
#ifndef WOLFSSL_AES_SMALL_TABLES
3044
0
#ifndef WC_NO_CACHE_RESISTANT
3045
0
    s0 |= PreFetchTd();
3046
0
#endif
3047
3048
0
#ifndef WOLFSSL_AES_TOUCH_LINES
3049
/* Unroll the loop. */
3050
0
#define DEC_ROUND_T_S(o)                                            \
3051
0
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
3052
0
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
3053
0
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
3054
0
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
3055
0
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
3056
0
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
3057
0
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
3058
0
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
3059
0
#define DEC_ROUND_S_T(o)                                            \
3060
0
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
3061
0
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
3062
0
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
3063
0
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
3064
0
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
3065
0
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
3066
0
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
3067
0
         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
3068
#else
3069
#define DEC_ROUND_T_S(o)                                                       \
3070
    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
3071
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
3072
    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
3073
                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
3074
    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
3075
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
3076
    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
3077
                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
3078
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
3079
3080
#define DEC_ROUND_S_T(o)                                                       \
3081
    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
3082
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
3083
    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
3084
                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
3085
    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
3086
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
3087
    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
3088
                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
3089
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
3090
#endif
3091
3092
0
#ifndef WOLFSSL_AES_NO_UNROLL
3093
0
                       DEC_ROUND_T_S( 0);
3094
0
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3095
0
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3096
0
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3097
0
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3098
0
    if (r > 5) {
3099
0
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3100
0
        if (r > 6) {
3101
0
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3102
0
        }
3103
0
    }
3104
0
    rk += r * 8;
3105
#else
3106
3107
    /*
3108
     * Nr - 1 full rounds:
3109
     */
3110
3111
    for (;;) {
3112
        DEC_ROUND_T_S(0);
3113
3114
        rk += 8;
3115
        if (--r == 0) {
3116
            break;
3117
        }
3118
3119
        DEC_ROUND_S_T(0);
3120
    }
3121
#endif
3122
    /*
3123
     * apply last round and
3124
     * map cipher state to byte array block:
3125
     */
3126
3127
0
#ifndef WC_NO_CACHE_RESISTANT
3128
0
    t0 |= PreFetchTd4();
3129
0
#endif
3130
3131
0
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3132
0
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3133
0
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3134
0
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3135
0
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3136
0
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3137
0
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3138
0
                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
3139
#else
3140
#ifndef WC_NO_CACHE_RESISTANT
3141
    s0 |= PreFetchTd4();
3142
#endif
3143
3144
    r *= 2;
3145
    for (rk += 4; r > 1; r--, rk += 4) {
3146
        t0 =
3147
            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3148
            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3149
            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3150
            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
3151
            rk[0];
3152
        t1 =
3153
            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3154
            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3155
            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3156
            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
3157
            rk[1];
3158
        t2 =
3159
            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3160
            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3161
            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3162
            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
3163
            rk[2];
3164
        t3 =
3165
            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3166
            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3167
            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3168
            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
3169
            rk[3];
3170
3171
        s0 =
3172
            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
3173
            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
3174
            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
3175
            (inv_col_mul(t0, 1, 3, 2, 0)      );
3176
        s1 =
3177
            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
3178
            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
3179
            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
3180
            (inv_col_mul(t1, 1, 3, 2, 0)      );
3181
        s2 =
3182
            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
3183
            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
3184
            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
3185
            (inv_col_mul(t2, 1, 3, 2, 0)      );
3186
        s3 =
3187
            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
3188
            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
3189
            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
3190
            (inv_col_mul(t3, 1, 3, 2, 0)      );
3191
    }
3192
3193
    t0 =
3194
        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3195
        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3196
        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3197
        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
3198
    t1 =
3199
        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3200
        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3201
        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3202
        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
3203
    t2 =
3204
        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3205
        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3206
        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3207
        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
3208
    t3 =
3209
        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3210
        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3211
        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3212
        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
3213
    s0 = t0 ^ rk[0];
3214
    s1 = t1 ^ rk[1];
3215
    s2 = t2 ^ rk[2];
3216
    s3 = t3 ^ rk[3];
3217
#endif
3218
3219
    /* write out */
3220
0
#ifdef LITTLE_ENDIAN_ORDER
3221
0
    s0 = ByteReverseWord32(s0);
3222
0
    s1 = ByteReverseWord32(s1);
3223
0
    s2 = ByteReverseWord32(s2);
3224
0
    s3 = ByteReverseWord32(s3);
3225
0
#endif
3226
3227
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
3228
0
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
3229
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
3230
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
3231
3232
0
}
3233
3234
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3235
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
3236
    !defined(MAX3266X_AES)
3237
/* Decrypt a number of blocks using AES.
3238
 *
3239
 * @param [in]  aes  AES object.
3240
 * @param [in]  in   Block to encrypt.
3241
 * @param [out] out  Encrypted block.
3242
 * @param [in]  sz   Number of blocks to encrypt.
3243
 */
3244
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3245
{
3246
    word32 i;
3247
3248
    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
3249
        AesDecrypt_C(aes, in, out, aes->rounds >> 1);
3250
        in += WC_AES_BLOCK_SIZE;
3251
        out += WC_AES_BLOCK_SIZE;
3252
    }
3253
}
3254
#endif
3255
3256
#else /* WC_AES_BITSLICED */
3257
3258
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
3259
static void bs_inv_sub_bytes(bs_word u[8])
3260
{
3261
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
3262
    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
3263
    bs_word RTL0, RTL1, RTL2;
3264
    bs_word sa0, sa1;
3265
    bs_word sb0, sb1;
3266
    bs_word ab0, ab1, ab2, ab3;
3267
    bs_word ab20, ab21, ab22, ab23;
3268
    bs_word al, ah, aa, bl, bh, bb;
3269
    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
3270
    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
3271
    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
3272
    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
3273
    bs_word rr1, rr2;
3274
    bs_word r10, r11;
3275
    bs_word cp1, cp2, cp3, cp4;
3276
    bs_word vr1, vr2, vr3;
3277
    bs_word pr1, pr2, pr3;
3278
    bs_word wr1, wr2, wr3;
3279
    bs_word qr1, qr2, qr3;
3280
    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
3281
    bs_word tinv10, tinv11, tinv12, tinv13;
3282
    bs_word t01, t02;
3283
    bs_word d0, d1, d2, d3;
3284
    bs_word dl, dd, dh;
3285
    bs_word sd0, sd1;
3286
    bs_word p0, p1, p2, p3, p4, p6, p7;
3287
    bs_word X11, X13, X14, X16, X18, X19;
3288
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
3289
3290
    U0 = u[7];
3291
    U1 = u[6];
3292
    U2 = u[5];
3293
    U3 = u[4];
3294
    U4 = u[3];
3295
    U5 = u[2];
3296
    U6 = u[1];
3297
    U7 = u[0];
3298
3299
    Y0 = U0 ^ U3;
3300
    Y2 = ~(U1 ^ U3);
3301
    Y4 = U0 ^ Y2;
3302
    RTL0 = U6 ^ U7;
3303
    Y1 = Y2 ^ RTL0;
3304
    Y7 = ~(U2 ^ Y1);
3305
    RTL1 = U3 ^ U4;
3306
    Y6 = ~(U7 ^ RTL1);
3307
    Y3 = Y1 ^ RTL1;
3308
    RTL2 = ~(U0 ^ U2);
3309
    Y5 = U5 ^ RTL2;
3310
    sa1 = Y0 ^ Y2;
3311
    sa0 = Y1 ^ Y3;
3312
    sb1 = Y4 ^ Y6;
3313
    sb0 = Y5 ^ Y7;
3314
    ah = Y0 ^ Y1;
3315
    al = Y2 ^ Y3;
3316
    aa = sa0 ^ sa1;
3317
    bh = Y4 ^ Y5;
3318
    bl = Y6 ^ Y7;
3319
    bb = sb0 ^ sb1;
3320
    ab20 = sa0 ^ sb0;
3321
    ab22 = al ^ bl;
3322
    ab23 = Y3 ^ Y7;
3323
    ab21 = sa1 ^ sb1;
3324
    abcd1 = ah & bh;
3325
    rr1 = Y0 & Y4;
3326
    ph11 = ab20 ^ abcd1;
3327
    t01 = Y1 & Y5;
3328
    ph01 = t01 ^ abcd1;
3329
    abcd2 = al & bl;
3330
    r1 = Y2 & Y6;
3331
    pl11 = ab22 ^ abcd2;
3332
    r2 = Y3 & Y7;
3333
    pl01 = r2 ^ abcd2;
3334
    r3 = sa0 & sb0;
3335
    vr1 = aa & bb;
3336
    pr1 = vr1 ^ r3;
3337
    wr1 = sa1 & sb1;
3338
    qr1 = wr1 ^ r3;
3339
    ab0 = ph11 ^ rr1;
3340
    ab1 = ph01 ^ ab21;
3341
    ab2 = pl11 ^ r1;
3342
    ab3 = pl01 ^ qr1;
3343
    cp1 = ab0 ^ pr1;
3344
    cp2 = ab1 ^ qr1;
3345
    cp3 = ab2 ^ pr1;
3346
    cp4 = ab3 ^ ab23;
3347
    tinv1 = cp3 ^ cp4;
3348
    tinv2 = cp3 & cp1;
3349
    tinv3 = cp2 ^ tinv2;
3350
    tinv4 = cp1 ^ cp2;
3351
    tinv5 = cp4 ^ tinv2;
3352
    tinv6 = tinv5 & tinv4;
3353
    tinv7 = tinv3 & tinv1;
3354
    d2 = cp4 ^ tinv7;
3355
    d0 = cp2 ^ tinv6;
3356
    tinv8 = cp1 & cp4;
3357
    tinv9 = tinv4 & tinv8;
3358
    tinv10 = tinv4 ^ tinv2;
3359
    d1 = tinv9 ^ tinv10;
3360
    tinv11 = cp2 & cp3;
3361
    tinv12 = tinv1 & tinv11;
3362
    tinv13 = tinv1 ^ tinv2;
3363
    d3 = tinv12 ^ tinv13;
3364
    sd1 = d1 ^ d3;
3365
    sd0 = d0 ^ d2;
3366
    dl = d0 ^ d1;
3367
    dh = d2 ^ d3;
3368
    dd = sd0 ^ sd1;
3369
    abcd3 = dh & bh;
3370
    rr2 = d3 & Y4;
3371
    t02 = d2 & Y5;
3372
    abcd4 = dl & bl;
3373
    r4 = d1 & Y6;
3374
    r5 = d0 & Y7;
3375
    r6 = sd0 & sb0;
3376
    vr2 = dd & bb;
3377
    wr2 = sd1 & sb1;
3378
    abcd5 = dh & ah;
3379
    r7 = d3 & Y0;
3380
    r8 = d2 & Y1;
3381
    abcd6 = dl & al;
3382
    r9 = d1 & Y2;
3383
    r10 = d0 & Y3;
3384
    r11 = sd0 & sa0;
3385
    vr3 = dd & aa;
3386
    wr3 = sd1 & sa1;
3387
    ph12 = rr2 ^ abcd3;
3388
    ph02 = t02 ^ abcd3;
3389
    pl12 = r4 ^ abcd4;
3390
    pl02 = r5 ^ abcd4;
3391
    pr2 = vr2 ^ r6;
3392
    qr2 = wr2 ^ r6;
3393
    p0 = ph12 ^ pr2;
3394
    p1 = ph02 ^ qr2;
3395
    p2 = pl12 ^ pr2;
3396
    p3 = pl02 ^ qr2;
3397
    ph13 = r7 ^ abcd5;
3398
    ph03 = r8 ^ abcd5;
3399
    pl13 = r9 ^ abcd6;
3400
    pl03 = r10 ^ abcd6;
3401
    pr3 = vr3 ^ r11;
3402
    qr3 = wr3 ^ r11;
3403
    p4 = ph13 ^ pr3;
3404
    S7 = ph03 ^ qr3;
3405
    p6 = pl13 ^ pr3;
3406
    p7 = pl03 ^ qr3;
3407
    S3 = p1 ^ p6;
3408
    S6 = p2 ^ p6;
3409
    S0 = p3 ^ p6;
3410
    X11 = p0 ^ p2;
3411
    S5 = S0 ^ X11;
3412
    X13 = p4 ^ p7;
3413
    X14 = X11 ^ X13;
3414
    S1 = S3 ^ X14;
3415
    X16 = p1 ^ S7;
3416
    S2 = X14 ^ X16;
3417
    X18 = p0 ^ p4;
3418
    X19 = S5 ^ X16;
3419
    S4 = X18 ^ X19;
3420
3421
    u[0] = S7;
3422
    u[1] = S6;
3423
    u[2] = S5;
3424
    u[3] = S4;
3425
    u[4] = S3;
3426
    u[5] = S2;
3427
    u[6] = S1;
3428
    u[7] = S0;
3429
}
3430
3431
static void bs_inv_shift_rows(bs_word* b)
3432
{
3433
    bs_word t[AES_BLOCK_BITS];
3434
    int i;
3435
3436
    for (i = 0; i < 128; i += 32) {
3437
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
3438
        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
3439
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
3440
        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
3441
    }
3442
3443
    XMEMCPY(b, t, sizeof(t));
3444
}
3445
3446
#define O0  0
3447
#define O1  8
3448
#define O2  16
3449
#define O3  24
3450
3451
#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
3452
    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
3453
          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
3454
    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
3455
          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
3456
    of2 =                     b[O0+7] ^             b[O1+7] ^               \
3457
                    b[O2+7] ^ b[O3+7];                                      \
3458
                                                                            \
3459
    br[0] =                                                   b[O1+0] ^     \
3460
            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
3461
    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
3462
            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
3463
    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
3464
            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
3465
    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
3466
            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
3467
    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
3468
            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
3469
    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
3470
            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
3471
    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
3472
            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
3473
    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
3474
            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
3475
3476
/* Inverse mix columns and shift rows. */
3477
static void bs_inv_mix_shift(bs_word* t, bs_word* b)
3478
{
3479
    bs_word* bp = b;
3480
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
3481
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
3482
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
3483
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
3484
    int i;
3485
3486
    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
3487
        bs_word* br;
3488
        bs_word of0;
3489
        bs_word of1;
3490
        bs_word of2;
3491
3492
        br = t + or0;
3493
        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
3494
        br = t + or1;
3495
        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
3496
        br = t + or2;
3497
        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
3498
        br = t + or3;
3499
        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
3500
3501
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3502
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3503
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3504
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3505
3506
        bp += AES_BLOCK_BITS / 4;
3507
    }
3508
}
3509
3510
static void bs_inv_sub_bytes_blocks(bs_word* b)
3511
{
3512
    int i;
3513
3514
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
3515
        bs_inv_sub_bytes(b + i);
3516
    }
3517
}
3518
3519
static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
3520
{
3521
    int i;
3522
    bs_word trans[AES_BLOCK_BITS];
3523
3524
    bs_transpose(trans, state);
3525
3526
    rk += r * AES_BLOCK_BITS;
3527
    bs_add_round_key(trans, trans, rk);
3528
    bs_inv_shift_rows(trans);
3529
    bs_inv_sub_bytes_blocks(trans);
3530
    rk -= AES_BLOCK_BITS;
3531
    bs_add_round_key(trans, trans, rk);
3532
    for (i = (int)r - 2; i >= 0; i--) {
3533
        bs_inv_mix_shift(state, trans);
3534
        bs_inv_sub_bytes_blocks(state);
3535
        rk -= AES_BLOCK_BITS;
3536
        bs_add_round_key(trans, state, rk);
3537
    }
3538
3539
    bs_inv_transpose(state, trans);
3540
}
3541
3542
#ifdef WOLFSSL_AES_DIRECT
3543
/* Decrypt a block using AES.
3544
 *
3545
 * @param [in]  aes       AES object.
3546
 * @param [in]  inBlock   Block to encrypt.
3547
 * @param [out] outBlock  Encrypted block.
3548
 * @param [in]  r         Rounds divided by 2.
3549
 */
3550
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3551
    word32 r)
3552
{
3553
    bs_word state[AES_BLOCK_BITS];
3554
3555
    (void)r;
3556
3557
    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
3558
    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
3559
3560
    bs_decrypt(state, aes->bs_key, aes->rounds);
3561
3562
    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
3563
}
3564
#endif
3565
3566
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3567
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3568
/* Decrypt a number of blocks using AES.
3569
 *
3570
 * @param [in]  aes  AES object.
3571
 * @param [in]  in   Block to encrypt.
3572
 * @param [out] out  Encrypted block.
3573
 * @param [in]  sz   Number of blocks to encrypt.
3574
 */
3575
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3576
{
3577
    bs_word state[AES_BLOCK_BITS];
3578
3579
    while (sz >= BS_BLOCK_SIZE) {
3580
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3581
        bs_decrypt(state, aes->bs_key, aes->rounds);
3582
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3583
        sz  -= BS_BLOCK_SIZE;
3584
        in  += BS_BLOCK_SIZE;
3585
        out += BS_BLOCK_SIZE;
3586
    }
3587
    if (sz > 0) {
3588
        XMEMCPY(state, in, sz);
3589
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3590
        bs_decrypt(state, aes->bs_key, aes->rounds);
3591
        XMEMCPY(out, state, sz);
3592
    }
3593
}
3594
#endif
3595
3596
#endif /* !WC_AES_BITSLICED */
3597
3598
#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
3599
/* Software AES - ECB Decrypt */
3600
static WARN_UNUSED_RESULT int wc_AesDecrypt(
3601
    Aes* aes, const byte* inBlock, byte* outBlock)
3602
0
{
3603
#if defined(MAX3266X_AES)
3604
    word32 keySize;
3605
#endif
3606
#if defined(MAX3266X_CB)
3607
    int ret_cb;
3608
#endif
3609
0
    word32 r;
3610
3611
0
    if (aes == NULL) {
3612
0
        return BAD_FUNC_ARG;
3613
0
    }
3614
3615
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3616
    {
3617
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3618
        if (ret < 0)
3619
            return ret;
3620
    }
3621
#endif
3622
3623
0
    r = aes->rounds >> 1;
3624
3625
0
    if (r > 7 || r == 0) {
3626
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3627
0
        return KEYUSAGE_E;
3628
0
    }
3629
3630
#ifdef WOLFSSL_AESNI
3631
    if (aes->use_aesni) {
3632
        ASSERT_SAVED_VECTOR_REGISTERS();
3633
3634
        #ifdef DEBUG_AESNI
3635
            printf("about to aes decrypt\n");
3636
            printf("in  = %p\n", inBlock);
3637
            printf("out = %p\n", outBlock);
3638
            printf("aes->key = %p\n", aes->key);
3639
            printf("aes->rounds = %d\n", aes->rounds);
3640
            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
3641
        #endif
3642
3643
        /* if input and output same will overwrite input iv */
3644
        if ((const byte*)aes->tmp != inBlock)
3645
            XMEMCPY(aes->tmp, inBlock, WC_AES_BLOCK_SIZE);
3646
        AES_ECB_decrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
3647
                        (int)aes->rounds);
3648
        return 0;
3649
    }
3650
    else {
3651
        #ifdef DEBUG_AESNI
3652
            printf("Skipping AES-NI\n");
3653
        #endif
3654
    }
3655
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
3656
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
3657
    if (aes->use_aes_hw_crypto) {
3658
        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
3659
            (int)aes->rounds);
3660
        return 0;
3661
    }
3662
#endif /* WOLFSSL_AESNI */
3663
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3664
    return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
3665
#endif
3666
#if defined(WOLFSSL_IMXRT_DCP)
3667
    if (aes->keylen == 16) {
3668
        DCPAesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
3669
        return 0;
3670
    }
3671
#endif
3672
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3673
    if (aes->useSWCrypt == 0) {
3674
        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
3675
                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
3676
    }
3677
#endif
3678
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3679
    if (wc_esp32AesSupportedKeyLen(aes)) {
3680
        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
3681
    }
3682
    else {
3683
        /* For example, the ESP32-S3 does not support HW for len = 24,
3684
         * so fall back to SW */
3685
    #ifdef DEBUG_WOLFSSL
3686
        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
3687
                        "unsupported keylen = %d", aes->keylen);
3688
    #endif
3689
    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
3690
#endif
3691
3692
#if defined(MAX3266X_AES)
3693
    if (wc_AesGetKeySize(aes, &keySize) == 0) {
3694
        return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
3695
                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
3696
                                    outBlock, (unsigned int)keySize);
3697
    }
3698
#endif
3699
3700
#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
3701
    #ifndef WOLF_CRYPTO_CB_FIND
3702
    if (aes->devId != INVALID_DEVID)
3703
    #endif
3704
    {
3705
        ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock,
3706
                                            WC_AES_BLOCK_SIZE);
3707
        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3708
            return ret_cb;
3709
        /* fall-through when unavailable */
3710
    }
3711
#endif
3712
3713
0
    AesDecrypt_C(aes, inBlock, outBlock, r);
3714
3715
0
    return 0;
3716
0
} /* wc_AesDecrypt[_SW]() */
3717
#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
3718
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
3719
#endif /* HAVE_AES_DECRYPT */
3720
3721
#endif /* NEED_AES_TABLES */
3722
3723
3724
3725
/* wc_AesSetKey */
3726
#if defined(STM32_CRYPTO)
3727
3728
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3729
            const byte* iv, int dir)
3730
    {
3731
        word32 *rk;
3732
3733
        (void)dir;
3734
3735
        if (aes == NULL || (keylen != 16 &&
3736
        #ifdef WOLFSSL_AES_192
3737
            keylen != 24 &&
3738
        #endif
3739
            keylen != 32)) {
3740
            return BAD_FUNC_ARG;
3741
        }
3742
3743
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3744
        {
3745
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3746
            if (ret < 0)
3747
                return ret;
3748
        }
3749
#endif
3750
3751
        rk = aes->key;
3752
        aes->keylen = keylen;
3753
        aes->rounds = keylen/4 + 6;
3754
        XMEMCPY(rk, userKey, keylen);
3755
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
3756
        ByteReverseWords(rk, rk, keylen);
3757
    #endif
3758
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
3759
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
3760
        defined(WOLFSSL_AES_CTS)
3761
        aes->left = 0;
3762
    #endif
3763
        return wc_AesSetIV(aes, iv);
3764
    }
3765
    #if defined(WOLFSSL_AES_DIRECT)
3766
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
3767
                            const byte* iv, int dir)
3768
        {
3769
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
3770
        }
3771
    #endif
3772
3773
#elif defined(HAVE_COLDFIRE_SEC)
3774
    #if defined (HAVE_THREADX)
3775
        #include "memory_pools.h"
3776
        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
3777
    #endif
3778
3779
    #define AES_BUFFER_SIZE (WC_AES_BLOCK_SIZE * 64)
3780
    static unsigned char *AESBuffIn = NULL;
3781
    static unsigned char *AESBuffOut = NULL;
3782
    static byte *secReg;
3783
    static byte *secKey;
3784
    static volatile SECdescriptorType *secDesc;
3785
3786
    static wolfSSL_Mutex Mutex_AesSEC;
3787
3788
    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
3789
    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
3790
3791
    extern volatile unsigned char __MBAR[];
3792
3793
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3794
        const byte* iv, int dir)
3795
    {
3796
        if (AESBuffIn == NULL) {
3797
        #if defined (HAVE_THREADX)
3798
            int s1, s2, s3, s4, s5;
3799
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
3800
                                  sizeof(SECdescriptorType), TX_NO_WAIT);
3801
            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
3802
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
3803
            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
3804
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
3805
            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
3806
                                  WC_AES_BLOCK_SIZE*2, TX_NO_WAIT);
3807
            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
3808
                                  WC_AES_BLOCK_SIZE, TX_NO_WAIT);
3809
3810
            if (s1 || s2 || s3 || s4 || s5)
3811
                return BAD_FUNC_ARG;
3812
        #else
3813
            #warning "Allocate non-Cache buffers"
3814
        #endif
3815
3816
            wc_InitMutex(&Mutex_AesSEC);
3817
        }
3818
3819
        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
3820
            return BAD_FUNC_ARG;
3821
3822
        if (aes == NULL)
3823
            return BAD_FUNC_ARG;
3824
3825
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3826
        {
3827
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3828
            if (ret < 0)
3829
                return ret;
3830
        }
3831
#endif
3832
3833
        aes->keylen = keylen;
3834
        aes->rounds = keylen/4 + 6;
3835
        XMEMCPY(aes->key, userKey, keylen);
3836
3837
        if (iv)
3838
            XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
3839
3840
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
3841
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
3842
        defined(WOLFSSL_AES_CTS)
3843
        aes->left = 0;
3844
    #endif
3845
3846
        return 0;
3847
    }
3848
#elif defined(FREESCALE_LTC)
3849
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
3850
        const byte* iv, int dir, int checkKeyLen)
3851
    {
3852
        if (aes == NULL)
3853
            return BAD_FUNC_ARG;
3854
3855
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3856
        {
3857
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3858
            if (ret < 0)
3859
                return ret;
3860
        }
3861
#endif
3862
3863
        if (checkKeyLen) {
3864
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
3865
                return BAD_FUNC_ARG;
3866
        }
3867
        (void)dir;
3868
3869
        aes->rounds = keylen/4 + 6;
3870
        XMEMCPY(aes->key, userKey, keylen);
3871
3872
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
3873
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
3874
        defined(WOLFSSL_AES_CTS)
3875
        aes->left = 0;
3876
    #endif
3877
3878
        return wc_AesSetIV(aes, iv);
3879
    }
3880
3881
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3882
        const byte* iv, int dir)
3883
    {
3884
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
3885
    }
3886
3887
3888
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
3889
                        const byte* iv, int dir)
3890
    {
3891
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
3892
    }
3893
#elif defined(FREESCALE_MMCAU)
3894
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
3895
        const byte* iv, int dir, int checkKeyLen)
3896
    {
3897
        int ret;
3898
        byte* rk;
3899
        byte* tmpKey = (byte*)userKey;
3900
        int tmpKeyDynamic = 0;
3901
        word32 alignOffset = 0;
3902
3903
        (void)dir;
3904
3905
        if (aes == NULL)
3906
            return BAD_FUNC_ARG;
3907
3908
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3909
        {
3910
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3911
            if (ret < 0)
3912
                return ret;
3913
        }
3914
#endif
3915
3916
        if (checkKeyLen) {
3917
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
3918
                return BAD_FUNC_ARG;
3919
        }
3920
3921
        rk = (byte*)aes->key;
3922
        if (rk == NULL)
3923
            return BAD_FUNC_ARG;
3924
3925
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
3926
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
3927
        defined(WOLFSSL_AES_CTS)
3928
        aes->left = 0;
3929
    #endif
3930
3931
        aes->rounds = keylen/4 + 6;
3932
3933
    #ifdef FREESCALE_MMCAU_CLASSIC
3934
        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
3935
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
3936
            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
3937
                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3938
            if (tmp == NULL) {
3939
                return MEMORY_E;
3940
            }
3941
            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
3942
                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
3943
            tmpKey = tmp + alignOffset;
3944
            XMEMCPY(tmpKey, userKey, keylen);
3945
            tmpKeyDynamic = 1;
3946
        #else
3947
            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
3948
            return BAD_ALIGN_E;
3949
        #endif
3950
        }
3951
    #endif
3952
3953
        ret = wolfSSL_CryptHwMutexLock();
3954
        if(ret == 0) {
3955
        #ifdef FREESCALE_MMCAU_CLASSIC
3956
            cau_aes_set_key(tmpKey, keylen*8, rk);
3957
        #else
3958
            MMCAU_AES_SetKey(tmpKey, keylen, rk);
3959
        #endif
3960
            wolfSSL_CryptHwMutexUnLock();
3961
3962
            ret = wc_AesSetIV(aes, iv);
3963
        }
3964
3965
        if (tmpKeyDynamic == 1) {
3966
            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3967
        }
3968
3969
        return ret;
3970
    }
3971
3972
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3973
        const byte* iv, int dir)
3974
    {
3975
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
3976
    }
3977
3978
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
3979
                        const byte* iv, int dir)
3980
    {
3981
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
3982
    }
3983
3984
#elif defined(WOLFSSL_NRF51_AES)
3985
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3986
        const byte* iv, int dir)
3987
    {
3988
        int ret;
3989
3990
        (void)dir;
3991
        (void)iv;
3992
3993
        if (aes == NULL || keylen != 16)
3994
            return BAD_FUNC_ARG;
3995
3996
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3997
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3998
        if (ret < 0)
3999
            return ret;
4000
#endif
4001
4002
        aes->keylen = keylen;
4003
        aes->rounds = keylen/4 + 6;
4004
        XMEMCPY(aes->key, userKey, keylen);
4005
        ret = nrf51_aes_set_key(userKey);
4006
4007
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4008
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4009
        defined(WOLFSSL_AES_CTS)
4010
        aes->left = 0;
4011
    #endif
4012
4013
        return ret;
4014
    }
4015
4016
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4017
                        const byte* iv, int dir)
4018
    {
4019
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4020
    }
4021
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4022
    /* This is the only definition for HW only.
4023
     * but needs to be renamed when fallback needed.
4024
     * See call in wc_AesSetKey() */
4025
    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
4026
        const byte* iv, int dir)
4027
    {
4028
        (void)dir;
4029
        (void)iv;
4030
        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
4031
        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
4032
            return BAD_FUNC_ARG;
4033
        }
4034
4035
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4036
        {
4037
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4038
            if (ret < 0)
4039
                return ret;
4040
        }
4041
#endif
4042
4043
    #if !defined(WOLFSSL_AES_128)
4044
        if (keylen == 16) {
4045
            return BAD_FUNC_ARG;
4046
        }
4047
    #endif
4048
4049
    #if !defined(WOLFSSL_AES_192)
4050
        if (keylen == 24) {
4051
            return BAD_FUNC_ARG;
4052
        }
4053
    #endif
4054
4055
    #if !defined(WOLFSSL_AES_256)
4056
        if (keylen == 32) {
4057
            return BAD_FUNC_ARG;
4058
        }
4059
    #endif
4060
4061
        aes->keylen = keylen;
4062
        aes->rounds = keylen/4 + 6;
4063
4064
        XMEMCPY(aes->key, userKey, keylen);
4065
        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4066
            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4067
            defined(WOLFSSL_AES_CTS)
4068
            aes->left = 0;
4069
        #endif
4070
        return wc_AesSetIV(aes, iv);
4071
    } /* wc_AesSetKey */
4072
4073
    /* end #elif ESP32 */
4074
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
4075
4076
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
4077
                    int dir)
4078
    {
4079
        SaSiError_t ret = SASI_OK;
4080
        SaSiAesIv_t iv_aes;
4081
4082
        if (aes == NULL ||
4083
           (keylen != AES_128_KEY_SIZE &&
4084
            keylen != AES_192_KEY_SIZE &&
4085
            keylen != AES_256_KEY_SIZE)) {
4086
            return BAD_FUNC_ARG;
4087
        }
4088
4089
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4090
        {
4091
            int ret2 =
4092
                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4093
            if (ret2 < 0)
4094
                return ret2;
4095
        }
4096
#endif
4097
4098
    #if defined(AES_MAX_KEY_SIZE)
4099
        if (keylen > (AES_MAX_KEY_SIZE/8)) {
4100
            return BAD_FUNC_ARG;
4101
        }
4102
    #endif
4103
        if (dir != AES_ENCRYPTION &&
4104
            dir != AES_DECRYPTION) {
4105
            return BAD_FUNC_ARG;
4106
        }
4107
4108
        if (dir == AES_ENCRYPTION) {
4109
            aes->ctx.mode = SASI_AES_ENCRYPT;
4110
            SaSi_AesInit(&aes->ctx.user_ctx,
4111
                         SASI_AES_ENCRYPT,
4112
                         SASI_AES_MODE_CBC,
4113
                         SASI_AES_PADDING_NONE);
4114
        }
4115
        else {
4116
            aes->ctx.mode = SASI_AES_DECRYPT;
4117
            SaSi_AesInit(&aes->ctx.user_ctx,
4118
                         SASI_AES_DECRYPT,
4119
                         SASI_AES_MODE_CBC,
4120
                         SASI_AES_PADDING_NONE);
4121
        }
4122
4123
        aes->keylen = keylen;
4124
        aes->rounds = keylen/4 + 6;
4125
        XMEMCPY(aes->key, userKey, keylen);
4126
4127
        aes->ctx.key.pKey = (byte*)aes->key;
4128
        aes->ctx.key.keySize= keylen;
4129
4130
        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
4131
                             SASI_AES_USER_KEY,
4132
                             &aes->ctx.key,
4133
                             sizeof(aes->ctx.key));
4134
        if (ret != SASI_OK) {
4135
            return BAD_FUNC_ARG;
4136
        }
4137
4138
        ret = wc_AesSetIV(aes, iv);
4139
4140
        if (iv)
4141
            XMEMCPY(iv_aes, iv, WC_AES_BLOCK_SIZE);
4142
        else
4143
            XMEMSET(iv_aes,  0, WC_AES_BLOCK_SIZE);
4144
4145
4146
        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
4147
        if (ret != SASI_OK) {
4148
            return ret;
4149
        }
4150
       return ret;
4151
    }
4152
    #if defined(WOLFSSL_AES_DIRECT)
4153
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4154
                            const byte* iv, int dir)
4155
        {
4156
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4157
        }
4158
    #endif
4159
4160
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
4161
    && !defined(WOLFSSL_QNX_CAAM)
4162
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4163
4164
#elif defined(WOLFSSL_AFALG)
4165
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4166
4167
#elif defined(WOLFSSL_DEVCRYPTO_AES)
4168
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
4169
4170
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4171
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
4172
4173
#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
4174
     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
4175
    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
4176
4177
#else
4178
    #define NEED_SOFTWARE_AES_SETKEY
4179
#endif
4180
4181
/* Either we fell though with no HW support at all,
4182
 * or perhaps there's HW support for *some* keylengths
4183
 * and we need both HW and SW. */
4184
#ifdef NEED_SOFTWARE_AES_SETKEY
4185
4186
#ifdef NEED_AES_TABLES
4187
4188
#ifndef WC_AES_BITSLICED
4189
/* Set the AES key and expand.
4190
 *
4191
 * @param [in]  aes    AES object.
4192
 * @param [in]  key    Block to encrypt.
4193
 * @param [in]  keySz  Number of bytes in key.
4194
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4195
 */
4196
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4197
0
{
4198
#ifdef WC_C_DYNAMIC_FALLBACK
4199
    word32* rk = aes->key_C_fallback;
4200
#else
4201
0
    word32* rk = aes->key;
4202
0
#endif
4203
0
    word32 temp;
4204
0
    unsigned int i = 0;
4205
4206
0
    XMEMCPY(rk, key, keySz);
4207
0
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
4208
0
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
4209
0
    !defined(MAX3266X_AES)
4210
    /* Always reverse words when using only SW */
4211
0
    {
4212
0
        ByteReverseWords(rk, rk, keySz);
4213
0
    }
4214
#else
4215
    /* Sometimes reverse words when using supported HW */
4216
    #if defined(WOLFSSL_ESPIDF)
4217
        /* Some platforms may need SW fallback (e.g. AES192) */
4218
        #if defined(NEED_AES_HW_FALLBACK)
4219
        {
4220
            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
4221
            if (wc_esp32AesSupportedKeyLen(aes)) {
4222
                /* don't reverse for HW supported key lengths */
4223
            }
4224
            else {
4225
                ByteReverseWords(rk, rk, keySz);
4226
            }
4227
        }
4228
        #else
4229
            /* If we don't need SW fallback, don't need to reverse words. */
4230
        #endif /* NEED_AES_HW_FALLBACK */
4231
    #endif /* WOLFSSL_ESPIDF */
4232
#endif /* LITTLE_ENDIAN_ORDER, etc */
4233
4234
0
    switch (keySz) {
4235
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
4236
0
        defined(WOLFSSL_AES_128)
4237
0
    case 16:
4238
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4239
        temp = (word32)-1;
4240
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4241
    #endif
4242
0
        while (1)
4243
0
        {
4244
0
            temp  = rk[3];
4245
0
            rk[4] = rk[0] ^
4246
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
4247
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4248
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4249
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4250
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4251
        #else
4252
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4253
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4254
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4255
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4256
        #endif
4257
0
                rcon[i];
4258
0
            rk[5] = rk[1] ^ rk[4];
4259
0
            rk[6] = rk[2] ^ rk[5];
4260
0
            rk[7] = rk[3] ^ rk[6];
4261
0
            if (++i == 10)
4262
0
                break;
4263
0
            rk += 4;
4264
0
        }
4265
0
        break;
4266
0
#endif /* 128 */
4267
4268
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
4269
0
        defined(WOLFSSL_AES_192)
4270
0
    case 24:
4271
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4272
        temp = (word32)-1;
4273
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4274
    #endif
4275
        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
4276
0
        while (1)
4277
0
        {
4278
0
            temp = rk[ 5];
4279
0
            rk[ 6] = rk[ 0] ^
4280
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
4281
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4282
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4283
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4284
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4285
        #else
4286
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4287
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4288
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4289
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4290
        #endif
4291
0
                rcon[i];
4292
0
            rk[ 7] = rk[ 1] ^ rk[ 6];
4293
0
            rk[ 8] = rk[ 2] ^ rk[ 7];
4294
0
            rk[ 9] = rk[ 3] ^ rk[ 8];
4295
0
            if (++i == 8)
4296
0
                break;
4297
0
            rk[10] = rk[ 4] ^ rk[ 9];
4298
0
            rk[11] = rk[ 5] ^ rk[10];
4299
0
            rk += 6;
4300
0
        }
4301
0
        break;
4302
0
#endif /* 192 */
4303
4304
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
4305
0
        defined(WOLFSSL_AES_256)
4306
0
    case 32:
4307
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4308
        temp = (word32)-1;
4309
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4310
    #endif
4311
0
        while (1)
4312
0
        {
4313
0
            temp = rk[ 7];
4314
0
            rk[ 8] = rk[ 0] ^
4315
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
4316
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4317
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4318
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4319
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4320
        #else
4321
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4322
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4323
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4324
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4325
        #endif
4326
0
                rcon[i];
4327
0
            rk[ 9] = rk[ 1] ^ rk[ 8];
4328
0
            rk[10] = rk[ 2] ^ rk[ 9];
4329
0
            rk[11] = rk[ 3] ^ rk[10];
4330
0
            if (++i == 7)
4331
0
                break;
4332
0
            temp = rk[11];
4333
0
            rk[12] = rk[ 4] ^
4334
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
4335
0
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
4336
0
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
4337
0
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
4338
0
                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
4339
        #else
4340
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
4341
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
4342
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
4343
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
4344
        #endif
4345
0
            rk[13] = rk[ 5] ^ rk[12];
4346
0
            rk[14] = rk[ 6] ^ rk[13];
4347
0
            rk[15] = rk[ 7] ^ rk[14];
4348
4349
0
            rk += 8;
4350
0
        }
4351
0
        break;
4352
0
#endif /* 256 */
4353
0
    } /* switch */
4354
0
    ForceZero(&temp, sizeof(temp));
4355
4356
0
#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
4357
0
    if (dir == AES_DECRYPTION) {
4358
0
        unsigned int j;
4359
4360
#ifdef WC_C_DYNAMIC_FALLBACK
4361
        rk = aes->key_C_fallback;
4362
#else
4363
0
        rk = aes->key;
4364
0
#endif
4365
4366
        /* invert the order of the round keys: */
4367
0
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
4368
0
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
4369
0
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
4370
0
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
4371
0
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
4372
0
        }
4373
0
        ForceZero(&temp, sizeof(temp));
4374
0
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
4375
        /* apply the inverse MixColumn transform to all round keys but the
4376
           first and the last: */
4377
0
        for (i = 1; i < aes->rounds; i++) {
4378
0
            rk += 4;
4379
0
            rk[0] =
4380
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
4381
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
4382
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
4383
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
4384
0
            rk[1] =
4385
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
4386
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
4387
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
4388
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
4389
0
            rk[2] =
4390
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
4391
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
4392
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
4393
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
4394
0
            rk[3] =
4395
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
4396
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
4397
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
4398
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
4399
0
        }
4400
0
    #endif
4401
0
    }
4402
#else
4403
    (void)dir;
4404
#endif /* HAVE_AES_DECRYPT */
4405
4406
#ifdef WOLFSSL_CHECK_MEM_ZERO
4407
    wc_MemZero_Check(&temp, sizeof(temp));
4408
#else
4409
0
    (void)temp;
4410
0
#endif
4411
0
}
4412
#else /* WC_AES_BITSLICED */
4413
/* Set the AES key and expand.
4414
 *
4415
 * @param [in]  aes    AES object.
4416
 * @param [in]  key    Block to encrypt.
4417
 * @param [in]  keySz  Number of bytes in key.
4418
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4419
 */
4420
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4421
{
4422
    /* No need to invert when decrypting. */
4423
    (void)dir;
4424
4425
    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
4426
}
4427
#endif /* WC_AES_BITSLICED */
4428
4429
#endif /* NEED_AES_TABLES */
4430
4431
#ifndef WOLFSSL_RISCV_ASM
4432
    /* Software AES - SetKey */
4433
    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
4434
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
4435
        int checkKeyLen)
4436
0
    {
4437
0
        int ret;
4438
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4439
        byte   local[32];
4440
        word32 localSz = 32;
4441
    #endif
4442
4443
0
        if (aes == NULL)
4444
0
            return BAD_FUNC_ARG;
4445
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4446
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4447
        if (ret < 0)
4448
            return ret;
4449
#endif
4450
4451
0
        switch (keylen) {
4452
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4453
0
        defined(WOLFSSL_AES_128)
4454
0
        case 16:
4455
0
    #endif
4456
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4457
0
        defined(WOLFSSL_AES_192)
4458
0
        case 24:
4459
0
    #endif
4460
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4461
0
        defined(WOLFSSL_AES_256)
4462
0
        case 32:
4463
0
    #endif
4464
0
            break;
4465
0
        default:
4466
0
            return BAD_FUNC_ARG;
4467
0
        }
4468
4469
    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
4470
        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
4471
            return WC_HW_E;
4472
        }
4473
    #endif
4474
4475
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4476
        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
4477
            keylen == (24 + WC_CAAM_BLOB_SZ) ||
4478
            keylen == (32 + WC_CAAM_BLOB_SZ)) {
4479
            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
4480
                return BAD_FUNC_ARG;
4481
            }
4482
4483
            /* set local values */
4484
            userKey = local;
4485
            keylen = localSz;
4486
        }
4487
    #endif
4488
4489
    #ifdef WOLFSSL_SECO_CAAM
4490
        /* if set to use hardware than import the key */
4491
        if (aes->devId == WOLFSSL_SECO_DEVID) {
4492
            int keyGroup = 1; /* group one was chosen arbitrarily */
4493
            unsigned int keyIdOut;
4494
            byte importiv[GCM_NONCE_MID_SZ];
4495
            int importivSz = GCM_NONCE_MID_SZ;
4496
            int keyType = 0;
4497
            WC_RNG rng;
4498
4499
            if (wc_InitRng(&rng) != 0) {
4500
                WOLFSSL_MSG("RNG init for IV failed");
4501
                return WC_HW_E;
4502
            }
4503
4504
            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
4505
                WOLFSSL_MSG("Generate IV failed");
4506
                wc_FreeRng(&rng);
4507
                return WC_HW_E;
4508
            }
4509
            wc_FreeRng(&rng);
4510
4511
            if (iv)
4512
                XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4513
            else
4514
                XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
4515
4516
            switch (keylen) {
4517
                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
4518
                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
4519
                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
4520
            }
4521
4522
            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
4523
                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
4524
            if (keyIdOut == 0) {
4525
                return WC_HW_E;
4526
            }
4527
            aes->blackKey = keyIdOut;
4528
            return 0;
4529
        }
4530
    #endif
4531
4532
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
4533
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
4534
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
4535
        #ifdef WOLF_CRYPTO_CB
4536
        if (aes->devId != INVALID_DEVID)
4537
        #endif
4538
        {
4539
            if (keylen > sizeof(aes->devKey)) {
4540
                return BAD_FUNC_ARG;
4541
            }
4542
            XMEMCPY(aes->devKey, userKey, keylen);
4543
        }
4544
    #endif
4545
4546
0
        if (checkKeyLen) {
4547
0
            if (keylen != 16 && keylen != 24 && keylen != 32) {
4548
0
                return BAD_FUNC_ARG;
4549
0
            }
4550
        #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
4551
            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
4552
             * all key sizes. Otherwise this condition is never true. */
4553
            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
4554
                return BAD_FUNC_ARG;
4555
            }
4556
        #endif
4557
0
        }
4558
4559
    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4560
        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4561
        defined(WOLFSSL_AES_CTS)
4562
        aes->left = 0;
4563
    #endif
4564
4565
0
        aes->keylen = (int)keylen;
4566
0
        aes->rounds = (keylen/4) + 6;
4567
0
        ret = wc_AesSetIV(aes, iv);
4568
0
        if (ret != 0)
4569
0
            return ret;
4570
4571
#ifdef WC_C_DYNAMIC_FALLBACK
4572
#ifdef NEED_AES_TABLES
4573
        AesSetKey_C(aes, userKey, keylen, dir);
4574
#endif /* NEED_AES_TABLES */
4575
#endif /* WC_C_DYNAMIC_FALLBACK */
4576
4577
    #ifdef WOLFSSL_AESNI
4578
4579
       /* The dynamics for determining whether AES-NI will be used are tricky.
4580
        *
4581
        * First, we check for CPU support and cache the result -- if AES-NI is
4582
        * missing, we always shortcut to the AesSetKey_C() path.
4583
        *
4584
        * Second, if the CPU supports AES-NI, we confirm on a per-call basis
4585
        * that it's safe to use in the caller context, using
4586
        * SAVE_VECTOR_REGISTERS2().  This is an always-true no-op in user-space
4587
        * builds, but has substantive logic behind it in kernel module builds.
4588
        *
4589
        * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on
4590
        * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with
4591
        * success but with AES-NI disabled (the earlier AesSetKey_C() allows
4592
        * future encrypt/decrypt calls to succeed), otherwise we fail.
4593
        *
4594
        * Upon successful return, aes->use_aesni will have a zero value if
4595
        * AES-NI is disabled, and a nonzero value if it's enabled.
4596
        *
4597
        * An additional, optional semantic is available via
4598
        * WC_FLAG_DONT_USE_AESNI, and is used in some kernel module builds to
4599
        * let the caller inhibit AES-NI.  When this macro is defined,
4600
        * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of
4601
        * uninitialized data in aes->use_aesni.  That's why support for
4602
        * WC_FLAG_DONT_USE_AESNI must remain optional -- wc_AesInit() was only
4603
        * added in release 3.11.0, so legacy applications inevitably call
4604
        * wc_AesSetKey() on uninitialized Aes contexts.  This must continue to
4605
        * function correctly with default build settings.
4606
        */
4607
4608
        if (checkedAESNI == 0) {
4609
            haveAESNI  = Check_CPU_support_AES();
4610
            checkedAESNI = 1;
4611
        }
4612
        if (haveAESNI
4613
#if defined(WC_FLAG_DONT_USE_AESNI) && !defined(WC_C_DYNAMIC_FALLBACK)
4614
            && (aes->use_aesni != WC_FLAG_DONT_USE_AESNI)
4615
#endif
4616
            )
4617
        {
4618
#if defined(WC_FLAG_DONT_USE_AESNI)
4619
            if (aes->use_aesni == WC_FLAG_DONT_USE_AESNI) {
4620
                aes->use_aesni = 0;
4621
                return 0;
4622
            }
4623
#endif
4624
            aes->use_aesni = 0;
4625
            #ifdef WOLFSSL_LINUXKM
4626
            /* runtime alignment check */
4627
            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
4628
                return BAD_ALIGN_E;
4629
            }
4630
            #endif /* WOLFSSL_LINUXKM */
4631
            ret = SAVE_VECTOR_REGISTERS2();
4632
            if (ret == 0) {
4633
                if (dir == AES_ENCRYPTION)
4634
                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
4635
#ifdef HAVE_AES_DECRYPT
4636
                else
4637
                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
4638
#endif
4639
4640
                RESTORE_VECTOR_REGISTERS();
4641
4642
                if (ret == 0)
4643
                    aes->use_aesni = 1;
4644
                else {
4645
#ifdef WC_C_DYNAMIC_FALLBACK
4646
                    ret = 0;
4647
#endif
4648
                }
4649
                return ret;
4650
            } else {
4651
#ifdef WC_C_DYNAMIC_FALLBACK
4652
                return 0;
4653
#else
4654
                return ret;
4655
#endif
4656
            }
4657
        }
4658
        else {
4659
            aes->use_aesni = 0;
4660
#ifdef WC_C_DYNAMIC_FALLBACK
4661
            /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C()
4662
             * above.
4663
             */
4664
            return 0;
4665
#endif
4666
        }
4667
    #endif /* WOLFSSL_AESNI */
4668
4669
    #if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
4670
        !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
4671
        Check_CPU_support_HwCrypto(aes);
4672
        if (aes->use_aes_hw_crypto) {
4673
            return AES_set_key_AARCH64(userKey, keylen, aes, dir);
4674
        }
4675
    #endif
4676
4677
    #ifdef WOLFSSL_KCAPI_AES
4678
        XMEMCPY(aes->devKey, userKey, keylen);
4679
        if (aes->init != 0) {
4680
            kcapi_cipher_destroy(aes->handle);
4681
            aes->handle = NULL;
4682
            aes->init = 0;
4683
        }
4684
        (void)dir;
4685
    #endif
4686
4687
0
        if (keylen > sizeof(aes->key)) {
4688
0
            return BAD_FUNC_ARG;
4689
0
        }
4690
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
4691
        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
4692
                                  ((psa_algorithm_t)0), dir);
4693
#endif
4694
4695
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
4696
        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
4697
         * instead of SE05x crypto by setting useSWCrypt */
4698
        if (aes->useSWCrypt == 0) {
4699
            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
4700
            if (ret == 0) {
4701
                ret = wc_AesSetIV(aes, iv);
4702
            }
4703
            return ret;
4704
        }
4705
#endif
4706
4707
0
        XMEMCPY(aes->key, userKey, keylen);
4708
4709
0
#ifndef WC_AES_BITSLICED
4710
0
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
4711
0
        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
4712
0
        && !defined(MAX3266X_AES)
4713
4714
        /* software */
4715
0
        ByteReverseWords(aes->key, aes->key, keylen);
4716
4717
    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4718
        if (wc_esp32AesSupportedKeyLen(aes)) {
4719
            /* supported lengths don't get reversed */
4720
            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
4721
        }
4722
        else {
4723
            word32* rk = aes->key;
4724
4725
            /* For example, the ESP32-S3 does not support HW for len = 24,
4726
             * so fall back to SW */
4727
        #ifdef DEBUG_WOLFSSL
4728
            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
4729
        #endif
4730
            XMEMCPY(rk, userKey, keylen);
4731
            /* When not ESP32 HW, we need to reverse endianness */
4732
            ByteReverseWords(rk, rk, keylen);
4733
        }
4734
    #endif
4735
4736
    #ifdef WOLFSSL_IMXRT_DCP
4737
        {
4738
            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
4739
            word32 temp = 0;
4740
            if (keylen == 16)
4741
                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
4742
            if (temp != 0)
4743
                return WC_HW_E;
4744
        }
4745
    #endif
4746
0
#endif /* !WC_AES_BITSLICED */
4747
4748
0
#ifdef NEED_AES_TABLES
4749
0
        AesSetKey_C(aes, userKey, keylen, dir);
4750
0
#endif /* NEED_AES_TABLES */
4751
4752
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
4753
        XMEMCPY((byte*)aes->key, userKey, keylen);
4754
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
4755
            ByteReverseWords(aes->key, aes->key, 32);
4756
        }
4757
#endif
4758
4759
    #if defined(WOLFSSL_DEVCRYPTO) && \
4760
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
4761
        aes->ctx.cfd = -1;
4762
    #endif
4763
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4764
        ForceZero(local, sizeof(local));
4765
    #endif
4766
0
        return ret;
4767
0
    } /* wc_AesSetKeyLocal */
4768
4769
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4770
            const byte* iv, int dir)
4771
0
    {
4772
0
        if (aes == NULL) {
4773
0
            return BAD_FUNC_ARG;
4774
0
        }
4775
0
        if (keylen > sizeof(aes->key)) {
4776
0
            return BAD_FUNC_ARG;
4777
0
        }
4778
4779
    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
4780
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
4781
        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
4782
        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
4783
            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
4784
            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
4785
        }
4786
        else {
4787
        #if  defined(WOLFSSL_HW_METRICS)
4788
            /* It is interesting to know how many times we could not complete
4789
             * AES in hardware due to unsupported lengths. */
4790
            wc_esp32AesUnupportedLengthCountAdd();
4791
        #endif
4792
        #ifdef DEBUG_WOLFSSL
4793
            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
4794
                           keylen);
4795
        #endif
4796
        }
4797
    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
4798
4799
0
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4800
4801
0
    } /* wc_AesSetKey() */
4802
#endif
4803
4804
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
4805
        /* AES-CTR and AES-DIRECT need to use this for key setup */
4806
        /* This function allows key sizes that are not 128/192/256 bits */
4807
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4808
                           const byte* iv, int dir)
4809
    {
4810
        if (aes == NULL) {
4811
            return BAD_FUNC_ARG;
4812
        }
4813
        if (keylen > sizeof(aes->key)) {
4814
            return BAD_FUNC_ARG;
4815
        }
4816
4817
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
4818
    }
4819
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
4820
#endif /* wc_AesSetKey block */
4821
4822
4823
/* wc_AesSetIV is shared between software and hardware */
4824
int wc_AesSetIV(Aes* aes, const byte* iv)
4825
0
{
4826
0
    if (aes == NULL)
4827
0
        return BAD_FUNC_ARG;
4828
4829
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4830
    {
4831
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4832
        if (ret < 0)
4833
            return ret;
4834
    }
4835
#endif
4836
4837
0
    if (iv)
4838
0
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
4839
0
    else
4840
0
        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
4841
4842
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4843
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
4844
    defined(WOLFSSL_AES_CTS)
4845
    /* Clear any unused bytes from last cipher op. */
4846
    aes->left = 0;
4847
#endif
4848
4849
0
    return 0;
4850
0
}
4851
4852
#ifdef WOLFSSL_AESNI
4853
4854
#ifdef WC_C_DYNAMIC_FALLBACK
4855
4856
#define VECTOR_REGISTERS_PUSH {                                      \
4857
        int orig_use_aesni = aes->use_aesni;                         \
4858
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
4859
            aes->use_aesni = 0;                                      \
4860
        }                                                            \
4861
        WC_DO_NOTHING
4862
4863
#define VECTOR_REGISTERS_POP                                         \
4864
        if (aes->use_aesni)                                          \
4865
            RESTORE_VECTOR_REGISTERS();                              \
4866
        else                                                         \
4867
            aes->use_aesni = orig_use_aesni;                         \
4868
    }                                                                \
4869
    WC_DO_NOTHING
4870
4871
#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
4872
4873
#define VECTOR_REGISTERS_PUSH { \
4874
        WC_DO_NOTHING
4875
4876
#define VECTOR_REGISTERS_POP                                         \
4877
    }                                                                \
4878
    WC_DO_NOTHING
4879
4880
#else
4881
4882
#define VECTOR_REGISTERS_PUSH { \
4883
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
4884
            return ret;                                                  \
4885
        }                                                                \
4886
        WC_DO_NOTHING
4887
4888
#define VECTOR_REGISTERS_POP \
4889
        if (aes->use_aesni) {                                            \
4890
            RESTORE_VECTOR_REGISTERS();                                  \
4891
        }                                                                \
4892
    }                                                                    \
4893
    WC_DO_NOTHING
4894
4895
#endif
4896
4897
#else /* !WOLFSSL_AESNI */
4898
4899
0
#define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
4900
0
#define VECTOR_REGISTERS_POP } WC_DO_NOTHING
4901
4902
#endif /* !WOLFSSL_AESNI */
4903
4904
4905
/* AES-DIRECT */
4906
#if defined(WOLFSSL_AES_DIRECT)
4907
    #if defined(HAVE_COLDFIRE_SEC)
4908
        #error "Coldfire SEC doesn't yet support AES direct"
4909
4910
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
4911
        !defined(WOLFSSL_QNX_CAAM)
4912
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4913
4914
    #elif defined(WOLFSSL_AFALG)
4915
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4916
4917
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
4918
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
4919
4920
    #else
4921
4922
        /* Allow direct access to one block encrypt */
4923
        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
4924
        {
4925
            int ret;
4926
4927
            if (aes == NULL)
4928
                return BAD_FUNC_ARG;
4929
            VECTOR_REGISTERS_PUSH;
4930
            ret = wc_AesEncrypt(aes, in, out);
4931
            VECTOR_REGISTERS_POP;
4932
            return ret;
4933
        }
4934
4935
        /* vector reg save/restore is explicit in all below calls to
4936
         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
4937
         * macro.
4938
         */
4939
        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
4940
4941
        #ifdef HAVE_AES_DECRYPT
4942
        /* Allow direct access to one block decrypt */
4943
        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
4944
        {
4945
            int ret;
4946
4947
            if (aes == NULL)
4948
                return BAD_FUNC_ARG;
4949
            VECTOR_REGISTERS_PUSH;
4950
            ret = wc_AesDecrypt(aes, in, out);
4951
            VECTOR_REGISTERS_POP;
4952
            return ret;
4953
        }
4954
4955
        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
4956
4957
        #endif /* HAVE_AES_DECRYPT */
4958
    #endif /* AES direct block */
4959
#endif /* WOLFSSL_AES_DIRECT */
4960
4961
4962
/* AES-CBC */
4963
#ifdef HAVE_AES_CBC
4964
#if defined(STM32_CRYPTO)
4965
4966
#ifdef WOLFSSL_STM32_CUBEMX
4967
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
4968
    {
4969
        int ret = 0;
4970
        CRYP_HandleTypeDef hcryp;
4971
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
4972
4973
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
4974
        if (sz % WC_AES_BLOCK_SIZE) {
4975
            return BAD_LENGTH_E;
4976
        }
4977
#endif
4978
        if (blocks == 0)
4979
            return 0;
4980
4981
        ret = wc_Stm32_Aes_Init(aes, &hcryp);
4982
        if (ret != 0)
4983
            return ret;
4984
4985
        ret = wolfSSL_CryptHwMutexLock();
4986
        if (ret != 0) {
4987
            return ret;
4988
        }
4989
4990
    #if defined(STM32_HAL_V2)
4991
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
4992
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
4993
    #elif defined(STM32_CRYPTO_AES_ONLY)
4994
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
4995
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
4996
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
4997
    #endif
4998
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
4999
        HAL_CRYP_Init(&hcryp);
5000
5001
    #if defined(STM32_HAL_V2)
5002
        ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5003
            (uint32_t*)out, STM32_HAL_TIMEOUT);
5004
    #elif defined(STM32_CRYPTO_AES_ONLY)
5005
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
5006
            out, STM32_HAL_TIMEOUT);
5007
    #else
5008
        ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
5009
                                      blocks * WC_AES_BLOCK_SIZE,
5010
                                      out, STM32_HAL_TIMEOUT);
5011
    #endif
5012
        if (ret != HAL_OK) {
5013
            ret = WC_TIMEOUT_E;
5014
        }
5015
5016
        /* store iv for next call */
5017
        XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5018
5019
        HAL_CRYP_DeInit(&hcryp);
5020
5021
        wolfSSL_CryptHwMutexUnLock();
5022
        wc_Stm32_Aes_Cleanup();
5023
5024
        return ret;
5025
    }
5026
    #ifdef HAVE_AES_DECRYPT
5027
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5028
    {
5029
        int ret = 0;
5030
        CRYP_HandleTypeDef hcryp;
5031
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5032
5033
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5034
        if (sz % WC_AES_BLOCK_SIZE) {
5035
            return BAD_LENGTH_E;
5036
        }
5037
#endif
5038
        if (blocks == 0)
5039
            return 0;
5040
5041
        ret = wc_Stm32_Aes_Init(aes, &hcryp);
5042
        if (ret != 0)
5043
            return ret;
5044
5045
        ret = wolfSSL_CryptHwMutexLock();
5046
        if (ret != 0) {
5047
            return ret;
5048
        }
5049
5050
        /* if input and output same will overwrite input iv */
5051
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5052
5053
    #if defined(STM32_HAL_V2)
5054
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
5055
        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
5056
    #elif defined(STM32_CRYPTO_AES_ONLY)
5057
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
5058
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
5059
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
5060
    #endif
5061
5062
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5063
        HAL_CRYP_Init(&hcryp);
5064
5065
    #if defined(STM32_HAL_V2)
5066
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
5067
            (uint32_t*)out, STM32_HAL_TIMEOUT);
5068
    #elif defined(STM32_CRYPTO_AES_ONLY)
5069
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
5070
            out, STM32_HAL_TIMEOUT);
5071
    #else
5072
        ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
5073
                                      blocks * WC_AES_BLOCK_SIZE,
5074
            out, STM32_HAL_TIMEOUT);
5075
    #endif
5076
        if (ret != HAL_OK) {
5077
            ret = WC_TIMEOUT_E;
5078
        }
5079
5080
        /* store iv for next call */
5081
        XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5082
5083
        HAL_CRYP_DeInit(&hcryp);
5084
        wolfSSL_CryptHwMutexUnLock();
5085
        wc_Stm32_Aes_Cleanup();
5086
5087
        return ret;
5088
    }
5089
    #endif /* HAVE_AES_DECRYPT */
5090
5091
#else /* Standard Peripheral Library */
5092
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5093
    {
5094
        int ret;
5095
        word32 *iv;
5096
        CRYP_InitTypeDef cryptInit;
5097
        CRYP_KeyInitTypeDef keyInit;
5098
        CRYP_IVInitTypeDef ivInit;
5099
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5100
5101
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5102
        if (sz % WC_AES_BLOCK_SIZE) {
5103
            return BAD_LENGTH_E;
5104
        }
5105
#endif
5106
        if (blocks == 0)
5107
            return 0;
5108
5109
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
5110
        if (ret != 0)
5111
            return ret;
5112
5113
        ret = wolfSSL_CryptHwMutexLock();
5114
        if (ret != 0) {
5115
            return ret;
5116
        }
5117
5118
        /* reset registers to their default values */
5119
        CRYP_DeInit();
5120
5121
        /* set key */
5122
        CRYP_KeyInit(&keyInit);
5123
5124
        /* set iv */
5125
        iv = aes->reg;
5126
        CRYP_IVStructInit(&ivInit);
5127
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
5128
        ivInit.CRYP_IV0Left  = iv[0];
5129
        ivInit.CRYP_IV0Right = iv[1];
5130
        ivInit.CRYP_IV1Left  = iv[2];
5131
        ivInit.CRYP_IV1Right = iv[3];
5132
        CRYP_IVInit(&ivInit);
5133
5134
        /* set direction and mode */
5135
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
5136
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
5137
        CRYP_Init(&cryptInit);
5138
5139
        /* enable crypto processor */
5140
        CRYP_Cmd(ENABLE);
5141
5142
        while (blocks--) {
5143
            /* flush IN/OUT FIFOs */
5144
            CRYP_FIFOFlush();
5145
5146
            CRYP_DataIn(*(uint32_t*)&in[0]);
5147
            CRYP_DataIn(*(uint32_t*)&in[4]);
5148
            CRYP_DataIn(*(uint32_t*)&in[8]);
5149
            CRYP_DataIn(*(uint32_t*)&in[12]);
5150
5151
            /* wait until the complete message has been processed */
5152
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5153
5154
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5155
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5156
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5157
            *(uint32_t*)&out[12] = CRYP_DataOut();
5158
5159
            /* store iv for next call */
5160
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5161
5162
            sz  -= WC_AES_BLOCK_SIZE;
5163
            in  += WC_AES_BLOCK_SIZE;
5164
            out += WC_AES_BLOCK_SIZE;
5165
        }
5166
5167
        /* disable crypto processor */
5168
        CRYP_Cmd(DISABLE);
5169
        wolfSSL_CryptHwMutexUnLock();
5170
        wc_Stm32_Aes_Cleanup();
5171
5172
        return ret;
5173
    }
5174
5175
    #ifdef HAVE_AES_DECRYPT
5176
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5177
    {
5178
        int ret;
5179
        word32 *iv;
5180
        CRYP_InitTypeDef cryptInit;
5181
        CRYP_KeyInitTypeDef keyInit;
5182
        CRYP_IVInitTypeDef ivInit;
5183
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5184
5185
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5186
        if (sz % WC_AES_BLOCK_SIZE) {
5187
            return BAD_LENGTH_E;
5188
        }
5189
#endif
5190
        if (blocks == 0)
5191
            return 0;
5192
5193
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
5194
        if (ret != 0)
5195
            return ret;
5196
5197
        ret = wolfSSL_CryptHwMutexLock();
5198
        if (ret != 0) {
5199
            return ret;
5200
        }
5201
5202
        /* if input and output same will overwrite input iv */
5203
        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5204
5205
        /* reset registers to their default values */
5206
        CRYP_DeInit();
5207
5208
        /* set direction and key */
5209
        CRYP_KeyInit(&keyInit);
5210
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5211
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
5212
        CRYP_Init(&cryptInit);
5213
5214
        /* enable crypto processor */
5215
        CRYP_Cmd(ENABLE);
5216
5217
        /* wait until key has been prepared */
5218
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5219
5220
        /* set direction and mode */
5221
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5222
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
5223
        CRYP_Init(&cryptInit);
5224
5225
        /* set iv */
5226
        iv = aes->reg;
5227
        CRYP_IVStructInit(&ivInit);
5228
        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
5229
        ivInit.CRYP_IV0Left  = iv[0];
5230
        ivInit.CRYP_IV0Right = iv[1];
5231
        ivInit.CRYP_IV1Left  = iv[2];
5232
        ivInit.CRYP_IV1Right = iv[3];
5233
        CRYP_IVInit(&ivInit);
5234
5235
        /* enable crypto processor */
5236
        CRYP_Cmd(ENABLE);
5237
5238
        while (blocks--) {
5239
            /* flush IN/OUT FIFOs */
5240
            CRYP_FIFOFlush();
5241
5242
            CRYP_DataIn(*(uint32_t*)&in[0]);
5243
            CRYP_DataIn(*(uint32_t*)&in[4]);
5244
            CRYP_DataIn(*(uint32_t*)&in[8]);
5245
            CRYP_DataIn(*(uint32_t*)&in[12]);
5246
5247
            /* wait until the complete message has been processed */
5248
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5249
5250
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5251
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5252
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5253
            *(uint32_t*)&out[12] = CRYP_DataOut();
5254
5255
            /* store iv for next call */
5256
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
5257
5258
            in  += WC_AES_BLOCK_SIZE;
5259
            out += WC_AES_BLOCK_SIZE;
5260
        }
5261
5262
        /* disable crypto processor */
5263
        CRYP_Cmd(DISABLE);
5264
        wolfSSL_CryptHwMutexUnLock();
5265
        wc_Stm32_Aes_Cleanup();
5266
5267
        return ret;
5268
    }
5269
    #endif /* HAVE_AES_DECRYPT */
5270
#endif /* WOLFSSL_STM32_CUBEMX */
5271
5272
#elif defined(HAVE_COLDFIRE_SEC)
5273
    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
5274
        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
5275
    {
5276
        #ifdef DEBUG_WOLFSSL
5277
            int i; int stat1, stat2; int ret;
5278
        #endif
5279
5280
        int size;
5281
        volatile int v;
5282
5283
        if ((pi == NULL) || (po == NULL))
5284
            return BAD_FUNC_ARG;    /*wrong pointer*/
5285
5286
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5287
        if (sz % WC_AES_BLOCK_SIZE) {
5288
            return BAD_LENGTH_E;
5289
        }
5290
#endif
5291
5292
        wc_LockMutex(&Mutex_AesSEC);
5293
5294
        /* Set descriptor for SEC */
5295
        secDesc->length1 = 0x0;
5296
        secDesc->pointer1 = NULL;
5297
5298
        secDesc->length2 = WC_AES_BLOCK_SIZE;
5299
        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
5300
5301
        switch(aes->rounds) {
5302
            case 10: secDesc->length3 = 16; break;
5303
            case 12: secDesc->length3 = 24; break;
5304
            case 14: secDesc->length3 = 32; break;
5305
        }
5306
        XMEMCPY(secKey, aes->key, secDesc->length3);
5307
5308
        secDesc->pointer3 = (byte *)secKey;
5309
        secDesc->pointer4 = AESBuffIn;
5310
        secDesc->pointer5 = AESBuffOut;
5311
        secDesc->length6 = 0x0;
5312
        secDesc->pointer6 = NULL;
5313
        secDesc->length7 = 0x0;
5314
        secDesc->pointer7 = NULL;
5315
        secDesc->nextDescriptorPtr = NULL;
5316
5317
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5318
        size = AES_BUFFER_SIZE;
5319
#endif
5320
        while (sz) {
5321
            secDesc->header = descHeader;
5322
            XMEMCPY(secReg, aes->reg, WC_AES_BLOCK_SIZE);
5323
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5324
            sz -= AES_BUFFER_SIZE;
5325
#else
5326
            if (sz < AES_BUFFER_SIZE) {
5327
                size = sz;
5328
                sz = 0;
5329
            } else {
5330
                size = AES_BUFFER_SIZE;
5331
                sz -= AES_BUFFER_SIZE;
5332
            }
5333
#endif
5334
5335
            secDesc->length4 = size;
5336
            secDesc->length5 = size;
5337
5338
            XMEMCPY(AESBuffIn, pi, size);
5339
            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
5340
                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-WC_AES_BLOCK_SIZE]),
5341
                        WC_AES_BLOCK_SIZE);
5342
            }
5343
5344
            /* Point SEC to the location of the descriptor */
5345
            MCF_SEC_FR0 = (uint32)secDesc;
5346
            /* Initialize SEC and wait for encryption to complete */
5347
            MCF_SEC_CCCR0 = 0x0000001a;
5348
            /* poll SISR to determine when channel is complete */
5349
            v=0;
5350
5351
            while ((secDesc->header>> 24) != 0xff) v++;
5352
5353
            #ifdef DEBUG_WOLFSSL
5354
                ret = MCF_SEC_SISRH;
5355
                stat1 = MCF_SEC_AESSR;
5356
                stat2 = MCF_SEC_AESISR;
5357
                if (ret & 0xe0000000) {
5358
                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
5359
                              "AESISR=%08x\n", i, ret, stat1, stat2);
5360
                }
5361
            #endif
5362
5363
            XMEMCPY(po, AESBuffOut, size);
5364
5365
            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
5366
                XMEMCPY((void*)aes->reg, (void*)&(po[size-WC_AES_BLOCK_SIZE]),
5367
                        WC_AES_BLOCK_SIZE);
5368
            } else {
5369
                XMEMCPY((void*)aes->reg, (void*)aes->tmp, WC_AES_BLOCK_SIZE);
5370
            }
5371
5372
            pi += size;
5373
            po += size;
5374
        }
5375
5376
        wc_UnLockMutex(&Mutex_AesSEC);
5377
        return 0;
5378
    }
5379
5380
    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
5381
    {
5382
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
5383
    }
5384
5385
    #ifdef HAVE_AES_DECRYPT
5386
    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
5387
    {
5388
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
5389
    }
5390
    #endif /* HAVE_AES_DECRYPT */
5391
5392
#elif defined(FREESCALE_LTC)
5393
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5394
    {
5395
        word32 keySize;
5396
        status_t status;
5397
        byte *iv, *enc_key;
5398
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5399
5400
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5401
        if (sz % WC_AES_BLOCK_SIZE) {
5402
            return BAD_LENGTH_E;
5403
        }
5404
#endif
5405
        if (blocks == 0)
5406
            return 0;
5407
5408
        iv      = (byte*)aes->reg;
5409
        enc_key = (byte*)aes->key;
5410
5411
        status = wc_AesGetKeySize(aes, &keySize);
5412
        if (status != 0) {
5413
            return status;
5414
        }
5415
5416
        status = wolfSSL_CryptHwMutexLock();
5417
        if (status != 0)
5418
            return status;
5419
        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
5420
            iv, enc_key, keySize);
5421
        wolfSSL_CryptHwMutexUnLock();
5422
5423
        /* store iv for next call */
5424
        if (status == kStatus_Success) {
5425
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5426
        }
5427
5428
        return (status == kStatus_Success) ? 0 : -1;
5429
    }
5430
5431
    #ifdef HAVE_AES_DECRYPT
5432
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5433
    {
5434
        word32 keySize;
5435
        status_t status;
5436
        byte* iv, *dec_key;
5437
        byte temp_block[WC_AES_BLOCK_SIZE];
5438
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5439
5440
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5441
        if (sz % WC_AES_BLOCK_SIZE) {
5442
            return BAD_LENGTH_E;
5443
        }
5444
#endif
5445
        if (blocks == 0)
5446
            return 0;
5447
5448
        iv      = (byte*)aes->reg;
5449
        dec_key = (byte*)aes->key;
5450
5451
        status = wc_AesGetKeySize(aes, &keySize);
5452
        if (status != 0) {
5453
            return status;
5454
        }
5455
5456
        /* get IV for next call */
5457
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5458
5459
        status = wolfSSL_CryptHwMutexLock();
5460
        if (status != 0)
5461
            return status;
5462
        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
5463
            iv, dec_key, keySize, kLTC_EncryptKey);
5464
        wolfSSL_CryptHwMutexUnLock();
5465
5466
        /* store IV for next call */
5467
        if (status == kStatus_Success) {
5468
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
5469
        }
5470
5471
        return (status == kStatus_Success) ? 0 : -1;
5472
    }
5473
    #endif /* HAVE_AES_DECRYPT */
5474
5475
#elif defined(FREESCALE_MMCAU)
5476
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5477
    {
5478
        int offset = 0;
5479
        byte *iv;
5480
        byte temp_block[WC_AES_BLOCK_SIZE];
5481
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5482
        int ret;
5483
5484
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5485
        if (sz % WC_AES_BLOCK_SIZE) {
5486
            return BAD_LENGTH_E;
5487
        }
5488
#endif
5489
        if (blocks == 0)
5490
            return 0;
5491
5492
        iv = (byte*)aes->reg;
5493
5494
        while (blocks--) {
5495
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
5496
5497
            /* XOR block with IV for CBC */
5498
            xorbuf(temp_block, iv, WC_AES_BLOCK_SIZE);
5499
5500
            ret = wc_AesEncrypt(aes, temp_block, out + offset);
5501
            if (ret != 0)
5502
                return ret;
5503
5504
            offset += WC_AES_BLOCK_SIZE;
5505
5506
            /* store IV for next block */
5507
            XMEMCPY(iv, out + offset - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5508
        }
5509
5510
        return 0;
5511
    }
5512
    #ifdef HAVE_AES_DECRYPT
5513
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5514
    {
5515
        int ret;
5516
        int offset = 0;
5517
        byte* iv;
5518
        byte temp_block[WC_AES_BLOCK_SIZE];
5519
        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
5520
5521
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5522
        if (sz % WC_AES_BLOCK_SIZE) {
5523
            return BAD_LENGTH_E;
5524
        }
5525
#endif
5526
        if (blocks == 0)
5527
            return 0;
5528
5529
        iv = (byte*)aes->reg;
5530
5531
        while (blocks--) {
5532
            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
5533
5534
            ret = wc_AesDecrypt(aes, in + offset, out + offset);
5535
            if (ret != 0)
5536
                return ret;
5537
5538
            /* XOR block with IV for CBC */
5539
            xorbuf(out + offset, iv, WC_AES_BLOCK_SIZE);
5540
5541
            /* store IV for next block */
5542
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
5543
5544
            offset += WC_AES_BLOCK_SIZE;
5545
        }
5546
5547
        return 0;
5548
    }
5549
    #endif /* HAVE_AES_DECRYPT */
5550
5551
#elif defined(MAX3266X_AES)
5552
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5553
    {
5554
        word32 keySize;
5555
        int status;
5556
        byte *iv;
5557
5558
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
5559
            return BAD_FUNC_ARG;
5560
        }
5561
5562
        /* Always enforce a length check */
5563
        if (sz % WC_AES_BLOCK_SIZE) {
5564
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5565
            return BAD_LENGTH_E;
5566
        #else
5567
            return BAD_FUNC_ARG;
5568
        #endif
5569
        }
5570
        if (sz == 0) {
5571
            return 0;
5572
        }
5573
5574
        iv = (byte*)aes->reg;
5575
        status = wc_AesGetKeySize(aes, &keySize);
5576
        if (status != 0) {
5577
            return status;
5578
        }
5579
5580
        status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
5581
                                        MXC_TPU_MODE_CBC, sz, out,
5582
                                        (unsigned int)keySize);
5583
        /* store iv for next call */
5584
        if (status == 0) {
5585
            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5586
        }
5587
        return (status == 0) ? 0 : -1;
5588
    }
5589
5590
    #ifdef HAVE_AES_DECRYPT
5591
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5592
    {
5593
        word32 keySize;
5594
        int status;
5595
        byte *iv;
5596
        byte temp_block[WC_AES_BLOCK_SIZE];
5597
5598
        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
5599
            return BAD_FUNC_ARG;
5600
        }
5601
5602
        /* Always enforce a length check */
5603
        if (sz % WC_AES_BLOCK_SIZE) {
5604
        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5605
            return BAD_LENGTH_E;
5606
        #else
5607
            return BAD_FUNC_ARG;
5608
        #endif
5609
        }
5610
        if (sz == 0) {
5611
            return 0;
5612
        }
5613
5614
        iv = (byte*)aes->reg;
5615
        status = wc_AesGetKeySize(aes, &keySize);
5616
        if (status != 0) {
5617
            return status;
5618
        }
5619
5620
        /* get IV for next call */
5621
        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5622
        status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
5623
                                        MXC_TPU_MODE_CBC, sz, out,
5624
                                        keySize);
5625
5626
        /* store iv for next call */
5627
        if (status == 0) {
5628
            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
5629
        }
5630
        return (status == 0) ? 0 : -1;
5631
    }
5632
    #endif /* HAVE_AES_DECRYPT */
5633
5634
5635
5636
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
5637
5638
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5639
    {
5640
        int ret;
5641
5642
        if (sz == 0)
5643
            return 0;
5644
5645
        /* hardware fails on input that is not a multiple of AES block size */
5646
        if (sz % WC_AES_BLOCK_SIZE != 0) {
5647
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5648
            return BAD_LENGTH_E;
5649
#else
5650
            return BAD_FUNC_ARG;
5651
#endif
5652
        }
5653
5654
        ret = wc_Pic32AesCrypt(
5655
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
5656
            out, in, sz, PIC32_ENCRYPTION,
5657
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
5658
5659
        /* store iv for next call */
5660
        if (ret == 0) {
5661
            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5662
        }
5663
5664
        return ret;
5665
    }
5666
    #ifdef HAVE_AES_DECRYPT
5667
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5668
    {
5669
        int ret;
5670
        byte scratch[WC_AES_BLOCK_SIZE];
5671
5672
        if (sz == 0)
5673
            return 0;
5674
5675
        /* hardware fails on input that is not a multiple of AES block size */
5676
        if (sz % WC_AES_BLOCK_SIZE != 0) {
5677
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5678
            return BAD_LENGTH_E;
5679
#else
5680
            return BAD_FUNC_ARG;
5681
#endif
5682
        }
5683
        XMEMCPY(scratch, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5684
5685
        ret = wc_Pic32AesCrypt(
5686
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
5687
            out, in, sz, PIC32_DECRYPTION,
5688
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
5689
5690
        /* store iv for next call */
5691
        if (ret == 0) {
5692
            XMEMCPY((byte*)aes->reg, scratch, WC_AES_BLOCK_SIZE);
5693
        }
5694
5695
        return ret;
5696
    }
5697
    #endif /* HAVE_AES_DECRYPT */
5698
#elif defined(WOLFSSL_ESP32_CRYPT) && \
5699
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
5700
5701
    /* We'll use SW for fall back:
5702
     *   unsupported key lengths
5703
     *   hardware busy */
5704
    #define NEED_SW_AESCBC
5705
    #define NEED_AESCBC_HW_FALLBACK
5706
5707
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
5708
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5709
    {
5710
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
5711
    }
5712
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5713
    {
5714
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
5715
    }
5716
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
5717
        !defined(WOLFSSL_QNX_CAAM)
5718
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
5719
5720
#elif defined(WOLFSSL_AFALG)
5721
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
5722
5723
#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
5724
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
5725
5726
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
5727
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
5728
5729
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5730
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
5731
5732
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
5733
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
5734
5735
#else
5736
    /* Reminder: Some HW implementations may also define this as needed.
5737
     * (e.g. for unsupported key length fallback)  */
5738
    #define NEED_SW_AESCBC
5739
#endif
5740
5741
#ifdef NEED_SW_AESCBC
5742
    /* Software AES - CBC Encrypt */
5743
5744
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5745
0
    {
5746
0
        word32 blocks;
5747
0
        int ret;
5748
5749
0
        if (aes == NULL || out == NULL || in == NULL) {
5750
0
            return BAD_FUNC_ARG;
5751
0
        }
5752
5753
0
        if (sz == 0) {
5754
0
            return 0;
5755
0
        }
5756
5757
0
        blocks = sz / WC_AES_BLOCK_SIZE;
5758
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5759
        if (sz % WC_AES_BLOCK_SIZE) {
5760
            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
5761
            return BAD_LENGTH_E;
5762
        }
5763
#endif
5764
5765
    #ifdef WOLFSSL_IMXRT_DCP
5766
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
5767
        if (aes->keylen == 16)
5768
            return DCPAesCbcEncrypt(aes, out, in, sz);
5769
    #endif
5770
5771
    #ifdef WOLF_CRYPTO_CB
5772
        #ifndef WOLF_CRYPTO_CB_FIND
5773
        if (aes->devId != INVALID_DEVID)
5774
        #endif
5775
        {
5776
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
5777
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5778
                return crypto_cb_ret;
5779
            /* fall-through when unavailable */
5780
        }
5781
    #endif
5782
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
5783
        /* if async and byte count above threshold */
5784
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
5785
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
5786
        #if defined(HAVE_CAVIUM)
5787
            return NitroxAesCbcEncrypt(aes, out, in, sz);
5788
        #elif defined(HAVE_INTEL_QA)
5789
            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
5790
                (const byte*)aes->devKey, aes->keylen,
5791
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
5792
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5793
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
5794
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
5795
                sw->aes.aes = aes;
5796
                sw->aes.out = out;
5797
                sw->aes.in = in;
5798
                sw->aes.sz = sz;
5799
                return WC_PENDING_E;
5800
            }
5801
        #endif
5802
        }
5803
    #endif /* WOLFSSL_ASYNC_CRYPT */
5804
5805
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
5806
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
5807
        if (aes->useSWCrypt == 0) {
5808
            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
5809
                                   kAlgorithm_SSS_AES_CBC);
5810
        }
5811
        else
5812
    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
5813
        if (wc_esp32AesSupportedKeyLen(aes)) {
5814
            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
5815
            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
5816
        }
5817
        else {
5818
            /* For example, the ESP32-S3 does not support HW for len = 24,
5819
             * so fall back to SW */
5820
        #ifdef DEBUG_WOLFSSL
5821
            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
5822
                          "unsupported keylen = %d", aes->keylen);
5823
        #endif
5824
        }
5825
    #elif defined(WOLFSSL_AESNI)
5826
        VECTOR_REGISTERS_PUSH;
5827
        if (aes->use_aesni) {
5828
            #ifdef DEBUG_AESNI
5829
                printf("about to aes cbc encrypt\n");
5830
                printf("in  = %p\n", in);
5831
                printf("out = %p\n", out);
5832
                printf("aes->key = %p\n", aes->key);
5833
                printf("aes->reg = %p\n", aes->reg);
5834
                printf("aes->rounds = %d\n", aes->rounds);
5835
                printf("sz = %d\n", sz);
5836
            #endif
5837
5838
            /* check alignment, decrypt doesn't need alignment */
5839
            if ((wc_ptr_t)in % AESNI_ALIGN) {
5840
            #ifndef NO_WOLFSSL_ALLOC_ALIGN
5841
                byte* tmp = (byte*)XMALLOC(sz + WC_AES_BLOCK_SIZE + AESNI_ALIGN,
5842
                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5843
                byte* tmp_align;
5844
                if (tmp == NULL)
5845
                    ret = MEMORY_E;
5846
                else {
5847
                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
5848
                    XMEMCPY(tmp_align, in, sz);
5849
                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
5850
                                          (byte*)aes->key, (int)aes->rounds);
5851
                    /* store iv for next call */
5852
                    XMEMCPY(aes->reg, tmp_align + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5853
5854
                    XMEMCPY(out, tmp_align, sz);
5855
                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5856
                    ret = 0;
5857
                }
5858
            #else
5859
                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
5860
                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
5861
                ret = BAD_ALIGN_E;
5862
            #endif
5863
            } else {
5864
                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
5865
                                      (int)aes->rounds);
5866
                /* store iv for next call */
5867
                XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
5868
5869
                ret = 0;
5870
            }
5871
        }
5872
        else
5873
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
5874
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
5875
        if (aes->use_aes_hw_crypto) {
5876
            AES_CBC_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
5877
                (byte*)aes->key, (int)aes->rounds);
5878
            ret = 0;
5879
        }
5880
        else
5881
    #endif
5882
0
        {
5883
0
            ret = 0;
5884
0
            while (blocks--) {
5885
0
                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
5886
0
                ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
5887
0
                if (ret != 0)
5888
0
                    break;
5889
0
                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
5890
5891
0
                out += WC_AES_BLOCK_SIZE;
5892
0
                in  += WC_AES_BLOCK_SIZE;
5893
0
            }
5894
0
        }
5895
5896
    #ifdef WOLFSSL_AESNI
5897
        VECTOR_REGISTERS_POP;
5898
    #endif
5899
5900
0
        return ret;
5901
0
    } /* wc_AesCbcEncrypt */
5902
5903
#ifdef HAVE_AES_DECRYPT
5904
    /* Software AES - CBC Decrypt */
5905
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5906
0
    {
5907
0
        word32 blocks;
5908
0
        int ret;
5909
5910
0
        if (aes == NULL || out == NULL || in == NULL) {
5911
0
            return BAD_FUNC_ARG;
5912
0
        }
5913
5914
0
        if (sz == 0) {
5915
0
            return 0;
5916
0
        }
5917
5918
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
5919
        if (wc_esp32AesSupportedKeyLen(aes)) {
5920
            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
5921
            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
5922
        }
5923
        else {
5924
            /* For example, the ESP32-S3 does not support HW for len = 24,
5925
             * so fall back to SW */
5926
        #ifdef DEBUG_WOLFSSL
5927
            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
5928
                          "unsupported keylen = %d", aes->keylen);
5929
        #endif
5930
        }
5931
    #endif
5932
5933
0
        blocks = sz / WC_AES_BLOCK_SIZE;
5934
0
        if (sz % WC_AES_BLOCK_SIZE) {
5935
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5936
            return BAD_LENGTH_E;
5937
#else
5938
0
            return BAD_FUNC_ARG;
5939
0
#endif
5940
0
        }
5941
5942
    #ifdef WOLFSSL_IMXRT_DCP
5943
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
5944
        if (aes->keylen == 16)
5945
            return DCPAesCbcDecrypt(aes, out, in, sz);
5946
    #endif
5947
5948
    #ifdef WOLF_CRYPTO_CB
5949
        #ifndef WOLF_CRYPTO_CB_FIND
5950
        if (aes->devId != INVALID_DEVID)
5951
        #endif
5952
        {
5953
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
5954
            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5955
                return crypto_cb_ret;
5956
            /* fall-through when unavailable */
5957
        }
5958
    #endif
5959
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
5960
        /* if async and byte count above threshold */
5961
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
5962
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
5963
        #if defined(HAVE_CAVIUM)
5964
            return NitroxAesCbcDecrypt(aes, out, in, sz);
5965
        #elif defined(HAVE_INTEL_QA)
5966
            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
5967
                (const byte*)aes->devKey, aes->keylen,
5968
                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
5969
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5970
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
5971
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
5972
                sw->aes.aes = aes;
5973
                sw->aes.out = out;
5974
                sw->aes.in = in;
5975
                sw->aes.sz = sz;
5976
                return WC_PENDING_E;
5977
            }
5978
        #endif
5979
        }
5980
    #endif
5981
5982
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
5983
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
5984
        if (aes->useSWCrypt == 0) {
5985
            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
5986
                                   kAlgorithm_SSS_AES_CBC);
5987
        }
5988
    #endif
5989
5990
0
        VECTOR_REGISTERS_PUSH;
5991
5992
    #ifdef WOLFSSL_AESNI
5993
        if (aes->use_aesni) {
5994
            #ifdef DEBUG_AESNI
5995
                printf("about to aes cbc decrypt\n");
5996
                printf("in  = %p\n", in);
5997
                printf("out = %p\n", out);
5998
                printf("aes->key = %p\n", aes->key);
5999
                printf("aes->reg = %p\n", aes->reg);
6000
                printf("aes->rounds = %d\n", aes->rounds);
6001
                printf("sz = %d\n", sz);
6002
            #endif
6003
6004
            /* if input and output same will overwrite input iv */
6005
            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
6006
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
6007
            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6008
                            aes->rounds);
6009
            #elif defined(WOLFSSL_AESNI_BY6)
6010
            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6011
                            aes->rounds);
6012
            #else /* WOLFSSL_AESNI_BYx */
6013
            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
6014
                            (int)aes->rounds);
6015
            #endif /* WOLFSSL_AESNI_BYx */
6016
            /* store iv for next call */
6017
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6018
            ret = 0;
6019
        }
6020
        else
6021
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6022
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6023
        if (aes->use_aes_hw_crypto) {
6024
            AES_CBC_decrypt_AARCH64(in, out, sz, (byte*)aes->reg,
6025
                (byte*)aes->key, (int)aes->rounds);
6026
            ret = 0;
6027
        }
6028
        else
6029
    #endif
6030
0
        {
6031
0
            ret = 0;
6032
#ifdef WC_AES_BITSLICED
6033
            if (in != out) {
6034
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
6035
6036
                while (blocks > BS_WORD_SIZE) {
6037
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
6038
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6039
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
6040
                              WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
6041
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
6042
                            WC_AES_BLOCK_SIZE);
6043
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6044
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6045
                    blocks -= BS_WORD_SIZE;
6046
                }
6047
                if (blocks > 0) {
6048
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
6049
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6050
                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
6051
                              WC_AES_BLOCK_SIZE * (blocks - 1));
6052
                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (blocks - 1)),
6053
                            WC_AES_BLOCK_SIZE);
6054
                    blocks = 0;
6055
                }
6056
            }
6057
            else {
6058
                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
6059
                int i;
6060
6061
                while (blocks > BS_WORD_SIZE) {
6062
                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
6063
                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * WC_AES_BLOCK_SIZE,
6064
                            WC_AES_BLOCK_SIZE);
6065
                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
6066
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
6067
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
6068
                                  WC_AES_BLOCK_SIZE);
6069
                    }
6070
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6071
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6072
6073
                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6074
                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
6075
                    blocks -= BS_WORD_SIZE;
6076
                }
6077
                if (blocks > 0) {
6078
                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
6079
                    XMEMCPY(aes->tmp, in + (blocks - 1) * WC_AES_BLOCK_SIZE,
6080
                            WC_AES_BLOCK_SIZE);
6081
                    for (i = blocks-1; i >= 1; i--) {
6082
                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
6083
                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
6084
                                  WC_AES_BLOCK_SIZE);
6085
                    }
6086
                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
6087
                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6088
6089
                    blocks = 0;
6090
                }
6091
            }
6092
#else
6093
0
            while (blocks--) {
6094
0
                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
6095
0
                ret = wc_AesDecrypt(aes, in, out);
6096
0
                if (ret != 0)
6097
0
                    return ret;
6098
0
                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
6099
                /* store iv for next call */
6100
0
                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
6101
6102
0
                out += WC_AES_BLOCK_SIZE;
6103
0
                in  += WC_AES_BLOCK_SIZE;
6104
0
            }
6105
0
#endif
6106
0
        }
6107
6108
0
        VECTOR_REGISTERS_POP;
6109
6110
0
        return ret;
6111
0
    }
6112
#endif /* HAVE_AES_DECRYPT */
6113
6114
#endif /* AES-CBC block */
6115
#endif /* HAVE_AES_CBC */
6116
6117
/* AES-CTR */
6118
#if defined(WOLFSSL_AES_COUNTER)
6119
6120
    #ifdef STM32_CRYPTO
6121
        #define NEED_AES_CTR_SOFT
6122
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
6123
6124
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
6125
        {
6126
            int ret = 0;
6127
        #ifdef WOLFSSL_STM32_CUBEMX
6128
            CRYP_HandleTypeDef hcryp;
6129
            #ifdef STM32_HAL_V2
6130
            word32 iv[WC_AES_BLOCK_SIZE/sizeof(word32)];
6131
            #endif
6132
        #else
6133
            word32 *iv;
6134
            CRYP_InitTypeDef cryptInit;
6135
            CRYP_KeyInitTypeDef keyInit;
6136
            CRYP_IVInitTypeDef ivInit;
6137
        #endif
6138
6139
        #ifdef WOLFSSL_STM32_CUBEMX
6140
            ret = wc_Stm32_Aes_Init(aes, &hcryp);
6141
            if (ret != 0) {
6142
                return ret;
6143
            }
6144
6145
            ret = wolfSSL_CryptHwMutexLock();
6146
            if (ret != 0) {
6147
                return ret;
6148
            }
6149
6150
        #if defined(STM32_HAL_V2)
6151
            hcryp.Init.Algorithm  = CRYP_AES_CTR;
6152
            ByteReverseWords(iv, aes->reg, WC_AES_BLOCK_SIZE);
6153
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
6154
        #elif defined(STM32_CRYPTO_AES_ONLY)
6155
            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
6156
            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
6157
            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
6158
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6159
        #else
6160
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
6161
        #endif
6162
            HAL_CRYP_Init(&hcryp);
6163
6164
        #if defined(STM32_HAL_V2)
6165
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, WC_AES_BLOCK_SIZE,
6166
                (uint32_t*)out, STM32_HAL_TIMEOUT);
6167
        #elif defined(STM32_CRYPTO_AES_ONLY)
6168
            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
6169
                out, STM32_HAL_TIMEOUT);
6170
        #else
6171
            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
6172
                out, STM32_HAL_TIMEOUT);
6173
        #endif
6174
            if (ret != HAL_OK) {
6175
                ret = WC_TIMEOUT_E;
6176
            }
6177
            HAL_CRYP_DeInit(&hcryp);
6178
6179
        #else /* Standard Peripheral Library */
6180
            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
6181
            if (ret != 0) {
6182
                return ret;
6183
            }
6184
6185
            ret = wolfSSL_CryptHwMutexLock();
6186
            if (ret != 0) {
6187
                return ret;
6188
            }
6189
6190
            /* reset registers to their default values */
6191
            CRYP_DeInit();
6192
6193
            /* set key */
6194
            CRYP_KeyInit(&keyInit);
6195
6196
            /* set iv */
6197
            iv = aes->reg;
6198
            CRYP_IVStructInit(&ivInit);
6199
            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
6200
            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
6201
            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
6202
            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
6203
            CRYP_IVInit(&ivInit);
6204
6205
            /* set direction and mode */
6206
            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
6207
            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
6208
            CRYP_Init(&cryptInit);
6209
6210
            /* enable crypto processor */
6211
            CRYP_Cmd(ENABLE);
6212
6213
            /* flush IN/OUT FIFOs */
6214
            CRYP_FIFOFlush();
6215
6216
            CRYP_DataIn(*(uint32_t*)&in[0]);
6217
            CRYP_DataIn(*(uint32_t*)&in[4]);
6218
            CRYP_DataIn(*(uint32_t*)&in[8]);
6219
            CRYP_DataIn(*(uint32_t*)&in[12]);
6220
6221
            /* wait until the complete message has been processed */
6222
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
6223
6224
            *(uint32_t*)&out[0]  = CRYP_DataOut();
6225
            *(uint32_t*)&out[4]  = CRYP_DataOut();
6226
            *(uint32_t*)&out[8]  = CRYP_DataOut();
6227
            *(uint32_t*)&out[12] = CRYP_DataOut();
6228
6229
            /* disable crypto processor */
6230
            CRYP_Cmd(DISABLE);
6231
        #endif /* WOLFSSL_STM32_CUBEMX */
6232
6233
            wolfSSL_CryptHwMutexUnLock();
6234
            wc_Stm32_Aes_Cleanup();
6235
            return ret;
6236
        }
6237
6238
6239
    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
6240
6241
        #define NEED_AES_CTR_SOFT
6242
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
6243
6244
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
6245
        {
6246
            word32 tmpIv[WC_AES_BLOCK_SIZE / sizeof(word32)];
6247
            XMEMCPY(tmpIv, aes->reg, WC_AES_BLOCK_SIZE);
6248
            return wc_Pic32AesCrypt(
6249
                aes->key, aes->keylen, tmpIv, WC_AES_BLOCK_SIZE,
6250
                out, in, WC_AES_BLOCK_SIZE,
6251
                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
6252
        }
6253
6254
    #elif defined(HAVE_COLDFIRE_SEC)
6255
        #error "Coldfire SEC doesn't currently support AES-CTR mode"
6256
6257
    #elif defined(FREESCALE_LTC)
6258
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6259
        {
6260
            int ret = 0;
6261
            word32 keySize;
6262
            byte *iv, *enc_key;
6263
            byte* tmp;
6264
6265
            if (aes == NULL || out == NULL || in == NULL) {
6266
                return BAD_FUNC_ARG;
6267
            }
6268
6269
            /* consume any unused bytes left in aes->tmp */
6270
            tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
6271
            while (aes->left && sz) {
6272
                *(out++) = *(in++) ^ *(tmp++);
6273
                aes->left--;
6274
                sz--;
6275
            }
6276
6277
            if (sz) {
6278
                iv      = (byte*)aes->reg;
6279
                enc_key = (byte*)aes->key;
6280
6281
                ret = wc_AesGetKeySize(aes, &keySize);
6282
                if (ret != 0)
6283
                    return ret;
6284
6285
                ret = wolfSSL_CryptHwMutexLock();
6286
                if (ret != 0)
6287
                    return ret;
6288
                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
6289
                    iv, enc_key, keySize, (byte*)aes->tmp,
6290
                    (uint32_t*)&aes->left);
6291
                wolfSSL_CryptHwMutexUnLock();
6292
            }
6293
6294
            return ret;
6295
        }
6296
6297
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
6298
        !defined(WOLFSSL_QNX_CAAM)
6299
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
6300
6301
    #elif defined(WOLFSSL_AFALG)
6302
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
6303
6304
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
6305
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6306
6307
    #elif defined(WOLFSSL_ESP32_CRYPT) && \
6308
        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6309
        /* esp32 doesn't support CRT mode by hw.     */
6310
        /* use aes ecnryption plus sw implementation */
6311
        #define NEED_AES_CTR_SOFT
6312
6313
    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6314
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
6315
    #else
6316
6317
        /* Use software based AES counter */
6318
        #define NEED_AES_CTR_SOFT
6319
    #endif
6320
6321
    #ifdef NEED_AES_CTR_SOFT
6322
        /* Increment AES counter */
6323
        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
6324
        {
6325
            /* in network byte order so start at end and work back */
6326
            int i;
6327
            for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
6328
                if (++inOutCtr[i])  /* we're done unless we overflow */
6329
                    return;
6330
            }
6331
        }
6332
6333
        /* Software AES - CTR Encrypt */
6334
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6335
        {
6336
            byte scratch[WC_AES_BLOCK_SIZE];
6337
            int ret = 0;
6338
            word32 processed;
6339
6340
            XMEMSET(scratch, 0, sizeof(scratch));
6341
6342
            if (aes == NULL || out == NULL || in == NULL) {
6343
                return BAD_FUNC_ARG;
6344
            }
6345
6346
        #ifdef WOLF_CRYPTO_CB
6347
            #ifndef WOLF_CRYPTO_CB_FIND
6348
            if (aes->devId != INVALID_DEVID)
6349
            #endif
6350
            {
6351
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
6352
                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6353
                    return crypto_cb_ret;
6354
                /* fall-through when unavailable */
6355
            }
6356
        #endif
6357
6358
            /* consume any unused bytes left in aes->tmp */
6359
            processed = min(aes->left, sz);
6360
            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
6361
                      processed);
6362
            out += processed;
6363
            in += processed;
6364
            aes->left -= processed;
6365
            sz -= processed;
6366
6367
        #if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6368
            !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6369
            if (aes->use_aes_hw_crypto) {
6370
                AES_CTR_encrypt_AARCH64(aes, out, in, sz);
6371
                return 0;
6372
            }
6373
        #endif
6374
6375
            VECTOR_REGISTERS_PUSH;
6376
6377
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
6378
            !defined(XTRANSFORM_AESCTRBLOCK)
6379
            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
6380
                word32 blocks = sz / WC_AES_BLOCK_SIZE;
6381
                byte* counter = (byte*)aes->reg;
6382
                byte* c = out;
6383
                while (blocks--) {
6384
                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
6385
                    c += WC_AES_BLOCK_SIZE;
6386
                    IncrementAesCounter(counter);
6387
                }
6388
6389
                /* reset number of blocks and then do encryption */
6390
                blocks = sz / WC_AES_BLOCK_SIZE;
6391
                wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
6392
                xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
6393
                in += WC_AES_BLOCK_SIZE * blocks;
6394
                out += WC_AES_BLOCK_SIZE * blocks;
6395
                sz -= blocks * WC_AES_BLOCK_SIZE;
6396
            }
6397
            else
6398
        #endif
6399
            {
6400
            #ifdef WOLFSSL_CHECK_MEM_ZERO
6401
                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
6402
                    WC_AES_BLOCK_SIZE);
6403
            #endif
6404
                /* do as many block size ops as possible */
6405
                while (sz >= WC_AES_BLOCK_SIZE) {
6406
                #ifdef XTRANSFORM_AESCTRBLOCK
6407
                    XTRANSFORM_AESCTRBLOCK(aes, out, in);
6408
                #else
6409
                    ret = wc_AesEncrypt(aes, (byte*)aes->reg, scratch);
6410
                    if (ret != 0)
6411
                        break;
6412
                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
6413
                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
6414
                #endif
6415
                    IncrementAesCounter((byte*)aes->reg);
6416
6417
                    out += WC_AES_BLOCK_SIZE;
6418
                    in  += WC_AES_BLOCK_SIZE;
6419
                    sz  -= WC_AES_BLOCK_SIZE;
6420
                    aes->left = 0;
6421
                }
6422
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
6423
            }
6424
6425
            /* handle non block size remaining and store unused byte count in left */
6426
            if ((ret == 0) && sz) {
6427
                ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
6428
                if (ret == 0) {
6429
                    IncrementAesCounter((byte*)aes->reg);
6430
                    aes->left = WC_AES_BLOCK_SIZE - sz;
6431
                    xorbufout(out, in, aes->tmp, sz);
6432
                }
6433
            }
6434
6435
            if (ret < 0)
6436
                ForceZero(scratch, WC_AES_BLOCK_SIZE);
6437
6438
        #ifdef WOLFSSL_CHECK_MEM_ZERO
6439
            wc_MemZero_Check(scratch, WC_AES_BLOCK_SIZE);
6440
        #endif
6441
6442
            VECTOR_REGISTERS_POP;
6443
6444
            return ret;
6445
        }
6446
6447
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
6448
                                        const byte* iv, int dir)
6449
        {
6450
            if (aes == NULL) {
6451
                return BAD_FUNC_ARG;
6452
            }
6453
            if (len > sizeof(aes->key)) {
6454
                return BAD_FUNC_ARG;
6455
            }
6456
6457
            return wc_AesSetKey(aes, key, len, iv, dir);
6458
        }
6459
6460
    #endif /* NEED_AES_CTR_SOFT */
6461
6462
#endif /* WOLFSSL_AES_COUNTER */
6463
#endif /* !WOLFSSL_RISCV_ASM */
6464
6465
6466
/*
6467
 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
6468
 * of two parts in order:
6469
 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
6470
 *      to the implicit IV.
6471
 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
6472
 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
6473
 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
6474
 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
6475
 * block counter during the encryption.
6476
 */
6477
6478
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
6479
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
6480
0
{
6481
0
    int i;
6482
0
    for (i = (int)ctrSz - 1; i >= 0; i--) {
6483
0
        if (++ctr[i])
6484
0
            break;
6485
0
    }
6486
0
}
6487
#endif /* HAVE_AESGCM || HAVE_AESCCM */
6488
6489
6490
#ifdef HAVE_AESGCM
6491
6492
#ifdef WOLFSSL_AESGCM_STREAM
6493
    /* Access initialization counter data. */
6494
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
6495
    /* Access counter data. */
6496
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
6497
    /* Access tag data. */
6498
    #define AES_TAG(aes)            ((aes)->streamData + 2 * WC_AES_BLOCK_SIZE)
6499
    /* Access last GHASH block. */
6500
    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE)
6501
    /* Access last encrypted block. */
6502
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
6503
6504
    #if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6505
        !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6506
        #define GHASH_ONE_BLOCK(aes, block)                                 \
6507
            do {                                                            \
6508
                if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {   \
6509
                    GHASH_ONE_BLOCK_AARCH64(aes, block);                    \
6510
                }                                                           \
6511
                else {                                                      \
6512
                    GHASH_ONE_BLOCK_SW(aes, block);                         \
6513
                }                                                           \
6514
            }                                                               \
6515
            while (0)
6516
    #else
6517
        #define GHASH_ONE_BLOCK     GHASH_ONE_BLOCK_SW
6518
    #endif
6519
#endif
6520
6521
#if defined(HAVE_COLDFIRE_SEC)
6522
    #error "Coldfire SEC doesn't currently support AES-GCM mode"
6523
6524
#endif
6525
6526
#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__)
6527
    /* implemented in wolfcrypt/src/port/arm/armv8-aes.c */
6528
6529
#elif defined(WOLFSSL_RISCV_ASM)
6530
    /* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
6531
6532
#elif defined(WOLFSSL_AFALG)
6533
    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
6534
6535
#elif defined(WOLFSSL_KCAPI_AES)
6536
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
6537
6538
#elif defined(WOLFSSL_DEVCRYPTO_AES)
6539
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6540
6541
#else /* software + AESNI implementation */
6542
6543
#if !defined(FREESCALE_LTC_AES_GCM)
6544
static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
6545
0
{
6546
0
    int i;
6547
6548
    /* in network byte order so start at end and work back */
6549
0
    for (i = WC_AES_BLOCK_SIZE - 1; i >= WC_AES_BLOCK_SIZE - CTR_SZ; i--) {
6550
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
6551
0
            return;
6552
0
    }
6553
0
}
6554
#endif /* !FREESCALE_LTC_AES_GCM */
6555
6556
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
6557
6558
static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
6559
0
{
6560
    /* Multiply the sz by 8 */
6561
0
    word32 szHi = (sz >> (8*sizeof(sz) - 3));
6562
0
    sz <<= 3;
6563
6564
    /* copy over the words of the sz into the destination buffer */
6565
0
    buf[0] = (byte)(szHi >> 24);
6566
0
    buf[1] = (byte)(szHi >> 16);
6567
0
    buf[2] = (byte)(szHi >>  8);
6568
0
    buf[3] = (byte)szHi;
6569
0
    buf[4] = (byte)(sz >> 24);
6570
0
    buf[5] = (byte)(sz >> 16);
6571
0
    buf[6] = (byte)(sz >>  8);
6572
0
    buf[7] = (byte)sz;
6573
0
}
6574
6575
6576
static WC_INLINE void RIGHTSHIFTX(byte* x)
6577
0
{
6578
0
    int i;
6579
0
    int carryIn = 0;
6580
0
    byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
6581
6582
0
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
6583
0
        int carryOut = (x[i] & 0x01) << 7;
6584
0
        x[i] = (byte) ((x[i] >> 1) | carryIn);
6585
0
        carryIn = carryOut;
6586
0
    }
6587
0
    x[0] ^= borrow;
6588
0
}
6589
6590
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
6591
6592
6593
#ifdef GCM_TABLE
6594
6595
void GenerateM0(Gcm* gcm)
6596
{
6597
    int i, j;
6598
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
6599
6600
    XMEMCPY(m[128], gcm->H, WC_AES_BLOCK_SIZE);
6601
6602
    for (i = 64; i > 0; i /= 2) {
6603
        XMEMCPY(m[i], m[i*2], WC_AES_BLOCK_SIZE);
6604
        RIGHTSHIFTX(m[i]);
6605
    }
6606
6607
    for (i = 2; i < 256; i *= 2) {
6608
        for (j = 1; j < i; j++) {
6609
            XMEMCPY(m[i+j], m[i], WC_AES_BLOCK_SIZE);
6610
            xorbuf(m[i+j], m[j], WC_AES_BLOCK_SIZE);
6611
        }
6612
    }
6613
6614
    XMEMSET(m[0], 0, WC_AES_BLOCK_SIZE);
6615
}
6616
6617
#elif defined(GCM_TABLE_4BIT)
6618
6619
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU)
6620
static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
6621
0
{
6622
0
    int i;
6623
0
    for (i = 15; i > 0; i--)
6624
0
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
6625
0
    r8[0] = (byte)(z8[0] >> 4);
6626
0
}
6627
#endif
6628
6629
void GenerateM0(Gcm* gcm)
6630
0
{
6631
0
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU)
6632
0
    int i;
6633
0
#endif
6634
0
    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
6635
6636
    /* 0 times -> 0x0 */
6637
0
    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
6638
    /* 1 times -> 0x8 */
6639
0
    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
6640
    /* 2 times -> 0x4 */
6641
0
    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
6642
0
    RIGHTSHIFTX(m[0x4]);
6643
    /* 4 times -> 0x2 */
6644
0
    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
6645
0
    RIGHTSHIFTX(m[0x2]);
6646
    /* 8 times -> 0x1 */
6647
0
    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
6648
0
    RIGHTSHIFTX(m[0x1]);
6649
6650
    /* 0x3 */
6651
0
    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
6652
0
    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
6653
6654
    /* 0x5 -> 0x7 */
6655
0
    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
6656
0
    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
6657
0
    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
6658
0
    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
6659
0
    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
6660
0
    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
6661
6662
    /* 0x9 -> 0xf */
6663
0
    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
6664
0
    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
6665
0
    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
6666
0
    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
6667
0
    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
6668
0
    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
6669
0
    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
6670
0
    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
6671
0
    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
6672
0
    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
6673
0
    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
6674
0
    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
6675
0
    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
6676
0
    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
6677
6678
0
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU)
6679
0
    for (i = 0; i < 16; i++) {
6680
0
        Shift4_M0(m[16+i], m[i]);
6681
0
    }
6682
0
#endif
6683
0
}
6684
6685
#endif /* GCM_TABLE */
6686
6687
#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
6688
    #define HAVE_INTEL_AVX1
6689
    #define HAVE_INTEL_AVX2
6690
#endif
6691
6692
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \
6693
    defined(WC_C_DYNAMIC_FALLBACK)
6694
void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m)
6695
                           XASM_LINK("GCM_generate_m0_aesni");
6696
#ifdef HAVE_INTEL_AVX1
6697
void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m)
6698
                          XASM_LINK("GCM_generate_m0_avx1");
6699
#endif
6700
#ifdef HAVE_INTEL_AVX2
6701
void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
6702
                          XASM_LINK("GCM_generate_m0_avx2");
6703
#endif
6704
#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */
6705
6706
/* Software AES - GCM SetKey */
6707
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
6708
0
{
6709
0
    int  ret;
6710
0
    byte iv[WC_AES_BLOCK_SIZE];
6711
6712
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
6713
        byte   local[32];
6714
        word32 localSz = 32;
6715
6716
        if (len == (16 + WC_CAAM_BLOB_SZ) ||
6717
          len == (24 + WC_CAAM_BLOB_SZ) ||
6718
          len == (32 + WC_CAAM_BLOB_SZ)) {
6719
            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
6720
                 return BAD_FUNC_ARG;
6721
            }
6722
6723
            /* set local values */
6724
            key = local;
6725
            len = localSz;
6726
        }
6727
    #endif
6728
6729
0
    if (!((len == 16) || (len == 24) || (len == 32)))
6730
0
        return BAD_FUNC_ARG;
6731
6732
0
    if (aes == NULL || key == NULL) {
6733
#ifdef WOLFSSL_IMX6_CAAM_BLOB
6734
        ForceZero(local, sizeof(local));
6735
#endif
6736
0
        return BAD_FUNC_ARG;
6737
0
    }
6738
#ifdef OPENSSL_EXTRA
6739
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
6740
    aes->gcm.aadLen = 0;
6741
#endif
6742
0
    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
6743
0
    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
6744
#ifdef WOLFSSL_AESGCM_STREAM
6745
    aes->gcmKeySet = 1;
6746
#endif
6747
    #if defined(WOLFSSL_SECO_CAAM)
6748
        if (aes->devId == WOLFSSL_SECO_DEVID) {
6749
            return ret;
6750
        }
6751
    #endif /* WOLFSSL_SECO_CAAM */
6752
6753
    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
6754
        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
6755
        return ret;
6756
    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
6757
6758
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
6759
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
6760
    if (ret == 0 && aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
6761
        AES_GCM_set_key_AARCH64(aes, iv);
6762
    }
6763
    else
6764
#endif
6765
0
#if !defined(FREESCALE_LTC_AES_GCM)
6766
0
    if (ret == 0) {
6767
0
        VECTOR_REGISTERS_PUSH;
6768
        /* AES-NI code generates its own H value, but generate it here too, to
6769
         * assure pure-C fallback is always usable.
6770
         */
6771
0
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
6772
0
        VECTOR_REGISTERS_POP;
6773
0
    }
6774
0
    if (ret == 0) {
6775
0
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
6776
#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT)
6777
        if (aes->use_aesni) {
6778
    #if defined(WC_C_DYNAMIC_FALLBACK)
6779
        #ifdef HAVE_INTEL_AVX2
6780
            if (IS_INTEL_AVX2(intel_flags)) {
6781
                GCM_generate_m0_avx2(aes->gcm.H, (byte*)aes->gcm.M0);
6782
            }
6783
            else
6784
        #endif
6785
        #if defined(HAVE_INTEL_AVX1)
6786
            if (IS_INTEL_AVX1(intel_flags)) {
6787
                GCM_generate_m0_avx1(aes->gcm.H, (byte*)aes->gcm.M0);
6788
            }
6789
            else
6790
        #endif
6791
            {
6792
                GCM_generate_m0_aesni(aes->gcm.H, (byte*)aes->gcm.M0);
6793
            }
6794
    #endif
6795
        }
6796
        else
6797
#endif
6798
0
        {
6799
0
            GenerateM0(&aes->gcm);
6800
0
        }
6801
0
#endif /* GCM_TABLE || GCM_TABLE_4BIT */
6802
0
    }
6803
0
#endif /* FREESCALE_LTC_AES_GCM */
6804
6805
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
6806
    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
6807
#endif
6808
6809
#ifdef WOLF_CRYPTO_CB
6810
    if (aes->devId != INVALID_DEVID) {
6811
        XMEMCPY(aes->devKey, key, len);
6812
    }
6813
#endif
6814
6815
#ifdef WOLFSSL_IMX6_CAAM_BLOB
6816
    ForceZero(local, sizeof(local));
6817
#endif
6818
0
    return ret;
6819
0
}
6820
6821
6822
#ifdef WOLFSSL_AESNI
6823
6824
void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
6825
                     const unsigned char* addt, const unsigned char* ivec,
6826
                     unsigned char *tag, word32 nbytes,
6827
                     word32 abytes, word32 ibytes,
6828
                     word32 tbytes, const unsigned char* key, int nr)
6829
                     XASM_LINK("AES_GCM_encrypt_aesni");
6830
#ifdef HAVE_INTEL_AVX1
6831
void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
6832
                          const unsigned char* addt, const unsigned char* ivec,
6833
                          unsigned char *tag, word32 nbytes,
6834
                          word32 abytes, word32 ibytes,
6835
                          word32 tbytes, const unsigned char* key,
6836
                          int nr)
6837
                          XASM_LINK("AES_GCM_encrypt_avx1");
6838
#ifdef HAVE_INTEL_AVX2
6839
void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
6840
                          const unsigned char* addt, const unsigned char* ivec,
6841
                          unsigned char *tag, word32 nbytes,
6842
                          word32 abytes, word32 ibytes,
6843
                          word32 tbytes, const unsigned char* key,
6844
                          int nr)
6845
                          XASM_LINK("AES_GCM_encrypt_avx2");
6846
#endif /* HAVE_INTEL_AVX2 */
6847
#endif /* HAVE_INTEL_AVX1 */
6848
6849
#ifdef HAVE_AES_DECRYPT
6850
void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
6851
                     const unsigned char* addt, const unsigned char* ivec,
6852
                     const unsigned char *tag, word32 nbytes, word32 abytes,
6853
                     word32 ibytes, word32 tbytes, const unsigned char* key,
6854
                     int nr, int* res)
6855
                     XASM_LINK("AES_GCM_decrypt_aesni");
6856
#ifdef HAVE_INTEL_AVX1
6857
void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
6858
                          const unsigned char* addt, const unsigned char* ivec,
6859
                          const unsigned char *tag, word32 nbytes,
6860
                          word32 abytes, word32 ibytes, word32 tbytes,
6861
                          const unsigned char* key, int nr, int* res)
6862
                          XASM_LINK("AES_GCM_decrypt_avx1");
6863
#ifdef HAVE_INTEL_AVX2
6864
void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
6865
                          const unsigned char* addt, const unsigned char* ivec,
6866
                          const unsigned char *tag, word32 nbytes,
6867
                          word32 abytes, word32 ibytes, word32 tbytes,
6868
                          const unsigned char* key, int nr, int* res)
6869
                          XASM_LINK("AES_GCM_decrypt_avx2");
6870
#endif /* HAVE_INTEL_AVX2 */
6871
#endif /* HAVE_INTEL_AVX1 */
6872
#endif /* HAVE_AES_DECRYPT */
6873
6874
#endif /* WOLFSSL_AESNI */
6875
6876
#if defined(GCM_SMALL)
6877
static void GMULT(byte* X, byte* Y)
6878
{
6879
    byte Z[WC_AES_BLOCK_SIZE];
6880
    byte V[WC_AES_BLOCK_SIZE];
6881
    int i, j;
6882
6883
    XMEMSET(Z, 0, WC_AES_BLOCK_SIZE);
6884
    XMEMCPY(V, X, WC_AES_BLOCK_SIZE);
6885
    for (i = 0; i < WC_AES_BLOCK_SIZE; i++)
6886
    {
6887
        byte y = Y[i];
6888
        for (j = 0; j < 8; j++)
6889
        {
6890
            if (y & 0x80) {
6891
                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
6892
            }
6893
6894
            RIGHTSHIFTX(V);
6895
            y = y << 1;
6896
        }
6897
    }
6898
    XMEMCPY(X, Z, WC_AES_BLOCK_SIZE);
6899
}
6900
6901
6902
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
6903
    word32 cSz, byte* s, word32 sSz)
6904
{
6905
    byte x[WC_AES_BLOCK_SIZE];
6906
    byte scratch[WC_AES_BLOCK_SIZE];
6907
    word32 blocks, partial;
6908
    byte* h;
6909
6910
    if (gcm == NULL) {
6911
        return;
6912
    }
6913
6914
    h = gcm->H;
6915
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
6916
6917
    /* Hash in A, the Additional Authentication Data */
6918
    if (aSz != 0 && a != NULL) {
6919
        blocks = aSz / WC_AES_BLOCK_SIZE;
6920
        partial = aSz % WC_AES_BLOCK_SIZE;
6921
        while (blocks--) {
6922
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
6923
            GMULT(x, h);
6924
            a += WC_AES_BLOCK_SIZE;
6925
        }
6926
        if (partial != 0) {
6927
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
6928
            XMEMCPY(scratch, a, partial);
6929
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
6930
            GMULT(x, h);
6931
        }
6932
    }
6933
6934
    /* Hash in C, the Ciphertext */
6935
    if (cSz != 0 && c != NULL) {
6936
        blocks = cSz / WC_AES_BLOCK_SIZE;
6937
        partial = cSz % WC_AES_BLOCK_SIZE;
6938
        while (blocks--) {
6939
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
6940
            GMULT(x, h);
6941
            c += WC_AES_BLOCK_SIZE;
6942
        }
6943
        if (partial != 0) {
6944
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
6945
            XMEMCPY(scratch, c, partial);
6946
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
6947
            GMULT(x, h);
6948
        }
6949
    }
6950
6951
    /* Hash in the lengths of A and C in bits */
6952
    FlattenSzInBits(&scratch[0], aSz);
6953
    FlattenSzInBits(&scratch[8], cSz);
6954
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
6955
    GMULT(x, h);
6956
6957
    /* Copy the result into s. */
6958
    XMEMCPY(s, x, sSz);
6959
}
6960
6961
#ifdef WOLFSSL_AESGCM_STREAM
6962
/* No extra initialization for small implementation.
6963
 *
6964
 * @param [in] aes  AES GCM object.
6965
 */
6966
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
6967
6968
/* GHASH one block of data..
6969
 *
6970
 * XOR block into tag and GMULT with H.
6971
 *
6972
 * @param [in, out] aes    AES GCM object.
6973
 * @param [in]      block  Block of AAD or cipher text.
6974
 */
6975
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
6976
    do {                                                \
6977
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
6978
        GMULT(AES_TAG(aes), (aes)->gcm.H);              \
6979
    }                                                   \
6980
    while (0)
6981
#endif /* WOLFSSL_AESGCM_STREAM */
6982
/* end GCM_SMALL */
6983
#elif defined(GCM_TABLE)
6984
6985
ALIGN16 static const byte R[256][2] = {
6986
    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
6987
    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
6988
    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
6989
    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
6990
    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
6991
    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
6992
    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
6993
    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
6994
    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
6995
    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
6996
    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
6997
    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
6998
    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
6999
    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
7000
    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
7001
    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
7002
    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
7003
    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
7004
    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
7005
    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
7006
    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
7007
    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
7008
    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
7009
    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
7010
    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
7011
    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
7012
    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
7013
    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
7014
    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
7015
    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
7016
    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
7017
    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
7018
    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
7019
    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
7020
    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
7021
    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
7022
    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
7023
    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
7024
    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
7025
    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
7026
    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
7027
    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
7028
    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
7029
    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
7030
    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
7031
    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
7032
    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
7033
    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
7034
    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
7035
    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
7036
    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
7037
    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
7038
    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
7039
    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
7040
    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
7041
    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
7042
    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
7043
    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
7044
    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
7045
    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
7046
    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
7047
    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
7048
    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
7049
    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
7050
7051
7052
static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE])
7053
{
7054
#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
7055
    int i, j;
7056
    byte Z[WC_AES_BLOCK_SIZE];
7057
    byte a;
7058
7059
    XMEMSET(Z, 0, sizeof(Z));
7060
7061
    for (i = 15; i > 0; i--) {
7062
        xorbuf(Z, m[x[i]], WC_AES_BLOCK_SIZE);
7063
        a = Z[15];
7064
7065
        for (j = 15; j > 0; j--) {
7066
            Z[j] = Z[j-1];
7067
        }
7068
7069
        Z[0]  = R[a][0];
7070
        Z[1] ^= R[a][1];
7071
    }
7072
    xorbuf(Z, m[x[0]], WC_AES_BLOCK_SIZE);
7073
7074
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
7075
#elif defined(WC_32BIT_CPU)
7076
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
7077
    byte a;
7078
    word32* pZ;
7079
    word32* pm;
7080
    word32* px = (word32*)(x);
7081
    int i;
7082
7083
    pZ = (word32*)(Z + 15 + 1);
7084
    pm = (word32*)(m[x[15]]);
7085
    pZ[0] = pm[0];
7086
    pZ[1] = pm[1];
7087
    pZ[2] = pm[2];
7088
    pZ[3] = pm[3];
7089
    a = Z[16 + 15];
7090
    Z[15]  = R[a][0];
7091
    Z[16] ^= R[a][1];
7092
    for (i = 14; i > 0; i--) {
7093
        pZ = (word32*)(Z + i + 1);
7094
        pm = (word32*)(m[x[i]]);
7095
        pZ[0] ^= pm[0];
7096
        pZ[1] ^= pm[1];
7097
        pZ[2] ^= pm[2];
7098
        pZ[3] ^= pm[3];
7099
        a = Z[16 + i];
7100
        Z[i]    = R[a][0];
7101
        Z[i+1] ^= R[a][1];
7102
    }
7103
    pZ = (word32*)(Z + 1);
7104
    pm = (word32*)(m[x[0]]);
7105
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
7106
    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
7107
#else
7108
    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
7109
    byte a;
7110
    word64* pZ;
7111
    word64* pm;
7112
    word64* px = (word64*)(x);
7113
    int i;
7114
7115
    pZ = (word64*)(Z + 15 + 1);
7116
    pm = (word64*)(m[x[15]]);
7117
    pZ[0] = pm[0];
7118
    pZ[1] = pm[1];
7119
    a = Z[16 + 15];
7120
    Z[15]  = R[a][0];
7121
    Z[16] ^= R[a][1];
7122
    for (i = 14; i > 0; i--) {
7123
        pZ = (word64*)(Z + i + 1);
7124
        pm = (word64*)(m[x[i]]);
7125
        pZ[0] ^= pm[0];
7126
        pZ[1] ^= pm[1];
7127
        a = Z[16 + i];
7128
        Z[i]    = R[a][0];
7129
        Z[i+1] ^= R[a][1];
7130
    }
7131
    pZ = (word64*)(Z + 1);
7132
    pm = (word64*)(m[x[0]]);
7133
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
7134
#endif
7135
}
7136
7137
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7138
    word32 cSz, byte* s, word32 sSz)
7139
{
7140
    byte x[WC_AES_BLOCK_SIZE];
7141
    byte scratch[WC_AES_BLOCK_SIZE];
7142
    word32 blocks, partial;
7143
7144
    if (gcm == NULL) {
7145
        return;
7146
    }
7147
7148
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
7149
7150
    /* Hash in A, the Additional Authentication Data */
7151
    if (aSz != 0 && a != NULL) {
7152
        blocks = aSz / WC_AES_BLOCK_SIZE;
7153
        partial = aSz % WC_AES_BLOCK_SIZE;
7154
        while (blocks--) {
7155
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
7156
            GMULT(x, gcm->M0);
7157
            a += WC_AES_BLOCK_SIZE;
7158
        }
7159
        if (partial != 0) {
7160
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7161
            XMEMCPY(scratch, a, partial);
7162
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7163
            GMULT(x, gcm->M0);
7164
        }
7165
    }
7166
7167
    /* Hash in C, the Ciphertext */
7168
    if (cSz != 0 && c != NULL) {
7169
        blocks = cSz / WC_AES_BLOCK_SIZE;
7170
        partial = cSz % WC_AES_BLOCK_SIZE;
7171
        while (blocks--) {
7172
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
7173
            GMULT(x, gcm->M0);
7174
            c += WC_AES_BLOCK_SIZE;
7175
        }
7176
        if (partial != 0) {
7177
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7178
            XMEMCPY(scratch, c, partial);
7179
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7180
            GMULT(x, gcm->M0);
7181
        }
7182
    }
7183
7184
    /* Hash in the lengths of A and C in bits */
7185
    FlattenSzInBits(&scratch[0], aSz);
7186
    FlattenSzInBits(&scratch[8], cSz);
7187
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7188
    GMULT(x, gcm->M0);
7189
7190
    /* Copy the result into s. */
7191
    XMEMCPY(s, x, sSz);
7192
}
7193
7194
#ifdef WOLFSSL_AESGCM_STREAM
7195
/* No extra initialization for table implementation.
7196
 *
7197
 * @param [in] aes  AES GCM object.
7198
 */
7199
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7200
7201
/* GHASH one block of data..
7202
 *
7203
 * XOR block into tag and GMULT with H using pre-computed table.
7204
 *
7205
 * @param [in, out] aes    AES GCM object.
7206
 * @param [in]      block  Block of AAD or cipher text.
7207
 */
7208
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
7209
    do {                                                \
7210
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
7211
        GMULT(AES_TAG(aes), aes->gcm.M0);               \
7212
    }                                                   \
7213
    while (0)
7214
#endif /* WOLFSSL_AESGCM_STREAM */
7215
/* end GCM_TABLE */
7216
#elif defined(GCM_TABLE_4BIT)
7217
7218
/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
7219
 *  R shifts right a reverse bit pair of bytes such that:
7220
 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
7221
 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
7222
 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
7223
 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
7224
 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
7225
 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
7226
 *  To calculate te rest, XOR result for each bit.
7227
 *   e.g. 6 = 4 ^ 2 => 48,c0
7228
 *
7229
 * Second half is same values rotated by 4-bits.
7230
 */
7231
#if defined(BIG_ENDIAN_ORDER) || defined(WC_16BIT_CPU)
7232
static const byte R[16][2] = {
7233
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
7234
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
7235
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
7236
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
7237
};
7238
#else
7239
static const word16 R[32] = {
7240
          0x0000,       0x201c,       0x4038,       0x6024,
7241
          0x8070,       0xa06c,       0xc048,       0xe054,
7242
          0x00e1,       0x20fd,       0x40d9,       0x60c5,
7243
          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
7244
7245
          0x0000,       0xc201,       0x8403,       0x4602,
7246
          0x0807,       0xca06,       0x8c04,       0x4e05,
7247
          0x100e,       0xd20f,       0x940d,       0x560c,
7248
          0x1809,       0xda08,       0x9c0a,       0x5e0b,
7249
};
7250
#endif
7251
7252
/* Multiply in GF(2^128) defined by polynomial:
7253
 *   x^128 + x^7 + x^2 + x^1 + 1.
7254
 *
7255
 * H: hash key = encrypt(key, 0)
7256
 * x = x * H in field
7257
 *
7258
 * x: cumulative result
7259
 * m: 4-bit table
7260
 *    [0..15] * H
7261
 */
7262
#if defined(BIG_ENDIAN_ORDER) || defined(WC_16BIT_CPU)
7263
static void GMULT(byte *x, byte m[16][WC_AES_BLOCK_SIZE])
7264
{
7265
    int i, j, n;
7266
    byte Z[WC_AES_BLOCK_SIZE];
7267
    byte a;
7268
7269
    XMEMSET(Z, 0, sizeof(Z));
7270
7271
    for (i = 15; i >= 0; i--) {
7272
        for (n = 0; n < 2; n++) {
7273
            if (n == 0)
7274
                xorbuf(Z, m[x[i] & 0xf], WC_AES_BLOCK_SIZE);
7275
            else {
7276
                xorbuf(Z, m[x[i] >> 4], WC_AES_BLOCK_SIZE);
7277
                if (i == 0)
7278
                    break;
7279
            }
7280
            a = Z[15] & 0xf;
7281
7282
            for (j = 15; j > 0; j--)
7283
                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
7284
            Z[0] >>= 4;
7285
7286
            Z[0] ^= R[a][0];
7287
            Z[1] ^= R[a][1];
7288
        }
7289
    }
7290
7291
    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
7292
}
7293
#elif defined(WC_32BIT_CPU)
7294
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
7295
{
7296
    int i;
7297
    word32 z8[4] = {0, 0, 0, 0};
7298
    byte a;
7299
    word32* x8 = (word32*)x;
7300
    word32* m8;
7301
    byte xi;
7302
    word32 n7, n6, n5, n4, n3, n2, n1, n0;
7303
7304
    for (i = 15; i > 0; i--) {
7305
        xi = x[i];
7306
7307
        /* XOR in (msn * H) */
7308
        m8 = (word32*)m[xi & 0xf];
7309
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
7310
7311
        /* Cache top byte for remainder calculations - lost in rotate. */
7312
        a = (byte)(z8[3] >> 24);
7313
7314
        /* Rotate Z by 8-bits */
7315
        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
7316
        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
7317
        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
7318
        z8[0] <<= 8;
7319
7320
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
7321
        z8[0] ^= (word32)R[16 + (a & 0xf)];
7322
7323
        xi >>= 4;
7324
        /* XOR in next significant nibble (XORed with H) * remainder */
7325
        m8 = (word32*)m[xi];
7326
        a ^= (byte)(m8[3] >> 20);
7327
        z8[0] ^= (word32)R[a >> 4];
7328
7329
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
7330
        m8 = (word32*)m[16 + xi];
7331
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
7332
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
7333
    }
7334
7335
    xi = x[0];
7336
7337
    /* XOR in most significant nibble * H */
7338
    m8 = (word32*)m[xi & 0xf];
7339
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
7340
7341
    /* Cache top byte for remainder calculations - lost in rotate. */
7342
    a = (z8[3] >> 24) & 0xf;
7343
7344
    /* Rotate z by 4-bits */
7345
    n7 = z8[3] & 0xf0f0f0f0ULL;
7346
    n6 = z8[3] & 0x0f0f0f0fULL;
7347
    n5 = z8[2] & 0xf0f0f0f0ULL;
7348
    n4 = z8[2] & 0x0f0f0f0fULL;
7349
    n3 = z8[1] & 0xf0f0f0f0ULL;
7350
    n2 = z8[1] & 0x0f0f0f0fULL;
7351
    n1 = z8[0] & 0xf0f0f0f0ULL;
7352
    n0 = z8[0] & 0x0f0f0f0fULL;
7353
    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
7354
    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
7355
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
7356
    z8[0] = (n1 >> 4) | (n0 << 12);
7357
7358
    /* XOR in most significant nibble * remainder */
7359
    z8[0] ^= (word32)R[a];
7360
    /* XOR in next significant nibble * H */
7361
    m8 = (word32*)m[xi >> 4];
7362
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
7363
7364
    /* Write back result. */
7365
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
7366
}
7367
#else
7368
static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
7369
0
{
7370
0
    int i;
7371
0
    word64 z8[2] = {0, 0};
7372
0
    byte a;
7373
0
    word64* x8 = (word64*)x;
7374
0
    word64* m8;
7375
0
    word64 n0, n1, n2, n3;
7376
0
    byte xi;
7377
7378
0
    for (i = 15; i > 0; i--) {
7379
0
        xi = x[i];
7380
7381
        /* XOR in (msn * H) */
7382
0
        m8 = (word64*)m[xi & 0xf];
7383
0
        z8[0] ^= m8[0];
7384
0
        z8[1] ^= m8[1];
7385
7386
        /* Cache top byte for remainder calculations - lost in rotate. */
7387
0
        a = (byte)(z8[1] >> 56);
7388
7389
        /* Rotate Z by 8-bits */
7390
0
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
7391
0
        z8[0] <<= 8;
7392
7393
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
7394
0
        m8 = (word64*)m[16 + (xi >> 4)];
7395
0
        z8[0] ^= m8[0];
7396
0
        z8[1] ^= m8[1];
7397
7398
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
7399
0
        z8[0] ^= (word64)R[16 + (a & 0xf)];
7400
        /* XOR in next significant nibble (XORed with H) * remainder */
7401
0
        m8 = (word64*)m[xi >> 4];
7402
0
        a ^= (byte)(m8[1] >> 52);
7403
0
        z8[0] ^= (word64)R[a >> 4];
7404
0
    }
7405
7406
0
    xi = x[0];
7407
7408
    /* XOR in most significant nibble * H */
7409
0
    m8 = (word64*)m[xi & 0xf];
7410
0
    z8[0] ^= m8[0];
7411
0
    z8[1] ^= m8[1];
7412
7413
    /* Cache top byte for remainder calculations - lost in rotate. */
7414
0
    a = (z8[1] >> 56) & 0xf;
7415
7416
    /* Rotate z by 4-bits */
7417
0
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
7418
0
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
7419
0
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
7420
0
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
7421
0
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
7422
0
    z8[0] = (n1 >> 4) | (n0 << 12);
7423
7424
    /* XOR in next significant nibble * H */
7425
0
    m8 = (word64*)m[xi >> 4];
7426
0
    z8[0] ^= m8[0];
7427
0
    z8[1] ^= m8[1];
7428
    /* XOR in most significant nibble * remainder */
7429
0
    z8[0] ^= (word64)R[a];
7430
7431
    /* Write back result. */
7432
0
    x8[0] = z8[0];
7433
0
    x8[1] = z8[1];
7434
0
}
7435
#endif
7436
7437
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7438
    word32 cSz, byte* s, word32 sSz)
7439
0
{
7440
0
    byte x[WC_AES_BLOCK_SIZE];
7441
0
    byte scratch[WC_AES_BLOCK_SIZE];
7442
0
    word32 blocks, partial;
7443
7444
0
    if (gcm == NULL) {
7445
0
        return;
7446
0
    }
7447
7448
0
    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
7449
7450
    /* Hash in A, the Additional Authentication Data */
7451
0
    if (aSz != 0 && a != NULL) {
7452
0
        blocks = aSz / WC_AES_BLOCK_SIZE;
7453
0
        partial = aSz % WC_AES_BLOCK_SIZE;
7454
0
        while (blocks--) {
7455
0
            xorbuf(x, a, WC_AES_BLOCK_SIZE);
7456
0
            GMULT(x, gcm->M0);
7457
0
            a += WC_AES_BLOCK_SIZE;
7458
0
        }
7459
0
        if (partial != 0) {
7460
0
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7461
0
            XMEMCPY(scratch, a, partial);
7462
0
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7463
0
            GMULT(x, gcm->M0);
7464
0
        }
7465
0
    }
7466
7467
    /* Hash in C, the Ciphertext */
7468
0
    if (cSz != 0 && c != NULL) {
7469
0
        blocks = cSz / WC_AES_BLOCK_SIZE;
7470
0
        partial = cSz % WC_AES_BLOCK_SIZE;
7471
0
        while (blocks--) {
7472
0
            xorbuf(x, c, WC_AES_BLOCK_SIZE);
7473
0
            GMULT(x, gcm->M0);
7474
0
            c += WC_AES_BLOCK_SIZE;
7475
0
        }
7476
0
        if (partial != 0) {
7477
0
            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
7478
0
            XMEMCPY(scratch, c, partial);
7479
0
            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7480
0
            GMULT(x, gcm->M0);
7481
0
        }
7482
0
    }
7483
7484
    /* Hash in the lengths of A and C in bits */
7485
0
    FlattenSzInBits(&scratch[0], aSz);
7486
0
    FlattenSzInBits(&scratch[8], cSz);
7487
0
    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
7488
0
    GMULT(x, gcm->M0);
7489
7490
    /* Copy the result into s. */
7491
0
    XMEMCPY(s, x, sSz);
7492
0
}
7493
7494
#ifdef WOLFSSL_AESGCM_STREAM
7495
/* No extra initialization for 4-bit table implementation.
7496
 *
7497
 * @param [in] aes  AES GCM object.
7498
 */
7499
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7500
7501
/* GHASH one block of data..
7502
 *
7503
 * XOR block into tag and GMULT with H using pre-computed table.
7504
 *
7505
 * @param [in, out] aes    AES GCM object.
7506
 * @param [in]      block  Block of AAD or cipher text.
7507
 */
7508
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
7509
    do {                                                \
7510
        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
7511
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
7512
    }                                                   \
7513
    while (0)
7514
#endif /* WOLFSSL_AESGCM_STREAM */
7515
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
7516
7517
#if !defined(FREESCALE_LTC_AES_GCM)
7518
static void GMULT(word64* X, word64* Y)
7519
{
7520
    word64 Z[2] = {0,0};
7521
    word64 V[2];
7522
    int i, j;
7523
    word64 v1;
7524
    V[0] = X[0];  V[1] = X[1];
7525
7526
    for (i = 0; i < 2; i++)
7527
    {
7528
        word64 y = Y[i];
7529
        for (j = 0; j < 64; j++)
7530
        {
7531
#ifndef AES_GCM_GMULT_NCT
7532
            word64 mask = 0 - (y >> 63);
7533
            Z[0] ^= V[0] & mask;
7534
            Z[1] ^= V[1] & mask;
7535
#else
7536
            if (y & 0x8000000000000000ULL) {
7537
                Z[0] ^= V[0];
7538
                Z[1] ^= V[1];
7539
            }
7540
#endif
7541
7542
            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
7543
            V[1] >>= 1;
7544
            V[1] |= V[0] << 63;
7545
            V[0] >>= 1;
7546
            V[0] ^= v1;
7547
            y <<= 1;
7548
        }
7549
    }
7550
    X[0] = Z[0];
7551
    X[1] = Z[1];
7552
}
7553
7554
7555
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7556
    word32 cSz, byte* s, word32 sSz)
7557
{
7558
    word64 x[2] = {0,0};
7559
    word32 blocks, partial;
7560
    word64 bigH[2];
7561
7562
    if (gcm == NULL) {
7563
        return;
7564
    }
7565
7566
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
7567
    #ifdef LITTLE_ENDIAN_ORDER
7568
        ByteReverseWords64(bigH, bigH, WC_AES_BLOCK_SIZE);
7569
    #endif
7570
7571
    /* Hash in A, the Additional Authentication Data */
7572
    if (aSz != 0 && a != NULL) {
7573
        word64 bigA[2];
7574
        blocks = aSz / WC_AES_BLOCK_SIZE;
7575
        partial = aSz % WC_AES_BLOCK_SIZE;
7576
        while (blocks--) {
7577
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
7578
            #ifdef LITTLE_ENDIAN_ORDER
7579
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
7580
            #endif
7581
            x[0] ^= bigA[0];
7582
            x[1] ^= bigA[1];
7583
            GMULT(x, bigH);
7584
            a += WC_AES_BLOCK_SIZE;
7585
        }
7586
        if (partial != 0) {
7587
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
7588
            XMEMCPY(bigA, a, partial);
7589
            #ifdef LITTLE_ENDIAN_ORDER
7590
                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
7591
            #endif
7592
            x[0] ^= bigA[0];
7593
            x[1] ^= bigA[1];
7594
            GMULT(x, bigH);
7595
        }
7596
#ifdef OPENSSL_EXTRA
7597
        /* store AAD partial tag for next call */
7598
        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
7599
        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
7600
        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
7601
        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
7602
#endif
7603
    }
7604
7605
    /* Hash in C, the Ciphertext */
7606
    if (cSz != 0 && c != NULL) {
7607
        word64 bigC[2];
7608
        blocks = cSz / WC_AES_BLOCK_SIZE;
7609
        partial = cSz % WC_AES_BLOCK_SIZE;
7610
#ifdef OPENSSL_EXTRA
7611
        /* Start from last AAD partial tag */
7612
        if(gcm->aadLen) {
7613
            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
7614
            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
7615
         }
7616
#endif
7617
        while (blocks--) {
7618
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
7619
            #ifdef LITTLE_ENDIAN_ORDER
7620
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
7621
            #endif
7622
            x[0] ^= bigC[0];
7623
            x[1] ^= bigC[1];
7624
            GMULT(x, bigH);
7625
            c += WC_AES_BLOCK_SIZE;
7626
        }
7627
        if (partial != 0) {
7628
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
7629
            XMEMCPY(bigC, c, partial);
7630
            #ifdef LITTLE_ENDIAN_ORDER
7631
                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
7632
            #endif
7633
            x[0] ^= bigC[0];
7634
            x[1] ^= bigC[1];
7635
            GMULT(x, bigH);
7636
        }
7637
    }
7638
7639
    /* Hash in the lengths in bits of A and C */
7640
    {
7641
        word64 len[2];
7642
        len[0] = aSz; len[1] = cSz;
7643
#ifdef OPENSSL_EXTRA
7644
        if (gcm->aadLen)
7645
            len[0] = (word64)gcm->aadLen;
7646
#endif
7647
        /* Lengths are in bytes. Convert to bits. */
7648
        len[0] *= 8;
7649
        len[1] *= 8;
7650
7651
        x[0] ^= len[0];
7652
        x[1] ^= len[1];
7653
        GMULT(x, bigH);
7654
    }
7655
    #ifdef LITTLE_ENDIAN_ORDER
7656
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
7657
    #endif
7658
    XMEMCPY(s, x, sSz);
7659
}
7660
#endif /* !FREESCALE_LTC_AES_GCM */
7661
7662
#ifdef WOLFSSL_AESGCM_STREAM
7663
7664
#ifdef LITTLE_ENDIAN_ORDER
7665
7666
/* No extra initialization for small implementation.
7667
 *
7668
 * @param [in] aes  AES GCM object.
7669
 */
7670
#define GHASH_INIT_EXTRA(aes)                                               \
7671
    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, WC_AES_BLOCK_SIZE)
7672
7673
/* GHASH one block of data..
7674
 *
7675
 * XOR block into tag and GMULT with H.
7676
 *
7677
 * @param [in, out] aes    AES GCM object.
7678
 * @param [in]      block  Block of AAD or cipher text.
7679
 */
7680
#define GHASH_ONE_BLOCK_SW(aes, block)                              \
7681
    do {                                                            \
7682
        word64* x = (word64*)AES_TAG(aes);                          \
7683
        word64* h = (word64*)aes->gcm.H;                            \
7684
        word64 block64[2];                                          \
7685
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);                 \
7686
        ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE);    \
7687
        x[0] ^= block64[0];                                         \
7688
        x[1] ^= block64[1];                                         \
7689
        GMULT(x, h);                                                \
7690
    }                                                               \
7691
    while (0)
7692
7693
#ifdef OPENSSL_EXTRA
7694
/* GHASH in AAD and cipher text lengths in bits.
7695
 *
7696
 * Convert tag back to little-endian.
7697
 *
7698
 * @param [in, out] aes  AES GCM object.
7699
 */
7700
#define GHASH_LEN_BLOCK(aes)                            \
7701
    do {                                                \
7702
        word64* x = (word64*)AES_TAG(aes);              \
7703
        word64* h = (word64*)aes->gcm.H;                \
7704
        word64 len[2];                                  \
7705
        len[0] = aes->aSz; len[1] = aes->cSz;           \
7706
        if (aes->gcm.aadLen)                            \
7707
            len[0] = (word64)aes->gcm.aadLen;           \
7708
        /* Lengths are in bytes. Convert to bits. */    \
7709
        len[0] *= 8;                                    \
7710
        len[1] *= 8;                                    \
7711
                                                        \
7712
        x[0] ^= len[0];                                 \
7713
        x[1] ^= len[1];                                 \
7714
        GMULT(x, h);                                    \
7715
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
7716
    }                                                   \
7717
    while (0)
7718
#else
7719
/* GHASH in AAD and cipher text lengths in bits.
7720
 *
7721
 * Convert tag back to little-endian.
7722
 *
7723
 * @param [in, out] aes  AES GCM object.
7724
 */
7725
#define GHASH_LEN_BLOCK(aes)                            \
7726
    do {                                                \
7727
        word64* x = (word64*)AES_TAG(aes);              \
7728
        word64* h = (word64*)aes->gcm.H;                \
7729
        word64 len[2];                                  \
7730
        len[0] = aes->aSz; len[1] = aes->cSz;           \
7731
        /* Lengths are in bytes. Convert to bits. */    \
7732
        len[0] *= 8;                                    \
7733
        len[1] *= 8;                                    \
7734
                                                        \
7735
        x[0] ^= len[0];                                 \
7736
        x[1] ^= len[1];                                 \
7737
        GMULT(x, h);                                    \
7738
        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
7739
    }                                                   \
7740
    while (0)
7741
#endif
7742
7743
#else
7744
7745
/* No extra initialization for small implementation.
7746
 *
7747
 * @param [in] aes  AES GCM object.
7748
 */
7749
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7750
7751
/* GHASH one block of data..
7752
 *
7753
 * XOR block into tag and GMULT with H.
7754
 *
7755
 * @param [in, out] aes    AES GCM object.
7756
 * @param [in]      block  Block of AAD or cipher text.
7757
 */
7758
#define GHASH_ONE_BLOCK_SW(aes, block)                  \
7759
    do {                                                \
7760
        word64* x = (word64*)AES_TAG(aes);              \
7761
        word64* h = (word64*)aes->gcm.H;                \
7762
        word64 block64[2];                              \
7763
        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);        \
7764
        x[0] ^= block64[0];                             \
7765
        x[1] ^= block64[1];                             \
7766
        GMULT(x, h);                                    \
7767
    }                                                   \
7768
    while (0)
7769
7770
#ifdef OPENSSL_EXTRA
7771
/* GHASH in AAD and cipher text lengths in bits.
7772
 *
7773
 * Convert tag back to little-endian.
7774
 *
7775
 * @param [in, out] aes  AES GCM object.
7776
 */
7777
#define GHASH_LEN_BLOCK(aes)                            \
7778
    do {                                                \
7779
        word64* x = (word64*)AES_TAG(aes);              \
7780
        word64* h = (word64*)aes->gcm.H;                \
7781
        word64 len[2];                                  \
7782
        len[0] = aes->aSz; len[1] = aes->cSz;           \
7783
        if (aes->gcm.aadLen)                            \
7784
            len[0] = (word64)aes->gcm.aadLen;           \
7785
        /* Lengths are in bytes. Convert to bits. */    \
7786
        len[0] *= 8;                                    \
7787
        len[1] *= 8;                                    \
7788
                                                        \
7789
        x[0] ^= len[0];                                 \
7790
        x[1] ^= len[1];                                 \
7791
        GMULT(x, h);                                    \
7792
    }                                                   \
7793
    while (0)
7794
#else
7795
/* GHASH in AAD and cipher text lengths in bits.
7796
 *
7797
 * Convert tag back to little-endian.
7798
 *
7799
 * @param [in, out] aes  AES GCM object.
7800
 */
7801
#define GHASH_LEN_BLOCK(aes)                            \
7802
    do {                                                \
7803
        word64* x = (word64*)AES_TAG(aes);              \
7804
        word64* h = (word64*)aes->gcm.H;                \
7805
        word64 len[2];                                  \
7806
        len[0] = aes->aSz; len[1] = aes->cSz;           \
7807
        /* Lengths are in bytes. Convert to bits. */    \
7808
        len[0] *= 8;                                    \
7809
        len[1] *= 8;                                    \
7810
                                                        \
7811
        x[0] ^= len[0];                                 \
7812
        x[1] ^= len[1];                                 \
7813
        GMULT(x, h);                                    \
7814
    }                                                   \
7815
    while (0)
7816
#endif
7817
7818
#endif /* !LITTLE_ENDIAN_ORDER */
7819
7820
#endif /* WOLFSSL_AESGCM_STREAM */
7821
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
7822
#else /* GCM_WORD32 */
7823
7824
static void GMULT(word32* X, word32* Y)
7825
{
7826
    word32 Z[4] = {0,0,0,0};
7827
    word32 V[4];
7828
    int i, j;
7829
7830
    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
7831
7832
    for (i = 0; i < 4; i++)
7833
    {
7834
        word32 y = Y[i];
7835
        for (j = 0; j < 32; j++)
7836
        {
7837
            if (y & 0x80000000) {
7838
                Z[0] ^= V[0];
7839
                Z[1] ^= V[1];
7840
                Z[2] ^= V[2];
7841
                Z[3] ^= V[3];
7842
            }
7843
7844
            if (V[3] & 0x00000001) {
7845
                V[3] >>= 1;
7846
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
7847
                V[2] >>= 1;
7848
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
7849
                V[1] >>= 1;
7850
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
7851
                V[0] >>= 1;
7852
                V[0] ^= 0xE1000000;
7853
            } else {
7854
                V[3] >>= 1;
7855
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
7856
                V[2] >>= 1;
7857
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
7858
                V[1] >>= 1;
7859
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
7860
                V[0] >>= 1;
7861
            }
7862
            y <<= 1;
7863
        }
7864
    }
7865
    X[0] = Z[0];
7866
    X[1] = Z[1];
7867
    X[2] = Z[2];
7868
    X[3] = Z[3];
7869
}
7870
7871
7872
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7873
    word32 cSz, byte* s, word32 sSz)
7874
{
7875
    word32 x[4] = {0,0,0,0};
7876
    word32 blocks, partial;
7877
    word32 bigH[4];
7878
7879
    if (gcm == NULL) {
7880
        return;
7881
    }
7882
7883
    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
7884
    #ifdef LITTLE_ENDIAN_ORDER
7885
        ByteReverseWords(bigH, bigH, WC_AES_BLOCK_SIZE);
7886
    #endif
7887
7888
    /* Hash in A, the Additional Authentication Data */
7889
    if (aSz != 0 && a != NULL) {
7890
        word32 bigA[4];
7891
        blocks = aSz / WC_AES_BLOCK_SIZE;
7892
        partial = aSz % WC_AES_BLOCK_SIZE;
7893
        while (blocks--) {
7894
            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
7895
            #ifdef LITTLE_ENDIAN_ORDER
7896
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
7897
            #endif
7898
            x[0] ^= bigA[0];
7899
            x[1] ^= bigA[1];
7900
            x[2] ^= bigA[2];
7901
            x[3] ^= bigA[3];
7902
            GMULT(x, bigH);
7903
            a += WC_AES_BLOCK_SIZE;
7904
        }
7905
        if (partial != 0) {
7906
            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
7907
            XMEMCPY(bigA, a, partial);
7908
            #ifdef LITTLE_ENDIAN_ORDER
7909
                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
7910
            #endif
7911
            x[0] ^= bigA[0];
7912
            x[1] ^= bigA[1];
7913
            x[2] ^= bigA[2];
7914
            x[3] ^= bigA[3];
7915
            GMULT(x, bigH);
7916
        }
7917
    }
7918
7919
    /* Hash in C, the Ciphertext */
7920
    if (cSz != 0 && c != NULL) {
7921
        word32 bigC[4];
7922
        blocks = cSz / WC_AES_BLOCK_SIZE;
7923
        partial = cSz % WC_AES_BLOCK_SIZE;
7924
        while (blocks--) {
7925
            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
7926
            #ifdef LITTLE_ENDIAN_ORDER
7927
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
7928
            #endif
7929
            x[0] ^= bigC[0];
7930
            x[1] ^= bigC[1];
7931
            x[2] ^= bigC[2];
7932
            x[3] ^= bigC[3];
7933
            GMULT(x, bigH);
7934
            c += WC_AES_BLOCK_SIZE;
7935
        }
7936
        if (partial != 0) {
7937
            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
7938
            XMEMCPY(bigC, c, partial);
7939
            #ifdef LITTLE_ENDIAN_ORDER
7940
                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
7941
            #endif
7942
            x[0] ^= bigC[0];
7943
            x[1] ^= bigC[1];
7944
            x[2] ^= bigC[2];
7945
            x[3] ^= bigC[3];
7946
            GMULT(x, bigH);
7947
        }
7948
    }
7949
7950
    /* Hash in the lengths in bits of A and C */
7951
    {
7952
        word32 len[4];
7953
7954
        /* Lengths are in bytes. Convert to bits. */
7955
        len[0] = (aSz >> (8*sizeof(aSz) - 3));
7956
        len[1] = aSz << 3;
7957
        len[2] = (cSz >> (8*sizeof(cSz) - 3));
7958
        len[3] = cSz << 3;
7959
7960
        x[0] ^= len[0];
7961
        x[1] ^= len[1];
7962
        x[2] ^= len[2];
7963
        x[3] ^= len[3];
7964
        GMULT(x, bigH);
7965
    }
7966
    #ifdef LITTLE_ENDIAN_ORDER
7967
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
7968
    #endif
7969
    XMEMCPY(s, x, sSz);
7970
}
7971
7972
#ifdef WOLFSSL_AESGCM_STREAM
7973
#ifdef LITTLE_ENDIAN_ORDER
7974
/* Little-endian 32-bit word implementation requires byte reversal of H.
7975
 *
7976
 * H is all-zeros block encrypted with key.
7977
 *
7978
 * @param [in, out] aes  AES GCM object.
7979
 */
7980
#define GHASH_INIT_EXTRA(aes) \
7981
    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, WC_AES_BLOCK_SIZE)
7982
7983
/* GHASH one block of data..
7984
 *
7985
 * XOR block, in big-endian form, into tag and GMULT with H.
7986
 *
7987
 * @param [in, out] aes    AES GCM object.
7988
 * @param [in]      block  Block of AAD or cipher text.
7989
 */
7990
#define GHASH_ONE_BLOCK_SW(aes, block)                          \
7991
    do {                                                        \
7992
        word32* x = (word32*)AES_TAG(aes);                      \
7993
        word32* h = (word32*)aes->gcm.H;                        \
7994
        word32 bigEnd[4];                                       \
7995
        XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE);              \
7996
        ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE);    \
7997
        x[0] ^= bigEnd[0];                                      \
7998
        x[1] ^= bigEnd[1];                                      \
7999
        x[2] ^= bigEnd[2];                                      \
8000
        x[3] ^= bigEnd[3];                                      \
8001
        GMULT(x, h);                                            \
8002
    }                                                           \
8003
    while (0)
8004
8005
/* GHASH in AAD and cipher text lengths in bits.
8006
 *
8007
 * Convert tag back to little-endian.
8008
 *
8009
 * @param [in, out] aes  AES GCM object.
8010
 */
8011
#define GHASH_LEN_BLOCK(aes)                                \
8012
    do {                                                    \
8013
        word32 len[4];                                      \
8014
        word32* x = (word32*)AES_TAG(aes);                  \
8015
        word32* h = (word32*)aes->gcm.H;                    \
8016
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
8017
        len[1] = aes->aSz << 3;                             \
8018
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
8019
        len[3] = aes->cSz << 3;                             \
8020
        x[0] ^= len[0];                                     \
8021
        x[1] ^= len[1];                                     \
8022
        x[2] ^= len[2];                                     \
8023
        x[3] ^= len[3];                                     \
8024
        GMULT(x, h);                                        \
8025
        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);          \
8026
    }                                                       \
8027
    while (0)
8028
#else
8029
/* No extra initialization for 32-bit word implementation.
8030
 *
8031
 * @param [in] aes  AES GCM object.
8032
 */
8033
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
8034
8035
/* GHASH one block of data..
8036
 *
8037
 * XOR block into tag and GMULT with H.
8038
 *
8039
 * @param [in, out] aes    AES GCM object.
8040
 * @param [in]      block  Block of AAD or cipher text.
8041
 */
8042
#define GHASH_ONE_BLOCK_SW(aes, block)                      \
8043
    do {                                                    \
8044
        word32* x = (word32*)AES_TAG(aes);                  \
8045
        word32* h = (word32*)aes->gcm.H;                    \
8046
        word32 block32[4];                                  \
8047
        XMEMCPY(block32, block, WC_AES_BLOCK_SIZE);         \
8048
        x[0] ^= block32[0];                                 \
8049
        x[1] ^= block32[1];                                 \
8050
        x[2] ^= block32[2];                                 \
8051
        x[3] ^= block32[3];                                 \
8052
        GMULT(x, h);                                        \
8053
    }                                                       \
8054
    while (0)
8055
8056
/* GHASH in AAD and cipher text lengths in bits.
8057
 *
8058
 * @param [in, out] aes  AES GCM object.
8059
 */
8060
#define GHASH_LEN_BLOCK(aes)                                \
8061
    do {                                                    \
8062
        word32 len[4];                                      \
8063
        word32* x = (word32*)AES_TAG(aes);                  \
8064
        word32* h = (word32*)aes->gcm.H;                    \
8065
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
8066
        len[1] = aes->aSz << 3;                             \
8067
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
8068
        len[3] = aes->cSz << 3;                             \
8069
        x[0] ^= len[0];                                     \
8070
        x[1] ^= len[1];                                     \
8071
        x[2] ^= len[2];                                     \
8072
        x[3] ^= len[3];                                     \
8073
        GMULT(x, h);                                        \
8074
    }                                                       \
8075
    while (0)
8076
#endif /* LITTLE_ENDIAN_ORDER */
8077
#endif /* WOLFSSL_AESGCM_STREAM */
8078
#endif /* end GCM_WORD32 */
8079
8080
#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
8081
#ifdef WOLFSSL_AESGCM_STREAM
8082
#ifndef GHASH_LEN_BLOCK
8083
/* Hash in the lengths of the AAD and cipher text in bits.
8084
 *
8085
 * Default implementation.
8086
 *
8087
 * @param [in, out] aes  AES GCM object.
8088
 */
8089
#define GHASH_LEN_BLOCK(aes)                      \
8090
    do {                                          \
8091
        byte scratch[WC_AES_BLOCK_SIZE];          \
8092
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
8093
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
8094
        GHASH_ONE_BLOCK(aes, scratch);            \
8095
    }                                             \
8096
    while (0)
8097
#endif
8098
8099
/* Initialize a GHASH for streaming operations.
8100
 *
8101
 * @param [in, out] aes  AES GCM object.
8102
 */
8103
static void GHASH_INIT(Aes* aes) {
8104
    /* Set tag to all zeros as initial value. */
8105
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
8106
    /* Reset counts of AAD and cipher text. */
8107
    aes->aOver = 0;
8108
    aes->cOver = 0;
8109
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
8110
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8111
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
8112
        ; /* Don't do extra initialization. */
8113
    }
8114
    else
8115
#endif
8116
    {
8117
        /* Extra initialization based on implementation. */
8118
        GHASH_INIT_EXTRA(aes);
8119
    }
8120
}
8121
8122
/* Update the GHASH with AAD and/or cipher text.
8123
 *
8124
 * @param [in,out] aes   AES GCM object.
8125
 * @param [in]     a     Additional authentication data buffer.
8126
 * @param [in]     aSz   Size of data in AAD buffer.
8127
 * @param [in]     c     Cipher text buffer.
8128
 * @param [in]     cSz   Size of data in cipher text buffer.
8129
 */
8130
static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
8131
    word32 cSz)
8132
{
8133
    word32 blocks;
8134
    word32 partial;
8135
8136
    /* Hash in A, the Additional Authentication Data */
8137
    if (aSz != 0 && a != NULL) {
8138
        /* Update count of AAD we have hashed. */
8139
        aes->aSz += aSz;
8140
        /* Check if we have unprocessed data. */
8141
        if (aes->aOver > 0) {
8142
            /* Calculate amount we can use - fill up the block. */
8143
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
8144
            if (sz > aSz) {
8145
                sz = (byte)aSz;
8146
            }
8147
            /* Copy extra into last GHASH block array and update count. */
8148
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
8149
            aes->aOver = (byte)(aes->aOver + sz);
8150
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
8151
                /* We have filled up the block and can process. */
8152
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
8153
                /* Reset count. */
8154
                aes->aOver = 0;
8155
            }
8156
            /* Used up some data. */
8157
            aSz -= sz;
8158
            a += sz;
8159
        }
8160
8161
        /* Calculate number of blocks of AAD and the leftover. */
8162
        blocks = aSz / WC_AES_BLOCK_SIZE;
8163
        partial = aSz % WC_AES_BLOCK_SIZE;
8164
        /* GHASH full blocks now. */
8165
        while (blocks--) {
8166
            GHASH_ONE_BLOCK(aes, a);
8167
            a += WC_AES_BLOCK_SIZE;
8168
        }
8169
        if (partial != 0) {
8170
            /* Cache the partial block. */
8171
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
8172
            aes->aOver = (byte)partial;
8173
        }
8174
    }
8175
    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
8176
        /* No more AAD coming and we have a partial block. */
8177
        /* Fill the rest of the block with zeros. */
8178
        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
8179
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
8180
        /* GHASH last AAD block. */
8181
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
8182
        /* Clear partial count for next time through. */
8183
        aes->aOver = 0;
8184
    }
8185
8186
    /* Hash in C, the Ciphertext */
8187
    if (cSz != 0 && c != NULL) {
8188
        /* Update count of cipher text we have hashed. */
8189
        aes->cSz += cSz;
8190
        if (aes->cOver > 0) {
8191
            /* Calculate amount we can use - fill up the block. */
8192
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
8193
            if (sz > cSz) {
8194
                sz = (byte)cSz;
8195
            }
8196
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
8197
            /* Update count of unused encrypted counter. */
8198
            aes->cOver = (byte)(aes->cOver + sz);
8199
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
8200
                /* We have filled up the block and can process. */
8201
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
8202
                /* Reset count. */
8203
                aes->cOver = 0;
8204
            }
8205
            /* Used up some data. */
8206
            cSz -= sz;
8207
            c += sz;
8208
        }
8209
8210
        /* Calculate number of blocks of cipher text and the leftover. */
8211
        blocks = cSz / WC_AES_BLOCK_SIZE;
8212
        partial = cSz % WC_AES_BLOCK_SIZE;
8213
        /* GHASH full blocks now. */
8214
        while (blocks--) {
8215
            GHASH_ONE_BLOCK(aes, c);
8216
            c += WC_AES_BLOCK_SIZE;
8217
        }
8218
        if (partial != 0) {
8219
            /* Cache the partial block. */
8220
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
8221
            aes->cOver = (byte)partial;
8222
        }
8223
    }
8224
}
8225
8226
/* Finalize the GHASH calculation.
8227
 *
8228
 * Complete hashing cipher text and hash the AAD and cipher text lengths.
8229
 *
8230
 * @param [in, out] aes  AES GCM object.
8231
 * @param [out]     s    Authentication tag.
8232
 * @param [in]      sSz  Size of authentication tag required.
8233
 */
8234
static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
8235
{
8236
    /* AAD block incomplete when > 0 */
8237
    byte over = aes->aOver;
8238
8239
    if (aes->cOver > 0) {
8240
        /* Cipher text block incomplete. */
8241
        over = aes->cOver;
8242
    }
8243
    if (over > 0) {
8244
        /* Zeroize the unused part of the block. */
8245
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
8246
            (size_t)WC_AES_BLOCK_SIZE - over);
8247
        /* Hash the last block of cipher text. */
8248
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
8249
    }
8250
    /* Hash in the lengths of AAD and cipher text in bits */
8251
    GHASH_LEN_BLOCK(aes);
8252
    /* Copy the result into s. */
8253
    XMEMCPY(s, AES_TAG(aes), sSz);
8254
    /* reset aes->gcm.H in case of reuse */
8255
    GHASH_INIT_EXTRA(aes);
8256
}
8257
#endif /* WOLFSSL_AESGCM_STREAM */
8258
8259
8260
#ifdef FREESCALE_LTC_AES_GCM
8261
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
8262
                   const byte* iv, word32 ivSz,
8263
                   byte* authTag, word32 authTagSz,
8264
                   const byte* authIn, word32 authInSz)
8265
{
8266
    status_t status;
8267
    word32 keySize;
8268
8269
    /* argument checks */
8270
    if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE || ivSz == 0) {
8271
        return BAD_FUNC_ARG;
8272
    }
8273
8274
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
8275
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
8276
        return BAD_FUNC_ARG;
8277
    }
8278
8279
    status = wc_AesGetKeySize(aes, &keySize);
8280
    if (status)
8281
        return status;
8282
8283
    status = wolfSSL_CryptHwMutexLock();
8284
    if (status != 0)
8285
        return status;
8286
8287
    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
8288
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
8289
    wolfSSL_CryptHwMutexUnLock();
8290
8291
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
8292
}
8293
8294
#else
8295
8296
#ifdef STM32_CRYPTO_AES_GCM
8297
8298
/* this function supports inline encrypt */
8299
static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
8300
                                  Aes* aes, byte* out, const byte* in, word32 sz,
8301
                                  const byte* iv, word32 ivSz,
8302
                                  byte* authTag, word32 authTagSz,
8303
                                  const byte* authIn, word32 authInSz)
8304
{
8305
    int ret;
8306
#ifdef WOLFSSL_STM32_CUBEMX
8307
    CRYP_HandleTypeDef hcryp;
8308
#else
8309
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
8310
#endif
8311
    word32 keySize;
8312
#ifdef WOLFSSL_STM32_CUBEMX
8313
    int status = HAL_OK;
8314
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
8315
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
8316
#else
8317
    int status = SUCCESS;
8318
#endif
8319
    word32 partial = sz % WC_AES_BLOCK_SIZE;
8320
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
8321
    word32 ctrInit[WC_AES_BLOCK_SIZE/sizeof(word32)];
8322
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
8323
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
8324
    byte* authInPadded = NULL;
8325
    int authPadSz, wasAlloc = 0, useSwGhash = 0;
8326
8327
    ret = wc_AesGetKeySize(aes, &keySize);
8328
    if (ret != 0)
8329
        return ret;
8330
8331
#ifdef WOLFSSL_STM32_CUBEMX
8332
    ret = wc_Stm32_Aes_Init(aes, &hcryp);
8333
    if (ret != 0)
8334
        return ret;
8335
#endif
8336
8337
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
8338
    if (ivSz == GCM_NONCE_MID_SZ) {
8339
        byte* pCtr = (byte*)ctr;
8340
        XMEMCPY(ctr, iv, ivSz);
8341
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
8342
    }
8343
    else {
8344
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
8345
    }
8346
    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
8347
8348
    /* Authentication buffer */
8349
#if STM_CRYPT_HEADER_WIDTH == 1
8350
    authPadSz = 0; /* CubeHAL supports byte mode */
8351
#else
8352
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
8353
#endif
8354
#ifdef WOLFSSL_STM32MP13
8355
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
8356
     * minimum of 16 bytes for the auth */
8357
    if ((authInSz > 0) && (authInSz < 16)) {
8358
        authPadSz = 16 - authInSz;
8359
    }
8360
#endif
8361
    if (authPadSz != 0) {
8362
        if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) {
8363
            authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
8364
        }
8365
        if (authPadSz <= sizeof(authhdr)) {
8366
            authInPadded = (byte*)authhdr;
8367
        }
8368
        else {
8369
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
8370
                DYNAMIC_TYPE_TMP_BUFFER);
8371
            if (authInPadded == NULL) {
8372
                wolfSSL_CryptHwMutexUnLock();
8373
                return MEMORY_E;
8374
            }
8375
            wasAlloc = 1;
8376
        }
8377
        XMEMSET(authInPadded, 0, authPadSz);
8378
        XMEMCPY(authInPadded, authIn, authInSz);
8379
    } else {
8380
        authPadSz = authInSz;
8381
        authInPadded = (byte*)authIn;
8382
    }
8383
8384
    /* for cases where hardware cannot be used for authTag calculate it */
8385
    /* if IV is not 12 calculate GHASH using software */
8386
    if (ivSz != GCM_NONCE_MID_SZ
8387
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
8388
        /* or hardware that does not support partial block */
8389
        || sz == 0 || partial != 0
8390
    #endif
8391
    #if STM_CRYPT_HEADER_WIDTH == 4
8392
        /* or authIn is not a multiple of 4  */
8393
        || authPadSz != authInSz
8394
    #endif
8395
    ) {
8396
        useSwGhash = 1;
8397
    }
8398
8399
    /* Hardware requires counter + 1 */
8400
    IncrementGcmCounter((byte*)ctr);
8401
8402
    ret = wolfSSL_CryptHwMutexLock();
8403
    if (ret != 0) {
8404
        return ret;
8405
    }
8406
8407
#ifdef WOLFSSL_STM32_CUBEMX
8408
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8409
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
8410
8411
#if defined(STM32_HAL_V2)
8412
    hcryp.Init.Algorithm = CRYP_AES_GCM;
8413
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
8414
    #ifdef CRYP_KEYIVCONFIG_ONCE
8415
    /* allows repeated calls to HAL_CRYP_Encrypt */
8416
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
8417
    #endif
8418
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
8419
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8420
    HAL_CRYP_Init(&hcryp);
8421
8422
    #ifndef CRYP_KEYIVCONFIG_ONCE
8423
    /* GCM payload phase - can handle partial blocks */
8424
    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
8425
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
8426
    #else
8427
    /* GCM payload phase - blocks */
8428
    if (blocks) {
8429
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
8430
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
8431
    }
8432
    /* GCM payload phase - partial remainder */
8433
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
8434
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8435
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
8436
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
8437
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
8438
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
8439
    }
8440
    #endif
8441
    if (status == HAL_OK && !useSwGhash) {
8442
        /* Compute the authTag */
8443
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
8444
            STM32_HAL_TIMEOUT);
8445
    }
8446
#elif defined(STM32_CRYPTO_AES_ONLY)
8447
    /* Set the CRYP parameters */
8448
    hcryp.Init.HeaderSize = authPadSz;
8449
    if (authPadSz == 0)
8450
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
8451
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
8452
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
8453
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
8454
    HAL_CRYP_Init(&hcryp);
8455
8456
    /* GCM init phase */
8457
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
8458
    if (status == HAL_OK) {
8459
        /* GCM header phase */
8460
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
8461
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
8462
    }
8463
    if (status == HAL_OK) {
8464
        /* GCM payload phase - blocks */
8465
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
8466
        if (blocks) {
8467
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
8468
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
8469
        }
8470
    }
8471
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
8472
        /* GCM payload phase - partial remainder */
8473
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8474
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
8475
        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
8476
                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
8477
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
8478
    }
8479
    if (status == HAL_OK && !useSwGhash) {
8480
        /* GCM final phase */
8481
        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
8482
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
8483
    }
8484
#else
8485
    hcryp.Init.HeaderSize = authPadSz;
8486
    HAL_CRYP_Init(&hcryp);
8487
    if (blocks) {
8488
        /* GCM payload phase - blocks */
8489
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
8490
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
8491
    }
8492
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
8493
        /* GCM payload phase - partial remainder */
8494
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8495
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
8496
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
8497
            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
8498
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
8499
    }
8500
    if (status == HAL_OK && !useSwGhash) {
8501
        /* Compute the authTag */
8502
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
8503
    }
8504
#endif
8505
8506
    if (status != HAL_OK)
8507
        ret = AES_GCM_AUTH_E;
8508
    HAL_CRYP_DeInit(&hcryp);
8509
8510
#else /* Standard Peripheral Library */
8511
    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
8512
    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
8513
                         (uint8_t*)keyCopy,      keySize * 8,
8514
                         (uint8_t*)in,           sz,
8515
                         (uint8_t*)authInPadded, authInSz,
8516
                         (uint8_t*)out,          (uint8_t*)tag);
8517
    if (status != SUCCESS)
8518
        ret = AES_GCM_AUTH_E;
8519
#endif /* WOLFSSL_STM32_CUBEMX */
8520
    wolfSSL_CryptHwMutexUnLock();
8521
    wc_Stm32_Aes_Cleanup();
8522
8523
    if (ret == 0) {
8524
        /* return authTag */
8525
        if (authTag) {
8526
            if (useSwGhash) {
8527
                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
8528
                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
8529
                if (ret == 0) {
8530
                    xorbuf(authTag, tag, authTagSz);
8531
                }
8532
            }
8533
            else {
8534
                /* use hardware calculated tag */
8535
                XMEMCPY(authTag, tag, authTagSz);
8536
            }
8537
        }
8538
    }
8539
8540
    /* Free memory */
8541
    if (wasAlloc) {
8542
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
8543
    }
8544
8545
    return ret;
8546
}
8547
8548
#endif /* STM32_CRYPTO_AES_GCM */
8549
8550
#ifdef WOLFSSL_AESNI
8551
/* For performance reasons, this code needs to be not inlined. */
8552
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
8553
                      Aes* aes, byte* out, const byte* in, word32 sz,
8554
                      const byte* iv, word32 ivSz,
8555
                      byte* authTag, word32 authTagSz,
8556
                      const byte* authIn, word32 authInSz);
8557
#else
8558
static
8559
#endif
8560
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
8561
                      Aes* aes, byte* out, const byte* in, word32 sz,
8562
                      const byte* iv, word32 ivSz,
8563
                      byte* authTag, word32 authTagSz,
8564
                      const byte* authIn, word32 authInSz)
8565
0
{
8566
0
    int ret = 0;
8567
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
8568
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
8569
0
    const byte* p = in;
8570
0
    byte* c = out;
8571
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
8572
0
    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
8573
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
8574
8575
0
    if (ivSz == GCM_NONCE_MID_SZ) {
8576
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
8577
0
        XMEMCPY(counter, iv, ivSz);
8578
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
8579
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
8580
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
8581
0
    }
8582
0
    else {
8583
        /* Counter is GHASH of IV. */
8584
#ifdef OPENSSL_EXTRA
8585
        word32 aadTemp = aes->gcm.aadLen;
8586
        aes->gcm.aadLen = 0;
8587
#endif
8588
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
8589
#ifdef OPENSSL_EXTRA
8590
        aes->gcm.aadLen = aadTemp;
8591
#endif
8592
0
    }
8593
0
    XMEMCPY(initialCounter, counter, WC_AES_BLOCK_SIZE);
8594
8595
#ifdef WOLFSSL_PIC32MZ_CRYPT
8596
    if (blocks) {
8597
        /* use initial IV for HW, but don't use it below */
8598
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
8599
8600
        ret = wc_Pic32AesCrypt(
8601
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
8602
            out, in, (blocks * WC_AES_BLOCK_SIZE),
8603
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
8604
        if (ret != 0)
8605
            return ret;
8606
    }
8607
    /* process remainder using partial handling */
8608
#endif
8609
8610
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
8611
    /* some hardware acceleration can gain performance from doing AES encryption
8612
     * of the whole buffer at once */
8613
    if (c != p && blocks > 0) { /* can not handle inline encryption */
8614
        while (blocks--) {
8615
            IncrementGcmCounter(counter);
8616
            XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
8617
            c += WC_AES_BLOCK_SIZE;
8618
        }
8619
8620
        /* reset number of blocks and then do encryption */
8621
        blocks = sz / WC_AES_BLOCK_SIZE;
8622
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
8623
        xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
8624
        p += WC_AES_BLOCK_SIZE * blocks;
8625
    }
8626
    else
8627
#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
8628
0
    {
8629
0
        while (blocks--) {
8630
0
            IncrementGcmCounter(counter);
8631
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
8632
0
            ret = wc_AesEncrypt(aes, counter, scratch);
8633
0
            if (ret != 0)
8634
0
                return ret;
8635
0
            xorbufout(c, scratch, p, WC_AES_BLOCK_SIZE);
8636
0
        #endif
8637
0
            p += WC_AES_BLOCK_SIZE;
8638
0
            c += WC_AES_BLOCK_SIZE;
8639
0
        }
8640
0
    }
8641
8642
0
    if (partial != 0) {
8643
0
        IncrementGcmCounter(counter);
8644
0
        ret = wc_AesEncrypt(aes, counter, scratch);
8645
0
        if (ret != 0)
8646
0
            return ret;
8647
0
        xorbufout(c, scratch, p, partial);
8648
0
    }
8649
0
    if (authTag) {
8650
0
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
8651
0
        ret = wc_AesEncrypt(aes, initialCounter, scratch);
8652
0
        if (ret != 0)
8653
0
            return ret;
8654
0
        xorbuf(authTag, scratch, authTagSz);
8655
#ifdef OPENSSL_EXTRA
8656
        if (!in && !sz)
8657
            /* store AAD size for next call */
8658
            aes->gcm.aadLen = authInSz;
8659
#endif
8660
0
    }
8661
8662
0
    return ret;
8663
0
}
8664
8665
/* Software AES - GCM Encrypt */
8666
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
8667
                   const byte* iv, word32 ivSz,
8668
                   byte* authTag, word32 authTagSz,
8669
                   const byte* authIn, word32 authInSz)
8670
0
{
8671
0
    int ret;
8672
8673
    /* argument checks */
8674
0
    if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE || ivSz == 0 ||
8675
0
        ((authTagSz > 0) && (authTag == NULL)) ||
8676
0
        ((authInSz > 0) && (authIn == NULL)))
8677
0
    {
8678
0
        return BAD_FUNC_ARG;
8679
0
    }
8680
8681
0
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
8682
0
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
8683
0
        return BAD_FUNC_ARG;
8684
0
    }
8685
8686
#ifdef WOLF_CRYPTO_CB
8687
    #ifndef WOLF_CRYPTO_CB_FIND
8688
    if (aes->devId != INVALID_DEVID)
8689
    #endif
8690
    {
8691
        int crypto_cb_ret =
8692
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
8693
                                      authTagSz, authIn, authInSz);
8694
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
8695
            return crypto_cb_ret;
8696
        /* fall-through when unavailable */
8697
    }
8698
#endif
8699
8700
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
8701
    /* if async and byte count above threshold */
8702
    /* only 12-byte IV is supported in HW */
8703
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
8704
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
8705
    #if defined(HAVE_CAVIUM)
8706
        #ifdef HAVE_CAVIUM_V
8707
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
8708
            return NitroxAesGcmEncrypt(aes, out, in, sz,
8709
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
8710
                authTag, authTagSz, authIn, authInSz);
8711
        }
8712
        #endif
8713
    #elif defined(HAVE_INTEL_QA)
8714
        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
8715
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
8716
            authTag, authTagSz, authIn, authInSz);
8717
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
8718
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
8719
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
8720
            sw->aes.aes = aes;
8721
            sw->aes.out = out;
8722
            sw->aes.in = in;
8723
            sw->aes.sz = sz;
8724
            sw->aes.iv = iv;
8725
            sw->aes.ivSz = ivSz;
8726
            sw->aes.authTag = authTag;
8727
            sw->aes.authTagSz = authTagSz;
8728
            sw->aes.authIn = authIn;
8729
            sw->aes.authInSz = authInSz;
8730
            return WC_PENDING_E;
8731
        }
8732
    #endif
8733
    }
8734
#endif /* WOLFSSL_ASYNC_CRYPT */
8735
8736
#ifdef WOLFSSL_SILABS_SE_ACCEL
8737
    return wc_AesGcmEncrypt_silabs(
8738
        aes, out, in, sz,
8739
        iv, ivSz,
8740
        authTag, authTagSz,
8741
        authIn, authInSz);
8742
#endif
8743
8744
#ifdef STM32_CRYPTO_AES_GCM
8745
    return wc_AesGcmEncrypt_STM32(
8746
        aes, out, in, sz, iv, ivSz,
8747
        authTag, authTagSz, authIn, authInSz);
8748
#endif /* STM32_CRYPTO_AES_GCM */
8749
8750
0
    VECTOR_REGISTERS_PUSH;
8751
8752
#ifdef WOLFSSL_AESNI
8753
    if (aes->use_aesni) {
8754
#ifdef HAVE_INTEL_AVX2
8755
        if (IS_INTEL_AVX2(intel_flags)) {
8756
            AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
8757
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
8758
            ret = 0;
8759
        }
8760
        else
8761
#endif
8762
#if defined(HAVE_INTEL_AVX1)
8763
        if (IS_INTEL_AVX1(intel_flags)) {
8764
            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
8765
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
8766
            ret = 0;
8767
        } else
8768
#endif
8769
        {
8770
            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
8771
                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
8772
            ret = 0;
8773
        }
8774
    }
8775
    else
8776
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
8777
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
8778
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
8779
        AES_GCM_encrypt_AARCH64(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
8780
            authIn, authInSz);
8781
        ret = 0;
8782
    }
8783
    else
8784
#endif /* WOLFSSL_AESNI */
8785
0
    {
8786
0
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
8787
0
                                authIn, authInSz);
8788
0
    }
8789
8790
0
    VECTOR_REGISTERS_POP;
8791
8792
0
    return ret;
8793
0
}
8794
#endif
8795
8796
8797
/* AES GCM Decrypt */
8798
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
8799
#ifdef FREESCALE_LTC_AES_GCM
8800
int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
8801
                   const byte* iv, word32 ivSz,
8802
                   const byte* authTag, word32 authTagSz,
8803
                   const byte* authIn, word32 authInSz)
8804
{
8805
    int ret;
8806
    word32 keySize;
8807
    status_t status;
8808
8809
    /* argument checks */
8810
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
8811
     * in and out are don't cares, as this is is the GMAC case. */
8812
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
8813
        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE || authTagSz == 0 ||
8814
        ivSz == 0 || ((authInSz > 0) && (authIn == NULL)))
8815
    {
8816
        return BAD_FUNC_ARG;
8817
    }
8818
8819
    ret = wc_AesGetKeySize(aes, &keySize);
8820
    if (ret != 0) {
8821
        return ret;
8822
    }
8823
8824
    status = wolfSSL_CryptHwMutexLock();
8825
    if (status != 0)
8826
        return status;
8827
8828
    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
8829
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
8830
    wolfSSL_CryptHwMutexUnLock();
8831
8832
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
8833
}
8834
8835
#else
8836
8837
#ifdef STM32_CRYPTO_AES_GCM
8838
/* this function supports inline decrypt */
8839
static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
8840
                                  Aes* aes, byte* out,
8841
                                  const byte* in, word32 sz,
8842
                                  const byte* iv, word32 ivSz,
8843
                                  const byte* authTag, word32 authTagSz,
8844
                                  const byte* authIn, word32 authInSz)
8845
{
8846
    int ret;
8847
#ifdef WOLFSSL_STM32_CUBEMX
8848
    int status = HAL_OK;
8849
    CRYP_HandleTypeDef hcryp;
8850
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
8851
#else
8852
    int status = SUCCESS;
8853
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
8854
#endif
8855
    word32 keySize;
8856
    word32 partial = sz % WC_AES_BLOCK_SIZE;
8857
    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
8858
    word32 tagExpected[WC_AES_BLOCK_SIZE/sizeof(word32)];
8859
    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
8860
    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
8861
    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
8862
    byte* authInPadded = NULL;
8863
    int authPadSz, wasAlloc = 0, tagComputed = 0;
8864
8865
    ret = wc_AesGetKeySize(aes, &keySize);
8866
    if (ret != 0)
8867
        return ret;
8868
8869
#ifdef WOLFSSL_STM32_CUBEMX
8870
    ret = wc_Stm32_Aes_Init(aes, &hcryp);
8871
    if (ret != 0)
8872
        return ret;
8873
#endif
8874
8875
    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
8876
    if (ivSz == GCM_NONCE_MID_SZ) {
8877
        byte* pCtr = (byte*)ctr;
8878
        XMEMCPY(ctr, iv, ivSz);
8879
        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
8880
    }
8881
    else {
8882
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
8883
    }
8884
8885
    /* Make copy of expected authTag, which could get corrupted in some
8886
     * Cube HAL versions without proper partial block support.
8887
     * For TLS blocks the authTag is after the output buffer, so save it */
8888
    XMEMCPY(tagExpected, authTag, authTagSz);
8889
8890
    /* Authentication buffer */
8891
#if STM_CRYPT_HEADER_WIDTH == 1
8892
    authPadSz = 0; /* CubeHAL supports byte mode */
8893
#else
8894
    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
8895
#endif
8896
#ifdef WOLFSSL_STM32MP13
8897
    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
8898
     * minimum of 16 bytes for the auth */
8899
    if ((authInSz > 0) && (authInSz < 16)) {
8900
        authPadSz = 16 - authInSz;
8901
    }
8902
#else
8903
    if (authPadSz != 0) {
8904
        authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
8905
    }
8906
    else {
8907
        authPadSz = authInSz;
8908
    }
8909
#endif
8910
8911
    /* for cases where hardware cannot be used for authTag calculate it */
8912
    /* if IV is not 12 calculate GHASH using software */
8913
    if (ivSz != GCM_NONCE_MID_SZ
8914
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
8915
        /* or hardware that does not support partial block */
8916
        || sz == 0 || partial != 0
8917
    #endif
8918
    #if STM_CRYPT_HEADER_WIDTH == 4
8919
        /* or authIn is not a multiple of 4  */
8920
        || authPadSz != authInSz
8921
    #endif
8922
    ) {
8923
        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
8924
        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
8925
        if (ret != 0)
8926
            return ret;
8927
        xorbuf(tag, partialBlock, sizeof(tag));
8928
        tagComputed = 1;
8929
    }
8930
8931
    /* if using hardware for authentication tag make sure its aligned and zero padded */
8932
    if (authPadSz != authInSz && !tagComputed) {
8933
        if (authPadSz <= sizeof(authhdr)) {
8934
            authInPadded = (byte*)authhdr;
8935
        }
8936
        else {
8937
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
8938
                DYNAMIC_TYPE_TMP_BUFFER);
8939
            if (authInPadded == NULL) {
8940
                wolfSSL_CryptHwMutexUnLock();
8941
                return MEMORY_E;
8942
            }
8943
            wasAlloc = 1;
8944
        }
8945
        XMEMSET(authInPadded, 0, authPadSz);
8946
        XMEMCPY(authInPadded, authIn, authInSz);
8947
    } else {
8948
        authInPadded = (byte*)authIn;
8949
    }
8950
8951
    /* Hardware requires counter + 1 */
8952
    IncrementGcmCounter((byte*)ctr);
8953
8954
    ret = wolfSSL_CryptHwMutexLock();
8955
    if (ret != 0) {
8956
        return ret;
8957
    }
8958
8959
#ifdef WOLFSSL_STM32_CUBEMX
8960
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8961
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
8962
8963
#if defined(STM32_HAL_V2)
8964
    hcryp.Init.Algorithm = CRYP_AES_GCM;
8965
    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
8966
    #ifdef CRYP_KEYIVCONFIG_ONCE
8967
    /* allows repeated calls to HAL_CRYP_Decrypt */
8968
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
8969
    #endif
8970
    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
8971
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8972
    HAL_CRYP_Init(&hcryp);
8973
8974
    #ifndef CRYP_KEYIVCONFIG_ONCE
8975
    /* GCM payload phase - can handle partial blocks */
8976
    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
8977
        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
8978
    #else
8979
    /* GCM payload phase - blocks */
8980
    if (blocks) {
8981
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
8982
            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
8983
    }
8984
    /* GCM payload phase - partial remainder */
8985
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
8986
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8987
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
8988
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
8989
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
8990
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
8991
    }
8992
    #endif
8993
    if (status == HAL_OK && !tagComputed) {
8994
        /* Compute the authTag */
8995
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
8996
            STM32_HAL_TIMEOUT);
8997
    }
8998
#elif defined(STM32_CRYPTO_AES_ONLY)
8999
    /* Set the CRYP parameters */
9000
    hcryp.Init.HeaderSize = authPadSz;
9001
    if (authPadSz == 0)
9002
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
9003
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
9004
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
9005
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
9006
    HAL_CRYP_Init(&hcryp);
9007
9008
    /* GCM init phase */
9009
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9010
    if (status == HAL_OK) {
9011
        /* GCM header phase */
9012
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
9013
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
9014
    }
9015
    if (status == HAL_OK) {
9016
        /* GCM payload phase - blocks */
9017
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
9018
        if (blocks) {
9019
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
9020
                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9021
        }
9022
    }
9023
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
9024
        /* GCM payload phase - partial remainder */
9025
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9026
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9027
        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
9028
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
9029
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9030
    }
9031
    if (status == HAL_OK && tagComputed == 0) {
9032
        /* GCM final phase */
9033
        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
9034
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
9035
    }
9036
#else
9037
    hcryp.Init.HeaderSize = authPadSz;
9038
    HAL_CRYP_Init(&hcryp);
9039
    if (blocks) {
9040
        /* GCM payload phase - blocks */
9041
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
9042
            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
9043
    }
9044
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
9045
        /* GCM payload phase - partial remainder */
9046
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
9047
        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
9048
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
9049
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
9050
        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
9051
    }
9052
    if (status == HAL_OK && tagComputed == 0) {
9053
        /* Compute the authTag */
9054
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
9055
    }
9056
#endif
9057
9058
    if (status != HAL_OK)
9059
        ret = AES_GCM_AUTH_E;
9060
9061
    HAL_CRYP_DeInit(&hcryp);
9062
9063
#else /* Standard Peripheral Library */
9064
    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
9065
9066
    /* Input size and auth size need to be the actual sizes, even though
9067
     * they are not block aligned, because this length (in bits) is used
9068
     * in the final GHASH. */
9069
    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
9070
    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
9071
                         (uint8_t*)keyCopy,      keySize * 8,
9072
                         (uint8_t*)in,           sz,
9073
                         (uint8_t*)authInPadded, authInSz,
9074
                         (uint8_t*)out,          (uint8_t*)partialBlock);
9075
    if (status != SUCCESS)
9076
        ret = AES_GCM_AUTH_E;
9077
    if (tagComputed == 0)
9078
        XMEMCPY(tag, partialBlock, authTagSz);
9079
#endif /* WOLFSSL_STM32_CUBEMX */
9080
    wolfSSL_CryptHwMutexUnLock();
9081
    wc_Stm32_Aes_Cleanup();
9082
9083
    /* Check authentication tag */
9084
    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
9085
        ret = AES_GCM_AUTH_E;
9086
    }
9087
9088
    /* Free memory */
9089
    if (wasAlloc) {
9090
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
9091
    }
9092
9093
    return ret;
9094
}
9095
9096
#endif /* STM32_CRYPTO_AES_GCM */
9097
9098
#ifdef WOLFSSL_AESNI
9099
/* For performance reasons, this code needs to be not inlined. */
9100
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
9101
                      Aes* aes, byte* out, const byte* in, word32 sz,
9102
                      const byte* iv, word32 ivSz,
9103
                      const byte* authTag, word32 authTagSz,
9104
                      const byte* authIn, word32 authInSz);
9105
#else
9106
static
9107
#endif
9108
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
9109
                      Aes* aes, byte* out, const byte* in, word32 sz,
9110
                      const byte* iv, word32 ivSz,
9111
                      const byte* authTag, word32 authTagSz,
9112
                      const byte* authIn, word32 authInSz)
9113
0
{
9114
0
    int ret;
9115
0
    word32 blocks = sz / WC_AES_BLOCK_SIZE;
9116
0
    word32 partial = sz % WC_AES_BLOCK_SIZE;
9117
0
    const byte* c = in;
9118
0
    byte* p = out;
9119
0
    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
9120
0
    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
9121
0
    ALIGN16 byte Tprime[WC_AES_BLOCK_SIZE];
9122
0
    ALIGN16 byte EKY0[WC_AES_BLOCK_SIZE];
9123
0
    sword32 res;
9124
9125
0
    if (ivSz == GCM_NONCE_MID_SZ) {
9126
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
9127
0
        XMEMCPY(counter, iv, ivSz);
9128
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
9129
0
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
9130
0
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
9131
0
    }
9132
0
    else {
9133
        /* Counter is GHASH of IV. */
9134
#ifdef OPENSSL_EXTRA
9135
        word32 aadTemp = aes->gcm.aadLen;
9136
        aes->gcm.aadLen = 0;
9137
#endif
9138
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
9139
#ifdef OPENSSL_EXTRA
9140
        aes->gcm.aadLen = aadTemp;
9141
#endif
9142
0
    }
9143
9144
    /* Calc the authTag again using received auth data and the cipher text */
9145
0
    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
9146
0
    ret = wc_AesEncrypt(aes, counter, EKY0);
9147
0
    if (ret != 0)
9148
0
        return ret;
9149
0
    xorbuf(Tprime, EKY0, sizeof(Tprime));
9150
#ifdef WC_AES_GCM_DEC_AUTH_EARLY
9151
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
9152
     * the pairwise bytes in the strings.
9153
     */
9154
    res = ConstantCompare(authTag, Tprime, authTagSz);
9155
    /* convert positive retval from ConstantCompare() to all-1s word, in
9156
     * constant time.
9157
     */
9158
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
9159
    ret = res & AES_GCM_AUTH_E;
9160
    if (ret != 0)
9161
        return ret;
9162
#endif
9163
9164
#ifdef OPENSSL_EXTRA
9165
    if (!out) {
9166
        /* authenticated, non-confidential data */
9167
        /* store AAD size for next call */
9168
        aes->gcm.aadLen = authInSz;
9169
    }
9170
#endif
9171
9172
#if defined(WOLFSSL_PIC32MZ_CRYPT)
9173
    if (blocks) {
9174
        /* use initial IV for HW, but don't use it below */
9175
        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
9176
9177
        ret = wc_Pic32AesCrypt(
9178
            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
9179
            out, in, (blocks * WC_AES_BLOCK_SIZE),
9180
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
9181
        if (ret != 0)
9182
            return ret;
9183
    }
9184
    /* process remainder using partial handling */
9185
#endif
9186
9187
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
9188
    /* some hardware acceleration can gain performance from doing AES encryption
9189
     * of the whole buffer at once */
9190
    if (c != p && blocks > 0) { /* can not handle inline decryption */
9191
        while (blocks--) {
9192
            IncrementGcmCounter(counter);
9193
            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
9194
            p += WC_AES_BLOCK_SIZE;
9195
        }
9196
9197
        /* reset number of blocks and then do encryption */
9198
        blocks = sz / WC_AES_BLOCK_SIZE;
9199
9200
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
9201
        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
9202
        c += WC_AES_BLOCK_SIZE * blocks;
9203
    }
9204
    else
9205
#endif /* HAVE_AES_ECB && !PIC32MZ */
9206
0
    {
9207
0
        while (blocks--) {
9208
0
            IncrementGcmCounter(counter);
9209
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
9210
0
            ret = wc_AesEncrypt(aes, counter, scratch);
9211
0
            if (ret != 0)
9212
0
                return ret;
9213
0
            xorbufout(p, scratch, c, WC_AES_BLOCK_SIZE);
9214
0
        #endif
9215
0
            p += WC_AES_BLOCK_SIZE;
9216
0
            c += WC_AES_BLOCK_SIZE;
9217
0
        }
9218
0
    }
9219
9220
0
    if (partial != 0) {
9221
0
        IncrementGcmCounter(counter);
9222
0
        ret = wc_AesEncrypt(aes, counter, scratch);
9223
0
        if (ret != 0)
9224
0
            return ret;
9225
0
        xorbuf(scratch, c, partial);
9226
0
        XMEMCPY(p, scratch, partial);
9227
0
    }
9228
9229
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
9230
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
9231
     * the pairwise bytes in the strings.
9232
     */
9233
0
    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
9234
    /* convert positive retval from ConstantCompare() to all-1s word, in
9235
     * constant time.
9236
     */
9237
0
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
9238
    /* now use res as a mask for constant time return of ret, unless tag
9239
     * mismatch, whereupon AES_GCM_AUTH_E is returned.
9240
     */
9241
0
    ret = (ret & ~res) | (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
9242
0
#endif
9243
0
    return ret;
9244
0
}
9245
9246
/* Software AES - GCM Decrypt */
9247
int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
9248
                     const byte* iv, word32 ivSz,
9249
                     const byte* authTag, word32 authTagSz,
9250
                     const byte* authIn, word32 authInSz)
9251
0
{
9252
0
    int ret;
9253
#ifdef WOLFSSL_AESNI
9254
    int res = WC_NO_ERR_TRACE(AES_GCM_AUTH_E);
9255
#endif
9256
9257
    /* argument checks */
9258
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
9259
     * in and out are don't cares, as this is is the GMAC case. */
9260
0
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
9261
0
        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE || authTagSz == 0 ||
9262
0
        ivSz == 0) {
9263
9264
0
        return BAD_FUNC_ARG;
9265
0
    }
9266
9267
#ifdef WOLF_CRYPTO_CB
9268
    #ifndef WOLF_CRYPTO_CB_FIND
9269
    if (aes->devId != INVALID_DEVID)
9270
    #endif
9271
    {
9272
        int crypto_cb_ret =
9273
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
9274
                                      authTag, authTagSz, authIn, authInSz);
9275
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
9276
            return crypto_cb_ret;
9277
        /* fall-through when unavailable */
9278
    }
9279
#endif
9280
9281
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
9282
    /* if async and byte count above threshold */
9283
    /* only 12-byte IV is supported in HW */
9284
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
9285
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
9286
    #if defined(HAVE_CAVIUM)
9287
        #ifdef HAVE_CAVIUM_V
9288
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
9289
            return NitroxAesGcmDecrypt(aes, out, in, sz,
9290
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
9291
                authTag, authTagSz, authIn, authInSz);
9292
        }
9293
        #endif
9294
    #elif defined(HAVE_INTEL_QA)
9295
        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
9296
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
9297
            authTag, authTagSz, authIn, authInSz);
9298
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
9299
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
9300
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
9301
            sw->aes.aes = aes;
9302
            sw->aes.out = out;
9303
            sw->aes.in = in;
9304
            sw->aes.sz = sz;
9305
            sw->aes.iv = iv;
9306
            sw->aes.ivSz = ivSz;
9307
            sw->aes.authTag = (byte*)authTag;
9308
            sw->aes.authTagSz = authTagSz;
9309
            sw->aes.authIn = authIn;
9310
            sw->aes.authInSz = authInSz;
9311
            return WC_PENDING_E;
9312
        }
9313
    #endif
9314
    }
9315
#endif /* WOLFSSL_ASYNC_CRYPT */
9316
9317
#ifdef WOLFSSL_SILABS_SE_ACCEL
9318
    return wc_AesGcmDecrypt_silabs(
9319
        aes, out, in, sz, iv, ivSz,
9320
        authTag, authTagSz, authIn, authInSz);
9321
9322
#endif
9323
9324
#ifdef STM32_CRYPTO_AES_GCM
9325
    /* The STM standard peripheral library API's doesn't support partial blocks */
9326
    return wc_AesGcmDecrypt_STM32(
9327
        aes, out, in, sz, iv, ivSz,
9328
        authTag, authTagSz, authIn, authInSz);
9329
#endif /* STM32_CRYPTO_AES_GCM */
9330
9331
0
    VECTOR_REGISTERS_PUSH;
9332
9333
#ifdef WOLFSSL_AESNI
9334
    if (aes->use_aesni) {
9335
#ifdef HAVE_INTEL_AVX2
9336
        if (IS_INTEL_AVX2(intel_flags)) {
9337
            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
9338
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
9339
            if (res == 0)
9340
                ret = AES_GCM_AUTH_E;
9341
            else
9342
                ret = 0;
9343
        }
9344
        else
9345
#endif
9346
#if defined(HAVE_INTEL_AVX1)
9347
        if (IS_INTEL_AVX1(intel_flags)) {
9348
            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
9349
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
9350
            if (res == 0)
9351
                ret = AES_GCM_AUTH_E;
9352
            else
9353
                ret = 0;
9354
        }
9355
        else
9356
#endif
9357
        {
9358
            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
9359
                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
9360
            if (res == 0)
9361
                ret = AES_GCM_AUTH_E;
9362
            else
9363
                ret = 0;
9364
        }
9365
    }
9366
    else
9367
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
9368
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
9369
    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
9370
        ret = AES_GCM_decrypt_AARCH64(aes, out, in, sz, iv, ivSz, authTag,
9371
            authTagSz, authIn, authInSz);
9372
    }
9373
    else
9374
#endif /* WOLFSSL_AESNI */
9375
0
    {
9376
0
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
9377
0
                                                             authIn, authInSz);
9378
0
    }
9379
9380
0
    VECTOR_REGISTERS_POP;
9381
9382
0
    return ret;
9383
0
}
9384
#endif
9385
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
9386
9387
#ifdef WOLFSSL_AESGCM_STREAM
9388
9389
/* Initialize the AES GCM cipher with an IV. C implementation.
9390
 *
9391
 * @param [in, out] aes   AES object.
9392
 * @param [in]      iv    IV/nonce buffer.
9393
 * @param [in]      ivSz  Length of IV/nonce data.
9394
 */
9395
static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
9396
{
9397
    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
9398
    int ret;
9399
9400
    if (ivSz == GCM_NONCE_MID_SZ) {
9401
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
9402
        XMEMCPY(counter, iv, ivSz);
9403
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
9404
                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
9405
        counter[WC_AES_BLOCK_SIZE - 1] = 1;
9406
    }
9407
    else {
9408
        /* Counter is GHASH of IV. */
9409
    #ifdef OPENSSL_EXTRA
9410
        word32 aadTemp = aes->gcm.aadLen;
9411
        aes->gcm.aadLen = 0;
9412
    #endif
9413
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
9414
    #ifdef OPENSSL_EXTRA
9415
        aes->gcm.aadLen = aadTemp;
9416
    #endif
9417
    }
9418
9419
    /* Copy in the counter for use with cipher. */
9420
    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
9421
    /* Encrypt initial counter into a buffer for GCM. */
9422
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
9423
    if (ret != 0)
9424
        return ret;
9425
    /* Reset state fields. */
9426
    aes->over = 0;
9427
    aes->aSz = 0;
9428
    aes->cSz = 0;
9429
    /* Initialization for GHASH. */
9430
    GHASH_INIT(aes);
9431
9432
    return 0;
9433
}
9434
9435
/* Update the AES GCM cipher with data. C implementation.
9436
 *
9437
 * Only enciphers data.
9438
 *
9439
 * @param [in, out] aes  AES object.
9440
 * @param [in]      out  Cipher text or plaintext buffer.
9441
 * @param [in]      in   Plaintext or cipher text buffer.
9442
 * @param [in]      sz   Length of data.
9443
 */
9444
static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
9445
    Aes* aes, byte* out, const byte* in, word32 sz)
9446
{
9447
    word32 blocks;
9448
    word32 partial;
9449
    int ret;
9450
9451
    /* Check if previous encrypted block was not used up. */
9452
    if (aes->over > 0) {
9453
        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
9454
        if (pSz > sz) pSz = (byte)sz;
9455
9456
        /* Use some/all of last encrypted block. */
9457
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
9458
        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
9459
9460
        /* Some data used. */
9461
        sz  -= pSz;
9462
        in  += pSz;
9463
        out += pSz;
9464
    }
9465
9466
    /* Calculate the number of blocks needing to be encrypted and any leftover.
9467
     */
9468
    blocks  = sz / WC_AES_BLOCK_SIZE;
9469
    partial = sz & (WC_AES_BLOCK_SIZE - 1);
9470
9471
#if defined(HAVE_AES_ECB)
9472
    /* Some hardware acceleration can gain performance from doing AES encryption
9473
     * of the whole buffer at once.
9474
     * Overwrites the cipher text before using plaintext - no inline encryption.
9475
     */
9476
    if ((out != in) && blocks > 0) {
9477
        word32 b;
9478
        /* Place incrementing counter blocks into cipher text. */
9479
        for (b = 0; b < blocks; b++) {
9480
            IncrementGcmCounter(AES_COUNTER(aes));
9481
            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
9482
        }
9483
9484
        /* Encrypt counter blocks. */
9485
        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
9486
        /* XOR in plaintext. */
9487
        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
9488
        /* Skip over processed data. */
9489
        in += WC_AES_BLOCK_SIZE * blocks;
9490
        out += WC_AES_BLOCK_SIZE * blocks;
9491
    }
9492
    else
9493
#endif /* HAVE_AES_ECB */
9494
    {
9495
        /* Encrypt block by block. */
9496
        while (blocks--) {
9497
            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
9498
            IncrementGcmCounter(AES_COUNTER(aes));
9499
            /* Encrypt counter into a buffer. */
9500
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
9501
            if (ret != 0)
9502
                return ret;
9503
            /* XOR plain text into encrypted counter into cipher text buffer. */
9504
            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
9505
            /* Data complete. */
9506
            in  += WC_AES_BLOCK_SIZE;
9507
            out += WC_AES_BLOCK_SIZE;
9508
        }
9509
    }
9510
9511
    if (partial != 0) {
9512
        /* Generate an extra block and use up as much as needed. */
9513
        IncrementGcmCounter(AES_COUNTER(aes));
9514
        /* Encrypt counter into cache. */
9515
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
9516
        if (ret != 0)
9517
            return ret;
9518
        /* XOR plain text into encrypted counter into cipher text buffer. */
9519
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
9520
        /* Keep amount of encrypted block used. */
9521
        aes->over = (byte)partial;
9522
    }
9523
9524
    return 0;
9525
}
9526
9527
/* Calculates authentication tag for AES GCM. C implementation.
9528
 *
9529
 * @param [in, out] aes        AES object.
9530
 * @param [out]     authTag    Buffer to store authentication tag in.
9531
 * @param [in]      authTagSz  Length of tag to create.
9532
 */
9533
static WARN_UNUSED_RESULT int AesGcmFinal_C(
9534
    Aes* aes, byte* authTag, word32 authTagSz)
9535
{
9536
    /* Calculate authentication tag. */
9537
    GHASH_FINAL(aes, authTag, authTagSz);
9538
    /* XOR in as much of encrypted counter as is required. */
9539
    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
9540
#ifdef OPENSSL_EXTRA
9541
    /* store AAD size for next call */
9542
    aes->gcm.aadLen = aes->aSz;
9543
#endif
9544
    /* Zeroize last block to protect sensitive data. */
9545
    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
9546
9547
    return 0;
9548
}
9549
9550
#ifdef WOLFSSL_AESNI
9551
9552
#ifdef __cplusplus
9553
    extern "C" {
9554
#endif
9555
9556
/* Assembly code implementations in: aes_gcm_asm.S */
9557
#ifdef HAVE_INTEL_AVX2
9558
extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
9559
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
9560
    unsigned char* counter, unsigned char* initCtr);
9561
extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
9562
    unsigned int abytes, unsigned char* tag, unsigned char* h);
9563
extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
9564
    unsigned char* out, const unsigned char* in, unsigned char* counter);
9565
extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
9566
    unsigned char* tag, unsigned char* h);
9567
9568
extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
9569
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9570
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9571
extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
9572
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9573
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
9574
#endif
9575
#ifdef HAVE_INTEL_AVX1
9576
extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
9577
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
9578
    unsigned char* counter, unsigned char* initCtr);
9579
extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
9580
    unsigned int abytes, unsigned char* tag, unsigned char* h);
9581
extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
9582
    unsigned char* out, const unsigned char* in, unsigned char* counter);
9583
extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
9584
    unsigned char* tag, unsigned char* h);
9585
9586
extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
9587
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9588
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9589
extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
9590
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9591
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
9592
#endif
9593
extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
9594
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
9595
    unsigned char* counter, unsigned char* initCtr);
9596
extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
9597
    unsigned int abytes, unsigned char* tag, unsigned char* h);
9598
extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
9599
    unsigned char* out, const unsigned char* in, unsigned char* counter);
9600
extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
9601
    unsigned char* tag, unsigned char* h);
9602
9603
extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
9604
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9605
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9606
extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
9607
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9608
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
9609
9610
#ifdef __cplusplus
9611
    } /* extern "C" */
9612
#endif
9613
9614
/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
9615
 *
9616
 * @param [in, out] aes   AES object.
9617
 * @param [in]      iv    IV/nonce buffer.
9618
 * @param [in]      ivSz  Length of IV/nonce data.
9619
 */
9620
static WARN_UNUSED_RESULT int AesGcmInit_aesni(
9621
    Aes* aes, const byte* iv, word32 ivSz)
9622
{
9623
    ASSERT_SAVED_VECTOR_REGISTERS();
9624
9625
    /* Reset state fields. */
9626
    aes->over = 0;
9627
    aes->aSz = 0;
9628
    aes->cSz = 0;
9629
    /* Set tag to all zeros as initial value. */
9630
    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
9631
    /* Reset counts of AAD and cipher text. */
9632
    aes->aOver = 0;
9633
    aes->cOver = 0;
9634
9635
#ifdef HAVE_INTEL_AVX2
9636
    if (IS_INTEL_AVX2(intel_flags)) {
9637
        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
9638
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
9639
    }
9640
    else
9641
#endif
9642
#ifdef HAVE_INTEL_AVX1
9643
    if (IS_INTEL_AVX1(intel_flags)) {
9644
        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
9645
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
9646
    }
9647
    else
9648
#endif
9649
    {
9650
        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
9651
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
9652
    }
9653
9654
    return 0;
9655
}
9656
9657
/* Update the AES GCM for encryption with authentication data.
9658
 *
9659
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
9660
 *
9661
 * @param [in, out] aes   AES object.
9662
 * @param [in]      a     Buffer holding authentication data.
9663
 * @param [in]      aSz   Length of authentication data in bytes.
9664
 * @param [in]      endA  Whether no more authentication data is expected.
9665
 */
9666
static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
9667
    Aes* aes, const byte* a, word32 aSz, int endA)
9668
{
9669
    word32 blocks;
9670
    int partial;
9671
9672
    ASSERT_SAVED_VECTOR_REGISTERS();
9673
9674
    if (aSz != 0 && a != NULL) {
9675
        /* Total count of AAD updated. */
9676
        aes->aSz += aSz;
9677
        /* Check if we have unprocessed data. */
9678
        if (aes->aOver > 0) {
9679
            /* Calculate amount we can use - fill up the block. */
9680
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
9681
            if (sz > aSz) {
9682
                sz = (byte)aSz;
9683
            }
9684
            /* Copy extra into last GHASH block array and update count. */
9685
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
9686
            aes->aOver = (byte)(aes->aOver + sz);
9687
            if (aes->aOver == WC_AES_BLOCK_SIZE) {
9688
                /* We have filled up the block and can process. */
9689
            #ifdef HAVE_INTEL_AVX2
9690
                if (IS_INTEL_AVX2(intel_flags)) {
9691
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
9692
                                             aes->gcm.H);
9693
                }
9694
                else
9695
            #endif
9696
            #ifdef HAVE_INTEL_AVX1
9697
                if (IS_INTEL_AVX1(intel_flags)) {
9698
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
9699
                                             aes->gcm.H);
9700
                }
9701
                else
9702
            #endif
9703
                {
9704
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
9705
                                              aes->gcm.H);
9706
                }
9707
                /* Reset count. */
9708
                aes->aOver = 0;
9709
            }
9710
            /* Used up some data. */
9711
            aSz -= sz;
9712
            a += sz;
9713
        }
9714
9715
        /* Calculate number of blocks of AAD and the leftover. */
9716
        blocks = aSz / WC_AES_BLOCK_SIZE;
9717
        partial = aSz % WC_AES_BLOCK_SIZE;
9718
        if (blocks > 0) {
9719
            /* GHASH full blocks now. */
9720
        #ifdef HAVE_INTEL_AVX2
9721
            if (IS_INTEL_AVX2(intel_flags)) {
9722
                AES_GCM_aad_update_avx2(a, blocks * WC_AES_BLOCK_SIZE,
9723
                                        AES_TAG(aes), aes->gcm.H);
9724
            }
9725
            else
9726
        #endif
9727
        #ifdef HAVE_INTEL_AVX1
9728
            if (IS_INTEL_AVX1(intel_flags)) {
9729
                AES_GCM_aad_update_avx1(a, blocks * WC_AES_BLOCK_SIZE,
9730
                                        AES_TAG(aes), aes->gcm.H);
9731
            }
9732
            else
9733
        #endif
9734
            {
9735
                AES_GCM_aad_update_aesni(a, blocks * WC_AES_BLOCK_SIZE,
9736
                                         AES_TAG(aes), aes->gcm.H);
9737
            }
9738
            /* Skip over to end of AAD blocks. */
9739
            a += blocks * WC_AES_BLOCK_SIZE;
9740
        }
9741
        if (partial != 0) {
9742
            /* Cache the partial block. */
9743
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
9744
            aes->aOver = (byte)partial;
9745
        }
9746
    }
9747
    if (endA && (aes->aOver > 0)) {
9748
        /* No more AAD coming and we have a partial block. */
9749
        /* Fill the rest of the block with zeros. */
9750
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
9751
                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
9752
        /* GHASH last AAD block. */
9753
    #ifdef HAVE_INTEL_AVX2
9754
        if (IS_INTEL_AVX2(intel_flags)) {
9755
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
9756
                                     aes->gcm.H);
9757
        }
9758
        else
9759
    #endif
9760
    #ifdef HAVE_INTEL_AVX1
9761
        if (IS_INTEL_AVX1(intel_flags)) {
9762
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
9763
                                     aes->gcm.H);
9764
        }
9765
        else
9766
    #endif
9767
        {
9768
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
9769
                                      aes->gcm.H);
9770
        }
9771
        /* Clear partial count for next time through. */
9772
        aes->aOver = 0;
9773
    }
9774
9775
    return 0;
9776
}
9777
9778
/* Update the AES GCM for encryption with data and/or authentication data.
9779
 *
9780
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
9781
 *
9782
 * @param [in, out] aes  AES object.
9783
 * @param [out]     c    Buffer to hold cipher text.
9784
 * @param [in]      p    Buffer holding plaintext.
9785
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
9786
 * @param [in]      a    Buffer holding authentication data.
9787
 * @param [in]      aSz  Length of authentication data in bytes.
9788
 */
9789
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
9790
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
9791
{
9792
    word32 blocks;
9793
    int partial;
9794
    int ret;
9795
9796
    ASSERT_SAVED_VECTOR_REGISTERS();
9797
9798
    /* Hash in A, the Authentication Data */
9799
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
9800
    if (ret != 0)
9801
        return ret;
9802
9803
    /* Encrypt plaintext and Hash in C, the Cipher text */
9804
    if (cSz != 0 && c != NULL) {
9805
        /* Update count of cipher text we have hashed. */
9806
        aes->cSz += cSz;
9807
        if (aes->cOver > 0) {
9808
            /* Calculate amount we can use - fill up the block. */
9809
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
9810
            if (sz > cSz) {
9811
                sz = (byte)cSz;
9812
            }
9813
            /* Encrypt some of the plaintext. */
9814
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
9815
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
9816
            /* Update count of unused encrypted counter. */
9817
            aes->cOver = (byte)(aes->cOver + sz);
9818
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
9819
                /* We have filled up the block and can process. */
9820
            #ifdef HAVE_INTEL_AVX2
9821
                if (IS_INTEL_AVX2(intel_flags)) {
9822
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
9823
                                             aes->gcm.H);
9824
                }
9825
                else
9826
            #endif
9827
            #ifdef HAVE_INTEL_AVX1
9828
                if (IS_INTEL_AVX1(intel_flags)) {
9829
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
9830
                                             aes->gcm.H);
9831
                }
9832
                else
9833
            #endif
9834
                {
9835
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
9836
                                              aes->gcm.H);
9837
                }
9838
                /* Reset count. */
9839
                aes->cOver = 0;
9840
            }
9841
            /* Used up some data. */
9842
            cSz -= sz;
9843
            p += sz;
9844
            c += sz;
9845
        }
9846
9847
        /* Calculate number of blocks of plaintext and the leftover. */
9848
        blocks = cSz / WC_AES_BLOCK_SIZE;
9849
        partial = cSz % WC_AES_BLOCK_SIZE;
9850
        if (blocks > 0) {
9851
            /* Encrypt and GHASH full blocks now. */
9852
        #ifdef HAVE_INTEL_AVX2
9853
            if (IS_INTEL_AVX2(intel_flags)) {
9854
                AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
9855
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
9856
                    AES_COUNTER(aes));
9857
            }
9858
            else
9859
        #endif
9860
        #ifdef HAVE_INTEL_AVX1
9861
            if (IS_INTEL_AVX1(intel_flags)) {
9862
                AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
9863
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
9864
                    AES_COUNTER(aes));
9865
            }
9866
            else
9867
        #endif
9868
            {
9869
                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
9870
                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
9871
                    AES_COUNTER(aes));
9872
            }
9873
            /* Skip over to end of blocks. */
9874
            p += blocks * WC_AES_BLOCK_SIZE;
9875
            c += blocks * WC_AES_BLOCK_SIZE;
9876
        }
9877
        if (partial != 0) {
9878
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
9879
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
9880
        #ifdef HAVE_INTEL_AVX2
9881
            if (IS_INTEL_AVX2(intel_flags)) {
9882
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
9883
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
9884
            }
9885
            else
9886
        #endif
9887
        #ifdef HAVE_INTEL_AVX1
9888
            if (IS_INTEL_AVX1(intel_flags)) {
9889
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
9890
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
9891
            }
9892
            else
9893
        #endif
9894
            {
9895
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
9896
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
9897
            }
9898
            /* XOR the remaining plaintext to calculate cipher text.
9899
             * Keep cipher text for GHASH of last partial block.
9900
             */
9901
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
9902
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
9903
            /* Update count of the block used. */
9904
            aes->cOver = (byte)partial;
9905
        }
9906
    }
9907
    return 0;
9908
}
9909
9910
/* Finalize the AES GCM for encryption and calculate the authentication tag.
9911
 *
9912
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
9913
 *
9914
 * @param [in, out] aes        AES object.
9915
 * @param [in]      authTag    Buffer to hold authentication tag.
9916
 * @param [in]      authTagSz  Length of authentication tag in bytes.
9917
 * @return  0 on success.
9918
 */
9919
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
9920
    Aes* aes, byte* authTag, word32 authTagSz)
9921
{
9922
    /* AAD block incomplete when > 0 */
9923
    byte over = aes->aOver;
9924
9925
    ASSERT_SAVED_VECTOR_REGISTERS();
9926
9927
    if (aes->cOver > 0) {
9928
        /* Cipher text block incomplete. */
9929
        over = aes->cOver;
9930
    }
9931
    if (over > 0) {
9932
        /* Fill the rest of the block with zeros. */
9933
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
9934
        /* GHASH last cipher block. */
9935
    #ifdef HAVE_INTEL_AVX2
9936
        if (IS_INTEL_AVX2(intel_flags)) {
9937
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
9938
                                     aes->gcm.H);
9939
        }
9940
        else
9941
    #endif
9942
    #ifdef HAVE_INTEL_AVX1
9943
        if (IS_INTEL_AVX1(intel_flags)) {
9944
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
9945
                                     aes->gcm.H);
9946
        }
9947
        else
9948
    #endif
9949
        {
9950
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
9951
                                      aes->gcm.H);
9952
        }
9953
    }
9954
    /* Calculate the authentication tag. */
9955
#ifdef HAVE_INTEL_AVX2
9956
    if (IS_INTEL_AVX2(intel_flags)) {
9957
        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
9958
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
9959
    }
9960
    else
9961
#endif
9962
#ifdef HAVE_INTEL_AVX1
9963
    if (IS_INTEL_AVX1(intel_flags)) {
9964
        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
9965
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
9966
    }
9967
    else
9968
#endif
9969
    {
9970
        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
9971
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
9972
    }
9973
9974
    return 0;
9975
}
9976
9977
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
9978
9979
#ifdef __cplusplus
9980
    extern "C" {
9981
#endif
9982
9983
/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
9984
#ifdef HAVE_INTEL_AVX2
9985
extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
9986
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9987
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9988
extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
9989
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9990
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
9991
#endif
9992
#ifdef HAVE_INTEL_AVX1
9993
extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
9994
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9995
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9996
extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
9997
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9998
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
9999
#endif
10000
extern void AES_GCM_decrypt_update_aesni(const unsigned char* key, int nr,
10001
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
10002
    unsigned char* tag, unsigned char* h, unsigned char* counter);
10003
extern void AES_GCM_decrypt_final_aesni(unsigned char* tag,
10004
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
10005
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
10006
10007
#ifdef __cplusplus
10008
    } /* extern "C" */
10009
#endif
10010
10011
/* Update the AES GCM for decryption with data and/or authentication data.
10012
 *
10013
 * @param [in, out] aes  AES object.
10014
 * @param [out]     p    Buffer to hold plaintext.
10015
 * @param [in]      c    Buffer holding cipher text.
10016
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
10017
 * @param [in]      a    Buffer holding authentication data.
10018
 * @param [in]      aSz  Length of authentication data in bytes.
10019
 */
10020
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
10021
    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
10022
{
10023
    word32 blocks;
10024
    int partial;
10025
    int ret;
10026
10027
    ASSERT_SAVED_VECTOR_REGISTERS();
10028
10029
    /* Hash in A, the Authentication Data */
10030
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
10031
    if (ret != 0)
10032
        return ret;
10033
10034
    /* Hash in C, the Cipher text, and decrypt. */
10035
    if (cSz != 0 && p != NULL) {
10036
        /* Update count of cipher text we have hashed. */
10037
        aes->cSz += cSz;
10038
        if (aes->cOver > 0) {
10039
            /* Calculate amount we can use - fill up the block. */
10040
            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
10041
            if (sz > cSz) {
10042
                sz = (byte)cSz;
10043
            }
10044
            /* Keep a copy of the cipher text for GHASH. */
10045
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
10046
            /* Decrypt some of the cipher text. */
10047
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
10048
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
10049
            /* Update count of unused encrypted counter. */
10050
            aes->cOver = (byte)(aes->cOver + sz);
10051
            if (aes->cOver == WC_AES_BLOCK_SIZE) {
10052
                /* We have filled up the block and can process. */
10053
            #ifdef HAVE_INTEL_AVX2
10054
                if (IS_INTEL_AVX2(intel_flags)) {
10055
                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
10056
                                             aes->gcm.H);
10057
                }
10058
                else
10059
            #endif
10060
            #ifdef HAVE_INTEL_AVX1
10061
                if (IS_INTEL_AVX1(intel_flags)) {
10062
                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
10063
                                             aes->gcm.H);
10064
                }
10065
                else
10066
            #endif
10067
                {
10068
                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
10069
                                              aes->gcm.H);
10070
                }
10071
                /* Reset count. */
10072
                aes->cOver = 0;
10073
            }
10074
            /* Used up some data. */
10075
            cSz -= sz;
10076
            c += sz;
10077
            p += sz;
10078
        }
10079
10080
        /* Calculate number of blocks of plaintext and the leftover. */
10081
        blocks = cSz / WC_AES_BLOCK_SIZE;
10082
        partial = cSz % WC_AES_BLOCK_SIZE;
10083
        if (blocks > 0) {
10084
            /* Decrypt and GHASH full blocks now. */
10085
        #ifdef HAVE_INTEL_AVX2
10086
            if (IS_INTEL_AVX2(intel_flags)) {
10087
                AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
10088
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
10089
                    AES_COUNTER(aes));
10090
            }
10091
            else
10092
        #endif
10093
        #ifdef HAVE_INTEL_AVX1
10094
            if (IS_INTEL_AVX1(intel_flags)) {
10095
                AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
10096
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
10097
                    AES_COUNTER(aes));
10098
            }
10099
            else
10100
        #endif
10101
            {
10102
                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
10103
                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
10104
                    AES_COUNTER(aes));
10105
            }
10106
            /* Skip over to end of blocks. */
10107
            c += blocks * WC_AES_BLOCK_SIZE;
10108
            p += blocks * WC_AES_BLOCK_SIZE;
10109
        }
10110
        if (partial != 0) {
10111
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
10112
            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
10113
        #ifdef HAVE_INTEL_AVX2
10114
            if (IS_INTEL_AVX2(intel_flags)) {
10115
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
10116
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
10117
            }
10118
            else
10119
        #endif
10120
        #ifdef HAVE_INTEL_AVX1
10121
            if (IS_INTEL_AVX1(intel_flags)) {
10122
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
10123
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
10124
            }
10125
            else
10126
        #endif
10127
            {
10128
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
10129
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
10130
            }
10131
            /* Keep cipher text for GHASH of last partial block. */
10132
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
10133
            /* XOR the remaining cipher text to calculate plaintext. */
10134
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
10135
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
10136
            /* Update count of the block used. */
10137
            aes->cOver = (byte)partial;
10138
        }
10139
    }
10140
10141
    return 0;
10142
}
10143
10144
/* Finalize the AES GCM for decryption and check the authentication tag.
10145
 *
10146
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
10147
 *
10148
 * @param [in, out] aes        AES object.
10149
 * @param [in]      authTag    Buffer holding authentication tag.
10150
 * @param [in]      authTagSz  Length of authentication tag in bytes.
10151
 * @return  0 on success.
10152
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
10153
 *          value.
10154
 */
10155
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
10156
    Aes* aes, const byte* authTag, word32 authTagSz)
10157
{
10158
    int ret = 0;
10159
    int res;
10160
    /* AAD block incomplete when > 0 */
10161
    byte over = aes->aOver;
10162
    byte *lastBlock = AES_LASTGBLOCK(aes);
10163
10164
    ASSERT_SAVED_VECTOR_REGISTERS();
10165
10166
    if (aes->cOver > 0) {
10167
        /* Cipher text block incomplete. */
10168
        over = aes->cOver;
10169
        lastBlock = AES_LASTBLOCK(aes);
10170
    }
10171
    if (over > 0) {
10172
        /* Zeroize the unused part of the block. */
10173
        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
10174
        /* Hash the last block of cipher text. */
10175
    #ifdef HAVE_INTEL_AVX2
10176
        if (IS_INTEL_AVX2(intel_flags)) {
10177
            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
10178
        }
10179
        else
10180
    #endif
10181
    #ifdef HAVE_INTEL_AVX1
10182
        if (IS_INTEL_AVX1(intel_flags)) {
10183
            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
10184
        }
10185
        else
10186
    #endif
10187
        {
10188
            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
10189
        }
10190
    }
10191
    /* Calculate and compare the authentication tag. */
10192
#ifdef HAVE_INTEL_AVX2
10193
    if (IS_INTEL_AVX2(intel_flags)) {
10194
        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
10195
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
10196
    }
10197
    else
10198
#endif
10199
#ifdef HAVE_INTEL_AVX1
10200
    if (IS_INTEL_AVX1(intel_flags)) {
10201
        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
10202
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
10203
    }
10204
    else
10205
#endif
10206
    {
10207
        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
10208
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
10209
    }
10210
10211
    /* Return error code when calculated doesn't match input. */
10212
    if (res == 0) {
10213
        ret = AES_GCM_AUTH_E;
10214
    }
10215
    return ret;
10216
}
10217
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
10218
#endif /* WOLFSSL_AESNI */
10219
10220
/* Initialize an AES GCM cipher for encryption or decryption.
10221
 *
10222
 * Must call wc_AesInit() before calling this function.
10223
 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
10224
 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
10225
 *
10226
 * @param [in, out] aes   AES object.
10227
 * @param [in]      key   Buffer holding key.
10228
 * @param [in]      len   Length of key in bytes.
10229
 * @param [in]      iv    Buffer holding IV/nonce.
10230
 * @param [in]      ivSz  Length of IV/nonce in bytes.
10231
 * @return  0 on success.
10232
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
10233
 *          is NULL, or the IV is NULL and no previous IV has been set.
10234
 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
10235
 */
10236
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
10237
    word32 ivSz)
10238
{
10239
    int ret = 0;
10240
10241
    /* Check validity of parameters. */
10242
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
10243
            ((ivSz == 0) && (iv != NULL)) ||
10244
            ((ivSz > 0) && (iv == NULL))) {
10245
        ret = BAD_FUNC_ARG;
10246
    }
10247
10248
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
10249
    if ((ret == 0) && (aes->streamData == NULL)) {
10250
        /* Allocate buffers for streaming. */
10251
        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
10252
        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
10253
                                                              DYNAMIC_TYPE_AES);
10254
        if (aes->streamData == NULL) {
10255
            ret = MEMORY_E;
10256
        }
10257
    }
10258
#endif
10259
10260
    /* Set the key if passed in. */
10261
    if ((ret == 0) && (key != NULL)) {
10262
        ret = wc_AesGcmSetKey(aes, key, len);
10263
    }
10264
10265
    if (ret == 0) {
10266
        /* Set the IV passed in if it is smaller than a block. */
10267
        if ((iv != NULL) && (ivSz <= WC_AES_BLOCK_SIZE)) {
10268
            XMEMMOVE((byte*)aes->reg, iv, ivSz);
10269
            aes->nonceSz = ivSz;
10270
        }
10271
        /* No IV passed in, check for cached IV. */
10272
        if ((iv == NULL) && (aes->nonceSz != 0)) {
10273
            /* Use the cached copy. */
10274
            iv = (byte*)aes->reg;
10275
            ivSz = aes->nonceSz;
10276
        }
10277
10278
        if (iv != NULL) {
10279
            /* Initialize with the IV. */
10280
10281
        #ifdef WOLFSSL_AESNI
10282
            if (aes->use_aesni) {
10283
                SAVE_VECTOR_REGISTERS(return _svr_ret;);
10284
                ret = AesGcmInit_aesni(aes, iv, ivSz);
10285
                RESTORE_VECTOR_REGISTERS();
10286
            }
10287
            else
10288
        #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10289
              !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10290
            if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10291
                AES_GCM_init_AARCH64(aes, iv, ivSz);
10292
10293
                /* Reset state fields. */
10294
                aes->over = 0;
10295
                aes->aSz = 0;
10296
                aes->cSz = 0;
10297
                /* Initialization for GHASH. */
10298
                GHASH_INIT(aes);
10299
            }
10300
            else
10301
        #endif /* WOLFSSL_AESNI */
10302
            {
10303
                ret = AesGcmInit_C(aes, iv, ivSz);
10304
            }
10305
10306
            if (ret == 0)
10307
                aes->nonceSet = 1;
10308
        }
10309
    }
10310
10311
    return ret;
10312
}
10313
10314
/* Initialize an AES GCM cipher for encryption.
10315
 *
10316
 * Must call wc_AesInit() before calling this function.
10317
 *
10318
 * @param [in, out] aes   AES object.
10319
 * @param [in]      key   Buffer holding key.
10320
 * @param [in]      len   Length of key in bytes.
10321
 * @param [in]      iv    Buffer holding IV/nonce.
10322
 * @param [in]      ivSz  Length of IV/nonce in bytes.
10323
 * @return  0 on success.
10324
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
10325
 *          is NULL, or the IV is NULL and no previous IV has been set.
10326
 */
10327
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
10328
    word32 ivSz)
10329
{
10330
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
10331
}
10332
10333
/* Initialize an AES GCM cipher for encryption. Get IV.
10334
 *
10335
 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
10336
 * function.
10337
 * Must call wc_AesInit() before calling this function.
10338
 *
10339
 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
10340
 *
10341
 * @param [in, out] aes   AES object.
10342
 * @param [in]      key   Buffer holding key.
10343
 * @param [in]      len   Length of key in bytes.
10344
 * @param [in]      iv    Buffer holding IV/nonce.
10345
 * @param [in]      ivSz  Length of IV/nonce in bytes.
10346
 * @return  0 on success.
10347
 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
10348
 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
10349
 *          nonce size.
10350
 */
10351
int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
10352
    word32 ivOutSz)
10353
{
10354
    int ret;
10355
10356
    /* Check validity of parameters. */
10357
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
10358
        ret = BAD_FUNC_ARG;
10359
    }
10360
    else {
10361
        /* Copy out the IV including generated part for decryption. */
10362
        XMEMCPY(ivOut, aes->reg, ivOutSz);
10363
        /* Initialize AES GCM cipher with key and cached Iv. */
10364
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
10365
    }
10366
10367
    return ret;
10368
}
10369
10370
/* Update the AES GCM for encryption with data and/or authentication data.
10371
 *
10372
 * All the AAD must be passed to update before the plaintext.
10373
 * Last part of AAD can be passed with first part of plaintext.
10374
 *
10375
 * Must set key and IV before calling this function.
10376
 * Must call wc_AesGcmInit() before calling this function.
10377
 *
10378
 * @param [in, out] aes       AES object.
10379
 * @param [out]     out       Buffer to hold cipher text.
10380
 * @param [in]      in        Buffer holding plaintext.
10381
 * @param [in]      sz        Length of plaintext in bytes.
10382
 * @param [in]      authIn    Buffer holding authentication data.
10383
 * @param [in]      authInSz  Length of authentication data in bytes.
10384
 * @return  0 on success.
10385
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
10386
 *          is NULL.
10387
 */
10388
int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
10389
    const byte* authIn, word32 authInSz)
10390
{
10391
    int ret = 0;
10392
10393
    /* Check validity of parameters. */
10394
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
10395
            ((out == NULL) || (in == NULL)))) {
10396
        ret = BAD_FUNC_ARG;
10397
    }
10398
10399
    /* Check key has been set. */
10400
    if ((ret == 0) && (!aes->gcmKeySet)) {
10401
        ret = MISSING_KEY;
10402
    }
10403
    /* Check IV has been set. */
10404
    if ((ret == 0) && (!aes->nonceSet)) {
10405
        ret = MISSING_IV;
10406
    }
10407
10408
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
10409
        aes->invokeCtr[0]++;
10410
        if (aes->invokeCtr[0] == 0) {
10411
            aes->invokeCtr[1]++;
10412
            if (aes->invokeCtr[1] == 0)
10413
                ret = AES_GCM_OVERFLOW_E;
10414
        }
10415
    }
10416
10417
    if (ret == 0) {
10418
        /* Encrypt with AAD and/or plaintext. */
10419
10420
    #ifdef WOLFSSL_AESNI
10421
        if (aes->use_aesni) {
10422
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
10423
            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
10424
            RESTORE_VECTOR_REGISTERS();
10425
        }
10426
        else
10427
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10428
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10429
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10430
            AES_GCM_crypt_update_AARCH64(aes, out, in, sz);
10431
            GHASH_UPDATE_AARCH64(aes, authIn, authInSz, out, sz);
10432
        }
10433
        else
10434
    #endif
10435
        {
10436
            /* Encrypt the plaintext. */
10437
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
10438
            if (ret == 0) {
10439
                /* Update the authentication tag with any authentication data and the
10440
                 * new cipher text. */
10441
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
10442
            }
10443
        }
10444
    }
10445
10446
    return ret;
10447
}
10448
10449
/* Finalize the AES GCM for encryption and return the authentication tag.
10450
 *
10451
 * Must set key and IV before calling this function.
10452
 * Must call wc_AesGcmInit() before calling this function.
10453
 *
10454
 * @param [in, out] aes        AES object.
10455
 * @param [out]     authTag    Buffer to hold authentication tag.
10456
 * @param [in]      authTagSz  Length of authentication tag in bytes.
10457
 * @return  0 on success.
10458
 */
10459
int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
10460
{
10461
    int ret = 0;
10462
10463
    /* Check validity of parameters. */
10464
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
10465
            (authTagSz == 0)) {
10466
        ret = BAD_FUNC_ARG;
10467
    }
10468
10469
    /* Check key has been set. */
10470
    if ((ret == 0) && (!aes->gcmKeySet)) {
10471
        ret = MISSING_KEY;
10472
    }
10473
    /* Check IV has been set. */
10474
    if ((ret == 0) && (!aes->nonceSet)) {
10475
        ret = MISSING_IV;
10476
    }
10477
10478
    if (ret == 0) {
10479
        /* Calculate authentication tag. */
10480
    #ifdef WOLFSSL_AESNI
10481
        if (aes->use_aesni) {
10482
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
10483
            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
10484
            RESTORE_VECTOR_REGISTERS();
10485
        }
10486
        else
10487
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10488
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10489
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10490
            AES_GCM_final_AARCH64(aes, authTag, authTagSz);
10491
        }
10492
        else
10493
    #endif
10494
        {
10495
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
10496
        }
10497
    }
10498
10499
    if ((ret == 0) && aes->ctrSet) {
10500
        IncCtr((byte*)aes->reg, aes->nonceSz);
10501
    }
10502
10503
    return ret;
10504
}
10505
10506
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
10507
/* Initialize an AES GCM cipher for decryption.
10508
 *
10509
 * Must call wc_AesInit() before calling this function.
10510
 *
10511
 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
10512
 * instead.
10513
 *
10514
 * @param [in, out] aes   AES object.
10515
 * @param [in]      key   Buffer holding key.
10516
 * @param [in]      len   Length of key in bytes.
10517
 * @param [in]      iv    Buffer holding IV/nonce.
10518
 * @param [in]      ivSz  Length of IV/nonce in bytes.
10519
 * @return  0 on success.
10520
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
10521
 *          is NULL, or the IV is NULL and no previous IV has been set.
10522
 */
10523
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
10524
    word32 ivSz)
10525
{
10526
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
10527
}
10528
10529
/* Update the AES GCM for decryption with data and/or authentication data.
10530
 *
10531
 * All the AAD must be passed to update before the cipher text.
10532
 * Last part of AAD can be passed with first part of cipher text.
10533
 *
10534
 * Must set key and IV before calling this function.
10535
 * Must call wc_AesGcmInit() before calling this function.
10536
 *
10537
 * @param [in, out] aes       AES object.
10538
 * @param [out]     out       Buffer to hold plaintext.
10539
 * @param [in]      in        Buffer holding cipher text.
10540
 * @param [in]      sz        Length of cipher text in bytes.
10541
 * @param [in]      authIn    Buffer holding authentication data.
10542
 * @param [in]      authInSz  Length of authentication data in bytes.
10543
 * @return  0 on success.
10544
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
10545
 *          is NULL.
10546
 */
10547
int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
10548
    const byte* authIn, word32 authInSz)
10549
{
10550
    int ret = 0;
10551
10552
    /* Check validity of parameters. */
10553
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
10554
            ((out == NULL) || (in == NULL)))) {
10555
        ret = BAD_FUNC_ARG;
10556
    }
10557
10558
    /* Check key has been set. */
10559
    if ((ret == 0) && (!aes->gcmKeySet)) {
10560
        ret = MISSING_KEY;
10561
    }
10562
    /* Check IV has been set. */
10563
    if ((ret == 0) && (!aes->nonceSet)) {
10564
        ret = MISSING_IV;
10565
    }
10566
10567
    if (ret == 0) {
10568
        /* Decrypt with AAD and/or cipher text. */
10569
    #ifdef WOLFSSL_AESNI
10570
        if (aes->use_aesni) {
10571
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
10572
            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
10573
            RESTORE_VECTOR_REGISTERS();
10574
        }
10575
        else
10576
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10577
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10578
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10579
            GHASH_UPDATE_AARCH64(aes, authIn, authInSz, in, sz);
10580
            AES_GCM_crypt_update_AARCH64(aes, out, in, sz);
10581
        }
10582
        else
10583
    #endif
10584
        {
10585
            /* Update the authentication tag with any authentication data and
10586
             * cipher text. */
10587
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
10588
            /* Decrypt the cipher text. */
10589
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
10590
        }
10591
    }
10592
10593
    return ret;
10594
}
10595
10596
/* Finalize the AES GCM for decryption and check the authentication tag.
10597
 *
10598
 * Must set key and IV before calling this function.
10599
 * Must call wc_AesGcmInit() before calling this function.
10600
 *
10601
 * @param [in, out] aes        AES object.
10602
 * @param [in]      authTag    Buffer holding authentication tag.
10603
 * @param [in]      authTagSz  Length of authentication tag in bytes.
10604
 * @return  0 on success.
10605
 */
10606
int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
10607
{
10608
    int ret = 0;
10609
10610
    /* Check validity of parameters. */
10611
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
10612
            (authTagSz == 0)) {
10613
        ret = BAD_FUNC_ARG;
10614
    }
10615
10616
    /* Check key has been set. */
10617
    if ((ret == 0) && (!aes->gcmKeySet)) {
10618
        ret = MISSING_KEY;
10619
    }
10620
    /* Check IV has been set. */
10621
    if ((ret == 0) && (!aes->nonceSet)) {
10622
        ret = MISSING_IV;
10623
    }
10624
10625
    if (ret == 0) {
10626
        /* Calculate authentication tag and compare with one passed in.. */
10627
    #ifdef WOLFSSL_AESNI
10628
        if (aes->use_aesni) {
10629
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
10630
            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
10631
            RESTORE_VECTOR_REGISTERS();
10632
        }
10633
        else
10634
    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
10635
          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10636
        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10637
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
10638
            AES_GCM_final_AARCH64(aes, calcTag, authTagSz);
10639
            /* Check calculated tag matches the one passed in. */
10640
            if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
10641
                ret = AES_GCM_AUTH_E;
10642
            }
10643
        }
10644
        else
10645
    #endif
10646
        {
10647
            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
10648
            /* Calculate authentication tag. */
10649
            ret = AesGcmFinal_C(aes, calcTag, authTagSz);
10650
            if (ret == 0) {
10651
                /* Check calculated tag matches the one passed in. */
10652
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
10653
                    ret = AES_GCM_AUTH_E;
10654
                }
10655
            }
10656
        }
10657
    }
10658
10659
    return ret;
10660
}
10661
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
10662
#endif /* WOLFSSL_AESGCM_STREAM */
10663
#endif /* WOLFSSL_XILINX_CRYPT */
10664
#endif /* end of block for AESGCM implementation selection */
10665
10666
10667
/* Common to all, abstract functions that build off of lower level AESGCM
10668
 * functions */
10669
#ifndef WC_NO_RNG
10670
10671
0
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
10672
0
    return (ivSz == GCM_NONCE_MIN_SZ ||
10673
0
            ivSz == GCM_NONCE_MID_SZ ||
10674
0
            ivSz == GCM_NONCE_MAX_SZ);
10675
0
}
10676
10677
10678
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
10679
0
{
10680
0
    int ret = 0;
10681
10682
0
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
10683
0
        ret = BAD_FUNC_ARG;
10684
0
    }
10685
10686
0
    if (ret == 0) {
10687
0
        XMEMCPY((byte*)aes->reg, iv, ivSz);
10688
10689
        /* If the IV is 96, allow for a 2^64 invocation counter.
10690
         * For any other size for the nonce, limit the invocation
10691
         * counter to 32-bits. (SP 800-38D 8.3) */
10692
0
        aes->invokeCtr[0] = 0;
10693
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
10694
    #ifdef WOLFSSL_AESGCM_STREAM
10695
        aes->ctrSet = 1;
10696
    #endif
10697
0
        aes->nonceSz = ivSz;
10698
0
    }
10699
10700
0
    return ret;
10701
0
}
10702
10703
10704
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
10705
                   const byte* ivFixed, word32 ivFixedSz,
10706
                   WC_RNG* rng)
10707
0
{
10708
0
    int ret = 0;
10709
10710
0
    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
10711
0
        (ivFixed == NULL && ivFixedSz != 0) ||
10712
0
        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
10713
10714
0
        ret = BAD_FUNC_ARG;
10715
0
    }
10716
10717
0
    if (ret == 0) {
10718
0
        byte* iv = (byte*)aes->reg;
10719
10720
0
        if (ivFixedSz)
10721
0
            XMEMCPY(iv, ivFixed, ivFixedSz);
10722
10723
0
        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
10724
0
    }
10725
10726
0
    if (ret == 0) {
10727
        /* If the IV is 96, allow for a 2^64 invocation counter.
10728
         * For any other size for the nonce, limit the invocation
10729
         * counter to 32-bits. (SP 800-38D 8.3) */
10730
0
        aes->invokeCtr[0] = 0;
10731
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
10732
    #ifdef WOLFSSL_AESGCM_STREAM
10733
        aes->ctrSet = 1;
10734
    #endif
10735
0
        aes->nonceSz = ivSz;
10736
0
    }
10737
10738
0
    return ret;
10739
0
}
10740
10741
10742
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
10743
                        byte* ivOut, word32 ivOutSz,
10744
                        byte* authTag, word32 authTagSz,
10745
                        const byte* authIn, word32 authInSz)
10746
0
{
10747
0
    int ret = 0;
10748
10749
0
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
10750
0
        ivOut == NULL || ivOutSz != aes->nonceSz ||
10751
0
        (authIn == NULL && authInSz != 0)) {
10752
10753
0
        ret = BAD_FUNC_ARG;
10754
0
    }
10755
10756
0
    if (ret == 0) {
10757
0
        aes->invokeCtr[0]++;
10758
0
        if (aes->invokeCtr[0] == 0) {
10759
0
            aes->invokeCtr[1]++;
10760
0
            if (aes->invokeCtr[1] == 0)
10761
0
                ret = AES_GCM_OVERFLOW_E;
10762
0
        }
10763
0
    }
10764
10765
0
    if (ret == 0) {
10766
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
10767
0
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
10768
0
                               (byte*)aes->reg, ivOutSz,
10769
0
                               authTag, authTagSz,
10770
0
                               authIn, authInSz);
10771
0
        if (ret == 0)
10772
0
            IncCtr((byte*)aes->reg, ivOutSz);
10773
0
    }
10774
10775
0
    return ret;
10776
0
}
10777
10778
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
10779
            const byte* authIn, word32 authInSz,
10780
            byte* authTag, word32 authTagSz, WC_RNG* rng)
10781
0
{
10782
#ifdef WOLFSSL_SMALL_STACK
10783
    Aes *aes;
10784
#else
10785
0
    Aes aes[1];
10786
0
#endif
10787
0
    int ret;
10788
10789
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
10790
0
        authTag == NULL || authTagSz == 0 || rng == NULL) {
10791
10792
0
        return BAD_FUNC_ARG;
10793
0
    }
10794
10795
#ifdef WOLFSSL_SMALL_STACK
10796
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
10797
#else
10798
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
10799
0
#endif
10800
0
    if (ret != 0)
10801
0
        return ret;
10802
10803
0
    ret = wc_AesGcmSetKey(aes, key, keySz);
10804
0
    if (ret == 0)
10805
0
        ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
10806
0
    if (ret == 0)
10807
0
        ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
10808
0
                                  authTag, authTagSz, authIn, authInSz);
10809
10810
#ifdef WOLFSSL_SMALL_STACK
10811
    wc_AesDelete(aes, NULL);
10812
#else
10813
0
    wc_AesFree(aes);
10814
0
#endif
10815
10816
0
    return ret;
10817
0
}
10818
10819
int wc_GmacVerify(const byte* key, word32 keySz,
10820
                  const byte* iv, word32 ivSz,
10821
                  const byte* authIn, word32 authInSz,
10822
                  const byte* authTag, word32 authTagSz)
10823
0
{
10824
0
    int ret;
10825
0
#ifdef HAVE_AES_DECRYPT
10826
#ifdef WOLFSSL_SMALL_STACK
10827
    Aes *aes = NULL;
10828
#else
10829
0
    Aes aes[1];
10830
0
#endif
10831
10832
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
10833
0
        authTag == NULL || authTagSz == 0 || authTagSz > WC_AES_BLOCK_SIZE) {
10834
10835
0
        return BAD_FUNC_ARG;
10836
0
    }
10837
10838
#ifdef WOLFSSL_SMALL_STACK
10839
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
10840
#else
10841
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
10842
0
#endif
10843
0
    if (ret == 0) {
10844
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
10845
0
        if (ret == 0)
10846
0
            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
10847
0
                                  authTag, authTagSz, authIn, authInSz);
10848
10849
0
    }
10850
#ifdef WOLFSSL_SMALL_STACK
10851
    wc_AesDelete(aes, NULL);
10852
#else
10853
0
    wc_AesFree(aes);
10854
0
#endif
10855
#else
10856
    (void)key;
10857
    (void)keySz;
10858
    (void)iv;
10859
    (void)ivSz;
10860
    (void)authIn;
10861
    (void)authInSz;
10862
    (void)authTag;
10863
    (void)authTagSz;
10864
    ret = NOT_COMPILED_IN;
10865
#endif
10866
0
    return ret;
10867
0
}
10868
10869
#endif /* WC_NO_RNG */
10870
10871
10872
int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
10873
0
{
10874
0
    if (gmac == NULL || key == NULL) {
10875
0
        return BAD_FUNC_ARG;
10876
0
    }
10877
0
    return wc_AesGcmSetKey(&gmac->aes, key, len);
10878
0
}
10879
10880
10881
int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
10882
                              const byte* authIn, word32 authInSz,
10883
                              byte* authTag, word32 authTagSz)
10884
0
{
10885
0
    if (gmac == NULL) {
10886
0
        return BAD_FUNC_ARG;
10887
0
    }
10888
10889
0
    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
10890
0
                                         authTag, authTagSz, authIn, authInSz);
10891
0
}
10892
10893
#endif /* HAVE_AESGCM */
10894
10895
10896
#ifdef HAVE_AESCCM
10897
10898
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
10899
{
10900
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
10901
        return BAD_FUNC_ARG;
10902
10903
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
10904
}
10905
10906
10907
/* Checks if the tag size is an accepted value based on RFC 3610 section 2
10908
 * returns 0 if tag size is ok
10909
 */
10910
int wc_AesCcmCheckTagSize(int sz)
10911
{
10912
    /* values here are from RFC 3610 section 2 */
10913
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
10914
            && sz != 16) {
10915
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
10916
        return BAD_FUNC_ARG;
10917
    }
10918
    return 0;
10919
}
10920
10921
#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__)
10922
    /* implemented in wolfcrypt/src/port/arm/armv8-aes.c */
10923
10924
#elif defined(WOLFSSL_RISCV_ASM)
10925
    /* implementation located in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
10926
10927
#elif defined(HAVE_COLDFIRE_SEC)
10928
    #error "Coldfire SEC doesn't currently support AES-CCM mode"
10929
10930
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
10931
        !defined(WOLFSSL_QNX_CAAM)
10932
    /* implemented in wolfcrypt/src/port/caam_aes.c */
10933
10934
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10935
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
10936
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
10937
                   const byte* nonce, word32 nonceSz,
10938
                   byte* authTag, word32 authTagSz,
10939
                   const byte* authIn, word32 authInSz)
10940
{
10941
    return wc_AesCcmEncrypt_silabs(
10942
        aes, out, in, inSz,
10943
        nonce, nonceSz,
10944
        authTag, authTagSz,
10945
        authIn, authInSz);
10946
}
10947
10948
#ifdef HAVE_AES_DECRYPT
10949
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
10950
                   const byte* nonce, word32 nonceSz,
10951
                   const byte* authTag, word32 authTagSz,
10952
                   const byte* authIn, word32 authInSz)
10953
{
10954
    return wc_AesCcmDecrypt_silabs(
10955
        aes, out, in, inSz,
10956
        nonce, nonceSz,
10957
        authTag, authTagSz,
10958
        authIn, authInSz);
10959
}
10960
#endif
10961
#elif defined(FREESCALE_LTC)
10962
10963
/* return 0 on success */
10964
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
10965
                   const byte* nonce, word32 nonceSz,
10966
                   byte* authTag, word32 authTagSz,
10967
                   const byte* authIn, word32 authInSz)
10968
{
10969
    byte *key;
10970
    word32 keySize;
10971
    status_t status;
10972
10973
    /* sanity check on arguments */
10974
    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
10975
     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
10976
     * don't allow it here either.
10977
     */
10978
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
10979
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
10980
        return BAD_FUNC_ARG;
10981
    }
10982
10983
    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
10984
        return BAD_FUNC_ARG;
10985
    }
10986
10987
    key = (byte*)aes->key;
10988
10989
    status = wc_AesGetKeySize(aes, &keySize);
10990
    if (status != 0) {
10991
        return status;
10992
    }
10993
10994
    status = wolfSSL_CryptHwMutexLock();
10995
    if (status != 0)
10996
        return status;
10997
10998
    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
10999
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
11000
    wolfSSL_CryptHwMutexUnLock();
11001
11002
    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
11003
}
11004
11005
#ifdef HAVE_AES_DECRYPT
11006
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
11007
                   const byte* nonce, word32 nonceSz,
11008
                   const byte* authTag, word32 authTagSz,
11009
                   const byte* authIn, word32 authInSz)
11010
{
11011
    byte *key;
11012
    word32 keySize;
11013
    status_t status;
11014
11015
    /* sanity check on arguments */
11016
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
11017
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
11018
        return BAD_FUNC_ARG;
11019
    }
11020
11021
    key = (byte*)aes->key;
11022
11023
    status = wc_AesGetKeySize(aes, &keySize);
11024
    if (status != 0) {
11025
        return status;
11026
    }
11027
11028
    status = wolfSSL_CryptHwMutexLock();
11029
    if (status != 0)
11030
        return status;
11031
    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
11032
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
11033
    wolfSSL_CryptHwMutexUnLock();
11034
11035
    if (status != kStatus_Success) {
11036
        XMEMSET(out, 0, inSz);
11037
        return AES_CCM_AUTH_E;
11038
    }
11039
    return 0;
11040
}
11041
#endif /* HAVE_AES_DECRYPT */
11042
11043
#else
11044
11045
/* Software CCM */
11046
static WARN_UNUSED_RESULT int roll_x(
11047
    Aes* aes, const byte* in, word32 inSz, byte* out)
11048
{
11049
    int ret;
11050
11051
    /* process the bulk of the data */
11052
    while (inSz >= WC_AES_BLOCK_SIZE) {
11053
        xorbuf(out, in, WC_AES_BLOCK_SIZE);
11054
        in += WC_AES_BLOCK_SIZE;
11055
        inSz -= WC_AES_BLOCK_SIZE;
11056
11057
        ret = wc_AesEncrypt(aes, out, out);
11058
        if (ret != 0)
11059
            return ret;
11060
    }
11061
11062
    /* process remainder of the data */
11063
    if (inSz > 0) {
11064
        xorbuf(out, in, inSz);
11065
        ret = wc_AesEncrypt(aes, out, out);
11066
        if (ret != 0)
11067
            return ret;
11068
    }
11069
11070
    return 0;
11071
}
11072
11073
static WARN_UNUSED_RESULT int roll_auth(
11074
    Aes* aes, const byte* in, word32 inSz, byte* out)
11075
{
11076
    word32 authLenSz;
11077
    word32 remainder;
11078
    int ret;
11079
11080
    /* encode the length in */
11081
    if (inSz <= 0xFEFF) {
11082
        authLenSz = 2;
11083
        out[0] ^= (byte)(inSz >> 8);
11084
        out[1] ^= (byte)inSz;
11085
    }
11086
    else {
11087
        authLenSz = 6;
11088
        out[0] ^= 0xFF;
11089
        out[1] ^= 0xFE;
11090
        out[2] ^= (byte)(inSz >> 24);
11091
        out[3] ^= (byte)(inSz >> 16);
11092
        out[4] ^= (byte)(inSz >>  8);
11093
        out[5] ^= (byte)inSz;
11094
    }
11095
    /* Note, the protocol handles auth data up to 2^64, but we are
11096
     * using 32-bit sizes right now, so the bigger data isn't handled
11097
     * else {}
11098
     */
11099
11100
    /* start fill out the rest of the first block */
11101
    remainder = WC_AES_BLOCK_SIZE - authLenSz;
11102
    if (inSz >= remainder) {
11103
        /* plenty of bulk data to fill the remainder of this block */
11104
        xorbuf(out + authLenSz, in, remainder);
11105
        inSz -= remainder;
11106
        in += remainder;
11107
    }
11108
    else {
11109
        /* not enough bulk data, copy what is available, and pad zero */
11110
        xorbuf(out + authLenSz, in, inSz);
11111
        inSz = 0;
11112
    }
11113
    ret = wc_AesEncrypt(aes, out, out);
11114
11115
    if ((ret == 0) && (inSz > 0)) {
11116
        ret = roll_x(aes, in, inSz, out);
11117
    }
11118
11119
    return ret;
11120
}
11121
11122
11123
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
11124
{
11125
    word32 i;
11126
11127
    for (i = 0; i < lenSz; i++) {
11128
        if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
11129
    }
11130
}
11131
11132
#ifdef WOLFSSL_AESNI
11133
static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
11134
{
11135
    word32 i;
11136
11137
    /* B+1 = B */
11138
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 1, B, WC_AES_BLOCK_SIZE);
11139
    /* B+2,B+3 = B,B+1 */
11140
    XMEMCPY(B + WC_AES_BLOCK_SIZE * 2, B, WC_AES_BLOCK_SIZE * 2);
11141
11142
    for (i = 0; i < lenSz; i++) {
11143
        if (++B[WC_AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
11144
    }
11145
    B[WC_AES_BLOCK_SIZE * 3 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 3 - 1] + 2U);
11146
    if (B[WC_AES_BLOCK_SIZE * 3 - 1] < 2U) {
11147
        for (i = 1; i < lenSz; i++) {
11148
            if (++B[WC_AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
11149
        }
11150
    }
11151
    B[WC_AES_BLOCK_SIZE * 4 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 4 - 1] + 3U);
11152
    if (B[WC_AES_BLOCK_SIZE * 4 - 1] < 3U) {
11153
        for (i = 1; i < lenSz; i++) {
11154
            if (++B[WC_AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
11155
        }
11156
    }
11157
}
11158
11159
static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
11160
{
11161
    word32 i;
11162
11163
    B[WC_AES_BLOCK_SIZE - 1] = (byte)(B[WC_AES_BLOCK_SIZE - 1] + 4U);
11164
    if (B[WC_AES_BLOCK_SIZE - 1] < 4U) {
11165
        for (i = 1; i < lenSz; i++) {
11166
            if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) break;
11167
        }
11168
    }
11169
}
11170
#endif
11171
11172
/* Software AES - CCM Encrypt */
11173
/* return 0 on success */
11174
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
11175
                   const byte* nonce, word32 nonceSz,
11176
                   byte* authTag, word32 authTagSz,
11177
                   const byte* authIn, word32 authInSz)
11178
{
11179
#ifdef WOLFSSL_AESNI
11180
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
11181
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
11182
#else
11183
    byte A[WC_AES_BLOCK_SIZE];
11184
    byte B[WC_AES_BLOCK_SIZE];
11185
#endif
11186
    byte lenSz;
11187
    word32 i;
11188
    byte mask = 0xFF;
11189
    const word32 wordSz = (word32)sizeof(word32);
11190
    int ret;
11191
11192
    /* sanity check on arguments */
11193
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
11194
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
11195
            authTagSz > WC_AES_BLOCK_SIZE)
11196
        return BAD_FUNC_ARG;
11197
11198
    /* Sanity check on authIn to prevent segfault in xorbuf() where
11199
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
11200
    if (authIn == NULL && authInSz > 0)
11201
        return BAD_FUNC_ARG;
11202
11203
    /* sanity check on tag size */
11204
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
11205
        return BAD_FUNC_ARG;
11206
    }
11207
11208
#ifdef WOLF_CRYPTO_CB
11209
    #ifndef WOLF_CRYPTO_CB_FIND
11210
    if (aes->devId != INVALID_DEVID)
11211
    #endif
11212
    {
11213
        int crypto_cb_ret =
11214
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
11215
                                      authTag, authTagSz, authIn, authInSz);
11216
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11217
            return crypto_cb_ret;
11218
        /* fall-through when unavailable */
11219
    }
11220
#endif
11221
11222
    XMEMSET(A, 0, sizeof(A));
11223
    XMEMCPY(B+1, nonce, nonceSz);
11224
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
11225
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
11226
                  + (8 * (((byte)authTagSz - 2) / 2))
11227
                  + (lenSz - 1));
11228
    for (i = 0; i < lenSz; i++) {
11229
        if (mask && i >= wordSz)
11230
            mask = 0x00;
11231
        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
11232
    }
11233
11234
#ifdef WOLFSSL_CHECK_MEM_ZERO
11235
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
11236
#endif
11237
11238
    VECTOR_REGISTERS_PUSH;
11239
    ret = wc_AesEncrypt(aes, B, A);
11240
#ifdef WOLFSSL_CHECK_MEM_ZERO
11241
    if (ret == 0)
11242
        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
11243
#endif
11244
11245
    if ((ret == 0) && (authInSz > 0))
11246
        ret = roll_auth(aes, authIn, authInSz, A);
11247
11248
    if ((ret == 0) && (inSz > 0))
11249
        ret = roll_x(aes, in, inSz, A);
11250
11251
    if (ret == 0) {
11252
        XMEMCPY(authTag, A, authTagSz);
11253
11254
        B[0] = (byte)(lenSz - 1U);
11255
        for (i = 0; i < lenSz; i++)
11256
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
11257
        ret = wc_AesEncrypt(aes, B, A);
11258
    }
11259
11260
    if (ret == 0) {
11261
        xorbuf(authTag, A, authTagSz);
11262
        B[15] = 1;
11263
    }
11264
#ifdef WOLFSSL_AESNI
11265
    if ((ret == 0) && aes->use_aesni) {
11266
        while (inSz >= WC_AES_BLOCK_SIZE * 4) {
11267
            AesCcmCtrIncSet4(B, lenSz);
11268
11269
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
11270
                            (int)aes->rounds);
11271
11272
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
11273
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE * 4);
11274
11275
            inSz -= WC_AES_BLOCK_SIZE * 4;
11276
            in += WC_AES_BLOCK_SIZE * 4;
11277
            out += WC_AES_BLOCK_SIZE * 4;
11278
11279
            AesCcmCtrInc4(B, lenSz);
11280
        }
11281
    }
11282
#endif
11283
    if (ret == 0) {
11284
        while (inSz >= WC_AES_BLOCK_SIZE) {
11285
            ret = wc_AesEncrypt(aes, B, A);
11286
            if (ret != 0)
11287
                break;
11288
            xorbuf(A, in, WC_AES_BLOCK_SIZE);
11289
            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
11290
11291
            AesCcmCtrInc(B, lenSz);
11292
            inSz -= WC_AES_BLOCK_SIZE;
11293
            in += WC_AES_BLOCK_SIZE;
11294
            out += WC_AES_BLOCK_SIZE;
11295
        }
11296
    }
11297
    if ((ret == 0) && (inSz > 0)) {
11298
        ret = wc_AesEncrypt(aes, B, A);
11299
    }
11300
    if ((ret == 0) && (inSz > 0)) {
11301
        xorbuf(A, in, inSz);
11302
        XMEMCPY(out, A, inSz);
11303
    }
11304
11305
    ForceZero(A, sizeof(A));
11306
    ForceZero(B, sizeof(B));
11307
11308
#ifdef WOLFSSL_CHECK_MEM_ZERO
11309
    wc_MemZero_Check(A, sizeof(A));
11310
    wc_MemZero_Check(B, sizeof(B));
11311
#endif
11312
11313
    VECTOR_REGISTERS_POP;
11314
11315
    return ret;
11316
}
11317
11318
#ifdef HAVE_AES_DECRYPT
11319
/* Software AES - CCM Decrypt */
11320
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
11321
                   const byte* nonce, word32 nonceSz,
11322
                   const byte* authTag, word32 authTagSz,
11323
                   const byte* authIn, word32 authInSz)
11324
{
11325
#ifdef WOLFSSL_AESNI
11326
    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
11327
    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
11328
#else
11329
    byte A[WC_AES_BLOCK_SIZE];
11330
    byte B[WC_AES_BLOCK_SIZE];
11331
#endif
11332
    byte* o;
11333
    byte lenSz;
11334
    word32 i, oSz;
11335
    byte mask = 0xFF;
11336
    const word32 wordSz = (word32)sizeof(word32);
11337
    int ret = 0;
11338
11339
    /* sanity check on arguments */
11340
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
11341
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
11342
        authTagSz > WC_AES_BLOCK_SIZE)
11343
        return BAD_FUNC_ARG;
11344
11345
    /* Sanity check on authIn to prevent segfault in xorbuf() where
11346
     * variable 'in' is dereferenced as the mask 'm' in misc.c */
11347
    if (authIn == NULL && authInSz > 0)
11348
        return BAD_FUNC_ARG;
11349
11350
    /* sanity check on tag size */
11351
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
11352
        return BAD_FUNC_ARG;
11353
    }
11354
11355
#ifdef WOLF_CRYPTO_CB
11356
    #ifndef WOLF_CRYPTO_CB_FIND
11357
    if (aes->devId != INVALID_DEVID)
11358
    #endif
11359
    {
11360
        int crypto_cb_ret =
11361
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
11362
            authTag, authTagSz, authIn, authInSz);
11363
        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11364
            return crypto_cb_ret;
11365
        /* fall-through when unavailable */
11366
    }
11367
#endif
11368
11369
    o = out;
11370
    oSz = inSz;
11371
    XMEMSET(A, 0, sizeof A);
11372
    XMEMCPY(B+1, nonce, nonceSz);
11373
    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
11374
11375
    B[0] = (byte)(lenSz - 1U);
11376
    for (i = 0; i < lenSz; i++)
11377
        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
11378
    B[15] = 1;
11379
11380
#ifdef WOLFSSL_CHECK_MEM_ZERO
11381
    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
11382
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
11383
#endif
11384
11385
    VECTOR_REGISTERS_PUSH;
11386
11387
#ifdef WOLFSSL_AESNI
11388
    if (aes->use_aesni) {
11389
        while (oSz >= WC_AES_BLOCK_SIZE * 4) {
11390
            AesCcmCtrIncSet4(B, lenSz);
11391
11392
            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
11393
                            (int)aes->rounds);
11394
11395
            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
11396
            XMEMCPY(o, A, WC_AES_BLOCK_SIZE * 4);
11397
11398
            oSz -= WC_AES_BLOCK_SIZE * 4;
11399
            in += WC_AES_BLOCK_SIZE * 4;
11400
            o += WC_AES_BLOCK_SIZE * 4;
11401
11402
            AesCcmCtrInc4(B, lenSz);
11403
        }
11404
    }
11405
#endif
11406
11407
    while (oSz >= WC_AES_BLOCK_SIZE) {
11408
        ret = wc_AesEncrypt(aes, B, A);
11409
        if (ret != 0)
11410
            break;
11411
        xorbuf(A, in, WC_AES_BLOCK_SIZE);
11412
        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
11413
        AesCcmCtrInc(B, lenSz);
11414
        oSz -= WC_AES_BLOCK_SIZE;
11415
        in += WC_AES_BLOCK_SIZE;
11416
        o += WC_AES_BLOCK_SIZE;
11417
    }
11418
11419
    if ((ret == 0) && (inSz > 0))
11420
        ret = wc_AesEncrypt(aes, B, A);
11421
11422
    if ((ret == 0) && (inSz > 0)) {
11423
        xorbuf(A, in, oSz);
11424
        XMEMCPY(o, A, oSz);
11425
        for (i = 0; i < lenSz; i++)
11426
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
11427
        ret = wc_AesEncrypt(aes, B, A);
11428
    }
11429
11430
    if (ret == 0) {
11431
        o = out;
11432
        oSz = inSz;
11433
11434
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
11435
                      + (8 * (((byte)authTagSz - 2) / 2))
11436
                      + (lenSz - 1));
11437
        for (i = 0; i < lenSz; i++) {
11438
            if (mask && i >= wordSz)
11439
                mask = 0x00;
11440
            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
11441
        }
11442
11443
        ret = wc_AesEncrypt(aes, B, A);
11444
    }
11445
11446
    if (ret == 0) {
11447
        if (authInSz > 0)
11448
            ret = roll_auth(aes, authIn, authInSz, A);
11449
    }
11450
    if ((ret == 0) && (inSz > 0))
11451
        ret = roll_x(aes, o, oSz, A);
11452
11453
    if (ret == 0) {
11454
        B[0] = (byte)(lenSz - 1U);
11455
        for (i = 0; i < lenSz; i++)
11456
            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
11457
        ret = wc_AesEncrypt(aes, B, B);
11458
    }
11459
11460
    if (ret == 0)
11461
        xorbuf(A, B, authTagSz);
11462
11463
    if (ret == 0) {
11464
        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
11465
            /* If the authTag check fails, don't keep the decrypted data.
11466
             * Unfortunately, you need the decrypted data to calculate the
11467
             * check value. */
11468
            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
11469
                        defined(ACVP_VECTOR_TESTING)
11470
            WOLFSSL_MSG("Preserve output for vector responses");
11471
            #else
11472
            if (inSz > 0)
11473
                XMEMSET(out, 0, inSz);
11474
            #endif
11475
            ret = AES_CCM_AUTH_E;
11476
        }
11477
    }
11478
11479
    ForceZero(A, sizeof(A));
11480
    ForceZero(B, sizeof(B));
11481
    o = NULL;
11482
11483
#ifdef WOLFSSL_CHECK_MEM_ZERO
11484
    wc_MemZero_Check(A, sizeof(A));
11485
    wc_MemZero_Check(B, sizeof(B));
11486
#endif
11487
11488
    VECTOR_REGISTERS_POP;
11489
11490
    return ret;
11491
}
11492
11493
#endif /* HAVE_AES_DECRYPT */
11494
#endif /* software CCM */
11495
11496
/* abstract functions that call lower level AESCCM functions */
11497
#ifndef WC_NO_RNG
11498
11499
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
11500
{
11501
    int ret = 0;
11502
11503
    if (aes == NULL || nonce == NULL ||
11504
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
11505
11506
        ret = BAD_FUNC_ARG;
11507
    }
11508
11509
    if (ret == 0) {
11510
        XMEMCPY(aes->reg, nonce, nonceSz);
11511
        aes->nonceSz = nonceSz;
11512
11513
        /* Invocation counter should be 2^61 */
11514
        aes->invokeCtr[0] = 0;
11515
        aes->invokeCtr[1] = 0xE0000000;
11516
    }
11517
11518
    return ret;
11519
}
11520
11521
11522
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
11523
                        byte* ivOut, word32 ivOutSz,
11524
                        byte* authTag, word32 authTagSz,
11525
                        const byte* authIn, word32 authInSz)
11526
{
11527
    int ret = 0;
11528
11529
    if (aes == NULL || out == NULL ||
11530
        (in == NULL && sz != 0) ||
11531
        ivOut == NULL ||
11532
        (authIn == NULL && authInSz != 0) ||
11533
        (ivOutSz != aes->nonceSz)) {
11534
11535
        ret = BAD_FUNC_ARG;
11536
    }
11537
11538
    if (ret == 0) {
11539
        aes->invokeCtr[0]++;
11540
        if (aes->invokeCtr[0] == 0) {
11541
            aes->invokeCtr[1]++;
11542
            if (aes->invokeCtr[1] == 0)
11543
                ret = AES_CCM_OVERFLOW_E;
11544
        }
11545
    }
11546
11547
    if (ret == 0) {
11548
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
11549
                               (byte*)aes->reg, aes->nonceSz,
11550
                               authTag, authTagSz,
11551
                               authIn, authInSz);
11552
        if (ret == 0) {
11553
            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
11554
            IncCtr((byte*)aes->reg, aes->nonceSz);
11555
        }
11556
    }
11557
11558
    return ret;
11559
}
11560
11561
#endif /* WC_NO_RNG */
11562
11563
#endif /* HAVE_AESCCM */
11564
11565
#ifndef WC_NO_CONSTRUCTORS
11566
Aes* wc_AesNew(void* heap, int devId, int *result_code)
11567
0
{
11568
0
    int ret;
11569
0
    Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
11570
0
    if (aes == NULL) {
11571
0
        ret = MEMORY_E;
11572
0
    }
11573
0
    else {
11574
0
        ret = wc_AesInit(aes, heap, devId);
11575
0
        if (ret != 0) {
11576
0
            XFREE(aes, heap, DYNAMIC_TYPE_AES);
11577
0
            aes = NULL;
11578
0
        }
11579
0
    }
11580
11581
0
    if (result_code != NULL)
11582
0
        *result_code = ret;
11583
11584
0
    return aes;
11585
0
}
11586
11587
int wc_AesDelete(Aes *aes, Aes** aes_p)
11588
0
{
11589
0
    if (aes == NULL)
11590
0
        return BAD_FUNC_ARG;
11591
0
    wc_AesFree(aes);
11592
0
    XFREE(aes, aes->heap, DYNAMIC_TYPE_AES);
11593
0
    if (aes_p != NULL)
11594
0
        *aes_p = NULL;
11595
0
    return 0;
11596
0
}
11597
#endif /* !WC_NO_CONSTRUCTORS */
11598
11599
/* Initialize Aes */
11600
int wc_AesInit(Aes* aes, void* heap, int devId)
11601
0
{
11602
0
    int ret = 0;
11603
11604
0
    if (aes == NULL)
11605
0
        return BAD_FUNC_ARG;
11606
11607
0
    XMEMSET(aes, 0, sizeof(*aes));
11608
11609
0
    aes->heap = heap;
11610
11611
#ifdef WOLF_CRYPTO_CB
11612
    aes->devId = devId;
11613
#else
11614
0
    (void)devId;
11615
0
#endif
11616
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
11617
    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
11618
                                                        aes->heap, devId);
11619
#endif /* WOLFSSL_ASYNC_CRYPT */
11620
11621
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
11622
    aes->alFd = WC_SOCK_NOTSET;
11623
    aes->rdFd = WC_SOCK_NOTSET;
11624
#endif
11625
#if defined(WOLFSSL_DEVCRYPTO) && \
11626
   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
11627
    aes->ctx.cfd = -1;
11628
#endif
11629
#if defined(WOLFSSL_IMXRT_DCP)
11630
    DCPAesInit(aes);
11631
#endif
11632
11633
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
11634
    ret = wc_psa_aes_init(aes);
11635
#endif
11636
11637
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
11638
    if (ret == 0)
11639
        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
11640
#endif
11641
11642
0
    return ret;
11643
0
}
11644
11645
#ifdef WOLF_PRIVATE_KEY_ID
11646
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
11647
{
11648
    int ret = 0;
11649
11650
    if (aes == NULL)
11651
        ret = BAD_FUNC_ARG;
11652
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
11653
        ret = BUFFER_E;
11654
11655
    if (ret == 0)
11656
        ret = wc_AesInit(aes, heap, devId);
11657
    if (ret == 0) {
11658
        XMEMCPY(aes->id, id, (size_t)len);
11659
        aes->idLen = len;
11660
        aes->labelLen = 0;
11661
    }
11662
11663
    return ret;
11664
}
11665
11666
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
11667
{
11668
    int ret = 0;
11669
    size_t labelLen = 0;
11670
11671
    if (aes == NULL || label == NULL)
11672
        ret = BAD_FUNC_ARG;
11673
    if (ret == 0) {
11674
        labelLen = XSTRLEN(label);
11675
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
11676
            ret = BUFFER_E;
11677
    }
11678
11679
    if (ret == 0)
11680
        ret = wc_AesInit(aes, heap, devId);
11681
    if (ret == 0) {
11682
        XMEMCPY(aes->label, label, labelLen);
11683
        aes->labelLen = (int)labelLen;
11684
        aes->idLen = 0;
11685
    }
11686
11687
    return ret;
11688
}
11689
#endif
11690
11691
/* Free Aes resources */
11692
void wc_AesFree(Aes* aes)
11693
0
{
11694
0
    if (aes == NULL) {
11695
0
        return;
11696
0
    }
11697
11698
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
11699
    (void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
11700
#endif
11701
11702
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
11703
    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
11704
#endif /* WOLFSSL_ASYNC_CRYPT */
11705
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
11706
    if (aes->rdFd > 0) { /* negative is error case */
11707
        close(aes->rdFd);
11708
        aes->rdFd = WC_SOCK_NOTSET;
11709
    }
11710
    if (aes->alFd > 0) {
11711
        close(aes->alFd);
11712
        aes->alFd = WC_SOCK_NOTSET;
11713
    }
11714
#endif /* WOLFSSL_AFALG */
11715
#ifdef WOLFSSL_KCAPI_AES
11716
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
11717
    if (aes->init == 1) {
11718
        kcapi_cipher_destroy(aes->handle);
11719
    }
11720
    aes->init = 0;
11721
    aes->handle = NULL;
11722
#endif
11723
#if defined(WOLFSSL_DEVCRYPTO) && \
11724
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
11725
    wc_DevCryptoFree(&aes->ctx);
11726
#endif
11727
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
11728
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
11729
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
11730
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
11731
#endif
11732
#if defined(WOLFSSL_IMXRT_DCP)
11733
    DCPAesFree(aes);
11734
#endif
11735
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
11736
    !defined(WOLFSSL_AESNI)
11737
    if (aes->streamData != NULL) {
11738
        ForceZero(aes->streamData, aes->streamData_sz);
11739
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
11740
        aes->streamData = NULL;
11741
    }
11742
#endif
11743
11744
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
11745
    if (aes->useSWCrypt == 0) {
11746
        se050_aes_free(aes);
11747
    }
11748
#endif
11749
11750
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
11751
    wc_psa_aes_free(aes);
11752
#endif
11753
11754
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11755
    wc_MAXQ10XX_AesFree(aes);
11756
#endif
11757
11758
#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
11759
    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
11760
    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
11761
    wc_fspsm_Aesfree(aes);
11762
#endif
11763
11764
0
    ForceZero(aes, sizeof(Aes));
11765
11766
#ifdef WOLFSSL_CHECK_MEM_ZERO
11767
    wc_MemZero_Check(aes, sizeof(Aes));
11768
#endif
11769
0
}
11770
11771
int wc_AesGetKeySize(Aes* aes, word32* keySize)
11772
0
{
11773
0
    int ret = 0;
11774
11775
0
    if (aes == NULL || keySize == NULL) {
11776
0
        return BAD_FUNC_ARG;
11777
0
    }
11778
11779
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
11780
    return wc_psa_aes_get_key_size(aes, keySize);
11781
#endif
11782
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
11783
    *keySize = aes->ctx.key.keySize;
11784
    return ret;
11785
#endif
11786
0
    switch (aes->rounds) {
11787
0
#ifdef WOLFSSL_AES_128
11788
0
    case 10:
11789
0
        *keySize = 16;
11790
0
        break;
11791
0
#endif
11792
0
#ifdef WOLFSSL_AES_192
11793
0
    case 12:
11794
0
        *keySize = 24;
11795
0
        break;
11796
0
#endif
11797
0
#ifdef WOLFSSL_AES_256
11798
0
    case 14:
11799
0
        *keySize = 32;
11800
0
        break;
11801
0
#endif
11802
0
    default:
11803
0
        *keySize = 0;
11804
0
        ret = BAD_FUNC_ARG;
11805
0
    }
11806
11807
0
    return ret;
11808
0
}
11809
11810
#endif /* !WOLFSSL_TI_CRYPT */
11811
11812
/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
11813
 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
11814
 */
11815
#ifndef VECTOR_REGISTERS_PUSH
11816
    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
11817
#endif
11818
#ifndef VECTOR_REGISTERS_POP
11819
    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
11820
#endif
11821
11822
#ifdef HAVE_AES_ECB
11823
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
11824
        !defined(WOLFSSL_QNX_CAAM)
11825
    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
11826
11827
#elif defined(WOLFSSL_AFALG)
11828
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
11829
11830
#elif defined(WOLFSSL_DEVCRYPTO_AES)
11831
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
11832
11833
#elif defined(WOLFSSL_RISCV_ASM)
11834
    /* implemented in wolfcrypt/src/port/riscv/riscv-64-aes.c */
11835
11836
#elif defined(MAX3266X_AES)
11837
11838
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11839
{
11840
    int status;
11841
    word32 keySize;
11842
11843
    if ((in == NULL) || (out == NULL) || (aes == NULL))
11844
        return BAD_FUNC_ARG;
11845
11846
    status = wc_AesGetKeySize(aes, &keySize);
11847
    if (status != 0) {
11848
        return status;
11849
    }
11850
11851
    status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key,
11852
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
11853
11854
    return status;
11855
}
11856
11857
#ifdef HAVE_AES_DECRYPT
11858
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11859
{
11860
    int status;
11861
    word32 keySize;
11862
11863
    if ((in == NULL) || (out == NULL) || (aes == NULL))
11864
        return BAD_FUNC_ARG;
11865
11866
    status = wc_AesGetKeySize(aes, &keySize);
11867
    if (status != 0) {
11868
        return status;
11869
    }
11870
11871
    status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key,
11872
                                        MXC_TPU_MODE_ECB, sz, out, keySize);
11873
11874
    return status;
11875
}
11876
#endif /* HAVE_AES_DECRYPT */
11877
11878
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
11879
11880
/* Software AES - ECB */
11881
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11882
{
11883
    if ((in == NULL) || (out == NULL) || (aes == NULL))
11884
        return BAD_FUNC_ARG;
11885
11886
    return AES_ECB_encrypt(aes, in, out, sz);
11887
}
11888
11889
11890
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11891
{
11892
    if ((in == NULL) || (out == NULL) || (aes == NULL))
11893
        return BAD_FUNC_ARG;
11894
11895
    return AES_ECB_decrypt(aes, in, out, sz);
11896
}
11897
11898
#else
11899
11900
/* Software AES - ECB */
11901
static WARN_UNUSED_RESULT int _AesEcbEncrypt(
11902
    Aes* aes, byte* out, const byte* in, word32 sz)
11903
{
11904
    int ret = 0;
11905
11906
#ifdef WOLF_CRYPTO_CB
11907
    #ifndef WOLF_CRYPTO_CB_FIND
11908
    if (aes->devId != INVALID_DEVID)
11909
    #endif
11910
    {
11911
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
11912
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11913
            return ret;
11914
        ret = 0;
11915
        /* fall-through when unavailable */
11916
    }
11917
#endif
11918
#ifdef WOLFSSL_IMXRT_DCP
11919
    if (aes->keylen == 16)
11920
        return DCPAesEcbEncrypt(aes, out, in, sz);
11921
#endif
11922
11923
    VECTOR_REGISTERS_PUSH;
11924
11925
#ifdef WOLFSSL_AESNI
11926
    if (aes->use_aesni) {
11927
        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
11928
    }
11929
    else
11930
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11931
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11932
    if (aes->use_aes_hw_crypto) {
11933
        word32 i;
11934
11935
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
11936
            AES_encrypt_AARCH64(in, out, (byte*)aes->key, (int)aes->rounds);
11937
            in += WC_AES_BLOCK_SIZE;
11938
            out += WC_AES_BLOCK_SIZE;
11939
        }
11940
    }
11941
    else
11942
#endif
11943
    {
11944
#ifdef NEED_AES_TABLES
11945
        AesEncryptBlocks_C(aes, in, out, sz);
11946
#else
11947
        word32 i;
11948
11949
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
11950
            ret = wc_AesEncryptDirect(aes, out, in);
11951
            if (ret != 0)
11952
                break;
11953
            in += WC_AES_BLOCK_SIZE;
11954
            out += WC_AES_BLOCK_SIZE;
11955
        }
11956
#endif
11957
    }
11958
11959
    VECTOR_REGISTERS_POP;
11960
11961
    return ret;
11962
}
11963
11964
#ifdef HAVE_AES_DECRYPT
11965
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
11966
    Aes* aes, byte* out, const byte* in, word32 sz)
11967
{
11968
    int ret = 0;
11969
11970
#ifdef WOLF_CRYPTO_CB
11971
    #ifndef WOLF_CRYPTO_CB_FIND
11972
    if (aes->devId != INVALID_DEVID)
11973
    #endif
11974
    {
11975
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
11976
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11977
            return ret;
11978
        ret = 0;
11979
        /* fall-through when unavailable */
11980
    }
11981
#endif
11982
#ifdef WOLFSSL_IMXRT_DCP
11983
    if (aes->keylen == 16)
11984
        return DCPAesEcbDecrypt(aes, out, in, sz);
11985
#endif
11986
11987
    VECTOR_REGISTERS_PUSH;
11988
11989
#ifdef WOLFSSL_AESNI
11990
    if (aes->use_aesni) {
11991
        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
11992
    }
11993
    else
11994
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11995
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11996
    if (aes->use_aes_hw_crypto) {
11997
        word32 i;
11998
11999
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
12000
            AES_decrypt_AARCH64(in, out, (byte*)aes->key, (int)aes->rounds);
12001
            in += WC_AES_BLOCK_SIZE;
12002
            out += WC_AES_BLOCK_SIZE;
12003
        }
12004
    }
12005
    else
12006
#endif
12007
    {
12008
#ifdef NEED_AES_TABLES
12009
        AesDecryptBlocks_C(aes, in, out, sz);
12010
#else
12011
        word32 i;
12012
12013
        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
12014
            ret = wc_AesDecryptDirect(aes, out, in);
12015
            if (ret != 0)
12016
                break;
12017
            in += WC_AES_BLOCK_SIZE;
12018
            out += WC_AES_BLOCK_SIZE;
12019
        }
12020
#endif
12021
    }
12022
12023
    VECTOR_REGISTERS_POP;
12024
12025
    return ret;
12026
}
12027
#endif
12028
12029
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12030
{
12031
    if ((in == NULL) || (out == NULL) || (aes == NULL))
12032
      return BAD_FUNC_ARG;
12033
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
12034
        return BAD_LENGTH_E;
12035
    }
12036
12037
    return _AesEcbEncrypt(aes, out, in, sz);
12038
}
12039
12040
#ifdef HAVE_AES_DECRYPT
12041
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12042
{
12043
    if ((in == NULL) || (out == NULL) || (aes == NULL))
12044
      return BAD_FUNC_ARG;
12045
    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
12046
        return BAD_LENGTH_E;
12047
    }
12048
12049
    return _AesEcbDecrypt(aes, out, in, sz);
12050
}
12051
#endif /* HAVE_AES_DECRYPT */
12052
#endif
12053
#endif /* HAVE_AES_ECB */
12054
12055
#if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_OFB)
12056
/* Feedback AES mode
12057
 *
12058
 * aes structure holding key to use for encryption
12059
 * out buffer to hold result of encryption (must be at least as large as input
12060
 *     buffer)
12061
 * in  buffer to encrypt
12062
 * sz  size of input buffer
12063
 * mode flag to specify AES mode
12064
 *
12065
 * returns 0 on success and negative error values on failure
12066
 */
12067
/* Software AES - CFB Encrypt */
12068
static WARN_UNUSED_RESULT int wc_AesFeedbackEncrypt(
12069
    Aes* aes, byte* out, const byte* in, word32 sz, byte mode)
12070
{
12071
    byte*  tmp = NULL;
12072
    int ret = 0;
12073
    word32 processed;
12074
12075
    if (aes == NULL || out == NULL || in == NULL) {
12076
        return BAD_FUNC_ARG;
12077
    }
12078
12079
    /* consume any unused bytes left in aes->tmp */
12080
    processed = min(aes->left, sz);
12081
    xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left, processed);
12082
#ifdef WOLFSSL_AES_CFB
12083
    if (mode == AES_CFB_MODE) {
12084
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out, processed);
12085
    }
12086
#endif
12087
    aes->left -= processed;
12088
    out += processed;
12089
    in += processed;
12090
    sz -= processed;
12091
12092
    VECTOR_REGISTERS_PUSH;
12093
12094
    while (sz >= WC_AES_BLOCK_SIZE) {
12095
        /* Using aes->tmp here for inline case i.e. in=out */
12096
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
12097
        if (ret != 0)
12098
            break;
12099
    #ifdef WOLFSSL_AES_OFB
12100
        if (mode == AES_OFB_MODE) {
12101
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
12102
        }
12103
    #endif
12104
        xorbuf((byte*)aes->tmp, in, WC_AES_BLOCK_SIZE);
12105
    #ifdef WOLFSSL_AES_CFB
12106
        if (mode == AES_CFB_MODE) {
12107
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
12108
        }
12109
    #endif
12110
        XMEMCPY(out, aes->tmp, WC_AES_BLOCK_SIZE);
12111
        out += WC_AES_BLOCK_SIZE;
12112
        in  += WC_AES_BLOCK_SIZE;
12113
        sz  -= WC_AES_BLOCK_SIZE;
12114
        aes->left = 0;
12115
    }
12116
12117
    /* encrypt left over data */
12118
    if ((ret == 0) && sz) {
12119
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
12120
    }
12121
    if ((ret == 0) && sz) {
12122
        aes->left = WC_AES_BLOCK_SIZE;
12123
        tmp = (byte*)aes->tmp;
12124
    #ifdef WOLFSSL_AES_OFB
12125
        if (mode == AES_OFB_MODE) {
12126
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
12127
        }
12128
    #endif
12129
12130
        xorbufout(out, in, tmp, sz);
12131
    #ifdef WOLFSSL_AES_CFB
12132
        if (mode == AES_CFB_MODE) {
12133
            XMEMCPY(aes->reg, out, sz);
12134
        }
12135
    #endif
12136
        aes->left -= sz;
12137
    }
12138
12139
    VECTOR_REGISTERS_POP;
12140
12141
    return ret;
12142
}
12143
12144
12145
#ifdef HAVE_AES_DECRYPT
12146
/* CFB 128
12147
 *
12148
 * aes structure holding key to use for decryption
12149
 * out buffer to hold result of decryption (must be at least as large as input
12150
 *     buffer)
12151
 * in  buffer to decrypt
12152
 * sz  size of input buffer
12153
 *
12154
 * returns 0 on success and negative error values on failure
12155
 */
12156
/* Software AES - CFB Decrypt */
12157
static WARN_UNUSED_RESULT int wc_AesFeedbackDecrypt(
12158
    Aes* aes, byte* out, const byte* in, word32 sz, byte mode)
12159
{
12160
    int ret = 0;
12161
    word32 processed;
12162
12163
    if (aes == NULL || out == NULL || in == NULL) {
12164
        return BAD_FUNC_ARG;
12165
    }
12166
12167
    #ifdef WOLFSSL_AES_CFB
12168
    /* check if more input needs copied over to aes->reg */
12169
    if (aes->left && sz && mode == AES_CFB_MODE) {
12170
        word32 size = min(aes->left, sz);
12171
        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, size);
12172
    }
12173
    #endif
12174
12175
    /* consume any unused bytes left in aes->tmp */
12176
    processed = min(aes->left, sz);
12177
    xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
12178
        processed);
12179
    aes->left -= processed;
12180
    out += processed;
12181
    in += processed;
12182
    sz -= processed;
12183
12184
    VECTOR_REGISTERS_PUSH;
12185
12186
    while (sz > WC_AES_BLOCK_SIZE) {
12187
        /* Using aes->tmp here for inline case i.e. in=out */
12188
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
12189
        if (ret != 0)
12190
            break;
12191
    #ifdef WOLFSSL_AES_OFB
12192
        if (mode == AES_OFB_MODE) {
12193
            XMEMCPY((byte*)aes->reg, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
12194
        }
12195
    #endif
12196
        xorbuf((byte*)aes->tmp, in, WC_AES_BLOCK_SIZE);
12197
    #ifdef WOLFSSL_AES_CFB
12198
        if (mode == AES_CFB_MODE) {
12199
            XMEMCPY(aes->reg, in, WC_AES_BLOCK_SIZE);
12200
        }
12201
    #endif
12202
        XMEMCPY(out, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
12203
        out += WC_AES_BLOCK_SIZE;
12204
        in  += WC_AES_BLOCK_SIZE;
12205
        sz  -= WC_AES_BLOCK_SIZE;
12206
        aes->left = 0;
12207
    }
12208
12209
    /* decrypt left over data */
12210
    if ((ret == 0) && sz) {
12211
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
12212
    }
12213
    if ((ret == 0) && sz) {
12214
    #ifdef WOLFSSL_AES_CFB
12215
        if (mode == AES_CFB_MODE) {
12216
            XMEMCPY(aes->reg, in, sz);
12217
        }
12218
    #endif
12219
    #ifdef WOLFSSL_AES_OFB
12220
        if (mode == AES_OFB_MODE) {
12221
            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
12222
        }
12223
    #endif
12224
12225
        aes->left = WC_AES_BLOCK_SIZE - sz;
12226
        xorbufout(out, in, aes->tmp, sz);
12227
    }
12228
12229
    VECTOR_REGISTERS_POP;
12230
12231
    return ret;
12232
}
12233
#endif /* HAVE_AES_DECRYPT */
12234
#endif /* WOLFSSL_AES_CFB */
12235
12236
#ifdef WOLFSSL_AES_CFB
12237
/* CFB 128
12238
 *
12239
 * aes structure holding key to use for encryption
12240
 * out buffer to hold result of encryption (must be at least as large as input
12241
 *     buffer)
12242
 * in  buffer to encrypt
12243
 * sz  size of input buffer
12244
 *
12245
 * returns 0 on success and negative error values on failure
12246
 */
12247
/* Software AES - CFB Encrypt */
12248
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12249
{
12250
    return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_CFB_MODE);
12251
}
12252
12253
12254
#ifdef HAVE_AES_DECRYPT
12255
/* CFB 128
12256
 *
12257
 * aes structure holding key to use for decryption
12258
 * out buffer to hold result of decryption (must be at least as large as input
12259
 *     buffer)
12260
 * in  buffer to decrypt
12261
 * sz  size of input buffer
12262
 *
12263
 * returns 0 on success and negative error values on failure
12264
 */
12265
/* Software AES - CFB Decrypt */
12266
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12267
{
12268
    return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_CFB_MODE);
12269
}
12270
#endif /* HAVE_AES_DECRYPT */
12271
12272
#ifndef WOLFSSL_NO_AES_CFB_1_8
12273
/* shift the whole WC_AES_BLOCK_SIZE array left by 8 or 1 bits */
12274
static void shiftLeftArray(byte* ary, byte shift)
12275
{
12276
    int i;
12277
12278
    if (shift == WOLFSSL_BIT_SIZE) {
12279
        /* shifting over by 8 bits */
12280
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
12281
            ary[i] = ary[i+1];
12282
        }
12283
        ary[i] = 0;
12284
    }
12285
    else {
12286
        /* shifting over by 7 or less bits */
12287
        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
12288
            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
12289
            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
12290
            ary[i] = (byte)((ary[i] << shift) + carry);
12291
        }
12292
        ary[i] = (byte)(ary[i] << shift);
12293
    }
12294
}
12295
12296
12297
/* returns 0 on success and negative values on failure */
12298
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
12299
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
12300
{
12301
    byte *pt;
12302
    int ret = 0;
12303
12304
    if (aes == NULL || out == NULL || in == NULL) {
12305
        return BAD_FUNC_ARG;
12306
    }
12307
12308
    if (sz == 0) {
12309
        return 0;
12310
    }
12311
12312
    VECTOR_REGISTERS_PUSH;
12313
12314
    while (sz > 0) {
12315
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
12316
        if (ret != 0)
12317
            break;
12318
        if (dir == AES_DECRYPTION) {
12319
            pt = (byte*)aes->reg;
12320
12321
            /* LSB + CAT */
12322
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
12323
            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
12324
        }
12325
12326
        /* MSB + XOR */
12327
    #ifdef BIG_ENDIAN_ORDER
12328
        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
12329
    #endif
12330
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
12331
        if (dir == AES_ENCRYPTION) {
12332
            pt = (byte*)aes->reg;
12333
12334
            /* LSB + CAT */
12335
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
12336
            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
12337
        }
12338
12339
        out += 1;
12340
        in  += 1;
12341
        sz  -= 1;
12342
    }
12343
12344
    VECTOR_REGISTERS_POP;
12345
12346
    return ret;
12347
}
12348
12349
12350
/* returns 0 on success and negative values on failure */
12351
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
12352
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
12353
{
12354
    byte tmp;
12355
    byte cur = 0; /* hold current work in order to handle inline in=out */
12356
    byte* pt;
12357
    int bit = 7;
12358
    int ret = 0;
12359
12360
    if (aes == NULL || out == NULL || in == NULL) {
12361
        return BAD_FUNC_ARG;
12362
    }
12363
12364
    if (sz == 0) {
12365
        return 0;
12366
    }
12367
12368
    VECTOR_REGISTERS_PUSH;
12369
12370
    while (sz > 0) {
12371
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
12372
        if (ret != 0)
12373
            break;
12374
        if (dir == AES_DECRYPTION) {
12375
            pt = (byte*)aes->reg;
12376
12377
            /* LSB + CAT */
12378
            tmp = (byte)((0X01U << bit) & in[0]);
12379
            tmp = (byte)(tmp >> bit);
12380
            tmp &= 0x01;
12381
            shiftLeftArray((byte*)aes->reg, 1);
12382
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
12383
        }
12384
12385
        /* MSB  + XOR */
12386
        tmp = (byte)((0X01U << bit) & in[0]);
12387
        pt = (byte*)aes->tmp;
12388
        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
12389
        tmp &= 0x01;
12390
        cur = (byte)(cur | (tmp << bit));
12391
12392
12393
        if (dir == AES_ENCRYPTION) {
12394
            pt = (byte*)aes->reg;
12395
12396
            /* LSB + CAT */
12397
            shiftLeftArray((byte*)aes->reg, 1);
12398
            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
12399
        }
12400
12401
        bit--;
12402
        if (bit < 0) {
12403
            out[0] = cur;
12404
            out += 1;
12405
            in  += 1;
12406
            sz  -= 1;
12407
            bit = 7U;
12408
            cur = 0;
12409
        }
12410
        else {
12411
            sz -= 1;
12412
        }
12413
    }
12414
12415
    if (ret == 0) {
12416
        if (bit >= 0 && bit < 7) {
12417
            out[0] = cur;
12418
        }
12419
    }
12420
12421
    VECTOR_REGISTERS_POP;
12422
12423
    return ret;
12424
}
12425
12426
12427
/* CFB 1
12428
 *
12429
 * aes structure holding key to use for encryption
12430
 * out buffer to hold result of encryption (must be at least as large as input
12431
 *     buffer)
12432
 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
12433
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
12434
 *
12435
 * returns 0 on success and negative values on failure
12436
 */
12437
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12438
{
12439
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
12440
}
12441
12442
12443
/* CFB 8
12444
 *
12445
 * aes structure holding key to use for encryption
12446
 * out buffer to hold result of encryption (must be at least as large as input
12447
 *     buffer)
12448
 * in  buffer to encrypt
12449
 * sz  size of input buffer
12450
 *
12451
 * returns 0 on success and negative values on failure
12452
 */
12453
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12454
{
12455
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
12456
}
12457
#ifdef HAVE_AES_DECRYPT
12458
12459
/* CFB 1
12460
 *
12461
 * aes structure holding key to use for encryption
12462
 * out buffer to hold result of encryption (must be at least as large as input
12463
 *     buffer)
12464
 * in  buffer to encrypt
12465
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
12466
 *
12467
 * returns 0 on success and negative values on failure
12468
 */
12469
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12470
{
12471
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
12472
}
12473
12474
12475
/* CFB 8
12476
 *
12477
 * aes structure holding key to use for encryption
12478
 * out buffer to hold result of encryption (must be at least as large as input
12479
 *     buffer)
12480
 * in  buffer to encrypt
12481
 * sz  size of input buffer
12482
 *
12483
 * returns 0 on success and negative values on failure
12484
 */
12485
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12486
{
12487
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
12488
}
12489
#endif /* HAVE_AES_DECRYPT */
12490
#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
12491
#endif /* WOLFSSL_AES_CFB */
12492
12493
#ifdef WOLFSSL_AES_OFB
12494
/* OFB
12495
 *
12496
 * aes structure holding key to use for encryption
12497
 * out buffer to hold result of encryption (must be at least as large as input
12498
 *     buffer)
12499
 * in  buffer to encrypt
12500
 * sz  size of input buffer
12501
 *
12502
 * returns 0 on success and negative error values on failure
12503
 */
12504
/* Software AES - CFB Encrypt */
12505
int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12506
{
12507
    return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_OFB_MODE);
12508
}
12509
12510
12511
#ifdef HAVE_AES_DECRYPT
12512
/* OFB
12513
 *
12514
 * aes structure holding key to use for decryption
12515
 * out buffer to hold result of decryption (must be at least as large as input
12516
 *     buffer)
12517
 * in  buffer to decrypt
12518
 * sz  size of input buffer
12519
 *
12520
 * returns 0 on success and negative error values on failure
12521
 */
12522
/* Software AES - OFB Decrypt */
12523
int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
12524
{
12525
    return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_OFB_MODE);
12526
}
12527
#endif /* HAVE_AES_DECRYPT */
12528
#endif /* WOLFSSL_AES_OFB */
12529
12530
12531
#ifdef HAVE_AES_KEYWRAP
12532
12533
/* Initialize key wrap counter with value */
12534
static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
12535
{
12536
    word32 i;
12537
    word32 bytes;
12538
12539
    bytes = sizeof(word32);
12540
    for (i = 0; i < sizeof(word32); i++) {
12541
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
12542
        bytes--;
12543
    }
12544
}
12545
12546
/* Increment key wrap counter */
12547
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
12548
{
12549
    int i;
12550
12551
    /* in network byte order so start at end and work back */
12552
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
12553
        if (++inOutCtr[i])  /* we're done unless we overflow */
12554
            return;
12555
    }
12556
}
12557
12558
/* Decrement key wrap counter */
12559
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
12560
{
12561
    int i;
12562
12563
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
12564
        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
12565
            return;
12566
    }
12567
}
12568
12569
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
12570
        word32 outSz, const byte* iv)
12571
{
12572
    word32 i;
12573
    byte* r;
12574
    int j;
12575
    int ret = 0;
12576
12577
    byte t[KEYWRAP_BLOCK_SIZE];
12578
    byte tmp[WC_AES_BLOCK_SIZE];
12579
12580
    /* n must be at least 2 64-bit blocks, output size is (n + 1) 8 bytes (64-bit) */
12581
    if (aes == NULL || in  == NULL || inSz < 2*KEYWRAP_BLOCK_SIZE ||
12582
        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
12583
        return BAD_FUNC_ARG;
12584
12585
    /* input must be multiple of 64-bits */
12586
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
12587
        return BAD_FUNC_ARG;
12588
12589
    r = out + 8;
12590
    XMEMCPY(r, in, inSz);
12591
    XMEMSET(t, 0, sizeof(t));
12592
12593
    /* user IV is optional */
12594
    if (iv == NULL) {
12595
        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
12596
    } else {
12597
        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
12598
    }
12599
12600
    VECTOR_REGISTERS_PUSH;
12601
12602
    for (j = 0; j <= 5; j++) {
12603
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
12604
            /* load R[i] */
12605
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
12606
12607
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
12608
            if (ret != 0)
12609
                break;
12610
12611
            /* calculate new A */
12612
            IncrementKeyWrapCounter(t);
12613
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
12614
12615
            /* save R[i] */
12616
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
12617
            r += KEYWRAP_BLOCK_SIZE;
12618
        }
12619
        if (ret != 0)
12620
            break;
12621
        r = out + KEYWRAP_BLOCK_SIZE;
12622
    }
12623
12624
    VECTOR_REGISTERS_POP;
12625
12626
    if (ret != 0)
12627
        return ret;
12628
12629
    /* C[0] = A */
12630
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
12631
12632
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
12633
}
12634
12635
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
12636
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
12637
                  byte* out, word32 outSz, const byte* iv)
12638
{
12639
#ifdef WOLFSSL_SMALL_STACK
12640
    Aes *aes = NULL;
12641
#else
12642
    Aes aes[1];
12643
#endif
12644
    int ret;
12645
12646
    if (key == NULL)
12647
        return BAD_FUNC_ARG;
12648
12649
#ifdef WOLFSSL_SMALL_STACK
12650
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
12651
                              DYNAMIC_TYPE_AES)) == NULL)
12652
        return MEMORY_E;
12653
#endif
12654
12655
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12656
    if (ret != 0)
12657
        goto out;
12658
12659
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
12660
    if (ret != 0) {
12661
        wc_AesFree(aes);
12662
        goto out;
12663
    }
12664
12665
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
12666
12667
    wc_AesFree(aes);
12668
12669
  out:
12670
#ifdef WOLFSSL_SMALL_STACK
12671
    XFREE(aes, NULL, DYNAMIC_TYPE_AES);
12672
#endif
12673
12674
    return ret;
12675
}
12676
12677
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
12678
        word32 outSz, const byte* iv)
12679
{
12680
    byte* r;
12681
    word32 i, n;
12682
    int j;
12683
    int ret = 0;
12684
12685
    byte t[KEYWRAP_BLOCK_SIZE];
12686
    byte tmp[WC_AES_BLOCK_SIZE];
12687
12688
    const byte* expIv;
12689
    const byte defaultIV[] = {
12690
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
12691
    };
12692
12693
    if (aes == NULL || in == NULL || inSz < 3 * KEYWRAP_BLOCK_SIZE ||
12694
        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
12695
        return BAD_FUNC_ARG;
12696
12697
    /* input must be multiple of 64-bits */
12698
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
12699
        return BAD_FUNC_ARG;
12700
12701
    /* user IV optional */
12702
    if (iv != NULL)
12703
        expIv = iv;
12704
    else
12705
        expIv = defaultIV;
12706
12707
    /* A = C[0], R[i] = C[i] */
12708
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
12709
    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
12710
    XMEMSET(t, 0, sizeof(t));
12711
12712
    VECTOR_REGISTERS_PUSH;
12713
12714
    /* initialize counter to 6n */
12715
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
12716
    InitKeyWrapCounter(t, 6 * n);
12717
12718
    for (j = 5; j >= 0; j--) {
12719
        for (i = n; i >= 1; i--) {
12720
12721
            /* calculate A */
12722
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
12723
            DecrementKeyWrapCounter(t);
12724
12725
            /* load R[i], starting at end of R */
12726
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
12727
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
12728
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
12729
            if (ret != 0)
12730
                break;
12731
12732
            /* save R[i] */
12733
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
12734
        }
12735
        if (ret != 0)
12736
            break;
12737
    }
12738
12739
    VECTOR_REGISTERS_POP;
12740
12741
    if (ret != 0)
12742
        return ret;
12743
12744
    /* verify IV */
12745
    if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
12746
        return BAD_KEYWRAP_IV_E;
12747
12748
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
12749
}
12750
12751
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
12752
                    byte* out, word32 outSz, const byte* iv)
12753
{
12754
#ifdef WOLFSSL_SMALL_STACK
12755
    Aes *aes = NULL;
12756
#else
12757
    Aes aes[1];
12758
#endif
12759
    int ret;
12760
12761
    (void)iv;
12762
12763
    if (key == NULL)
12764
        return BAD_FUNC_ARG;
12765
12766
#ifdef WOLFSSL_SMALL_STACK
12767
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
12768
                              DYNAMIC_TYPE_AES)) == NULL)
12769
        return MEMORY_E;
12770
#endif
12771
12772
12773
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12774
    if (ret != 0)
12775
        goto out;
12776
12777
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
12778
    if (ret != 0) {
12779
        wc_AesFree(aes);
12780
        goto out;
12781
    }
12782
12783
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
12784
12785
    wc_AesFree(aes);
12786
12787
  out:
12788
#ifdef WOLFSSL_SMALL_STACK
12789
    XFREE(aes, NULL, DYNAMIC_TYPE_AES);
12790
#endif
12791
12792
    return ret;
12793
}
12794
12795
#endif /* HAVE_AES_KEYWRAP */
12796
12797
#ifdef WOLFSSL_AES_XTS
12798
12799
/* Galois Field to use */
12800
#define GF_XTS 0x87
12801
12802
/* Set up keys for encryption and/or decryption.
12803
 *
12804
 * aes   buffer holding aes subkeys
12805
 * heap  heap hint to use for memory. Can be NULL
12806
 * devId id to use with async crypto. Can be 0
12807
 *
12808
 * return 0 on success
12809
 */
12810
int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
12811
{
12812
    int    ret = 0;
12813
12814
    if (aes == NULL) {
12815
        return BAD_FUNC_ARG;
12816
    }
12817
12818
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
12819
        return ret;
12820
    }
12821
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
12822
        (void)wc_AesFree(&aes->tweak);
12823
        return ret;
12824
    }
12825
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
12826
    if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) {
12827
        (void)wc_AesFree(&aes->tweak);
12828
        (void)wc_AesFree(&aes->aes);
12829
        return ret;
12830
    }
12831
#endif
12832
12833
    return 0;
12834
}
12835
12836
/* Set up keys for encryption and/or decryption.
12837
 *
12838
 * aes   buffer holding aes subkeys
12839
 * key   AES key for encrypt/decrypt and tweak process (concatenated)
12840
 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
12841
 *       32 for a 16 byte key.
12842
 * dir   direction: AES_ENCRYPTION, AES_DECRYPTION, or
12843
 *       AES_ENCRYPTION_AND_DECRYPTION
12844
 *
12845
 * return 0 on success
12846
 */
12847
int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
12848
{
12849
    word32 keySz;
12850
    int    ret = 0;
12851
12852
    if (aes == NULL || key == NULL) {
12853
        return BAD_FUNC_ARG;
12854
    }
12855
12856
    if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION)
12857
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
12858
        && (dir != AES_ENCRYPTION_AND_DECRYPTION)
12859
#endif
12860
        )
12861
    {
12862
        return BAD_FUNC_ARG;
12863
    }
12864
12865
    if ((len != (AES_128_KEY_SIZE*2)) &&
12866
#ifndef HAVE_FIPS
12867
        /* XTS-384 not allowed by FIPS and can not be treated like
12868
         * RSA-4096 bit keys back in the day, can not vendor affirm
12869
         * the use of 2 concatenated 192-bit keys (XTS-384) */
12870
        (len != (AES_192_KEY_SIZE*2)) &&
12871
#endif
12872
        (len != (AES_256_KEY_SIZE*2)))
12873
    {
12874
        WOLFSSL_MSG("Unsupported key size");
12875
        return WC_KEY_SIZE_E;
12876
    }
12877
12878
    keySz = len/2;
12879
12880
#ifdef HAVE_FIPS
12881
    if (XMEMCMP(key, key + keySz, keySz) == 0) {
12882
        WOLFSSL_MSG("FIPS AES-XTS main and tweak keys must differ");
12883
        return BAD_FUNC_ARG;
12884
    }
12885
#endif
12886
12887
    if (dir == AES_ENCRYPTION
12888
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
12889
        || dir == AES_ENCRYPTION_AND_DECRYPTION
12890
#endif
12891
        )
12892
    {
12893
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
12894
    }
12895
12896
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
12897
    if ((ret == 0) && ((dir == AES_DECRYPTION)
12898
                       || (dir == AES_ENCRYPTION_AND_DECRYPTION)))
12899
        ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION);
12900
#else
12901
    if (dir == AES_DECRYPTION)
12902
        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
12903
#endif
12904
12905
    if (ret == 0)
12906
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
12907
                AES_ENCRYPTION);
12908
12909
#ifdef WOLFSSL_AESNI
12910
    if (ret == 0) {
12911
        /* With WC_C_DYNAMIC_FALLBACK, the main and tweak keys could have
12912
         * conflicting _aesni status, but the AES-XTS asm implementations need
12913
         * them to all be AESNI.  If any aren't, disable AESNI on all.
12914
         */
12915
    #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
12916
        if ((((dir == AES_ENCRYPTION) ||
12917
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
12918
             && (aes->aes.use_aesni != aes->tweak.use_aesni))
12919
            ||
12920
            (((dir == AES_DECRYPTION) ||
12921
              (dir == AES_ENCRYPTION_AND_DECRYPTION))
12922
             && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)))
12923
        {
12924
        #ifdef WC_C_DYNAMIC_FALLBACK
12925
            aes->aes.use_aesni = 0;
12926
            aes->aes_decrypt.use_aesni = 0;
12927
            aes->tweak.use_aesni = 0;
12928
        #else
12929
            ret = SYSLIB_FAILED_E;
12930
        #endif
12931
        }
12932
    #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
12933
        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
12934
        #ifdef WC_C_DYNAMIC_FALLBACK
12935
            aes->aes.use_aesni = 0;
12936
            aes->tweak.use_aesni = 0;
12937
        #else
12938
            ret = SYSLIB_FAILED_E;
12939
        #endif
12940
        }
12941
    #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
12942
    }
12943
#endif /* WOLFSSL_AESNI */
12944
12945
    return ret;
12946
}
12947
12948
/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
12949
 *
12950
 * Note: is up to user to call wc_AesXtsFree when done.
12951
 *
12952
 * return 0 on success
12953
 */
12954
int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
12955
        void* heap, int devId)
12956
{
12957
    int    ret = 0;
12958
12959
    if (aes == NULL || key == NULL) {
12960
        return BAD_FUNC_ARG;
12961
    }
12962
12963
    ret = wc_AesXtsInit(aes, heap, devId);
12964
    if (ret != 0)
12965
        return ret;
12966
12967
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
12968
12969
    if (ret != 0)
12970
        wc_AesXtsFree(aes);
12971
12972
    return ret;
12973
}
12974
12975
12976
/* This is used to free up resources used by Aes structs
12977
 *
12978
 * aes AES keys to free
12979
 *
12980
 * return 0 on success
12981
 */
12982
int wc_AesXtsFree(XtsAes* aes)
12983
{
12984
    if (aes != NULL) {
12985
        wc_AesFree(&aes->aes);
12986
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
12987
        wc_AesFree(&aes->aes_decrypt);
12988
#endif
12989
        wc_AesFree(&aes->tweak);
12990
    }
12991
12992
    return 0;
12993
}
12994
12995
12996
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
12997
 * instead of a byte array. This just converts the word64 to a byte array and
12998
 * calls wc_AesXtsEncrypt.
12999
 *
13000
 * aes    AES keys to use for block encrypt/decrypt
13001
 * out    output buffer to hold cipher text
13002
 * in     input plain text buffer to encrypt
13003
 * sz     size of both out and in buffers
13004
 * sector value to use for tweak
13005
 *
13006
 * returns 0 on success
13007
 */
13008
int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
13009
        word32 sz, word64 sector)
13010
{
13011
    byte* pt;
13012
    byte  i[WC_AES_BLOCK_SIZE];
13013
13014
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
13015
#ifdef BIG_ENDIAN_ORDER
13016
    sector = ByteReverseWord64(sector);
13017
#endif
13018
    pt = (byte*)&sector;
13019
    XMEMCPY(i, pt, sizeof(word64));
13020
13021
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
13022
}
13023
13024
13025
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
13026
 * instead of a byte array. This just converts the word64 to a byte array.
13027
 *
13028
 * aes    AES keys to use for block encrypt/decrypt
13029
 * out    output buffer to hold plain text
13030
 * in     input cipher text buffer to encrypt
13031
 * sz     size of both out and in buffers
13032
 * sector value to use for tweak
13033
 *
13034
 * returns 0 on success
13035
 */
13036
int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
13037
        word64 sector)
13038
{
13039
    byte* pt;
13040
    byte  i[WC_AES_BLOCK_SIZE];
13041
13042
    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
13043
#ifdef BIG_ENDIAN_ORDER
13044
    sector = ByteReverseWord64(sector);
13045
#endif
13046
    pt = (byte*)&sector;
13047
    XMEMCPY(i, pt, sizeof(word64));
13048
13049
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
13050
}
13051
13052
#ifdef WOLFSSL_AESNI
13053
13054
#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
13055
    #define USE_INTEL_SPEEDUP
13056
#endif
13057
13058
#if defined(USE_INTEL_SPEEDUP)
13059
    #define HAVE_INTEL_AVX1
13060
    #define HAVE_INTEL_AVX2
13061
#endif /* USE_INTEL_SPEEDUP */
13062
13063
void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
13064
                     const unsigned char* i, const unsigned char* key,
13065
                     const unsigned char* key2, int nr)
13066
                     XASM_LINK("AES_XTS_encrypt_aesni");
13067
#ifdef WOLFSSL_AESXTS_STREAM
13068
void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
13069
                     int tweak_nr)
13070
                     XASM_LINK("AES_XTS_init_aesni");
13071
void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
13072
                     const unsigned char* key, unsigned char *i, int nr)
13073
                     XASM_LINK("AES_XTS_encrypt_update_aesni");
13074
#endif
13075
#ifdef HAVE_INTEL_AVX1
13076
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
13077
                     word32 sz, const unsigned char* i,
13078
                     const unsigned char* key, const unsigned char* key2,
13079
                     int nr)
13080
                     XASM_LINK("AES_XTS_encrypt_avx1");
13081
#ifdef WOLFSSL_AESXTS_STREAM
13082
void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
13083
                     int tweak_nr)
13084
                     XASM_LINK("AES_XTS_init_avx1");
13085
void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
13086
                     const unsigned char* key, unsigned char *i, int nr)
13087
                     XASM_LINK("AES_XTS_encrypt_update_avx1");
13088
#endif
13089
#endif /* HAVE_INTEL_AVX1 */
13090
13091
#ifdef HAVE_AES_DECRYPT
13092
void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
13093
                     const unsigned char* i, const unsigned char* key,
13094
                     const unsigned char* key2, int nr)
13095
                     XASM_LINK("AES_XTS_decrypt_aesni");
13096
#ifdef WOLFSSL_AESXTS_STREAM
13097
void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
13098
                     const unsigned char* key, unsigned char *i, int nr)
13099
                     XASM_LINK("AES_XTS_decrypt_update_aesni");
13100
#endif
13101
#ifdef HAVE_INTEL_AVX1
13102
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
13103
                     word32 sz, const unsigned char* i,
13104
                     const unsigned char* key, const unsigned char* key2,
13105
                     int nr)
13106
                     XASM_LINK("AES_XTS_decrypt_avx1");
13107
#ifdef WOLFSSL_AESXTS_STREAM
13108
void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
13109
                     const unsigned char* key, unsigned char *i, int nr)
13110
                     XASM_LINK("AES_XTS_decrypt_update_avx1");
13111
#endif
13112
#endif /* HAVE_INTEL_AVX1 */
13113
#endif /* HAVE_AES_DECRYPT */
13114
13115
#endif /* WOLFSSL_AESNI */
13116
13117
#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
13118
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13119
#ifdef HAVE_AES_ECB
13120
/* helper function for encrypting / decrypting full buffer at once */
13121
static WARN_UNUSED_RESULT int _AesXtsHelper(
13122
    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
13123
{
13124
    word32 outSz   = sz;
13125
    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
13126
    byte*  pt      = out;
13127
13128
    outSz -= WC_AES_BLOCK_SIZE;
13129
13130
    while (outSz > 0) {
13131
        word32 j;
13132
        byte carry = 0;
13133
13134
        /* multiply by shift left and propagate carry */
13135
        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
13136
            byte tmpC;
13137
13138
            tmpC   = (pt[j] >> 7) & 0x01;
13139
            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
13140
            carry  = tmpC;
13141
        }
13142
        if (carry) {
13143
            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
13144
        }
13145
13146
        pt += WC_AES_BLOCK_SIZE;
13147
    }
13148
13149
    xorbuf(out, in, totalSz);
13150
#ifndef WOLFSSL_RISCV_ASM
13151
    if (dir == AES_ENCRYPTION) {
13152
        return _AesEcbEncrypt(aes, out, out, totalSz);
13153
    }
13154
    else {
13155
        return _AesEcbDecrypt(aes, out, out, totalSz);
13156
    }
13157
#else
13158
    if (dir == AES_ENCRYPTION) {
13159
        return wc_AesEcbEncrypt(aes, out, out, totalSz);
13160
    }
13161
    else {
13162
        return wc_AesEcbDecrypt(aes, out, out, totalSz);
13163
    }
13164
#endif
13165
}
13166
#endif /* HAVE_AES_ECB */
13167
13168
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
13169
 *
13170
 * xaes  AES keys to use for block encrypt/decrypt
13171
 * out   output buffer to hold cipher text
13172
 * in    input plain text buffer to encrypt
13173
 * sz    size of both out and in buffers
13174
 * i     value to use for tweak
13175
 *
13176
 * returns 0 on success
13177
 */
13178
/* Software AES - XTS Encrypt  */
13179
13180
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
13181
                                  word32 sz,
13182
                                  byte *i);
13183
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
13184
        const byte* i)
13185
{
13186
    int ret;
13187
    byte tweak_block[WC_AES_BLOCK_SIZE];
13188
13189
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
13190
    if (ret != 0)
13191
        return ret;
13192
13193
    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
13194
}
13195
13196
#ifdef WOLFSSL_AESXTS_STREAM
13197
13198
/* Block-streaming AES-XTS tweak setup.
13199
 *
13200
 * xaes  AES keys to use for block encrypt/decrypt
13201
 * i     readwrite value to use for tweak
13202
 *
13203
 * returns 0 on success
13204
 */
13205
static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
13206
    return wc_AesEncryptDirect(&xaes->tweak, i, i);
13207
}
13208
13209
#endif /* WOLFSSL_AESXTS_STREAM */
13210
13211
/* Block-streaming AES-XTS.
13212
 *
13213
 * Supply block-aligned input data with successive calls.  Final call need not
13214
 * be block aligned.
13215
 *
13216
 * xaes  AES keys to use for block encrypt/decrypt
13217
 * out   output buffer to hold cipher text
13218
 * in    input plain text buffer to encrypt
13219
 * sz    size of both out and in buffers
13220
 *
13221
 * returns 0 on success
13222
 */
13223
/* Software AES - XTS Encrypt  */
13224
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
13225
                                  word32 sz,
13226
                                  byte *i)
13227
{
13228
    int ret = 0;
13229
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
13230
    Aes *aes = &xaes->aes;
13231
13232
#ifdef HAVE_AES_ECB
13233
    /* encrypt all of buffer at once when possible */
13234
    if (in != out) { /* can not handle inline */
13235
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
13236
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
13237
            return ret;
13238
    }
13239
#endif
13240
13241
    while (blocks > 0) {
13242
        word32 j;
13243
        byte carry = 0;
13244
13245
#ifdef HAVE_AES_ECB
13246
        if (in == out)
13247
#endif
13248
        { /* check for if inline */
13249
            byte buf[WC_AES_BLOCK_SIZE];
13250
13251
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
13252
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
13253
            ret = wc_AesEncryptDirect(aes, out, buf);
13254
            if (ret != 0)
13255
                return ret;
13256
        }
13257
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
13258
13259
        /* multiply by shift left and propagate carry */
13260
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
13261
            byte tmpC;
13262
13263
            tmpC   = (i[j] >> 7) & 0x01;
13264
            i[j] = (byte)((i[j] << 1) + carry);
13265
            carry  = tmpC;
13266
        }
13267
        if (carry) {
13268
            i[0] ^= GF_XTS;
13269
        }
13270
13271
        in  += WC_AES_BLOCK_SIZE;
13272
        out += WC_AES_BLOCK_SIZE;
13273
        sz  -= WC_AES_BLOCK_SIZE;
13274
        blocks--;
13275
    }
13276
13277
    /* stealing operation of XTS to handle left overs */
13278
    if (sz > 0) {
13279
        byte buf[WC_AES_BLOCK_SIZE];
13280
13281
        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
13282
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
13283
            return BUFFER_E;
13284
        }
13285
        if (in != out) {
13286
            XMEMCPY(out, buf, sz);
13287
            XMEMCPY(buf, in, sz);
13288
        }
13289
        else {
13290
            byte buf2[WC_AES_BLOCK_SIZE];
13291
13292
            XMEMCPY(buf2, buf, sz);
13293
            XMEMCPY(buf, in, sz);
13294
            XMEMCPY(out, buf2, sz);
13295
        }
13296
13297
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
13298
        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
13299
        if (ret == 0)
13300
            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
13301
    }
13302
13303
    return ret;
13304
}
13305
13306
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
13307
 *
13308
 * xaes  AES keys to use for block encrypt/decrypt
13309
 * out   output buffer to hold cipher text
13310
 * in    input plain text buffer to encrypt
13311
 * sz    size of both out and in buffers
13312
 * i     value to use for tweak
13313
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
13314
 *       adds a sanity check on how the user calls the function.
13315
 *
13316
 * returns 0 on success
13317
 */
13318
int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
13319
        const byte* i, word32 iSz)
13320
{
13321
    int ret;
13322
13323
    Aes *aes;
13324
13325
    if (xaes == NULL || out == NULL || in == NULL) {
13326
        return BAD_FUNC_ARG;
13327
    }
13328
13329
#if FIPS_VERSION3_GE(6,0,0)
13330
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
13331
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
13332
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
13333
     */
13334
    if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
13335
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
13336
        return BAD_FUNC_ARG;
13337
    }
13338
#endif
13339
13340
    aes = &xaes->aes;
13341
13342
    if (aes->keylen == 0) {
13343
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
13344
        return BAD_FUNC_ARG;
13345
    }
13346
13347
    if (iSz < WC_AES_BLOCK_SIZE) {
13348
        return BAD_FUNC_ARG;
13349
    }
13350
13351
    if (sz < WC_AES_BLOCK_SIZE) {
13352
        WOLFSSL_MSG("Plain text input too small for encryption");
13353
        return BAD_FUNC_ARG;
13354
    }
13355
13356
    {
13357
#ifdef WOLFSSL_AESNI
13358
        if (aes->use_aesni) {
13359
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13360
#if defined(HAVE_INTEL_AVX1)
13361
            if (IS_INTEL_AVX1(intel_flags)) {
13362
                AES_XTS_encrypt_avx1(in, out, sz, i,
13363
                                     (const byte*)aes->key,
13364
                                     (const byte*)xaes->tweak.key,
13365
                                     (int)aes->rounds);
13366
                ret = 0;
13367
            }
13368
            else
13369
#endif
13370
            {
13371
                AES_XTS_encrypt_aesni(in, out, sz, i,
13372
                                      (const byte*)aes->key,
13373
                                      (const byte*)xaes->tweak.key,
13374
                                      (int)aes->rounds);
13375
                ret = 0;
13376
            }
13377
            RESTORE_VECTOR_REGISTERS();
13378
        }
13379
        else
13380
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13381
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13382
        if (aes->use_aes_hw_crypto) {
13383
            AES_XTS_encrypt_AARCH64(xaes, out, in, sz, i);
13384
            ret = 0;
13385
        }
13386
        else
13387
#endif
13388
        {
13389
            ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
13390
        }
13391
    }
13392
13393
    return ret;
13394
}
13395
13396
#ifdef WOLFSSL_AESXTS_STREAM
13397
13398
/* Block-streaming AES-XTS.
13399
 *
13400
 * xaes  AES keys to use for block encrypt/decrypt
13401
 * i     readwrite value to use for tweak
13402
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
13403
 *       adds a sanity check on how the user calls the function.
13404
 *
13405
 * returns 0 on success
13406
 */
13407
int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
13408
                         struct XtsAesStreamData *stream)
13409
{
13410
    int ret;
13411
13412
    Aes *aes;
13413
13414
    if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
13415
        return BAD_FUNC_ARG;
13416
    }
13417
13418
    if (iSz < WC_AES_BLOCK_SIZE) {
13419
        return BAD_FUNC_ARG;
13420
    }
13421
13422
    aes = &xaes->aes;
13423
13424
    if (aes->keylen == 0) {
13425
        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
13426
        return BAD_FUNC_ARG;
13427
    }
13428
13429
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
13430
    stream->bytes_crypted_with_this_tweak = 0;
13431
13432
    {
13433
#ifdef WOLFSSL_AESNI
13434
        if (aes->use_aesni) {
13435
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13436
#if defined(HAVE_INTEL_AVX1)
13437
            if (IS_INTEL_AVX1(intel_flags)) {
13438
                AES_XTS_init_avx1(stream->tweak_block,
13439
                                  (const byte*)xaes->tweak.key,
13440
                                  (int)xaes->tweak.rounds);
13441
                ret = 0;
13442
            }
13443
            else
13444
#endif
13445
            {
13446
                AES_XTS_init_aesni(stream->tweak_block,
13447
                                   (const byte*)xaes->tweak.key,
13448
                                   (int)xaes->tweak.rounds);
13449
                ret = 0;
13450
            }
13451
            RESTORE_VECTOR_REGISTERS();
13452
        }
13453
        else
13454
#endif /* WOLFSSL_AESNI */
13455
        {
13456
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
13457
        }
13458
    }
13459
13460
    return ret;
13461
}
13462
13463
/* Block-streaming AES-XTS
13464
 *
13465
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
13466
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsEncryptUpdate().
13467
 * wc_AesXtsEncryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
13468
 *
13469
 * xaes  AES keys to use for block encrypt/decrypt
13470
 * out   output buffer to hold cipher text
13471
 * in    input plain text buffer to encrypt
13472
 * sz    size of both out and in buffers -- must be >= WC_AES_BLOCK_SIZE.
13473
 * i     value to use for tweak
13474
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
13475
 *       adds a sanity check on how the user calls the function.
13476
 *
13477
 * returns 0 on success
13478
 */
13479
static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
13480
                           struct XtsAesStreamData *stream)
13481
{
13482
    int ret;
13483
13484
#ifdef WOLFSSL_AESNI
13485
    Aes *aes;
13486
#endif
13487
13488
    if (xaes == NULL || out == NULL || in == NULL) {
13489
        return BAD_FUNC_ARG;
13490
    }
13491
13492
#ifdef WOLFSSL_AESNI
13493
    aes = &xaes->aes;
13494
#endif
13495
13496
    if (sz < WC_AES_BLOCK_SIZE) {
13497
        WOLFSSL_MSG("Plain text input too small for encryption");
13498
        return BAD_FUNC_ARG;
13499
    }
13500
13501
    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
13502
    {
13503
        WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
13504
        return BAD_FUNC_ARG;
13505
    }
13506
13507
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
13508
    (void)WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
13509
                             stream->bytes_crypted_with_this_tweak);
13510
#endif
13511
#if FIPS_VERSION3_GE(6,0,0)
13512
    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
13513
     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
13514
     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
13515
     */
13516
    if (stream->bytes_crypted_with_this_tweak >
13517
        FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
13518
    {
13519
        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
13520
        return BAD_FUNC_ARG;
13521
    }
13522
#endif
13523
    {
13524
#ifdef WOLFSSL_AESNI
13525
        if (aes->use_aesni) {
13526
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13527
#if defined(HAVE_INTEL_AVX1)
13528
            if (IS_INTEL_AVX1(intel_flags)) {
13529
                AES_XTS_encrypt_update_avx1(in, out, sz,
13530
                                            (const byte*)aes->key,
13531
                                            stream->tweak_block,
13532
                                            (int)aes->rounds);
13533
                ret = 0;
13534
            }
13535
            else
13536
#endif
13537
            {
13538
                AES_XTS_encrypt_update_aesni(in, out, sz,
13539
                                            (const byte*)aes->key,
13540
                                            stream->tweak_block,
13541
                                            (int)aes->rounds);
13542
                ret = 0;
13543
            }
13544
            RESTORE_VECTOR_REGISTERS();
13545
        }
13546
        else
13547
#endif /* WOLFSSL_AESNI */
13548
        {
13549
            ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
13550
        }
13551
    }
13552
13553
    return ret;
13554
}
13555
13556
int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
13557
                           struct XtsAesStreamData *stream)
13558
{
13559
    if (stream == NULL)
13560
        return BAD_FUNC_ARG;
13561
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
13562
        return BAD_FUNC_ARG;
13563
    return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
13564
}
13565
13566
int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
13567
                           struct XtsAesStreamData *stream)
13568
{
13569
    int ret;
13570
    if (stream == NULL)
13571
        return BAD_FUNC_ARG;
13572
    if (sz > 0)
13573
        ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
13574
    else
13575
        ret = 0;
13576
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
13577
     * after finalization.
13578
     */
13579
    stream->bytes_crypted_with_this_tweak |= 1U;
13580
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
13581
#ifdef WOLFSSL_CHECK_MEM_ZERO
13582
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
13583
#endif
13584
    return ret;
13585
}
13586
13587
#endif /* WOLFSSL_AESXTS_STREAM */
13588
13589
13590
/* Same process as encryption but use aes_decrypt key.
13591
 *
13592
 * xaes  AES keys to use for block encrypt/decrypt
13593
 * out   output buffer to hold plain text
13594
 * in    input cipher text buffer to decrypt
13595
 * sz    size of both out and in buffers
13596
 * i     value to use for tweak
13597
 *
13598
 * returns 0 on success
13599
 */
13600
/* Software AES - XTS Decrypt */
13601
13602
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
13603
                                  word32 sz, byte *i);
13604
13605
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
13606
        const byte* i)
13607
{
13608
    int ret;
13609
    byte tweak_block[WC_AES_BLOCK_SIZE];
13610
13611
    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
13612
    if (ret != 0)
13613
        return ret;
13614
13615
    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
13616
}
13617
13618
/* Block-streaming AES-XTS.
13619
 *
13620
 * Same process as encryption but use decrypt key.
13621
 *
13622
 * Supply block-aligned input data with successive calls.  Final call need not
13623
 * be block aligned.
13624
 *
13625
 * xaes  AES keys to use for block encrypt/decrypt
13626
 * out   output buffer to hold plain text
13627
 * in    input cipher text buffer to decrypt
13628
 * sz    size of both out and in buffers
13629
 * i     value to use for tweak
13630
 *
13631
 * returns 0 on success
13632
 */
13633
/* Software AES - XTS Decrypt */
13634
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
13635
                                  word32 sz, byte *i)
13636
{
13637
    int ret = 0;
13638
    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
13639
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
13640
    Aes *aes = &xaes->aes_decrypt;
13641
#else
13642
    Aes *aes = &xaes->aes;
13643
#endif
13644
    word32 j;
13645
    byte carry = 0;
13646
    byte stl = (sz % WC_AES_BLOCK_SIZE);
13647
13648
    /* if Stealing then break out of loop one block early to handle special
13649
     * case */
13650
    if (stl > 0) {
13651
        blocks--;
13652
    }
13653
13654
#ifdef HAVE_AES_ECB
13655
    /* decrypt all of buffer at once when possible */
13656
    if (in != out) { /* can not handle inline */
13657
        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
13658
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
13659
            return ret;
13660
    }
13661
#endif
13662
13663
    while (blocks > 0) {
13664
#ifdef HAVE_AES_ECB
13665
        if (in == out)
13666
#endif
13667
        { /* check for if inline */
13668
            byte buf[WC_AES_BLOCK_SIZE];
13669
13670
            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
13671
            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
13672
            ret = wc_AesDecryptDirect(aes, out, buf);
13673
            if (ret != 0)
13674
                return ret;
13675
        }
13676
        xorbuf(out, i, WC_AES_BLOCK_SIZE);
13677
13678
        /* multiply by shift left and propagate carry */
13679
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
13680
            byte tmpC;
13681
13682
            tmpC   = (i[j] >> 7) & 0x01;
13683
            i[j] = (byte)((i[j] << 1) + carry);
13684
            carry  = tmpC;
13685
        }
13686
        if (carry) {
13687
            i[0] ^= GF_XTS;
13688
        }
13689
        carry = 0;
13690
13691
        in  += WC_AES_BLOCK_SIZE;
13692
        out += WC_AES_BLOCK_SIZE;
13693
        sz  -= WC_AES_BLOCK_SIZE;
13694
        blocks--;
13695
    }
13696
13697
    /* stealing operation of XTS to handle left overs */
13698
    if (sz >= WC_AES_BLOCK_SIZE) {
13699
        byte buf[WC_AES_BLOCK_SIZE];
13700
        byte tmp2[WC_AES_BLOCK_SIZE];
13701
13702
        /* multiply by shift left and propagate carry */
13703
        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
13704
            byte tmpC;
13705
13706
            tmpC   = (i[j] >> 7) & 0x01;
13707
            tmp2[j] = (byte)((i[j] << 1) + carry);
13708
            carry  = tmpC;
13709
        }
13710
        if (carry) {
13711
            tmp2[0] ^= GF_XTS;
13712
        }
13713
13714
        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
13715
        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
13716
        ret = wc_AesDecryptDirect(aes, out, buf);
13717
        if (ret != 0)
13718
            return ret;
13719
        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
13720
13721
        /* tmp2 holds partial | last */
13722
        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
13723
        in  += WC_AES_BLOCK_SIZE;
13724
        out += WC_AES_BLOCK_SIZE;
13725
        sz  -= WC_AES_BLOCK_SIZE;
13726
13727
        /* Make buffer with end of cipher text | last */
13728
        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
13729
        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
13730
            return BUFFER_E;
13731
        }
13732
        XMEMCPY(buf, in,   sz);
13733
        XMEMCPY(out, tmp2, sz);
13734
13735
        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
13736
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
13737
        if (ret != 0)
13738
            return ret;
13739
        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
13740
        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
13741
    }
13742
13743
    return ret;
13744
}
13745
13746
/* Same process as encryption but Aes key is AES_DECRYPTION type.
13747
 *
13748
 * xaes  AES keys to use for block encrypt/decrypt
13749
 * out   output buffer to hold plain text
13750
 * in    input cipher text buffer to decrypt
13751
 * sz    size of both out and in buffers
13752
 * i     value to use for tweak
13753
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
13754
 *       adds a sanity check on how the user calls the function.
13755
 *
13756
 * returns 0 on success
13757
 */
13758
int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
13759
        const byte* i, word32 iSz)
13760
{
13761
    int ret;
13762
    Aes *aes;
13763
13764
    if (xaes == NULL || out == NULL || in == NULL) {
13765
        return BAD_FUNC_ARG;
13766
    }
13767
13768
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
13769
    aes = &xaes->aes_decrypt;
13770
#else
13771
    aes = &xaes->aes;
13772
#endif
13773
13774
/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
13775
 * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
13776
 * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes or
13777
 * 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
13778
 * return whenever sz / WC_AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
13779
 * not a sequence of complete blocks.
13780
 */
13781
13782
    if (aes->keylen == 0) {
13783
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
13784
        return BAD_FUNC_ARG;
13785
    }
13786
13787
    if (iSz < WC_AES_BLOCK_SIZE) {
13788
        return BAD_FUNC_ARG;
13789
    }
13790
13791
    if (sz < WC_AES_BLOCK_SIZE) {
13792
        WOLFSSL_MSG("Cipher text input too small for decryption");
13793
        return BAD_FUNC_ARG;
13794
    }
13795
13796
    {
13797
#ifdef WOLFSSL_AESNI
13798
        if (aes->use_aesni) {
13799
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13800
#if defined(HAVE_INTEL_AVX1)
13801
            if (IS_INTEL_AVX1(intel_flags)) {
13802
                AES_XTS_decrypt_avx1(in, out, sz, i,
13803
                                     (const byte*)aes->key,
13804
                                     (const byte*)xaes->tweak.key,
13805
                                     (int)aes->rounds);
13806
                ret = 0;
13807
            }
13808
            else
13809
#endif
13810
            {
13811
                AES_XTS_decrypt_aesni(in, out, sz, i,
13812
                                      (const byte*)aes->key,
13813
                                      (const byte*)xaes->tweak.key,
13814
                                      (int)aes->rounds);
13815
                ret = 0;
13816
            }
13817
            RESTORE_VECTOR_REGISTERS();
13818
        }
13819
        else
13820
#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
13821
      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
13822
        if (aes->use_aes_hw_crypto) {
13823
            AES_XTS_decrypt_AARCH64(xaes, out, in, sz, i);
13824
            ret = 0;
13825
        }
13826
        else
13827
#endif
13828
        {
13829
            ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
13830
        }
13831
13832
        return ret;
13833
    }
13834
}
13835
13836
#ifdef WOLFSSL_AESXTS_STREAM
13837
13838
/* Same process as encryption but Aes key is AES_DECRYPTION type.
13839
 *
13840
 * xaes  AES keys to use for block encrypt/decrypt
13841
 * i     readwrite value to use for tweak
13842
 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
13843
 *       adds a sanity check on how the user calls the function.
13844
 *
13845
 * returns 0 on success
13846
 */
13847
int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
13848
                         struct XtsAesStreamData *stream)
13849
{
13850
    int ret;
13851
    Aes *aes;
13852
13853
    if (xaes == NULL) {
13854
        return BAD_FUNC_ARG;
13855
    }
13856
13857
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
13858
    aes = &xaes->aes_decrypt;
13859
#else
13860
    aes = &xaes->aes;
13861
#endif
13862
13863
    if (aes->keylen == 0) {
13864
        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
13865
        return BAD_FUNC_ARG;
13866
    }
13867
13868
    if (iSz < WC_AES_BLOCK_SIZE) {
13869
        return BAD_FUNC_ARG;
13870
    }
13871
13872
    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
13873
    stream->bytes_crypted_with_this_tweak = 0;
13874
13875
    {
13876
#ifdef WOLFSSL_AESNI
13877
        if (aes->use_aesni) {
13878
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13879
#if defined(HAVE_INTEL_AVX1)
13880
            if (IS_INTEL_AVX1(intel_flags)) {
13881
                AES_XTS_init_avx1(stream->tweak_block,
13882
                                  (const byte*)xaes->tweak.key,
13883
                                  (int)xaes->tweak.rounds);
13884
                ret = 0;
13885
            }
13886
            else
13887
#endif
13888
            {
13889
                AES_XTS_init_aesni(stream->tweak_block,
13890
                                   (const byte*)xaes->tweak.key,
13891
                                   (int)xaes->tweak.rounds);
13892
                ret = 0;
13893
            }
13894
            RESTORE_VECTOR_REGISTERS();
13895
        }
13896
        else
13897
#endif /* WOLFSSL_AESNI */
13898
        {
13899
            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
13900
        }
13901
13902
    }
13903
13904
    return ret;
13905
}
13906
13907
/* Block-streaming AES-XTS
13908
 *
13909
 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
13910
 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsDecryptUpdate().
13911
 * wc_AesXtsDecryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
13912
 *
13913
 * xaes  AES keys to use for block encrypt/decrypt
13914
 * out   output buffer to hold plain text
13915
 * in    input cipher text buffer to decrypt
13916
 * sz    size of both out and in buffers
13917
 * i     tweak buffer of size WC_AES_BLOCK_SIZE.
13918
 *
13919
 * returns 0 on success
13920
 */
13921
static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
13922
                           struct XtsAesStreamData *stream)
13923
{
13924
    int ret;
13925
#ifdef WOLFSSL_AESNI
13926
    Aes *aes;
13927
#endif
13928
13929
    if (xaes == NULL || out == NULL || in == NULL) {
13930
        return BAD_FUNC_ARG;
13931
    }
13932
13933
#ifdef WOLFSSL_AESNI
13934
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
13935
    aes = &xaes->aes_decrypt;
13936
#else
13937
    aes = &xaes->aes;
13938
#endif
13939
#endif
13940
13941
    if (sz < WC_AES_BLOCK_SIZE) {
13942
        WOLFSSL_MSG("Cipher text input too small for decryption");
13943
        return BAD_FUNC_ARG;
13944
    }
13945
13946
    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
13947
    {
13948
        WOLFSSL_MSG("Call to AesXtsDecryptUpdate after previous finalizing call");
13949
        return BAD_FUNC_ARG;
13950
    }
13951
13952
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
13953
    (void)WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
13954
                             stream->bytes_crypted_with_this_tweak);
13955
#endif
13956
13957
    {
13958
#ifdef WOLFSSL_AESNI
13959
        if (aes->use_aesni) {
13960
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
13961
#if defined(HAVE_INTEL_AVX1)
13962
            if (IS_INTEL_AVX1(intel_flags)) {
13963
                AES_XTS_decrypt_update_avx1(in, out, sz,
13964
                                            (const byte*)aes->key,
13965
                                            stream->tweak_block,
13966
                                            (int)aes->rounds);
13967
                ret = 0;
13968
            }
13969
            else
13970
#endif
13971
            {
13972
                AES_XTS_decrypt_update_aesni(in, out, sz,
13973
                                             (const byte*)aes->key,
13974
                                             stream->tweak_block,
13975
                                             (int)aes->rounds);
13976
                ret = 0;
13977
            }
13978
            RESTORE_VECTOR_REGISTERS();
13979
        }
13980
        else
13981
#endif /* WOLFSSL_AESNI */
13982
        {
13983
            ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
13984
                                         stream->tweak_block);
13985
        }
13986
    }
13987
13988
    return ret;
13989
}
13990
13991
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
13992
                           struct XtsAesStreamData *stream)
13993
{
13994
    if (stream == NULL)
13995
        return BAD_FUNC_ARG;
13996
    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
13997
        return BAD_FUNC_ARG;
13998
    return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
13999
}
14000
14001
int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
14002
                           struct XtsAesStreamData *stream)
14003
{
14004
    int ret;
14005
    if (stream == NULL)
14006
        return BAD_FUNC_ARG;
14007
    if (sz > 0)
14008
        ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
14009
    else
14010
        ret = 0;
14011
    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
14012
    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
14013
     * after finalization.
14014
     */
14015
    stream->bytes_crypted_with_this_tweak |= 1U;
14016
#ifdef WOLFSSL_CHECK_MEM_ZERO
14017
    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
14018
#endif
14019
    return ret;
14020
}
14021
14022
#endif /* WOLFSSL_AESXTS_STREAM */
14023
#endif
14024
14025
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
14026
 * sectorSz bytes
14027
 *
14028
 * xaes     AES keys to use for block encrypt
14029
 * out      output buffer to hold cipher text
14030
 * in       input plain text buffer to encrypt
14031
 * sz       size of both out and in buffers
14032
 * sector   value to use for tweak
14033
 * sectorSz size of the sector
14034
 *
14035
 * returns 0 on success
14036
 */
14037
int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
14038
        word32 sz, word64 sector, word32 sectorSz)
14039
{
14040
    int ret  = 0;
14041
    word32 iter = 0;
14042
    word32 sectorCount;
14043
    word32 remainder;
14044
14045
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
14046
        return BAD_FUNC_ARG;
14047
    }
14048
14049
    if (sz < WC_AES_BLOCK_SIZE) {
14050
        WOLFSSL_MSG("Cipher text input too small for encryption");
14051
        return BAD_FUNC_ARG;
14052
    }
14053
14054
    sectorCount  = sz / sectorSz;
14055
    remainder = sz % sectorSz;
14056
14057
    while (sectorCount) {
14058
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
14059
                in + (iter * sectorSz), sectorSz, sector);
14060
        if (ret != 0)
14061
            break;
14062
14063
        sectorCount--;
14064
        iter++;
14065
        sector++;
14066
    }
14067
14068
    if (remainder && ret == 0)
14069
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
14070
                in + (iter * sectorSz), remainder, sector);
14071
14072
    return ret;
14073
}
14074
14075
/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
14076
 *
14077
 * xaes     AES keys to use for block decrypt
14078
 * out      output buffer to hold cipher text
14079
 * in       input plain text buffer to encrypt
14080
 * sz       size of both out and in buffers
14081
 * sector   value to use for tweak
14082
 * sectorSz size of the sector
14083
 *
14084
 * returns 0 on success
14085
 */
14086
int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
14087
        word32 sz, word64 sector, word32 sectorSz)
14088
{
14089
    int ret  = 0;
14090
    word32 iter = 0;
14091
    word32 sectorCount;
14092
    word32 remainder;
14093
14094
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
14095
        return BAD_FUNC_ARG;
14096
    }
14097
14098
    if (sz < WC_AES_BLOCK_SIZE) {
14099
        WOLFSSL_MSG("Cipher text input too small for decryption");
14100
        return BAD_FUNC_ARG;
14101
    }
14102
14103
    sectorCount  = sz / sectorSz;
14104
    remainder = sz % sectorSz;
14105
14106
    while (sectorCount) {
14107
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
14108
                in + (iter * sectorSz), sectorSz, sector);
14109
        if (ret != 0)
14110
            break;
14111
14112
        sectorCount--;
14113
        iter++;
14114
        sector++;
14115
    }
14116
14117
    if (remainder && ret == 0)
14118
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
14119
                in + (iter * sectorSz), remainder, sector);
14120
14121
    return ret;
14122
}
14123
#endif /* WOLFSSL_AES_XTS */
14124
14125
#ifdef WOLFSSL_AES_SIV
14126
14127
/*
14128
 * See RFC 5297 Section 2.4.
14129
 */
14130
static WARN_UNUSED_RESULT int S2V(
14131
    const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc,
14132
    const byte* nonce, word32 nonceSz, const byte* data,
14133
    word32 dataSz, byte* out)
14134
{
14135
#ifdef WOLFSSL_SMALL_STACK
14136
    byte* tmp[3] = {NULL, NULL, NULL};
14137
    int i;
14138
    Cmac* cmac;
14139
#else
14140
    byte tmp[3][WC_AES_BLOCK_SIZE];
14141
    Cmac cmac[1];
14142
#endif
14143
    word32 macSz = WC_AES_BLOCK_SIZE;
14144
    int ret = 0;
14145
    byte tmpi = 0;
14146
    word32 ai;
14147
    word32 zeroBytes;
14148
14149
#ifdef WOLFSSL_SMALL_STACK
14150
    for (i = 0; i < 3; ++i) {
14151
        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14152
        if (tmp[i] == NULL) {
14153
            ret = MEMORY_E;
14154
            break;
14155
        }
14156
    }
14157
    if (ret == 0)
14158
#endif
14159
14160
    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
14161
        /* See RFC 5297 Section 7. */
14162
        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
14163
                    " 126.");
14164
        ret = BAD_FUNC_ARG;
14165
    }
14166
14167
    if (ret == 0) {
14168
        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
14169
        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
14170
14171
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
14172
                                 key, keySz);
14173
    }
14174
14175
    if (ret == 0) {
14176
        /* Loop over authenticated associated data AD1..ADn */
14177
        for (ai = 0; ai < numAssoc; ++ai) {
14178
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
14179
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
14180
                                     assoc[ai].assocSz, key, keySz);
14181
            if (ret != 0)
14182
                break;
14183
            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
14184
            tmpi = (byte)(1 - tmpi);
14185
        }
14186
14187
        /* Add nonce as final AD. See RFC 5297 Section 3. */
14188
        if ((ret == 0) && (nonceSz > 0)) {
14189
            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
14190
            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
14191
                                     nonceSz, key, keySz);
14192
            if (ret == 0) {
14193
                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
14194
            }
14195
            tmpi = (byte)(1U - tmpi);
14196
        }
14197
14198
        /* For simplicity of the remaining code, make sure the "final" result
14199
           is always in tmp[0]. */
14200
        if (tmpi == 1) {
14201
            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
14202
        }
14203
    }
14204
14205
    if (ret == 0) {
14206
        if (dataSz >= WC_AES_BLOCK_SIZE) {
14207
14208
        #ifdef WOLFSSL_SMALL_STACK
14209
            cmac = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC);
14210
            if (cmac == NULL) {
14211
                ret = MEMORY_E;
14212
            }
14213
            if (ret == 0)
14214
        #endif
14215
            {
14216
            #ifdef WOLFSSL_CHECK_MEM_ZERO
14217
                /* Aes part is checked by wc_AesFree. */
14218
                wc_MemZero_Add("wc_AesCmacGenerate cmac",
14219
                    ((unsigned char *)cmac) + sizeof(Aes),
14220
                    sizeof(Cmac) - sizeof(Aes));
14221
            #endif
14222
                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
14223
                       WC_AES_BLOCK_SIZE);
14224
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
14225
                if (ret == 0) {
14226
                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
14227
                }
14228
                if (ret == 0) {
14229
                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
14230
                }
14231
                if (ret == 0) {
14232
                    ret = wc_CmacFinal(cmac, out, &macSz);
14233
                }
14234
            }
14235
        #ifdef WOLFSSL_SMALL_STACK
14236
            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
14237
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
14238
            wc_MemZero_Check(cmac, sizeof(Cmac));
14239
        #endif
14240
        }
14241
        else {
14242
            XMEMCPY(tmp[2], data, dataSz);
14243
            tmp[2][dataSz] |= 0x80;
14244
            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
14245
            if (zeroBytes != 0) {
14246
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
14247
            }
14248
            ShiftAndXorRb(tmp[1], tmp[0]);
14249
            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
14250
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
14251
                                     keySz);
14252
        }
14253
    }
14254
14255
#ifdef WOLFSSL_SMALL_STACK
14256
    for (i = 0; i < 3; ++i) {
14257
        if (tmp[i] != NULL) {
14258
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
14259
        }
14260
    }
14261
#endif
14262
14263
    return ret;
14264
}
14265
14266
static WARN_UNUSED_RESULT int AesSivCipher(
14267
    const byte* key, word32 keySz, const AesSivAssoc* assoc,
14268
    word32 numAssoc, const byte* nonce, word32 nonceSz,
14269
    const byte* data, word32 dataSz, byte* siv, byte* out,
14270
    int enc)
14271
{
14272
    int ret = 0;
14273
#ifdef WOLFSSL_SMALL_STACK
14274
    Aes* aes = NULL;
14275
#else
14276
    Aes aes[1];
14277
#endif
14278
    byte sivTmp[WC_AES_BLOCK_SIZE];
14279
14280
    if (key == NULL || siv == NULL || out == NULL) {
14281
        WOLFSSL_MSG("Bad parameter");
14282
        ret = BAD_FUNC_ARG;
14283
    }
14284
14285
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
14286
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
14287
        ret = BAD_FUNC_ARG;
14288
    }
14289
14290
    if (ret == 0) {
14291
        if (enc == 1) {
14292
            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
14293
                      dataSz, sivTmp);
14294
            if (ret != 0) {
14295
                WOLFSSL_MSG("S2V failed.");
14296
            }
14297
            else {
14298
                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
14299
            }
14300
        }
14301
        else {
14302
            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
14303
        }
14304
    }
14305
14306
    if (ret == 0) {
14307
#ifdef WOLFSSL_SMALL_STACK
14308
        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
14309
#else
14310
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14311
#endif
14312
        if (ret != 0) {
14313
            WOLFSSL_MSG("Failed to initialized AES object.");
14314
        }
14315
    }
14316
14317
    if (ret == 0 && dataSz > 0) {
14318
        sivTmp[12] &= 0x7f;
14319
        sivTmp[8] &= 0x7f;
14320
        ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
14321
                           AES_ENCRYPTION);
14322
        if (ret != 0) {
14323
            WOLFSSL_MSG("Failed to set key for AES-CTR.");
14324
        }
14325
        else {
14326
            ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
14327
            if (ret != 0) {
14328
                WOLFSSL_MSG("AES-CTR encryption failed.");
14329
            }
14330
        }
14331
    }
14332
14333
    if (ret == 0 && enc == 0) {
14334
        ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out, dataSz,
14335
                  sivTmp);
14336
        if (ret != 0) {
14337
            WOLFSSL_MSG("S2V failed.");
14338
        }
14339
14340
        if (XMEMCMP(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
14341
            WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
14342
            ret = AES_SIV_AUTH_E;
14343
        }
14344
    }
14345
14346
#ifdef WOLFSSL_SMALL_STACK
14347
    wc_AesDelete(aes, NULL);
14348
#else
14349
    wc_AesFree(aes);
14350
#endif
14351
14352
    return ret;
14353
}
14354
14355
/*
14356
 * See RFC 5297 Section 2.6.
14357
 */
14358
int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
14359
                     word32 assocSz, const byte* nonce, word32 nonceSz,
14360
                     const byte* in, word32 inSz, byte* siv, byte* out)
14361
{
14362
    AesSivAssoc ad;
14363
    ad.assoc = assoc;
14364
    ad.assocSz = assocSz;
14365
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
14366
                        siv, out, 1);
14367
}
14368
14369
/*
14370
 * See RFC 5297 Section 2.7.
14371
 */
14372
int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
14373
                     word32 assocSz, const byte* nonce, word32 nonceSz,
14374
                     const byte* in, word32 inSz, byte* siv, byte* out)
14375
{
14376
    AesSivAssoc ad;
14377
    ad.assoc = assoc;
14378
    ad.assocSz = assocSz;
14379
    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
14380
                        siv, out, 0);
14381
}
14382
14383
/*
14384
 * See RFC 5297 Section 2.6.
14385
 */
14386
int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
14387
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
14388
                        const byte* in, word32 inSz, byte* siv, byte* out)
14389
{
14390
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
14391
                        siv, out, 1);
14392
}
14393
14394
/*
14395
 * See RFC 5297 Section 2.7.
14396
 */
14397
int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
14398
                        word32 numAssoc, const byte* nonce, word32 nonceSz,
14399
                        const byte* in, word32 inSz, byte* siv, byte* out)
14400
{
14401
    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
14402
                        siv, out, 0);
14403
}
14404
14405
#endif /* WOLFSSL_AES_SIV */
14406
14407
#if defined(WOLFSSL_AES_EAX)
14408
14409
/*
14410
 * AES EAX one-shot API
14411
 * Encrypts input data and computes an auth tag over the input
14412
 * auth data and ciphertext
14413
 *
14414
 * Returns 0 on success
14415
 * Returns error code on failure
14416
 */
14417
int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
14418
                          const byte* in, word32 inSz,
14419
                          const byte* nonce, word32 nonceSz,
14420
                          /* output computed auth tag */
14421
                          byte* authTag, word32 authTagSz,
14422
                          /* input data to authenticate */
14423
                          const byte* authIn, word32 authInSz)
14424
{
14425
#if defined(WOLFSSL_SMALL_STACK)
14426
    AesEax *eax;
14427
#else
14428
    AesEax eax_mem;
14429
    AesEax *eax = &eax_mem;
14430
#endif
14431
    int ret;
14432
    int eaxInited = 0;
14433
14434
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
14435
                              || authTag == NULL || authIn == NULL) {
14436
        return BAD_FUNC_ARG;
14437
    }
14438
14439
#if defined(WOLFSSL_SMALL_STACK)
14440
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
14441
                                 NULL,
14442
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
14443
        return MEMORY_E;
14444
    }
14445
#endif
14446
14447
    if ((ret = wc_AesEaxInit(eax,
14448
                             key, keySz,
14449
                             nonce, nonceSz,
14450
                             authIn, authInSz)) != 0) {
14451
        goto cleanup;
14452
    }
14453
    eaxInited = 1;
14454
14455
    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
14456
        goto cleanup;
14457
    }
14458
14459
    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
14460
        goto cleanup;
14461
    }
14462
14463
cleanup:
14464
    if (eaxInited)
14465
        wc_AesEaxFree(eax);
14466
#if defined(WOLFSSL_SMALL_STACK)
14467
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
14468
#endif
14469
    return ret;
14470
}
14471
14472
14473
/*
14474
 * AES EAX one-shot API
14475
 * Decrypts and authenticates data against a supplied auth tag
14476
 *
14477
 * Returns 0 on success
14478
 * Returns error code on failure
14479
 */
14480
int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
14481
                          const byte* in, word32 inSz,
14482
                          const byte* nonce, word32 nonceSz,
14483
                          /* auth tag to verify against */
14484
                          const byte* authTag, word32 authTagSz,
14485
                          /* input data to authenticate */
14486
                          const byte* authIn, word32 authInSz)
14487
{
14488
#if defined(WOLFSSL_SMALL_STACK)
14489
    AesEax *eax;
14490
#else
14491
    AesEax eax_mem;
14492
    AesEax *eax = &eax_mem;
14493
#endif
14494
    int ret;
14495
    int eaxInited = 0;
14496
14497
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
14498
                              || authTag == NULL || authIn == NULL) {
14499
        return BAD_FUNC_ARG;
14500
    }
14501
14502
#if defined(WOLFSSL_SMALL_STACK)
14503
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
14504
                                 NULL,
14505
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
14506
        return MEMORY_E;
14507
    }
14508
#endif
14509
14510
    if ((ret = wc_AesEaxInit(eax,
14511
                             key, keySz,
14512
                             nonce, nonceSz,
14513
                             authIn, authInSz)) != 0) {
14514
14515
        goto cleanup;
14516
    }
14517
    eaxInited = 1;
14518
14519
    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
14520
        goto cleanup;
14521
    }
14522
14523
    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
14524
        goto cleanup;
14525
    }
14526
14527
cleanup:
14528
    if (eaxInited)
14529
        wc_AesEaxFree(eax);
14530
#if defined(WOLFSSL_SMALL_STACK)
14531
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
14532
#endif
14533
    return ret;
14534
}
14535
14536
14537
/*
14538
 * AES EAX Incremental API:
14539
 * Initializes an AES EAX encryption or decryption operation. This must be
14540
 * called before any other EAX APIs are used on the AesEax struct
14541
 *
14542
 * Returns 0 on success
14543
 * Returns error code on failure
14544
 */
14545
int  wc_AesEaxInit(AesEax* eax,
14546
                   const byte* key, word32 keySz,
14547
                   const byte* nonce, word32 nonceSz,
14548
                   const byte* authIn, word32 authInSz)
14549
{
14550
    int ret = 0;
14551
    word32 cmacSize;
14552
    int aesInited = 0;
14553
    int nonceCmacInited = 0;
14554
    int aadCmacInited = 0;
14555
14556
    if (eax == NULL || key == NULL ||  nonce == NULL) {
14557
        return BAD_FUNC_ARG;
14558
    }
14559
14560
    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
14561
14562
    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
14563
        goto out;
14564
    }
14565
    aesInited = 1;
14566
14567
    if ((ret = wc_AesSetKey(&eax->aes,
14568
                            key,
14569
                            keySz,
14570
                            NULL,
14571
                            AES_ENCRYPTION)) != 0) {
14572
        goto out;
14573
    }
14574
14575
    /*
14576
    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
14577
    *   N' = OMAC^0_K(N)
14578
    */
14579
    if ((ret = wc_InitCmac(&eax->nonceCmac,
14580
                           key,
14581
                           keySz,
14582
                           WC_CMAC_AES,
14583
                           NULL)) != 0) {
14584
        return ret;
14585
    }
14586
    nonceCmacInited = 1;
14587
14588
    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
14589
                             eax->prefixBuf,
14590
                             sizeof(eax->prefixBuf))) != 0) {
14591
        goto out;
14592
    }
14593
14594
    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
14595
        goto out;
14596
    }
14597
14598
    cmacSize = WC_AES_BLOCK_SIZE;
14599
    if ((ret = wc_CmacFinal(&eax->nonceCmac,
14600
                            eax->nonceCmacFinal,
14601
                            &cmacSize)) != 0) {
14602
        goto out;
14603
    }
14604
14605
    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
14606
        goto out;
14607
    }
14608
14609
    /*
14610
     * start the OMAC used to build the auth tag chunk for the AD .
14611
     * This CMAC is continued in subsequent update calls when more auth data is
14612
     * provided
14613
     *   H' = OMAC^1_K(H)
14614
     */
14615
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 1;
14616
    if ((ret = wc_InitCmac(&eax->aadCmac,
14617
                           key,
14618
                           keySz,
14619
                           WC_CMAC_AES,
14620
                           NULL)) != 0) {
14621
        goto out;
14622
    }
14623
    aadCmacInited = 1;
14624
14625
    if ((ret = wc_CmacUpdate(&eax->aadCmac,
14626
                             eax->prefixBuf,
14627
                             sizeof(eax->prefixBuf))) != 0) {
14628
        goto out;
14629
    }
14630
14631
    if (authIn != NULL) {
14632
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
14633
            goto out;
14634
        }
14635
    }
14636
14637
    /*
14638
     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
14639
     * updated in subsequent calls to encrypt/decrypt
14640
     *  C' = OMAC^2_K(C)
14641
     */
14642
    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 2;
14643
    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
14644
                           key,
14645
                           keySz,
14646
                           WC_CMAC_AES,
14647
                           NULL)) != 0) {
14648
        goto out;
14649
    }
14650
14651
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
14652
                             eax->prefixBuf,
14653
                             sizeof(eax->prefixBuf))) != 0) {
14654
        goto out;
14655
    }
14656
14657
out:
14658
14659
    if (ret != 0) {
14660
        if (aesInited)
14661
            wc_AesFree(&eax->aes);
14662
        if (nonceCmacInited)
14663
            wc_CmacFree(&eax->nonceCmac);
14664
        if (aadCmacInited)
14665
            wc_CmacFree(&eax->aadCmac);
14666
    }
14667
14668
    return ret;
14669
}
14670
14671
14672
/*
14673
 * AES EAX Incremental API:
14674
 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
14675
 * the authentication stream
14676
 *
14677
 * Returns 0 on success
14678
 * Returns error code on failure
14679
 */
14680
int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
14681
                            const byte* in, word32 inSz,
14682
                            const byte* authIn, word32 authInSz)
14683
{
14684
    int ret;
14685
14686
    if (eax == NULL || out == NULL ||  in == NULL) {
14687
        return BAD_FUNC_ARG;
14688
    }
14689
14690
    /*
14691
     * Encrypt the plaintext using AES CTR
14692
     *  C = CTR(M)
14693
     */
14694
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
14695
        return ret;
14696
    }
14697
14698
    /*
14699
     * update OMAC with new ciphertext
14700
     *  C' = OMAC^2_K(C)
14701
     */
14702
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
14703
        return ret;
14704
    }
14705
14706
    /* If there exists new auth data, update the OMAC for that as well */
14707
    if (authIn != NULL) {
14708
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
14709
            return ret;
14710
        }
14711
    }
14712
14713
    return 0;
14714
}
14715
14716
14717
/*
14718
 * AES EAX Incremental API:
14719
 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
14720
 * the authentication stream
14721
 *
14722
 * Returns 0 on success
14723
 * Returns error code on failure
14724
 */
14725
int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
14726
                            const byte* in, word32 inSz,
14727
                            const byte* authIn, word32 authInSz)
14728
{
14729
    int ret;
14730
14731
    if (eax == NULL || out == NULL ||  in == NULL) {
14732
        return BAD_FUNC_ARG;
14733
    }
14734
14735
    /*
14736
     * Decrypt the plaintext using AES CTR
14737
     *  C = CTR(M)
14738
     */
14739
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
14740
        return ret;
14741
    }
14742
14743
    /*
14744
     * update OMAC with new ciphertext
14745
     *  C' = OMAC^2_K(C)
14746
     */
14747
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
14748
        return ret;
14749
    }
14750
14751
    /* If there exists new auth data, update the OMAC for that as well */
14752
    if (authIn != NULL) {
14753
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
14754
            return ret;
14755
        }
14756
    }
14757
14758
    return 0;
14759
}
14760
14761
14762
/*
14763
 * AES EAX Incremental API:
14764
 * Provides additional auth data information to the authentication
14765
 * stream for an authenticated encryption or decryption operation
14766
 *
14767
 * Returns 0 on success
14768
 * Returns error code on failure
14769
 */
14770
int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
14771
{
14772
    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
14773
}
14774
14775
14776
/*
14777
 * AES EAX Incremental API:
14778
 * Finalizes the authenticated encryption operation, computing the auth tag
14779
 * over previously supplied auth data and computed ciphertext
14780
 *
14781
 * Returns 0 on success
14782
 * Returns error code on failure
14783
 */
14784
int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
14785
{
14786
    word32 cmacSize;
14787
    int ret;
14788
    word32 i;
14789
14790
    if (eax == NULL || authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE) {
14791
        return BAD_FUNC_ARG;
14792
    }
14793
14794
    /* Complete the OMAC for the ciphertext */
14795
    cmacSize = WC_AES_BLOCK_SIZE;
14796
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
14797
                                  eax->ciphertextCmacFinal,
14798
                                  &cmacSize)) != 0) {
14799
        return ret;
14800
    }
14801
14802
    /* Complete the OMAC for auth data */
14803
    cmacSize = WC_AES_BLOCK_SIZE;
14804
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
14805
                                  eax->aadCmacFinal,
14806
                                  &cmacSize)) != 0) {
14807
        return ret;
14808
    }
14809
14810
    /*
14811
     * Concatenate all three auth tag chunks into the final tag, truncating
14812
     * at the specified tag length
14813
     *   T = Tag [first authTagSz bytes]
14814
     */
14815
    for (i = 0; i < authTagSz; i++) {
14816
        authTag[i] = eax->nonceCmacFinal[i]
14817
                    ^ eax->aadCmacFinal[i]
14818
                    ^ eax->ciphertextCmacFinal[i];
14819
    }
14820
14821
    return 0;
14822
}
14823
14824
14825
/*
14826
 * AES EAX Incremental API:
14827
 * Finalizes the authenticated decryption operation, computing the auth tag
14828
 * for the previously supplied auth data and cipher text and validating it
14829
 * against a provided auth tag
14830
 *
14831
 * Returns 0 on success
14832
 * Return error code for failure
14833
 */
14834
int wc_AesEaxDecryptFinal(AesEax* eax,
14835
                          const byte* authIn, word32 authInSz)
14836
{
14837
    int ret;
14838
    word32 i;
14839
    word32 cmacSize;
14840
14841
#if defined(WOLFSSL_SMALL_STACK)
14842
    byte *authTag;
14843
#else
14844
    byte authTag[WC_AES_BLOCK_SIZE];
14845
#endif
14846
14847
    if (eax == NULL || authIn == NULL || authInSz > WC_AES_BLOCK_SIZE) {
14848
        return BAD_FUNC_ARG;
14849
    }
14850
14851
    /* Complete the OMAC for the ciphertext */
14852
    cmacSize = WC_AES_BLOCK_SIZE;
14853
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
14854
                                  eax->ciphertextCmacFinal,
14855
                                  &cmacSize)) != 0) {
14856
        return ret;
14857
    }
14858
14859
    /* Complete the OMAC for auth data */
14860
    cmacSize = WC_AES_BLOCK_SIZE;
14861
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
14862
                                  eax->aadCmacFinal,
14863
                                  &cmacSize)) != 0) {
14864
        return ret;
14865
    }
14866
14867
#if defined(WOLFSSL_SMALL_STACK)
14868
    authTag = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14869
    if (authTag == NULL) {
14870
        return MEMORY_E;
14871
    }
14872
#endif
14873
14874
    /*
14875
     * Concatenate all three auth tag chunks into the final tag, truncating
14876
     * at the specified tag length
14877
     *   T = Tag [first authInSz bytes]
14878
     */
14879
    for (i = 0; i < authInSz; i++) {
14880
        authTag[i] = eax->nonceCmacFinal[i]
14881
                    ^ eax->aadCmacFinal[i]
14882
                    ^ eax->ciphertextCmacFinal[i];
14883
    }
14884
14885
    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
14886
        ret = AES_EAX_AUTH_E;
14887
    }
14888
    else {
14889
        ret = 0;
14890
    }
14891
14892
#if defined(WOLFSSL_SMALL_STACK)
14893
    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14894
#endif
14895
14896
    return ret;
14897
}
14898
14899
/*
14900
 * Frees the underlying CMAC and AES contexts. Must be called when done using
14901
 * the AES EAX context structure.
14902
 *
14903
 * Returns 0 on success
14904
 * Returns error code on failure
14905
 */
14906
int wc_AesEaxFree(AesEax* eax)
14907
{
14908
    if (eax == NULL) {
14909
        return BAD_FUNC_ARG;
14910
    }
14911
14912
    (void)wc_CmacFree(&eax->ciphertextCmac);
14913
    (void)wc_CmacFree(&eax->aadCmac);
14914
    wc_AesFree(&eax->aes);
14915
14916
    return 0;
14917
}
14918
14919
#endif /* WOLFSSL_AES_EAX */
14920
14921
#ifdef WOLFSSL_AES_CTS
14922
14923
14924
/* One-shot API */
14925
int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out,
14926
                     const byte* in, word32 inSz,
14927
                     const byte* iv)
14928
{
14929
#ifdef WOLFSSL_SMALL_STACK
14930
    Aes *aes = NULL;
14931
#else
14932
    Aes aes[1];
14933
#endif
14934
    int ret = 0;
14935
    word32 outSz = inSz;
14936
14937
    if (key == NULL || out == NULL || in == NULL || iv == NULL)
14938
        return BAD_FUNC_ARG;
14939
14940
#ifdef WOLFSSL_SMALL_STACK
14941
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
14942
#else
14943
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14944
#endif
14945
    if (ret == 0)
14946
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
14947
    if (ret == 0)
14948
        ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz);
14949
    if (ret == 0) {
14950
        out += outSz;
14951
        outSz = inSz - outSz;
14952
        ret = wc_AesCtsEncryptFinal(aes, out, &outSz);
14953
    }
14954
14955
#ifdef WOLFSSL_SMALL_STACK
14956
    wc_AesDelete(aes, NULL);
14957
#else
14958
    wc_AesFree(aes);
14959
#endif
14960
    return ret;
14961
}
14962
14963
int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out,
14964
                     const byte* in, word32 inSz,
14965
                     const byte* iv)
14966
{
14967
#ifdef WOLFSSL_SMALL_STACK
14968
    Aes *aes = NULL;
14969
#else
14970
    Aes aes[1];
14971
#endif
14972
    int ret = 0;
14973
    word32 outSz = inSz;
14974
14975
    if (key == NULL || out == NULL || in == NULL || iv == NULL) {
14976
        return BAD_FUNC_ARG;
14977
    }
14978
14979
#ifdef WOLFSSL_SMALL_STACK
14980
    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
14981
#else
14982
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14983
#endif
14984
    if (ret == 0)
14985
        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
14986
    if (ret == 0)
14987
        ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz);
14988
    if (ret == 0) {
14989
        out += outSz;
14990
        outSz = inSz - outSz;
14991
        ret = wc_AesCtsDecryptFinal(aes, out, &outSz);
14992
    }
14993
14994
#ifdef WOLFSSL_SMALL_STACK
14995
    wc_AesDelete(aes, NULL);
14996
#else
14997
    wc_AesFree(aes);
14998
#endif
14999
    return ret;
15000
}
15001
15002
static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz,
15003
                        const byte* in, word32 inSz, int enc)
15004
{
15005
    word32 blocks = 0;
15006
    int ret = 0;
15007
    word32 writtenSz = 0;
15008
    word32 tmpOutSz;
15009
15010
    if (aes == NULL || out == NULL || in == NULL || outSz == NULL)
15011
        return BAD_FUNC_ARG;
15012
15013
    /* Error out early for easy sanity check */
15014
    if (*outSz < inSz)
15015
        return BUFFER_E;
15016
    tmpOutSz = *outSz;
15017
15018
    /* We need to store last two blocks of plaintext */
15019
    if (aes->left > 0) {
15020
        word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left);
15021
        XMEMCPY(aes->ctsBlock + aes->left, in, copySz);
15022
        aes->left += copySz;
15023
        in += copySz;
15024
        inSz -= copySz;
15025
15026
        if (aes->left == WC_AES_BLOCK_SIZE * 2) {
15027
            if (inSz > WC_AES_BLOCK_SIZE) {
15028
                if (tmpOutSz < WC_AES_BLOCK_SIZE * 2)
15029
                    return BUFFER_E;
15030
                if (enc) {
15031
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
15032
                                           WC_AES_BLOCK_SIZE * 2);
15033
                }
15034
                else {
15035
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
15036
                                           WC_AES_BLOCK_SIZE * 2);
15037
                }
15038
                if (ret != 0)
15039
                    return ret;
15040
                out += WC_AES_BLOCK_SIZE * 2;
15041
                writtenSz += WC_AES_BLOCK_SIZE * 2;
15042
                tmpOutSz -= WC_AES_BLOCK_SIZE * 2;
15043
                aes->left = 0;
15044
            }
15045
            else if (inSz > 0) {
15046
                if (tmpOutSz < WC_AES_BLOCK_SIZE)
15047
                    return BUFFER_E;
15048
                if (enc) {
15049
                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
15050
                                           WC_AES_BLOCK_SIZE);
15051
                }
15052
                else {
15053
                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
15054
                                           WC_AES_BLOCK_SIZE);
15055
                }
15056
                if (ret != 0)
15057
                    return ret;
15058
                out += WC_AES_BLOCK_SIZE;
15059
                writtenSz += WC_AES_BLOCK_SIZE;
15060
                tmpOutSz -= WC_AES_BLOCK_SIZE;
15061
                /* Move the last block in ctsBlock to the beginning for
15062
                 * next operation */
15063
                XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE,
15064
                        WC_AES_BLOCK_SIZE);
15065
                XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz);
15066
                aes->left = WC_AES_BLOCK_SIZE + inSz;
15067
                *outSz = writtenSz;
15068
                return ret; /* Return the result of encryption */
15069
            }
15070
            else {
15071
                /* Can't output data as we need > 1 block for Final call */
15072
                *outSz = writtenSz;
15073
                return 0;
15074
            }
15075
        }
15076
        else {
15077
            /* All input has been absorbed into aes->ctsBlock */
15078
            *outSz = 0;
15079
            return 0;
15080
        }
15081
    }
15082
    if (inSz > WC_AES_BLOCK_SIZE) {
15083
        /* We need to store the last two full or partial blocks */
15084
        blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE;
15085
        blocks -= 2;
15086
    }
15087
    if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE)
15088
        return BUFFER_E;
15089
    if (enc)
15090
        ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
15091
    else
15092
        ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
15093
    in += blocks * WC_AES_BLOCK_SIZE;
15094
    inSz -= blocks * WC_AES_BLOCK_SIZE;
15095
    XMEMCPY(aes->ctsBlock, in, inSz);
15096
    aes->left = inSz;
15097
    writtenSz += blocks * WC_AES_BLOCK_SIZE;
15098
    *outSz = writtenSz;
15099
    return ret;
15100
}
15101
15102
/* Incremental API */
15103
int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz,
15104
                           const byte* in, word32 inSz)
15105
{
15106
    return AesCtsUpdate(aes, out, outSz, in, inSz, 1);
15107
}
15108
15109
int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz)
15110
{
15111
    int ret = 0;
15112
15113
    if (aes == NULL || out == NULL || outSz == NULL)
15114
        return BAD_FUNC_ARG;
15115
    if (*outSz < aes->left)
15116
        return BUFFER_E;
15117
15118
    /* Input must be at least two complete or partial blocks */
15119
    if (aes->left <= WC_AES_BLOCK_SIZE)
15120
        return BAD_FUNC_ARG;
15121
15122
    /* Zero padding */
15123
    XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left);
15124
15125
    ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock,
15126
                           WC_AES_BLOCK_SIZE * 2);
15127
    if (ret != 0)
15128
        return ret;
15129
15130
    XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
15131
    XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock,
15132
            aes->left - WC_AES_BLOCK_SIZE);
15133
    *outSz = aes->left;
15134
    return ret;
15135
}
15136
15137
int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz,
15138
                           const byte* in, word32 inSz)
15139
{
15140
    return AesCtsUpdate(aes, out, outSz, in, inSz, 0);
15141
}
15142
15143
int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz)
15144
{
15145
    int ret = 0;
15146
    byte iv[WC_AES_BLOCK_SIZE];
15147
    byte tmp[WC_AES_BLOCK_SIZE];
15148
    word32 partialSz;
15149
    word32 padSz;
15150
15151
    if (aes == NULL || out == NULL || outSz == NULL)
15152
        return BAD_FUNC_ARG;
15153
    if (*outSz < aes->left)
15154
        return BUFFER_E;
15155
15156
    /* Input must be at least two complete or partial blocks */
15157
    if (aes->left <= WC_AES_BLOCK_SIZE)
15158
        return BAD_FUNC_ARG;
15159
15160
    partialSz = aes->left - WC_AES_BLOCK_SIZE;
15161
    padSz = 2 * WC_AES_BLOCK_SIZE - aes->left;
15162
    /* Zero pad */
15163
    XMEMSET(aes->ctsBlock + aes->left, 0, padSz);
15164
15165
    /* Store IV */
15166
    XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE);
15167
    /* Load IV */
15168
    XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
15169
15170
    ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE);
15171
    if (ret != 0)
15172
        return ret;
15173
15174
    /* Write out partial block */
15175
    XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz);
15176
    /* Retrieve the padding */
15177
    XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz);
15178
    /* Restore IV */
15179
    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
15180
15181
    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE,
15182
                           WC_AES_BLOCK_SIZE);
15183
    if (ret != 0)
15184
        return ret;
15185
15186
    *outSz = aes->left;
15187
    return ret;
15188
}
15189
15190
#endif /* WOLFSSL_AES_CTS */
15191
15192
15193
#endif /* !NO_AES */